+++ /dev/null
-// Scintilla source code edit control
-/** @file Accessor.h
- ** Rapid easy access to contents of a Scintilla.
- **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
-
-class Accessor;
-
-typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
-
-/**
- * Interface to data in a Scintilla.
- */
-class Accessor {
-protected:
- enum {extremePosition=0x7FFFFFFF};
- /** @a bufferSize is a trade off between time taken to copy the characters
- * and retrieval overhead.
- * @a slopSize positions the buffer before the desired position
- * in case there is some backtracking. */
- enum {bufferSize=4000, slopSize=bufferSize/8};
- char buf[bufferSize+1];
- int startPos;
- int endPos;
- int codePage;
-
- virtual bool InternalIsLeadByte(char ch)=0;
- virtual void Fill(int position)=0;
-
-public:
- Accessor() : startPos(extremePosition), endPos(0), codePage(0) {}
- virtual ~Accessor() {}
- char operator[](int position) {
- if (position < startPos || position >= endPos) {
- Fill(position);
- }
- return buf[position - startPos];
- }
- /** Safe version of operator[], returning a defined value for invalid position. */
- char SafeGetCharAt(int position, char chDefault=' ') {
- if (position < startPos || position >= endPos) {
- Fill(position);
- if (position < startPos || position >= endPos) {
- // Position is outside range of document
- return chDefault;
- }
- }
- return buf[position - startPos];
- }
- bool IsLeadByte(char ch) {
- return codePage && InternalIsLeadByte(ch);
- }
- void SetCodePage(int codePage_) { codePage = codePage_; }
-
- virtual bool Match(int pos, const char *s)=0;
- virtual char StyleAt(int position)=0;
- virtual int GetLine(int position)=0;
- virtual int LineStart(int line)=0;
- virtual int LevelAt(int line)=0;
- virtual int Length()=0;
- virtual void Flush()=0;
- virtual int GetLineState(int line)=0;
- virtual int SetLineState(int line, int state)=0;
- virtual int GetPropertyInt(const char *key, int defaultValue=0)=0;
- virtual char *GetProperties()=0;
-
- // Style setting
- virtual void StartAt(unsigned int start, char chMask=31)=0;
- virtual void SetFlags(char chFlags_, char chWhile_)=0;
- virtual unsigned int GetStartSegment()=0;
- virtual void StartSegment(unsigned int pos)=0;
- virtual void ColourTo(unsigned int pos, int chAttr)=0;
- virtual void SetLevel(int line, int level)=0;
- virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0;
- virtual void IndicatorFill(int start, int end, int indicator, int value)=0;
-};
--- /dev/null
+// Scintilla source code edit control
+/** @file ILexer.h
+ ** Interface between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ILEXER_H
+#define ILEXER_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+#ifdef _WIN32
+ #define SCI_METHOD __stdcall
+#else
+ #define SCI_METHOD
+#endif
+
+enum { dvOriginal=0 };
+
+class IDocument {
+public:
+ virtual int SCI_METHOD Version() const = 0;
+ virtual void SCI_METHOD SetErrorStatus(int status) = 0;
+ virtual int SCI_METHOD Length() const = 0;
+ virtual void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const = 0;
+ virtual char SCI_METHOD StyleAt(int position) const = 0;
+ virtual int SCI_METHOD LineFromPosition(int position) const = 0;
+ virtual int SCI_METHOD LineStart(int line) const = 0;
+ virtual int SCI_METHOD GetLevel(int line) const = 0;
+ virtual int SCI_METHOD SetLevel(int line, int level) = 0;
+ virtual int SCI_METHOD GetLineState(int line) const = 0;
+ virtual int SCI_METHOD SetLineState(int line, int state) = 0;
+ virtual void SCI_METHOD StartStyling(int position, char mask) = 0;
+ virtual bool SCI_METHOD SetStyleFor(int length, char style) = 0;
+ virtual bool SCI_METHOD SetStyles(int length, const char *styles) = 0;
+ virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0;
+ virtual void SCI_METHOD DecorationFillRange(int position, int value, int fillLength) = 0;
+ virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0;
+ virtual int SCI_METHOD CodePage() const = 0;
+ virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0;
+ virtual const char * SCI_METHOD BufferPointer() = 0;
+ virtual int SCI_METHOD GetLineIndentation(int line) = 0;
+};
+
+enum { lvOriginal=0 };
+
+class ILexer {
+public:
+ virtual int SCI_METHOD Version() const = 0;
+ virtual void SCI_METHOD Release() = 0;
+ virtual const char * SCI_METHOD PropertyNames() = 0;
+ virtual int SCI_METHOD PropertyType(const char *name) = 0;
+ virtual const char * SCI_METHOD DescribeProperty(const char *name) = 0;
+ virtual int SCI_METHOD PropertySet(const char *key, const char *val) = 0;
+ virtual const char * SCI_METHOD DescribeWordListSets() = 0;
+ virtual int SCI_METHOD WordListSet(int n, const char *wl) = 0;
+ virtual void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ virtual void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0;
+};
+
+class ILoader {
+public:
+ virtual int SCI_METHOD Release() = 0;
+ // Returns a status code from SC_STATUS_*
+ virtual int SCI_METHOD AddData(char *data, int length) = 0;
+ virtual void * SCI_METHOD ConvertToDocument() = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
+++ /dev/null
-// Scintilla source code edit control
-/** @file KeyWords.h
- ** Colourise for particular languages.
- **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-/**
- */
-class WordList {
-public:
- // Each word contains at least one character - a empty word acts as sentinel at the end.
- char **words;
- char *list;
- int len;
- bool onlyLineEnds; ///< Delimited by any white space or only line ends
- bool sorted;
- int starts[256];
- WordList(bool onlyLineEnds_ = false) :
- words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
- sorted(false)
- {}
- ~WordList() { Clear(); }
- operator bool() { return len ? true : false; }
- void Clear();
- void Set(const char *s);
- bool InList(const char *s);
- bool InListAbbreviated(const char *s, const char marker);
-};
-
-typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler);
-
-/**
- * A LexerModule is responsible for lexing and folding a particular language.
- * The class maintains a list of LexerModules which can be searched to find a
- * module appropriate to a particular language.
- */
-class LexerModule {
-protected:
- const LexerModule *next;
- int language;
- LexerFunction fnLexer;
- LexerFunction fnFolder;
- const char * const * wordListDescriptions;
- int styleBits;
-
- static const LexerModule *base;
- static int nextLanguage;
-
-public:
- const char *languageName;
- LexerModule(int language_,
- LexerFunction fnLexer_,
- const char *languageName_=0,
- LexerFunction fnFolder_=0,
- const char * const wordListDescriptions_[] = NULL,
- int styleBits_=5);
- virtual ~LexerModule() {
- }
- int GetLanguage() const { return language; }
-
- // -1 is returned if no WordList information is available
- int GetNumWordLists() const;
- const char *GetWordListDescription(int index) const;
-
- int GetStyleBitsNeeded() const;
-
- virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- static const LexerModule *Find(int language);
- static const LexerModule *Find(const char *languageName);
-};
-
-#ifdef SCI_NAMESPACE
-}
-#endif
-
-/**
- * Check if a character is a space.
- * This is ASCII specific but is safe with chars >= 0x80.
- */
-inline bool isspacechar(unsigned char ch) {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
-inline bool iswordchar(char ch) {
- return isascii(ch) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-inline bool iswordstart(char ch) {
- return isascii(ch) && (isalnum(ch) || ch == '_');
-}
-
-inline bool isoperator(char ch) {
- if (isascii(ch) && isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
- ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
- ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
- ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
- ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
- ch == '?' || ch == '!' || ch == '.' || ch == '~')
- return true;
- return false;
-}
#define PLAT_GTK 0
#define PLAT_GTK_WIN32 0
+#define PLAT_GTK_MACOSX 0
#define PLAT_MACOSX 0
#define PLAT_WIN 0
#define PLAT_WX 0
+#define PLAT_QT 0
#define PLAT_FOX 0
#if defined(FOX)
#undef PLAT_WX
#define PLAT_WX 1
+#elif defined(SCINTILLA_QT)
+#undef PLAT_QT
+#define PLAT_QT 1
+
#elif defined(GTK)
#undef PLAT_GTK
#define PLAT_GTK 1
#define PLAT_GTK_WIN32 1
#endif
+#if defined(__APPLE__)
+#undef PLAT_GTK_MACOSX
+#define PLAT_GTK_MACOSX 1
+#endif
+
#elif defined(__APPLE__)
#undef PLAT_MACOSX
namespace Scintilla {
#endif
+typedef float XYPOSITION;
+typedef double XYACCUMULATOR;
+//#define XYPOSITION int
+
// Underlying the implementation of the platform classes are platform specific types.
// Sometimes these need to be passed around by client code so they are defined here
*/
class Point {
public:
- int x;
- int y;
+ XYPOSITION x;
+ XYPOSITION y;
- explicit Point(int x_=0, int y_=0) : x(x_), y(y_) {
+ explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) {
}
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
*/
class PRectangle {
public:
- int left;
- int top;
- int right;
- int bottom;
+ XYPOSITION left;
+ XYPOSITION top;
+ XYPOSITION right;
+ XYPOSITION bottom;
- PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) :
+ PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) :
left(left_), top(top_), right(right_), bottom(bottom_) {
}
return (right > other.left) && (left < other.right) &&
(bottom > other.top) && (top < other.bottom);
}
- void Move(int xDelta, int yDelta) {
+ void Move(XYPOSITION xDelta, XYPOSITION yDelta) {
left += xDelta;
top += yDelta;
right += xDelta;
bottom += yDelta;
}
- int Width() { return right - left; }
- int Height() { return bottom - top; }
+ XYPOSITION Width() { return right - left; }
+ XYPOSITION Height() { return bottom - top; }
bool Empty() {
return (Height() <= 0) || (Width() <= 0);
}
};
-/**
- * In some circumstances, including Win32 in paletted mode and GTK+, each colour
- * must be allocated before use. The desired colours are held in the ColourDesired class,
- * and after allocation the allocation entry is stored in the ColourAllocated class. In other
- * circumstances, such as Win32 in true colour mode, the allocation process just copies
- * the RGB values from the desired to the allocated class.
- * As each desired colour requires allocation before it can be used, the ColourPair class
- * holds both a ColourDesired and a ColourAllocated
- * The Palette class is responsible for managing the palette of colours which contains a
- * list of ColourPair objects and performs the allocation.
- */
-
/**
* Holds a desired RGB colour.
*/
};
/**
- * Holds an allocated RGB colour which may be an approximation to the desired colour.
- */
-class ColourAllocated {
- long coAllocated;
-
-public:
-
- ColourAllocated(long lcol=0) {
- coAllocated = lcol;
- }
-
- void Set(long lcol) {
- coAllocated = lcol;
- }
-
- long AsLong() const {
- return coAllocated;
- }
-};
-
-/**
- * Colour pairs hold a desired colour and an allocated colour.
+ * Font management.
*/
-struct ColourPair {
- ColourDesired desired;
- ColourAllocated allocated;
- ColourPair(ColourDesired desired_=ColourDesired(0,0,0)) {
- desired = desired_;
- allocated.Set(desired.AsLong());
- }
- void Copy() {
- allocated.Set(desired.AsLong());
+struct FontParameters {
+ const char *faceName;
+ float size;
+ int weight;
+ bool italic;
+ int extraFontFlag;
+ int technology;
+ int characterSet;
+
+ FontParameters(
+ const char *faceName_,
+ float size_=10,
+ int weight_=400,
+ bool italic_=false,
+ int extraFontFlag_=0,
+ int technology_=0,
+ int characterSet_=0) :
+
+ faceName(faceName_),
+ size(size_),
+ weight(weight_),
+ italic(italic_),
+ extraFontFlag(extraFontFlag_),
+ technology(technology_),
+ characterSet(characterSet_)
+ {
}
-};
-
-class Window; // Forward declaration for Palette
-
-/**
- * Colour palette management.
- */
-class Palette {
- int used;
- int size;
- ColourPair *entries;
-#if PLAT_GTK
- void *allocatedPalette; // GdkColor *
- int allocatedLen;
-#endif
- // Private so Palette objects can not be copied
- Palette(const Palette &) {}
- Palette &operator=(const Palette &) { return *this; }
-public:
-#if PLAT_WIN
- void *hpal;
-#endif
- bool allowRealization;
-
- Palette();
- ~Palette();
- void Release();
-
- /**
- * This method either adds a colour to the list of wanted colours (want==true)
- * or retrieves the allocated colour back to the ColourPair.
- * This is one method to make it easier to keep the code for wanting and retrieving in sync.
- */
- void WantFind(ColourPair &cp, bool want);
-
- void Allocate(Window &w);
};
-/**
- * Font management.
- */
class Font {
protected:
FontID fid;
int ascent;
#endif
// Private so Font objects can not be copied
- Font(const Font &) {}
- Font &operator=(const Font &) { fid=0; return *this; }
+ Font(const Font &);
+ Font &operator=(const Font &);
public:
Font();
virtual ~Font();
- virtual void Create(const char *faceName, int characterSet, int size,
- bool bold, bool italic, int extraFontFlag=0);
+ virtual void Create(const FontParameters &fp);
virtual void Release();
FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
+#if PLAT_WX
+ void SetAscent(int ascent_) { ascent = ascent_; }
+#endif
friend class Surface;
- friend class SurfaceImpl;
+ friend class SurfaceImpl;
};
/**
Surface(const Surface &) {}
Surface &operator=(const Surface &) { return *this; }
public:
- Surface() {};
- virtual ~Surface() {};
- static Surface *Allocate();
+ Surface() {}
+ virtual ~Surface() {}
+ static Surface *Allocate(int technology);
virtual void Init(WindowID wid)=0;
virtual void Init(SurfaceID sid, WindowID wid)=0;
virtual void Release()=0;
virtual bool Initialised()=0;
- virtual void PenColour(ColourAllocated fore)=0;
+ virtual void PenColour(ColourDesired fore)=0;
virtual int LogPixelsY()=0;
virtual int DeviceHeightFont(int points)=0;
virtual void MoveTo(int x_, int y_)=0;
virtual void LineTo(int x_, int y_)=0;
- virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0;
- virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
- virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0;
+ virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back)=0;
+ virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
+ virtual void FillRectangle(PRectangle rc, ColourDesired back)=0;
virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0;
- virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
- virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
- ColourAllocated outline, int alphaOutline, int flags)=0;
- virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
+ virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
+ virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill,
+ ColourDesired outline, int alphaOutline, int flags)=0;
+ virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
+ virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
- virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
- virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
- virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0;
- virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0;
- virtual int WidthText(Font &font_, const char *s, int len)=0;
- virtual int WidthChar(Font &font_, char ch)=0;
- virtual int Ascent(Font &font_)=0;
- virtual int Descent(Font &font_)=0;
- virtual int InternalLeading(Font &font_)=0;
- virtual int ExternalLeading(Font &font_)=0;
- virtual int Height(Font &font_)=0;
- virtual int AverageCharWidth(Font &font_)=0;
-
- virtual int SetPalette(Palette *pal, bool inBackGround)=0;
+ virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
+ virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
+ virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0;
+ virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0;
+ virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0;
+ virtual XYPOSITION WidthChar(Font &font_, char ch)=0;
+ virtual XYPOSITION Ascent(Font &font_)=0;
+ virtual XYPOSITION Descent(Font &font_)=0;
+ virtual XYPOSITION InternalLeading(Font &font_)=0;
+ virtual XYPOSITION ExternalLeading(Font &font_)=0;
+ virtual XYPOSITION Height(Font &font_)=0;
+ virtual XYPOSITION AverageCharWidth(Font &font_)=0;
+
virtual void SetClip(PRectangle rc)=0;
virtual void FlushCachedState()=0;
void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX
- void SetWindow(void *ref) { windowRef = ref; };
- void SetControl(void *_control) { control = _control; };
+ void SetWindow(void *ref) { windowRef = ref; }
+ void SetControl(void *_control) { control = _control; }
#endif
private:
Cursor cursorLast;
static ListBox *Allocate();
virtual void SetFont(Font &font)=0;
- virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0;
+ virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0;
virtual void SetAverageCharWidth(int width)=0;
virtual void SetVisibleRows(int rows)=0;
virtual int GetVisibleRows() const=0;
virtual int Find(const char *prefix)=0;
virtual void GetValue(int n, char *value, int len)=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
+ virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
virtual void SetList(const char* list, char separator, char typesep)=0;
*/
class DynamicLibrary {
public:
- virtual ~DynamicLibrary() {};
+ virtual ~DynamicLibrary() {}
/// @return Pointer to function "name", or NULL on failure.
virtual Function FindFunction(const char *name) = 0;
#pragma warning(disable: 4244 4309 4514 4710)
#endif
+#if defined(__GNUC__) && defined(SCINTILLA_QT)
+#pragma GCC diagnostic ignored "-Wmissing-braces"
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#pragma GCC diagnostic ignored "-Wchar-subscripts"
+#endif
+
#endif
+++ /dev/null
-// Scintilla source code edit control
-/** @file PropSet.h
- ** An interface to the methods needed for access to property sets inside lexers.
- **/
-// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#ifndef PROPSET_H
-#define PROPSET_H
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-class PropertyGet {
-public:
- virtual char *ToString() const=0; // Caller must delete[] the return value
- virtual int GetInt(const char *key, int defaultValue=0) const=0;
- virtual ~PropertyGet() {}
-};
-
-#ifdef SCI_NAMESPACE
-}
-#endif
-
-#endif
+++ /dev/null
-// SciTE - Scintilla based Text Editor
-/** @file SString.h
- ** A simple string class.
- **/
-// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#ifndef SSTRING_H
-#define SSTRING_H
-
-
-// These functions are implemented because each platform calls them something different.
-int CompareCaseInsensitive(const char *a, const char *b);
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
-bool EqualCaseInsensitive(const char *a, const char *b);
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-// Define another string class.
-// While it would be 'better' to use std::string, that doubles the executable size.
-// An SString may contain embedded nul characters.
-
-/**
- * Base class from which the two other classes (SBuffer & SString)
- * are derived.
- */
-class SContainer {
-public:
- /** Type of string lengths (sizes) and positions (indexes). */
- typedef size_t lenpos_t;
- /** Out of bounds value indicating that the string argument should be measured. */
- enum { measure_length=0xffffffffU};
-
-protected:
- char *s; ///< The C string
- lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
-
- SContainer() : s(0), sSize(0) {}
- ~SContainer() {
- delete []s; // Suppose it was allocated using StringAllocate
- s = 0;
- sSize = 0;
- }
- /** Size of buffer. */
- lenpos_t size() const {
- if (s) {
- return sSize;
- } else {
- return 0;
- }
- }
-public:
- /**
- * Allocate uninitialized memory big enough to fit a string of the given length.
- * @return the pointer to the new string
- */
- static char *StringAllocate(lenpos_t len);
- /**
- * Duplicate a buffer/C string.
- * Allocate memory of the given size, or big enough to fit the string if length isn't given;
- * then copy the given string in the allocated memory.
- * @return the pointer to the new string
- */
- static char *StringAllocate(
- const char *s, ///< The string to duplicate
- lenpos_t len=measure_length); ///< The length of memory to allocate. Optional.
-};
-
-
-/**
- * @brief A string buffer class.
- *
- * Main use is to ask an API the length of a string it can provide,
- * then to allocate a buffer of the given size, and to provide this buffer
- * to the API to put the string.
- * This class is intended to be shortlived, to be transformed as SString
- * as soon as it holds the string, so it has little members.
- * Note: we assume the buffer is filled by the API. If the length can be shorter,
- * we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
- */
-class SBuffer : protected SContainer {
-public:
- SBuffer(lenpos_t len) {
- s = StringAllocate(len);
- if (s) {
- *s = '\0';
- sSize = len;
- } else {
- sSize = 0;
- }
- }
-private:
- /// Copy constructor
- // Here only to be on the safe size, user should avoid returning SBuffer values.
- SBuffer(const SBuffer &source) : SContainer() {
- s = StringAllocate(source.s, source.sSize);
- sSize = (s) ? source.sSize : 0;
- }
- /// Default assignment operator
- // Same here, shouldn't be used
- SBuffer &operator=(const SBuffer &source) {
- if (this != &source) {
- delete []s;
- s = StringAllocate(source.s, source.sSize);
- sSize = (s) ? source.sSize : 0;
- }
- return *this;
- }
-public:
- /** Provide direct read/write access to buffer. */
- char *ptr() {
- return s;
- }
- /** Ownership of the buffer have been taken, so release it. */
- void reset() {
- s = 0;
- sSize = 0;
- }
- /** Size of buffer. */
- lenpos_t size() const {
- return SContainer::size();
- }
-};
-
-
-/**
- * @brief A simple string class.
- *
- * Hold the length of the string for quick operations,
- * can have a buffer bigger than the string to avoid too many memory allocations and copies.
- * May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
- * functions to allow reliable manipulations of these strings, other than simple appends, etc.
- */
-class SString : protected SContainer {
- lenpos_t sLen; ///< The size of the string in s
- lenpos_t sizeGrowth; ///< Minimum growth size when appending strings
- enum { sizeGrowthDefault = 64 };
-
- bool grow(lenpos_t lenNew);
- SString &assign(const char *sOther, lenpos_t sSize_=measure_length);
-
-public:
- SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
- SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
- s = StringAllocate(source.s, source.sLen);
- sSize = sLen = (s) ? source.sLen : 0;
- }
- SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
- s = StringAllocate(s_);
- sSize = sLen = (s) ? strlen(s) : 0;
- }
- SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) {
- s = buf.ptr();
- sSize = sLen = buf.size();
- // Consumes the given buffer!
- buf.reset();
- }
- SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
- // note: expects the "last" argument to point one beyond the range end (a la STL iterators)
- s = StringAllocate(s_ + first, last - first);
- sSize = sLen = (s) ? last - first : 0;
- }
- SString(int i);
- SString(double d, int precision);
- ~SString() {
- sLen = 0;
- }
- void clear() {
- if (s) {
- *s = '\0';
- }
- sLen = 0;
- }
- /** Size of buffer. */
- lenpos_t size() const {
- return SContainer::size();
- }
- /** Size of string in buffer. */
- lenpos_t length() const {
- return sLen;
- }
- /** Read access to a character of the string. */
- char operator[](lenpos_t i) const {
- return (s && i < sSize) ? s[i] : '\0';
- }
- SString &operator=(const char *source) {
- return assign(source);
- }
- SString &operator=(const SString &source) {
- if (this != &source) {
- assign(source.s, source.sLen);
- }
- return *this;
- }
- bool operator==(const SString &sOther) const;
- bool operator!=(const SString &sOther) const {
- return !operator==(sOther);
- }
- bool operator==(const char *sOther) const;
- bool operator!=(const char *sOther) const {
- return !operator==(sOther);
- }
- bool contains(char ch) const {
- return (s && *s) ? strchr(s, ch) != 0 : false;
- }
- void setsizegrowth(lenpos_t sizeGrowth_) {
- sizeGrowth = sizeGrowth_;
- }
- const char *c_str() const {
- return s ? s : "";
- }
- /** Give ownership of buffer to caller which must use delete[] to free buffer. */
- char *detach() {
- char *sRet = s;
- s = 0;
- sSize = 0;
- sLen = 0;
- return sRet;
- }
- SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
- SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
- SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
- SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
- SString &operator+=(const char *sOther) {
- return append(sOther, static_cast<lenpos_t>(measure_length));
- }
- SString &operator+=(const SString &sOther) {
- return append(sOther.s, sOther.sLen);
- }
- SString &operator+=(char ch) {
- return append(&ch, 1);
- }
- SString &appendwithseparator(const char *sOther, char sep) {
- return append(sOther, strlen(sOther), sep);
- }
- SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);
-
- /**
- * Remove @a len characters from the @a pos position, included.
- * Characters at pos + len and beyond replace characters at pos.
- * If @a len is 0, or greater than the length of the string
- * starting at @a pos, the string is just truncated at @a pos.
- */
- void remove(lenpos_t pos, lenpos_t len);
-
- SString &change(lenpos_t pos, char ch) {
- if (pos < sLen) { // character changed must be in string bounds
- *(s + pos) = ch;
- }
- return *this;
- }
- /** Read an integral numeric value from the string. */
- int value() const {
- return s ? atoi(s) : 0;
- }
- bool startswith(const char *prefix);
- bool endswith(const char *suffix);
- int search(const char *sFind, lenpos_t start=0) const;
- bool contains(const char *sFind) const {
- return search(sFind) >= 0;
- }
- int substitute(char chFind, char chReplace);
- int substitute(const char *sFind, const char *sReplace);
- int remove(const char *sFind) {
- return substitute(sFind, "");
- }
-};
-
-
-/**
- * Duplicate a C string.
- * Allocate memory of the given size, or big enough to fit the string if length isn't given;
- * then copy the given string in the allocated memory.
- * @return the pointer to the new string
- */
-inline char *StringDup(
- const char *s, ///< The string to duplicate
- SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional.
-{
- return SContainer::StringAllocate(s, len);
-}
-
-#ifdef SCI_NAMESPACE
-}
-#endif
-
-#endif
#define SCLEX_NIMROD 96
#define SCLEX_SML 97
#define SCLEX_MARKDOWN 98
+#define SCLEX_TXT2TAGS 99
+#define SCLEX_A68K 100
+#define SCLEX_MODULA 101
+#define SCLEX_COFFEESCRIPT 102
+#define SCLEX_TCMD 103
+#define SCLEX_AVS 104
+#define SCLEX_ECL 105
+#define SCLEX_OSCRIPT 106
+#define SCLEX_VISUALPROLOG 107
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
#define SCE_C_COMMENTDOCKEYWORD 17
#define SCE_C_COMMENTDOCKEYWORDERROR 18
#define SCE_C_GLOBALCLASS 19
+#define SCE_C_STRINGRAW 20
+#define SCE_C_TRIPLEVERBATIM 21
+#define SCE_C_HASHQUOTEDSTRING 22
+#define SCE_C_PREPROCESSORCOMMENT 23
#define SCE_D_DEFAULT 0
#define SCE_D_COMMENT 1
#define SCE_D_COMMENTLINE 2
#define SCE_PL_SUB_PROTOTYPE 40
#define SCE_PL_FORMAT_IDENT 41
#define SCE_PL_FORMAT 42
+#define SCE_PL_STRING_VAR 43
+#define SCE_PL_XLAT 44
+#define SCE_PL_REGEX_VAR 54
+#define SCE_PL_REGSUBST_VAR 55
+#define SCE_PL_BACKTICKS_VAR 57
+#define SCE_PL_HERE_QQ_VAR 61
+#define SCE_PL_HERE_QX_VAR 62
+#define SCE_PL_STRING_QQ_VAR 64
+#define SCE_PL_STRING_QX_VAR 65
+#define SCE_PL_STRING_QR_VAR 66
#define SCE_RB_DEFAULT 0
#define SCE_RB_ERROR 1
#define SCE_RB_COMMENTLINE 2
#define SCE_L_TAG 2
#define SCE_L_MATH 3
#define SCE_L_COMMENT 4
+#define SCE_L_TAG2 5
+#define SCE_L_MATH2 6
+#define SCE_L_COMMENT2 7
+#define SCE_L_VERBATIM 8
+#define SCE_L_SHORTCMD 9
+#define SCE_L_SPECIAL 10
+#define SCE_L_CMDOPT 11
+#define SCE_L_ERROR 12
#define SCE_LUA_DEFAULT 0
#define SCE_LUA_COMMENT 1
#define SCE_LUA_COMMENTLINE 2
#define SCE_LUA_WORD6 17
#define SCE_LUA_WORD7 18
#define SCE_LUA_WORD8 19
+#define SCE_LUA_LABEL 20
#define SCE_ERR_DEFAULT 0
#define SCE_ERR_PYTHON 1
#define SCE_ERR_GCC 2
#define SCE_BAT_COMMAND 5
#define SCE_BAT_IDENTIFIER 6
#define SCE_BAT_OPERATOR 7
+#define SCE_TCMD_DEFAULT 0
+#define SCE_TCMD_COMMENT 1
+#define SCE_TCMD_WORD 2
+#define SCE_TCMD_LABEL 3
+#define SCE_TCMD_HIDE 4
+#define SCE_TCMD_COMMAND 5
+#define SCE_TCMD_IDENTIFIER 6
+#define SCE_TCMD_OPERATOR 7
+#define SCE_TCMD_ENVIRONMENT 8
+#define SCE_TCMD_EXPANSION 9
+#define SCE_TCMD_CLABEL 10
#define SCE_MAKE_DEFAULT 0
#define SCE_MAKE_COMMENT 1
#define SCE_MAKE_PREPROCESSOR 2
#define SCE_ASM_CHARACTER 12
#define SCE_ASM_STRINGEOL 13
#define SCE_ASM_EXTINSTRUCTION 14
+#define SCE_ASM_COMMENTDIRECTIVE 15
#define SCE_F_DEFAULT 0
#define SCE_F_COMMENT 1
#define SCE_F_NUMBER 2
#define SCE_CSS_EXTENDED_IDENTIFIER 19
#define SCE_CSS_EXTENDED_PSEUDOCLASS 20
#define SCE_CSS_EXTENDED_PSEUDOELEMENT 21
+#define SCE_CSS_MEDIA 22
+#define SCE_CSS_VARIABLE 23
#define SCE_POV_DEFAULT 0
#define SCE_POV_COMMENT 1
#define SCE_POV_COMMENTLINE 2
#define SCE_FS_DATE 16
#define SCE_FS_STRINGEOL 17
#define SCE_FS_CONSTANT 18
-#define SCE_FS_ASM 19
-#define SCE_FS_LABEL 20
-#define SCE_FS_ERROR 21
-#define SCE_FS_HEXNUMBER 22
-#define SCE_FS_BINNUMBER 23
+#define SCE_FS_WORDOPERATOR 19
+#define SCE_FS_DISABLEDCODE 20
+#define SCE_FS_DEFAULT_C 21
+#define SCE_FS_COMMENTDOC_C 22
+#define SCE_FS_COMMENTLINEDOC_C 23
+#define SCE_FS_KEYWORD_C 24
+#define SCE_FS_KEYWORD2_C 25
+#define SCE_FS_NUMBER_C 26
+#define SCE_FS_STRING_C 27
+#define SCE_FS_PREPROCESSOR_C 28
+#define SCE_FS_OPERATOR_C 29
+#define SCE_FS_IDENTIFIER_C 30
+#define SCE_FS_STRINGEOL_C 31
#define SCE_CSOUND_DEFAULT 0
#define SCE_CSOUND_COMMENT 1
#define SCE_CSOUND_NUMBER 2
#define SCE_POWERSHELL_KEYWORD 8
#define SCE_POWERSHELL_CMDLET 9
#define SCE_POWERSHELL_ALIAS 10
+#define SCE_POWERSHELL_FUNCTION 11
+#define SCE_POWERSHELL_USER1 12
+#define SCE_POWERSHELL_COMMENTSTREAM 13
#define SCE_MYSQL_DEFAULT 0
#define SCE_MYSQL_COMMENT 1
#define SCE_MYSQL_COMMENTLINE 2
#define SCE_MARKDOWN_CODE 19
#define SCE_MARKDOWN_CODE2 20
#define SCE_MARKDOWN_CODEBK 21
+#define SCE_TXT2TAGS_DEFAULT 0
+#define SCE_TXT2TAGS_LINE_BEGIN 1
+#define SCE_TXT2TAGS_STRONG1 2
+#define SCE_TXT2TAGS_STRONG2 3
+#define SCE_TXT2TAGS_EM1 4
+#define SCE_TXT2TAGS_EM2 5
+#define SCE_TXT2TAGS_HEADER1 6
+#define SCE_TXT2TAGS_HEADER2 7
+#define SCE_TXT2TAGS_HEADER3 8
+#define SCE_TXT2TAGS_HEADER4 9
+#define SCE_TXT2TAGS_HEADER5 10
+#define SCE_TXT2TAGS_HEADER6 11
+#define SCE_TXT2TAGS_PRECHAR 12
+#define SCE_TXT2TAGS_ULIST_ITEM 13
+#define SCE_TXT2TAGS_OLIST_ITEM 14
+#define SCE_TXT2TAGS_BLOCKQUOTE 15
+#define SCE_TXT2TAGS_STRIKEOUT 16
+#define SCE_TXT2TAGS_HRULE 17
+#define SCE_TXT2TAGS_LINK 18
+#define SCE_TXT2TAGS_CODE 19
+#define SCE_TXT2TAGS_CODE2 20
+#define SCE_TXT2TAGS_CODEBK 21
+#define SCE_TXT2TAGS_COMMENT 22
+#define SCE_TXT2TAGS_OPTION 23
+#define SCE_TXT2TAGS_PREPROC 24
+#define SCE_TXT2TAGS_POSTPROC 25
+#define SCE_A68K_DEFAULT 0
+#define SCE_A68K_COMMENT 1
+#define SCE_A68K_NUMBER_DEC 2
+#define SCE_A68K_NUMBER_BIN 3
+#define SCE_A68K_NUMBER_HEX 4
+#define SCE_A68K_STRING1 5
+#define SCE_A68K_OPERATOR 6
+#define SCE_A68K_CPUINSTRUCTION 7
+#define SCE_A68K_EXTINSTRUCTION 8
+#define SCE_A68K_REGISTER 9
+#define SCE_A68K_DIRECTIVE 10
+#define SCE_A68K_MACRO_ARG 11
+#define SCE_A68K_LABEL 12
+#define SCE_A68K_STRING2 13
+#define SCE_A68K_IDENTIFIER 14
+#define SCE_A68K_MACRO_DECLARATION 15
+#define SCE_A68K_COMMENT_WORD 16
+#define SCE_A68K_COMMENT_SPECIAL 17
+#define SCE_A68K_COMMENT_DOXYGEN 18
+#define SCE_MODULA_DEFAULT 0
+#define SCE_MODULA_COMMENT 1
+#define SCE_MODULA_DOXYCOMM 2
+#define SCE_MODULA_DOXYKEY 3
+#define SCE_MODULA_KEYWORD 4
+#define SCE_MODULA_RESERVED 5
+#define SCE_MODULA_NUMBER 6
+#define SCE_MODULA_BASENUM 7
+#define SCE_MODULA_FLOAT 8
+#define SCE_MODULA_STRING 9
+#define SCE_MODULA_STRSPEC 10
+#define SCE_MODULA_CHAR 11
+#define SCE_MODULA_CHARSPEC 12
+#define SCE_MODULA_PROC 13
+#define SCE_MODULA_PRAGMA 14
+#define SCE_MODULA_PRGKEY 15
+#define SCE_MODULA_OPERATOR 16
+#define SCE_MODULA_BADSTR 17
+#define SCE_COFFEESCRIPT_DEFAULT 0
+#define SCE_COFFEESCRIPT_COMMENT 1
+#define SCE_COFFEESCRIPT_COMMENTLINE 2
+#define SCE_COFFEESCRIPT_COMMENTDOC 3
+#define SCE_COFFEESCRIPT_NUMBER 4
+#define SCE_COFFEESCRIPT_WORD 5
+#define SCE_COFFEESCRIPT_STRING 6
+#define SCE_COFFEESCRIPT_CHARACTER 7
+#define SCE_COFFEESCRIPT_UUID 8
+#define SCE_COFFEESCRIPT_PREPROCESSOR 9
+#define SCE_COFFEESCRIPT_OPERATOR 10
+#define SCE_COFFEESCRIPT_IDENTIFIER 11
+#define SCE_COFFEESCRIPT_STRINGEOL 12
+#define SCE_COFFEESCRIPT_VERBATIM 13
+#define SCE_COFFEESCRIPT_REGEX 14
+#define SCE_COFFEESCRIPT_COMMENTLINEDOC 15
+#define SCE_COFFEESCRIPT_WORD2 16
+#define SCE_COFFEESCRIPT_COMMENTDOCKEYWORD 17
+#define SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR 18
+#define SCE_COFFEESCRIPT_GLOBALCLASS 19
+#define SCE_COFFEESCRIPT_STRINGRAW 20
+#define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21
+#define SCE_COFFEESCRIPT_HASHQUOTEDSTRING 22
+#define SCE_COFFEESCRIPT_COMMENTBLOCK 22
+#define SCE_COFFEESCRIPT_VERBOSE_REGEX 23
+#define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24
+#define SCE_AVS_DEFAULT 0
+#define SCE_AVS_COMMENTBLOCK 1
+#define SCE_AVS_COMMENTBLOCKN 2
+#define SCE_AVS_COMMENTLINE 3
+#define SCE_AVS_NUMBER 4
+#define SCE_AVS_OPERATOR 5
+#define SCE_AVS_IDENTIFIER 6
+#define SCE_AVS_STRING 7
+#define SCE_AVS_TRIPLESTRING 8
+#define SCE_AVS_KEYWORD 9
+#define SCE_AVS_FILTER 10
+#define SCE_AVS_PLUGIN 11
+#define SCE_AVS_FUNCTION 12
+#define SCE_AVS_CLIPPROP 13
+#define SCE_AVS_USERDFN 14
+#define SCE_ECL_DEFAULT 0
+#define SCE_ECL_COMMENT 1
+#define SCE_ECL_COMMENTLINE 2
+#define SCE_ECL_NUMBER 3
+#define SCE_ECL_STRING 4
+#define SCE_ECL_WORD0 5
+#define SCE_ECL_OPERATOR 6
+#define SCE_ECL_CHARACTER 7
+#define SCE_ECL_UUID 8
+#define SCE_ECL_PREPROCESSOR 9
+#define SCE_ECL_UNKNOWN 10
+#define SCE_ECL_IDENTIFIER 11
+#define SCE_ECL_STRINGEOL 12
+#define SCE_ECL_VERBATIM 13
+#define SCE_ECL_REGEX 14
+#define SCE_ECL_COMMENTLINEDOC 15
+#define SCE_ECL_WORD1 16
+#define SCE_ECL_COMMENTDOCKEYWORD 17
+#define SCE_ECL_COMMENTDOCKEYWORDERROR 18
+#define SCE_ECL_WORD2 19
+#define SCE_ECL_WORD3 20
+#define SCE_ECL_WORD4 21
+#define SCE_ECL_WORD5 22
+#define SCE_ECL_COMMENTDOC 23
+#define SCE_ECL_ADDED 24
+#define SCE_ECL_DELETED 25
+#define SCE_ECL_CHANGED 26
+#define SCE_ECL_MOVED 27
+#define SCE_OSCRIPT_DEFAULT 0
+#define SCE_OSCRIPT_LINE_COMMENT 1
+#define SCE_OSCRIPT_BLOCK_COMMENT 2
+#define SCE_OSCRIPT_DOC_COMMENT 3
+#define SCE_OSCRIPT_PREPROCESSOR 4
+#define SCE_OSCRIPT_NUMBER 5
+#define SCE_OSCRIPT_SINGLEQUOTE_STRING 6
+#define SCE_OSCRIPT_DOUBLEQUOTE_STRING 7
+#define SCE_OSCRIPT_CONSTANT 8
+#define SCE_OSCRIPT_IDENTIFIER 9
+#define SCE_OSCRIPT_GLOBAL 10
+#define SCE_OSCRIPT_KEYWORD 11
+#define SCE_OSCRIPT_OPERATOR 12
+#define SCE_OSCRIPT_LABEL 13
+#define SCE_OSCRIPT_TYPE 14
+#define SCE_OSCRIPT_FUNCTION 15
+#define SCE_OSCRIPT_OBJECT 16
+#define SCE_OSCRIPT_PROPERTY 17
+#define SCE_OSCRIPT_METHOD 18
+#define SCE_VISUALPROLOG_DEFAULT 0
+#define SCE_VISUALPROLOG_KEY_MAJOR 1
+#define SCE_VISUALPROLOG_KEY_MINOR 2
+#define SCE_VISUALPROLOG_KEY_DIRECTIVE 3
+#define SCE_VISUALPROLOG_COMMENT_BLOCK 4
+#define SCE_VISUALPROLOG_COMMENT_LINE 5
+#define SCE_VISUALPROLOG_COMMENT_KEY 6
+#define SCE_VISUALPROLOG_COMMENT_KEY_ERROR 7
+#define SCE_VISUALPROLOG_IDENTIFIER 8
+#define SCE_VISUALPROLOG_VARIABLE 9
+#define SCE_VISUALPROLOG_ANONYMOUS 10
+#define SCE_VISUALPROLOG_NUMBER 11
+#define SCE_VISUALPROLOG_OPERATOR 12
+#define SCE_VISUALPROLOG_CHARACTER 13
+#define SCE_VISUALPROLOG_CHARACTER_TOO_MANY 14
+#define SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR 15
+#define SCE_VISUALPROLOG_STRING 16
+#define SCE_VISUALPROLOG_STRING_ESCAPE 17
+#define SCE_VISUALPROLOG_STRING_ESCAPE_ERROR 18
+#define SCE_VISUALPROLOG_STRING_EOL_OPEN 19
+#define SCE_VISUALPROLOG_STRING_VERBATIM 20
+#define SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL 21
+#define SCE_VISUALPROLOG_STRING_VERBATIM_EOL 22
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
#endif
#ifndef SCINTILLA_H
#define SCINTILLA_H
-#if defined(LCCWIN) && LCCWIN
-typedef BOOL bool;
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-#if PLAT_WIN
+#if defined(_WIN32)
/* Return false on failure: */
-bool Scintilla_RegisterClasses(void *hInstance);
-bool Scintilla_ReleaseResources();
+int Scintilla_RegisterClasses(void *hInstance);
+int Scintilla_ReleaseResources();
#endif
int Scintilla_LinkLexers();
#define SCI_ADDSTYLEDTEXT 2002
#define SCI_INSERTTEXT 2003
#define SCI_CLEARALL 2004
+#define SCI_DELETERANGE 2645
#define SCI_CLEARDOCUMENTSTYLE 2005
#define SCI_GETLENGTH 2006
#define SCI_GETCHARAT 2007
#define SCI_SETTABWIDTH 2036
#define SCI_GETTABWIDTH 2121
#define SC_CP_UTF8 65001
-#define SC_CP_DBCS 1
#define SCI_SETCODEPAGE 2037
-#define SCI_SETUSEPALETTE 2039
#define MARKER_MAX 31
#define SC_MARK_CIRCLE 0
#define SC_MARK_ROUNDRECT 1
#define SC_MARK_LEFTRECT 27
#define SC_MARK_AVAILABLE 28
#define SC_MARK_UNDERLINE 29
+#define SC_MARK_RGBAIMAGE 30
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
#define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042
+#define SCI_MARKERSETBACKSELECTED 2292
+#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045
#define SCI_GETMARGINMASKN 2245
#define SCI_SETMARGINSENSITIVEN 2246
#define SCI_GETMARGINSENSITIVEN 2247
+#define SCI_SETMARGINCURSORN 2248
+#define SCI_GETMARGINCURSORN 2249
#define STYLE_DEFAULT 32
#define STYLE_LINENUMBER 33
#define STYLE_BRACELIGHT 34
#define SCI_STYLEGETCHANGEABLE 2492
#define SCI_STYLEGETHOTSPOT 2493
#define SCI_STYLESETCASE 2060
+#define SC_FONT_SIZE_MULTIPLIER 100
+#define SCI_STYLESETSIZEFRACTIONAL 2061
+#define SCI_STYLEGETSIZEFRACTIONAL 2062
+#define SC_WEIGHT_NORMAL 400
+#define SC_WEIGHT_SEMIBOLD 600
+#define SC_WEIGHT_BOLD 700
+#define SCI_STYLESETWEIGHT 2063
+#define SCI_STYLEGETWEIGHT 2064
#define SCI_STYLESETCHARACTERSET 2066
#define SCI_STYLESETHOTSPOT 2409
#define SCI_SETSELFORE 2067
#define SCI_GETCARETPERIOD 2075
#define SCI_SETCARETPERIOD 2076
#define SCI_SETWORDCHARS 2077
+#define SCI_GETWORDCHARS 2646
#define SCI_BEGINUNDOACTION 2078
#define SCI_ENDUNDOACTION 2079
#define INDIC_PLAIN 0
#define INDIC_HIDDEN 5
#define INDIC_BOX 6
#define INDIC_ROUNDBOX 7
+#define INDIC_STRAIGHTBOX 8
+#define INDIC_DASH 9
+#define INDIC_DOTS 10
+#define INDIC_SQUIGGLELOW 11
+#define INDIC_DOTBOX 12
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
#define SCI_GETLINEINDENTATION 2127
#define SCI_GETLINEINDENTPOSITION 2128
#define SCI_GETCOLUMN 2129
+#define SCI_COUNTCHARACTERS 2633
#define SCI_SETHSCROLLBAR 2130
#define SCI_GETHSCROLLBAR 2131
#define SC_IV_NONE 0
#define SCI_GETLINEENDPOSITION 2136
#define SCI_GETCODEPAGE 2137
#define SCI_GETCARETFORE 2138
-#define SCI_GETUSEPALETTE 2139
#define SCI_GETREADONLY 2140
#define SCI_SETCURRENTPOS 2141
#define SCI_SETSELECTIONSTART 2142
#define SCI_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145
+#define SCI_SETEMPTYSELECTION 2556
#define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0
#define SCI_CALLTIPSETFORE 2206
#define SCI_CALLTIPSETFOREHLT 2207
#define SCI_CALLTIPUSESTYLE 2212
+#define SCI_CALLTIPSETPOSITION 2213
#define SCI_VISIBLEFROMDOCLINE 2220
#define SCI_DOCLINEFROMVISIBLE 2221
#define SCI_WRAPCOUNT 2235
#define SCI_SHOWLINES 2226
#define SCI_HIDELINES 2227
#define SCI_GETLINEVISIBLE 2228
+#define SCI_GETALLLINESVISIBLE 2236
#define SCI_SETFOLDEXPANDED 2229
#define SCI_GETFOLDEXPANDED 2230
#define SCI_TOGGLEFOLD 2231
#define SC_WRAPVISUALFLAG_NONE 0x0000
#define SC_WRAPVISUALFLAG_END 0x0001
#define SC_WRAPVISUALFLAG_START 0x0002
+#define SC_WRAPVISUALFLAG_MARGIN 0x0004
#define SCI_SETWRAPVISUALFLAGS 2460
#define SCI_GETWRAPVISUALFLAGS 2461
#define SC_WRAPVISUALFLAGLOC_DEFAULT 0x0000
#define SCI_SETFONTQUALITY 2611
#define SCI_GETFONTQUALITY 2612
#define SCI_SETFIRSTVISIBLELINE 2613
+#define SC_MULTIPASTE_ONCE 0
+#define SC_MULTIPASTE_EACH 1
+#define SCI_SETMULTIPASTE 2614
+#define SCI_GETMULTIPASTE 2615
+#define SCI_GETTAG 2616
#define SCI_TARGETFROMSELECTION 2287
#define SCI_LINESJOIN 2288
#define SCI_LINESSPLIT 2289
#define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351
+#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352
+#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356
#define SCI_SETMOUSEDOWNCAPTURES 2384
#define SCI_GETMOUSEDOWNCAPTURES 2385
#define SC_CURSORNORMAL -1
+#define SC_CURSORARROW 2
#define SC_CURSORWAIT 4
+#define SC_CURSORREVERSEARROW 7
#define SCI_SETCURSOR 2386
#define SCI_GETCURSOR 2387
#define SCI_SETCONTROLCHARSYMBOL 2388
#define SCI_WORDRIGHTEND 2441
#define SCI_WORDRIGHTENDEXTEND 2442
#define SCI_SETWHITESPACECHARS 2443
+#define SCI_GETWHITESPACECHARS 2647
+#define SCI_SETPUNCTUATIONCHARS 2648
+#define SCI_GETPUNCTUATIONCHARS 2649
#define SCI_SETCHARSDEFAULT 2444
#define SCI_AUTOCGETCURRENT 2445
#define SCI_AUTOCGETCURRENTTEXT 2610
+#define SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE 0
+#define SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE 1
+#define SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR 2634
+#define SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR 2635
#define SCI_ALLOCATE 2446
#define SCI_TARGETASUTF8 2447
#define SCI_SETLENGTHFORENCODE 2448
#define SCI_FINDCOLUMN 2456
#define SCI_GETCARETSTICKY 2457
#define SCI_SETCARETSTICKY 2458
+#define SC_CARETSTICKY_OFF 0
+#define SC_CARETSTICKY_ON 1
+#define SC_CARETSTICKY_WHITESPACE 2
#define SCI_TOGGLECARETSTICKY 2459
#define SCI_SETPASTECONVERTENDINGS 2467
#define SCI_GETPASTECONVERTENDINGS 2468
#define SCI_GETPOSITIONCACHE 2515
#define SCI_COPYALLOWLINE 2519
#define SCI_GETCHARACTERPOINTER 2520
+#define SCI_GETRANGEPOINTER 2643
+#define SCI_GETGAPPOSITION 2644
#define SCI_SETKEYSUNICODE 2521
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524
+#define SCI_INDICSETOUTLINEALPHA 2558
+#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527
#define SCI_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538
+#define SC_MARGINOPTION_NONE 0
+#define SC_MARGINOPTION_SUBLINESELECT 1
+#define SCI_SETMARGINOPTIONS 2539
+#define SCI_GETMARGINOPTIONS 2557
#define SCI_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542
#define SCI_GETADDITIONALCARETFORE 2605
#define SCI_ROTATESELECTION 2606
#define SCI_SWAPMAINANCHORCARET 2607
+#define SCI_CHANGELEXERSTATE 2617
+#define SCI_CONTRACTEDFOLDNEXT 2618
+#define SCI_VERTICALCENTRECARET 2619
+#define SCI_MOVESELECTEDLINESUP 2620
+#define SCI_MOVESELECTEDLINESDOWN 2621
+#define SCI_SETIDENTIFIER 2622
+#define SCI_GETIDENTIFIER 2623
+#define SCI_RGBAIMAGESETWIDTH 2624
+#define SCI_RGBAIMAGESETHEIGHT 2625
+#define SCI_MARKERDEFINERGBAIMAGE 2626
+#define SCI_REGISTERRGBAIMAGE 2627
+#define SCI_SCROLLTOSTART 2628
+#define SCI_SCROLLTOEND 2629
+#define SC_TECHNOLOGY_DEFAULT 0
+#define SC_TECHNOLOGY_DIRECTWRITE 1
+#define SCI_SETTECHNOLOGY 2630
+#define SCI_GETTECHNOLOGY 2631
+#define SCI_CREATELOADER 2632
+#define SCI_FINDINDICATORSHOW 2640
+#define SCI_FINDINDICATORFLASH 2641
+#define SCI_FINDINDICATORHIDE 2642
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
#define SCI_GETPROPERTYINT 4010
#define SCI_GETSTYLEBITSNEEDED 4011
#define SCI_GETLEXERLANGUAGE 4012
+#define SCI_PRIVATELEXERCALL 4013
+#define SCI_PROPERTYNAMES 4014
+#define SC_TYPE_BOOLEAN 0
+#define SC_TYPE_INTEGER 1
+#define SC_TYPE_STRING 2
+#define SCI_PROPERTYTYPE 4015
+#define SCI_DESCRIBEPROPERTY 4016
+#define SCI_DESCRIBEKEYWORDSETS 4017
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
#define SC_MOD_CHANGEMARGIN 0x10000
#define SC_MOD_CHANGEANNOTATION 0x20000
#define SC_MOD_CONTAINER 0x40000
-#define SC_MODEVENTMASKALL 0x7FFFF
+#define SC_MOD_LEXERSTATE 0x80000
+#define SC_MODEVENTMASKALL 0xFFFFF
+#define SC_UPDATE_CONTENT 0x1
+#define SC_UPDATE_SELECTION 0x2
+#define SC_UPDATE_V_SCROLL 0x4
+#define SC_UPDATE_H_SCROLL 0x8
#define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCMOD_SUPER 8
+#define SCMOD_META 16
#define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002
#define SCN_INDICATORRELEASE 2024
#define SCN_AUTOCCANCELLED 2025
#define SCN_AUTOCCHARDELETED 2026
+#define SCN_HOTSPOTRELEASECLICK 2027
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* These structures are defined to be exactly the same shape as the Win32
#define TextRange Sci_TextRange
#define TextToFind Sci_TextToFind
-#ifdef PLATFORM_H
+typedef void *Sci_SurfaceID;
+
+struct Sci_Rectangle {
+ int left;
+ int top;
+ int right;
+ int bottom;
+};
/* This structure is used in printing and requires some of the graphics types
* from Platform.h. Not needed by most client code. */
struct Sci_RangeToFormat {
- SurfaceID hdc;
- SurfaceID hdcTarget;
- PRectangle rc;
- PRectangle rcPage;
- Sci_CharacterRange chrg;
+ Sci_SurfaceID hdc;
+ Sci_SurfaceID hdcTarget;
+ struct Sci_Rectangle rc;
+ struct Sci_Rectangle rcPage;
+ struct Sci_CharacterRange chrg;
};
#define RangeToFormat Sci_RangeToFormat
-#endif
-
struct Sci_NotifyHeader {
/* Compatible with Windows NMHDR.
* hwndFrom is really an environment specific window handle or pointer
struct SCNotification {
struct Sci_NotifyHeader nmhdr;
- int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
+ int position;
+ /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
+ /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
+ /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
+ /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
+ /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+
int ch; /* SCN_CHARADDED, SCN_KEY */
- int modifiers; /* SCN_KEY */
+ int modifiers;
+ /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
+ /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
+
int modificationType; /* SCN_MODIFIED */
- const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+ const char *text;
+ /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
+
int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
- int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
+ int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
+ int updated; /* SCN_UPDATEUI */
};
#ifdef SCI_NAMESPACE
}
#endif
+#ifdef INCLUDE_DEPRECATED_FEATURES
+
+#define SC_CP_DBCS 1
+#define SCI_SETUSEPALETTE 2039
+#define SCI_GETUSEPALETTE 2139
+
+#endif
+
#endif
# Delete all text in the document.
fun void ClearAll=2004(,)
+# Delete a range of text in the document.
+fun void DeleteRange=2645(position pos, int deleteLength)
+
# Set all style bytes to 0, remove all folding information.
fun void ClearDocumentStyle=2005(,)
# This is the same value as CP_UTF8 in Windows
val SC_CP_UTF8=65001
-# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
-val SC_CP_DBCS=1
-
# Set the code page used to interpret the bytes of the document as characters.
# The SC_CP_UTF8 value can be used to enter Unicode mode.
set void SetCodePage=2037(int codePage,)
-# In palette mode, Scintilla uses the environment's palette calls to display
-# more colours. This may lead to ugly displays.
-set void SetUsePalette=2039(bool usePalette,)
-
enu MarkerSymbol=SC_MARK_
val MARKER_MAX=31
val SC_MARK_CIRCLE=0
val SC_MARK_CIRCLEMINUS=20
val SC_MARK_CIRCLEMINUSCONNECTED=21
-# Invisible mark that only sets the line background color.
+# Invisible mark that only sets the line background colour.
val SC_MARK_BACKGROUND=22
val SC_MARK_DOTDOTDOT=23
val SC_MARK_ARROWS=24
val SC_MARK_LEFTRECT=27
val SC_MARK_AVAILABLE=28
val SC_MARK_UNDERLINE=29
+val SC_MARK_RGBAIMAGE=30
val SC_MARK_CHARACTER=10000
fun void MarkerDefine=2040(int markerNumber, int markerSymbol)
# Set the foreground colour used for a particular marker number.
-fun void MarkerSetFore=2041(int markerNumber, colour fore)
+set void MarkerSetFore=2041(int markerNumber, colour fore)
# Set the background colour used for a particular marker number.
-fun void MarkerSetBack=2042(int markerNumber, colour back)
+set void MarkerSetBack=2042(int markerNumber, colour back)
+
+# Set the background colour used for a particular marker number when its folding block is selected.
+set void MarkerSetBackSelected=2292(int markerNumber, colour back)
+
+# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
+fun void MarkerEnableHighlight=2293(bool enabled,)
# Add a marker to a line, returning an ID which can be used to find or delete the marker.
fun int MarkerAdd=2043(int line, int markerNumber)
# Get a bit mask of all the markers set on a line.
fun int MarkerGet=2046(int line,)
-# Find the next line after lineStart that includes a marker in mask.
+# Find the next line at or after lineStart that includes a marker in mask.
+# Return -1 when no more lines.
fun int MarkerNext=2047(int lineStart, int markerMask)
# Find the previous line before lineStart that includes a marker in mask.
fun void MarkerAddSet=2466(int line, int set)
# Set the alpha used for a marker that is drawn in the text area, not the margin.
-fun void MarkerSetAlpha=2476(int markerNumber, int alpha)
+set void MarkerSetAlpha=2476(int markerNumber, int alpha)
enu MarginType=SC_MARGIN_
val SC_MARGIN_SYMBOL=0
# Retrieve the mouse click sensitivity of a margin.
get bool GetMarginSensitiveN=2247(int margin,)
+# Set the cursor shown when the mouse is inside a margin.
+set void SetMarginCursorN=2248(int margin, int cursor)
+
+# Retrieve the cursor shown in a margin.
+get int GetMarginCursorN=2249(int margin,)
+
# Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles.
# Style 39 is for future use.
enu StylesCommon=STYLE_
val SC_CHARSET_8859_15=1000
# Clear all the styles and make equivalent to the global default style.
-set void StyleClearAll=2050(,)
+fun void StyleClearAll=2050(,)
# Set the foreground colour of a style.
set void StyleSetFore=2051(int style, colour fore)
# Get the font of a style.
# Returns the length of the fontName
-fun int StyleGetFont=2486(int style, stringresult fontName)
+get int StyleGetFont=2486(int style, stringresult fontName)
# Get is a style to have its end of line filled or not.
get bool StyleGetEOLFilled=2487(int style,)
# Get is a style mixed case, or to force upper or lower case.
get int StyleGetCase=2489(int style,)
-# Get the character set of the font in a style.
+# Get the character get of the font in a style.
get int StyleGetCharacterSet=2490(int style,)
# Get is a style visible or not.
# Set a style to be mixed case, or to force upper or lower case.
set void StyleSetCase=2060(int style, int caseForce)
+val SC_FONT_SIZE_MULTIPLIER=100
+
+# Set the size of characters of a style. Size is in points multiplied by 100.
+set void StyleSetSizeFractional=2061(int style, int caseForce)
+
+# Get the size of characters of a style in points multiplied by 100
+get int StyleGetSizeFractional=2062(int style,)
+
+enu FontWeight=SC_WEIGHT_
+val SC_WEIGHT_NORMAL=400
+val SC_WEIGHT_SEMIBOLD=600
+val SC_WEIGHT_BOLD=700
+
+# Set the weight of characters of a style.
+set void StyleSetWeight=2063(int style, int weight)
+
+# Get the weight of characters of a style.
+get int StyleGetWeight=2064(int style,)
+
# Set the character set of the font in a style.
set void StyleSetCharacterSet=2066(int style, int characterSet)
# First sets defaults like SetCharsDefault.
set void SetWordChars=2077(, string characters)
+# Get the set of characters making up words for when moving or selecting by word.
+# Retuns the number of characters
+get int GetWordChars=2646(, stringresult characters)
+
# Start a sequence of actions that is undone and redone as a unit.
# May be nested.
fun void BeginUndoAction=2078(,)
val INDIC_HIDDEN=5
val INDIC_BOX=6
val INDIC_ROUNDBOX=7
+val INDIC_STRAIGHTBOX=8
+val INDIC_DASH=9
+val INDIC_DOTS=10
+val INDIC_SQUIGGLELOW=11
+val INDIC_DOTBOX=12
val INDIC_MAX=31
val INDIC_CONTAINER=8
val INDIC0_MASK=0x20
# Retrieve the column number of a position, taking tab width into account.
get int GetColumn=2129(position pos,)
+# Count characters between two positions.
+fun int CountCharacters=2633(int startPos, int endPos)
+
# Show or hide the horizontal scroll bar.
set void SetHScrollBar=2130(bool show,)
-
# Is the horizontal scroll bar visible?
get bool GetHScrollBar=2131(,)
get int GetHighlightGuide=2135(,)
# Get the position after the last visible characters on a line.
-get int GetLineEndPosition=2136(int line,)
+get position GetLineEndPosition=2136(int line,)
# Get the code page used to interpret the bytes of the document as characters.
get int GetCodePage=2137(,)
# Get the foreground colour of the caret.
get colour GetCaretFore=2138(,)
-# In palette mode?
-get bool GetUsePalette=2139(,)
-
# In read-only mode?
get bool GetReadOnly=2140(,)
# Returns the position at the end of the selection.
get position GetSelectionEnd=2145(,)
+# Set caret to a position, while removing any existing selection.
+fun void SetEmptySelection=2556(position pos,)
+
# Sets the print magnification added to the point size of each style for printing.
set void SetPrintMagnification=2146(int magnification,)
# Enable use of STYLE_CALLTIP and set call tip tab size in pixels.
set void CallTipUseStyle=2212(int tabSize,)
+# Set position of calltip, above or below text.
+set void CallTipSetPosition=2213(bool above,)
+
# Find the display line of a document line taking hidden lines into account.
fun int VisibleFromDocLine=2220(int line,)
# Is a line visible?
get bool GetLineVisible=2228(int line,)
+# Are all lines visible?
+get bool GetAllLinesVisible=2236(,)
+
# Show the children of a header line.
set void SetFoldExpanded=2229(int line, bool expanded)
val SC_FOLDFLAG_LEVELNUMBERS=0x0040
# Set some style options for folding.
-fun void SetFoldFlags=2233(int flags,)
+set void SetFoldFlags=2233(int flags,)
# Ensure a particular line is visible by expanding any header line hiding it.
# Use the currently set visibility policy to determine which range to display.
val SC_WRAPVISUALFLAG_NONE=0x0000
val SC_WRAPVISUALFLAG_END=0x0001
val SC_WRAPVISUALFLAG_START=0x0002
+val SC_WRAPVISUALFLAG_MARGIN=0x0004
# Set the display mode of visual flags for wrapped lines.
set void SetWrapVisualFlags=2460(int wrapVisualFlags,)
# Append a string to the end of the document without changing the selection.
fun void AppendText=2282(int length, string text)
-# Is drawing done in two phases with backgrounds drawn before foregrounds?
+# Is drawing done in two phases with backgrounds drawn before faoregrounds?
get bool GetTwoPhaseDraw=2283(,)
# In twoPhaseDraw mode, drawing is performed in two phases, first the background
# Scroll so that a display line is at the top of the display.
set void SetFirstVisibleLine=2613(int lineDisplay,)
+enu MultiPaste=SC_MULTIPASTE_
+val SC_MULTIPASTE_ONCE=0
+val SC_MULTIPASTE_EACH=1
+
+# Change the effect of pasting when there are multiple selections.
+set void SetMultiPaste=2614(int multiPaste,)
+
+# Retrieve the effect of pasting when there are multiple selections..
+get int GetMultiPaste=2615(,)
+
+# Retrieve the value of a tag from a regular expression search.
+get int GetTag=2616(int tagNumber, stringresult tagValue)
+
# Make the target range start and end be the same as the selection range start and end.
fun void TargetFromSelection=2287(,)
# Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2)
+# Use specified indicator to highlight matching braces instead of changing their style.
+fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
+
# Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,)
+# Use specified indicator to highlight non matching brace instead of changing its style.
+fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
+
# Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,)
enu CursorShape=SC_CURSOR
val SC_CURSORNORMAL=-1
+val SC_CURSORARROW=2
val SC_CURSORWAIT=4
+val SC_CURSORREVERSEARROW=7
# Sets the cursor to one of the SC_CURSOR* values.
set void SetCursor=2386(int cursorType,)
# Get cursor type.
# Delete forwards from the current position to the end of the line.
fun void DelLineRight=2396(,)
-# Get and Set the xOffset (ie, horizonal scroll position).
+# Get and Set the xOffset (ie, horizontal scroll position).
set void SetXOffset=2397(int newOffset,)
get int GetXOffset=2398(,)
# where most code reside, and the lines after the caret, eg. the body of a function.
val CARET_EVEN=0x08
-# Set the way the caret is kept visible when going sideway.
+# Set the way the caret is kept visible when going sideways.
# The exclusion zone is given in pixels.
fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop)
# Should be called after SetWordChars.
set void SetWhitespaceChars=2443(, string characters)
+# Get the set of characters making up whitespace for when moving or selecting by word.
+get int GetWhitespaceChars=2647(, stringresult characters)
+
+# Set the set of characters making up punctuation characters
+# Should be called after SetWordChars.
+set void SetPunctuationChars=2648(, string characters)
+
+# Get the set of characters making up punctuation characters
+get int GetPunctuationChars=2649(, stringresult characters)
+
# Reset the set of characters for whitespace and word characters to the defaults.
fun void SetCharsDefault=2444(,)
# Get currently selected item position in the auto-completion list
-fun int AutoCGetCurrent=2445(,)
+get int AutoCGetCurrent=2445(,)
# Get currently selected item text in the auto-completion list
# Returns the length of the item text
-fun int AutoCGetCurrentText=2610(, stringresult s)
+get int AutoCGetCurrentText=2610(, stringresult s)
+
+enu CaseInsensitiveBehaviour=SC_CASEINSENSITIVEBEHAVIOUR_
+val SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=0
+val SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE=1
+
+# Set auto-completion case insensitive behaviour to either prefer case-sensitive matches or have no preference.
+set void AutoCSetCaseInsensitiveBehaviour=2634(int behaviour,)
+
+# Get auto-completion case insensitive behaviour.
+get int AutoCGetCaseInsensitiveBehaviour=2635(,)
# Enlarge the document to a particular size of text bytes.
fun void Allocate=2446(int bytes,)
fun int FindColumn=2456(int line, int column)
# Can the caret preferred x position only be changed by explicit movement commands?
-get bool GetCaretSticky=2457(,)
+get int GetCaretSticky=2457(,)
# Stop the caret preferred x position changing when the user types.
-set void SetCaretSticky=2458(bool useCaretStickyBehaviour,)
+set void SetCaretSticky=2458(int useCaretStickyBehaviour,)
+
+enu CaretSticky=SC_CARETSTICKY_
+val SC_CARETSTICKY_OFF=0
+val SC_CARETSTICKY_ON=1
+val SC_CARETSTICKY_WHITESPACE=2
# Switch between sticky and non-sticky: meant to be bound to a key.
fun void ToggleCaretSticky=2459(,)
# Set the value used for IndicatorFillRange
set void SetIndicatorValue=2502(int value,)
-# Get the current indicator vaue
+# Get the current indicator value
get int GetIndicatorValue=2503(,)
# Turn a indicator on over a range.
# characters in the document.
get int GetCharacterPointer=2520(,)
+# Return a read-only pointer to a range of characters in the document.
+# May move the gap so that the range is contiguous, but will only move up
+# to rangeLength bytes.
+get int GetRangePointer=2643(int position, int rangeLength)
+
+# Return a position which, to avoid performance costs, should not be within
+# the range of a call to GetRangePointer.
+get position GetGapPosition=2644(,)
+
# Always interpret keyboard input as Unicode
set void SetKeysUnicode=2521(bool keysUnicode,)
# Get the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int indicator,)
+# Set the alpha outline colour of the given indicator.
+set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
+
+# Get the alpha outline colour of the given indicator.
+get int IndicGetOutlineAlpha=2559(int indicator,)
+
# Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,)
# Get the start of the range of style numbers used for margin text
get int MarginGetStyleOffset=2538(,)
+enu MarginOption=SC_MARGINOPTION_
+val SC_MARGINOPTION_NONE=0
+val SC_MARGINOPTION_SUBLINESELECT=1
+
+# Set the margin options.
+set void SetMarginOptions=2539(int marginOptions,)
+
+# Get the margin options.
+get int GetMarginOptions=2557(,)
+
# Set the annotation text for a line
set void AnnotationSetText=2540(int line, string text)
fun void ClearSelections=2571(,)
# Set a simple selection
-fun int SetSelection=2572(int caret,int anchor)
+fun int SetSelection=2572(int caret, int anchor)
# Add a selection
-fun int AddSelection=2573(int caret,int anchor)
+fun int AddSelection=2573(int caret, int anchor)
# Set the main selection
set void SetMainSelection=2574(int selection,)
get position GetSelectionNStart=2585(int selection,)
# Sets the position that ends the selection - this becomes the currentPosition.
-set void SetSelectionNEnd=2586(int selection, position pos,)
+set void SetSelectionNEnd=2586(int selection, position pos)
# Returns the position at the end of the selection.
get position GetSelectionNEnd=2587(int selection,)
# Swap that caret and anchor of the main selection.
fun void SwapMainAnchorCaret=2607(,)
+# Indicate that the internal state of a lexer has changed over a range and therefore
+# there may be a need to redraw.
+fun int ChangeLexerState=2617(position start, position end)
+
+# Find the next line at or after lineStart that is a contracted fold header line.
+# Return -1 when no more lines.
+fun int ContractedFoldNext=2618(int lineStart,)
+
+# Centre current line in window.
+fun void VerticalCentreCaret=2619(,)
+
+# Move the selected lines up one line, shifting the line above after the selection
+fun void MoveSelectedLinesUp=2620(,)
+
+# Move the selected lines down one line, shifting the line below before the selection
+fun void MoveSelectedLinesDown=2621(,)
+
+# Set the identifier reported as idFrom in notification messages.
+set void SetIdentifier=2622(int identifier,)
+
+# Get the identifier.
+get int GetIdentifier=2623(,)
+
+# Set the width for future RGBA image data.
+set void RGBAImageSetWidth=2624(int width,)
+
+# Set the height for future RGBA image data.
+set void RGBAImageSetHeight=2625(int height,)
+
+# Define a marker from RGBA data.
+# It has the width and height from RGBAImageSetWidth/Height
+fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels)
+
+# Register an RGBA image for use in autocompletion lists.
+# It has the width and height from RGBAImageSetWidth/Height
+fun void RegisterRGBAImage=2627(int type, string pixels)
+
+# Scroll to start of document.
+fun void ScrollToStart=2628(,)
+
+# Scroll to end of document.
+fun void ScrollToEnd=2629(,)
+
+val SC_TECHNOLOGY_DEFAULT=0
+val SC_TECHNOLOGY_DIRECTWRITE=1
+
+# Set the technology used.
+set void SetTechnology=2630(int technology,)
+
+# Get the tech.
+get int GetTechnology=2631(,)
+
+# Create an ILoader*.
+fun int CreateLoader=2632(int bytes,)
+
+# On OS X, show a find indicator.
+fun void FindIndicatorShow=2640(position start, position end)
+
+# On OS X, flash a find indicator, then fade out.
+fun void FindIndicatorFlash=2641(position start, position end)
+
+# On OS X, hide the find indicator.
+fun void FindIndicatorHide=2642(,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
fun void LoadLexerLibrary=4007(, string path)
# Retrieve a "property" value previously set with SetProperty.
-fun int GetProperty=4008(string key, stringresult buf)
+get int GetProperty=4008(string key, stringresult buf)
# Retrieve a "property" value previously set with SetProperty,
# with "$()" variable replacement on returned buffer.
-fun int GetPropertyExpanded=4009(string key, stringresult buf)
+get int GetPropertyExpanded=4009(string key, stringresult buf)
# Retrieve a "property" value previously set with SetProperty,
# interpreted as an int AFTER any "$()" variable replacement.
# Return the length of the text.
get int GetLexerLanguage=4012(, stringresult text)
+# For private communication between an application and a known lexer.
+fun int PrivateLexerCall=4013(int operation, int pointer)
+
+# Retrieve a '\n' separated list of properties understood by the current lexer.
+fun int PropertyNames=4014(, stringresult names)
+
+enu TypeProperty=SC_TYPE_
+val SC_TYPE_BOOLEAN=0
+val SC_TYPE_INTEGER=1
+val SC_TYPE_STRING=2
+
+# Retrieve the type of a property.
+fun int PropertyType=4015(string name,)
+
+# Describe a property.
+fun int DescribeProperty=4016(string name, stringresult description)
+
+# Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer.
+fun int DescribeKeyWordSets=4017(, stringresult descriptions)
+
# Notifications
# Type of modification and the action which caused the modification.
# These are defined as a bit mask to make it easy to specify which notifications are wanted.
# One bit is set from each of SC_MOD_* and SC_PERFORMED_*.
-enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_LAST
+enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_MULTISTEPUNDOREDO SC_LASTSTEPINUNDOREDO SC_MULTILINEUNDOREDO SC_STARTACTION SC_MODEVENTMASKALL
val SC_MOD_INSERTTEXT=0x1
val SC_MOD_DELETETEXT=0x2
val SC_MOD_CHANGESTYLE=0x4
val SC_MOD_CHANGEMARGIN=0x10000
val SC_MOD_CHANGEANNOTATION=0x20000
val SC_MOD_CONTAINER=0x40000
-val SC_MODEVENTMASKALL=0x7FFFF
+val SC_MOD_LEXERSTATE=0x80000
+val SC_MODEVENTMASKALL=0xFFFFF
+
+enu Update=SC_UPDATE_
+val SC_UPDATE_CONTENT=0x1
+val SC_UPDATE_SELECTION=0x2
+val SC_UPDATE_V_SCROLL=0x4
+val SC_UPDATE_H_SCROLL=0x8
# For compatibility, these go through the COMMAND notification rather than NOTIFY
# and should have had exactly the same values as the EN_* constants.
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCMOD_SUPER=8
+val SCMOD_META=16
################################################
# For SciLexer.h
val SCLEX_NIMROD=96
val SCLEX_SML=97
val SCLEX_MARKDOWN=98
+val SCLEX_TXT2TAGS=99
+val SCLEX_A68K=100
+val SCLEX_MODULA=101
+val SCLEX_COFFEESCRIPT=102
+val SCLEX_TCMD=103
+val SCLEX_AVS=104
+val SCLEX_ECL=105
+val SCLEX_OSCRIPT=106
+val SCLEX_VISUALPROLOG=107
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1.
val SCE_C_COMMENTDOCKEYWORD=17
val SCE_C_COMMENTDOCKEYWORDERROR=18
val SCE_C_GLOBALCLASS=19
+val SCE_C_STRINGRAW=20
+val SCE_C_TRIPLEVERBATIM=21
+val SCE_C_HASHQUOTEDSTRING=22
+val SCE_C_PREPROCESSORCOMMENT=23
# Lexical states for SCLEX_D
lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0
val SCE_TCL_COMMENT_BOX=20
val SCE_TCL_BLOCK_COMMENT=21
# Lexical states for SCLEX_HTML, SCLEX_XML
-lex HTML=SCLEX_HTML SCE_H
-lex XML=SCLEX_XML SCE_H
-lex ASP=SCLEX_ASP SCE_H
-lex PHP=SCLEX_PHP SCE_H
+lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
+lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
+lex ASP=SCLEX_ASP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
+lex PHP=SCLEX_PHP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
val SCE_H_DEFAULT=0
val SCE_H_TAG=1
val SCE_H_TAGUNKNOWN=2
val SCE_PL_SUB_PROTOTYPE=40
val SCE_PL_FORMAT_IDENT=41
val SCE_PL_FORMAT=42
+val SCE_PL_STRING_VAR=43
+val SCE_PL_XLAT=44
+val SCE_PL_REGEX_VAR=54
+val SCE_PL_REGSUBST_VAR=55
+val SCE_PL_BACKTICKS_VAR=57
+val SCE_PL_HERE_QQ_VAR=61
+val SCE_PL_HERE_QX_VAR=62
+val SCE_PL_STRING_QQ_VAR=64
+val SCE_PL_STRING_QX_VAR=65
+val SCE_PL_STRING_QR_VAR=66
# Lexical states for SCLEX_RUBY
lex Ruby=SCLEX_RUBY SCE_RB_
val SCE_RB_DEFAULT=0
val SCE_L_TAG=2
val SCE_L_MATH=3
val SCE_L_COMMENT=4
+val SCE_L_TAG2=5
+val SCE_L_MATH2=6
+val SCE_L_COMMENT2=7
+val SCE_L_VERBATIM=8
+val SCE_L_SHORTCMD=9
+val SCE_L_SPECIAL=10
+val SCE_L_CMDOPT=11
+val SCE_L_ERROR=12
# Lexical states for SCLEX_LUA
lex Lua=SCLEX_LUA SCE_LUA_
val SCE_LUA_DEFAULT=0
val SCE_LUA_WORD6=17
val SCE_LUA_WORD7=18
val SCE_LUA_WORD8=19
+val SCE_LUA_LABEL=20
# Lexical states for SCLEX_ERRORLIST
lex ErrorList=SCLEX_ERRORLIST SCE_ERR_
val SCE_ERR_DEFAULT=0
val SCE_BAT_COMMAND=5
val SCE_BAT_IDENTIFIER=6
val SCE_BAT_OPERATOR=7
+# Lexical states for SCLEX_TCMD
+lex TCMD=SCLEX_TCMD SCE_TCMD_
+val SCE_TCMD_DEFAULT=0
+val SCE_TCMD_COMMENT=1
+val SCE_TCMD_WORD=2
+val SCE_TCMD_LABEL=3
+val SCE_TCMD_HIDE=4
+val SCE_TCMD_COMMAND=5
+val SCE_TCMD_IDENTIFIER=6
+val SCE_TCMD_OPERATOR=7
+val SCE_TCMD_ENVIRONMENT=8
+val SCE_TCMD_EXPANSION=9
+val SCE_TCMD_CLABEL=10
# Lexical states for SCLEX_MAKEFILE
lex MakeFile=SCLEX_MAKEFILE SCE_MAKE_
val SCE_MAKE_DEFAULT=0
val SCE_ASM_CHARACTER=12
val SCE_ASM_STRINGEOL=13
val SCE_ASM_EXTINSTRUCTION=14
+val SCE_ASM_COMMENTDIRECTIVE=15
# Lexical states for SCLEX_FORTRAN
lex Fortran=SCLEX_FORTRAN SCE_F_
lex F77=SCLEX_F77 SCE_F_
val SCE_CSS_EXTENDED_IDENTIFIER=19
val SCE_CSS_EXTENDED_PSEUDOCLASS=20
val SCE_CSS_EXTENDED_PSEUDOELEMENT=21
+val SCE_CSS_MEDIA=22
+val SCE_CSS_VARIABLE=23
# Lexical states for SCLEX_POV
lex POV=SCLEX_POV SCE_POV_
val SCE_POV_DEFAULT=0
val SCE_ST_CHARACTER=15
val SCE_ST_SPEC_SEL=16
# Lexical states for SCLEX_FLAGSHIP (clipper)
-lex FlagShip=SCLEX_FLAGSHIP SCE_B_
+lex FlagShip=SCLEX_FLAGSHIP SCE_FS_
val SCE_FS_DEFAULT=0
val SCE_FS_COMMENT=1
val SCE_FS_COMMENTLINE=2
val SCE_FS_DATE=16
val SCE_FS_STRINGEOL=17
val SCE_FS_CONSTANT=18
-val SCE_FS_ASM=19
-val SCE_FS_LABEL=20
-val SCE_FS_ERROR=21
-val SCE_FS_HEXNUMBER=22
-val SCE_FS_BINNUMBER=23
+val SCE_FS_WORDOPERATOR=19
+val SCE_FS_DISABLEDCODE=20
+val SCE_FS_DEFAULT_C=21
+val SCE_FS_COMMENTDOC_C=22
+val SCE_FS_COMMENTLINEDOC_C=23
+val SCE_FS_KEYWORD_C=24
+val SCE_FS_KEYWORD2_C=25
+val SCE_FS_NUMBER_C=26
+val SCE_FS_STRING_C=27
+val SCE_FS_PREPROCESSOR_C=28
+val SCE_FS_OPERATOR_C=29
+val SCE_FS_IDENTIFIER_C=30
+val SCE_FS_STRINGEOL_C=31
# Lexical states for SCLEX_CSOUND
lex Csound=SCLEX_CSOUND SCE_CSOUND_
val SCE_CSOUND_DEFAULT=0
val SCE_POWERSHELL_KEYWORD=8
val SCE_POWERSHELL_CMDLET=9
val SCE_POWERSHELL_ALIAS=10
+val SCE_POWERSHELL_FUNCTION=11
+val SCE_POWERSHELL_USER1=12
+val SCE_POWERSHELL_COMMENTSTREAM=13
# Lexical state for SCLEX_MYSQL
lex MySQL=SCLEX_MYSQL SCE_MYSQL_
val SCE_MYSQL_DEFAULT=0
val SCE_MARKDOWN_CODE=19
val SCE_MARKDOWN_CODE2=20
val SCE_MARKDOWN_CODEBK=21
+# Lexical state for SCLEX_TXT2TAGS
+lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_
+val SCE_TXT2TAGS_DEFAULT=0
+val SCE_TXT2TAGS_LINE_BEGIN=1
+val SCE_TXT2TAGS_STRONG1=2
+val SCE_TXT2TAGS_STRONG2=3
+val SCE_TXT2TAGS_EM1=4
+val SCE_TXT2TAGS_EM2=5
+val SCE_TXT2TAGS_HEADER1=6
+val SCE_TXT2TAGS_HEADER2=7
+val SCE_TXT2TAGS_HEADER3=8
+val SCE_TXT2TAGS_HEADER4=9
+val SCE_TXT2TAGS_HEADER5=10
+val SCE_TXT2TAGS_HEADER6=11
+val SCE_TXT2TAGS_PRECHAR=12
+val SCE_TXT2TAGS_ULIST_ITEM=13
+val SCE_TXT2TAGS_OLIST_ITEM=14
+val SCE_TXT2TAGS_BLOCKQUOTE=15
+val SCE_TXT2TAGS_STRIKEOUT=16
+val SCE_TXT2TAGS_HRULE=17
+val SCE_TXT2TAGS_LINK=18
+val SCE_TXT2TAGS_CODE=19
+val SCE_TXT2TAGS_CODE2=20
+val SCE_TXT2TAGS_CODEBK=21
+val SCE_TXT2TAGS_COMMENT=22
+val SCE_TXT2TAGS_OPTION=23
+val SCE_TXT2TAGS_PREPROC=24
+val SCE_TXT2TAGS_POSTPROC=25
+# Lexical states for SCLEX_A68K
+lex A68k=SCLEX_A68K SCE_A68K_
+val SCE_A68K_DEFAULT=0
+val SCE_A68K_COMMENT=1
+val SCE_A68K_NUMBER_DEC=2
+val SCE_A68K_NUMBER_BIN=3
+val SCE_A68K_NUMBER_HEX=4
+val SCE_A68K_STRING1=5
+val SCE_A68K_OPERATOR=6
+val SCE_A68K_CPUINSTRUCTION=7
+val SCE_A68K_EXTINSTRUCTION=8
+val SCE_A68K_REGISTER=9
+val SCE_A68K_DIRECTIVE=10
+val SCE_A68K_MACRO_ARG=11
+val SCE_A68K_LABEL=12
+val SCE_A68K_STRING2=13
+val SCE_A68K_IDENTIFIER=14
+val SCE_A68K_MACRO_DECLARATION=15
+val SCE_A68K_COMMENT_WORD=16
+val SCE_A68K_COMMENT_SPECIAL=17
+val SCE_A68K_COMMENT_DOXYGEN=18
+# Lexical states for SCLEX_MODULA
+lex Modula=SCLEX_MODULA SCE_MODULA_
+val SCE_MODULA_DEFAULT=0
+val SCE_MODULA_COMMENT=1
+val SCE_MODULA_DOXYCOMM=2
+val SCE_MODULA_DOXYKEY=3
+val SCE_MODULA_KEYWORD=4
+val SCE_MODULA_RESERVED=5
+val SCE_MODULA_NUMBER=6
+val SCE_MODULA_BASENUM=7
+val SCE_MODULA_FLOAT=8
+val SCE_MODULA_STRING=9
+val SCE_MODULA_STRSPEC=10
+val SCE_MODULA_CHAR=11
+val SCE_MODULA_CHARSPEC=12
+val SCE_MODULA_PROC=13
+val SCE_MODULA_PRAGMA=14
+val SCE_MODULA_PRGKEY=15
+val SCE_MODULA_OPERATOR=16
+val SCE_MODULA_BADSTR=17
+# Lexical states for SCLEX_COFFEESCRIPT
+lex CoffeeScript=SCLEX_COFFEESCRIPT SCE_COFFEESCRIPT_
+val SCE_COFFEESCRIPT_DEFAULT=0
+val SCE_COFFEESCRIPT_COMMENT=1
+val SCE_COFFEESCRIPT_COMMENTLINE=2
+val SCE_COFFEESCRIPT_COMMENTDOC=3
+val SCE_COFFEESCRIPT_NUMBER=4
+val SCE_COFFEESCRIPT_WORD=5
+val SCE_COFFEESCRIPT_STRING=6
+val SCE_COFFEESCRIPT_CHARACTER=7
+val SCE_COFFEESCRIPT_UUID=8
+val SCE_COFFEESCRIPT_PREPROCESSOR=9
+val SCE_COFFEESCRIPT_OPERATOR=10
+val SCE_COFFEESCRIPT_IDENTIFIER=11
+val SCE_COFFEESCRIPT_STRINGEOL=12
+val SCE_COFFEESCRIPT_VERBATIM=13
+val SCE_COFFEESCRIPT_REGEX=14
+val SCE_COFFEESCRIPT_COMMENTLINEDOC=15
+val SCE_COFFEESCRIPT_WORD2=16
+val SCE_COFFEESCRIPT_COMMENTDOCKEYWORD=17
+val SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18
+val SCE_COFFEESCRIPT_GLOBALCLASS=19
+val SCE_COFFEESCRIPT_STRINGRAW=20
+val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21
+val SCE_COFFEESCRIPT_HASHQUOTEDSTRING=22
+val SCE_COFFEESCRIPT_COMMENTBLOCK=22
+val SCE_COFFEESCRIPT_VERBOSE_REGEX=23
+val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24
+# Lexical states for SCLEX_AVS
+lex AVS=SCLEX_AVS SCE_AVS_
+val SCE_AVS_DEFAULT=0
+val SCE_AVS_COMMENTBLOCK=1
+val SCE_AVS_COMMENTBLOCKN=2
+val SCE_AVS_COMMENTLINE=3
+val SCE_AVS_NUMBER=4
+val SCE_AVS_OPERATOR=5
+val SCE_AVS_IDENTIFIER=6
+val SCE_AVS_STRING=7
+val SCE_AVS_TRIPLESTRING=8
+val SCE_AVS_KEYWORD=9
+val SCE_AVS_FILTER=10
+val SCE_AVS_PLUGIN=11
+val SCE_AVS_FUNCTION=12
+val SCE_AVS_CLIPPROP=13
+val SCE_AVS_USERDFN=14
+# Lexical states for SCLEX_ECL
+lex ECL=SCLEX_ECL SCE_ECL_
+val SCE_ECL_DEFAULT=0
+val SCE_ECL_COMMENT=1
+val SCE_ECL_COMMENTLINE=2
+val SCE_ECL_NUMBER=3
+val SCE_ECL_STRING=4
+val SCE_ECL_WORD0=5
+val SCE_ECL_OPERATOR=6
+val SCE_ECL_CHARACTER=7
+val SCE_ECL_UUID=8
+val SCE_ECL_PREPROCESSOR=9
+val SCE_ECL_UNKNOWN=10
+val SCE_ECL_IDENTIFIER=11
+val SCE_ECL_STRINGEOL=12
+val SCE_ECL_VERBATIM=13
+val SCE_ECL_REGEX=14
+val SCE_ECL_COMMENTLINEDOC=15
+val SCE_ECL_WORD1=16
+val SCE_ECL_COMMENTDOCKEYWORD=17
+val SCE_ECL_COMMENTDOCKEYWORDERROR=18
+val SCE_ECL_WORD2=19
+val SCE_ECL_WORD3=20
+val SCE_ECL_WORD4=21
+val SCE_ECL_WORD5=22
+val SCE_ECL_COMMENTDOC=23
+val SCE_ECL_ADDED=24
+val SCE_ECL_DELETED=25
+val SCE_ECL_CHANGED=26
+val SCE_ECL_MOVED=27
+# Lexical states for SCLEX_OSCRIPT
+lex OScript=SCLEX_OSCRIPT SCE_OSCRIPT_
+val SCE_OSCRIPT_DEFAULT=0
+val SCE_OSCRIPT_LINE_COMMENT=1
+val SCE_OSCRIPT_BLOCK_COMMENT=2
+val SCE_OSCRIPT_DOC_COMMENT=3
+val SCE_OSCRIPT_PREPROCESSOR=4
+val SCE_OSCRIPT_NUMBER=5
+val SCE_OSCRIPT_SINGLEQUOTE_STRING=6
+val SCE_OSCRIPT_DOUBLEQUOTE_STRING=7
+val SCE_OSCRIPT_CONSTANT=8
+val SCE_OSCRIPT_IDENTIFIER=9
+val SCE_OSCRIPT_GLOBAL=10
+val SCE_OSCRIPT_KEYWORD=11
+val SCE_OSCRIPT_OPERATOR=12
+val SCE_OSCRIPT_LABEL=13
+val SCE_OSCRIPT_TYPE=14
+val SCE_OSCRIPT_FUNCTION=15
+val SCE_OSCRIPT_OBJECT=16
+val SCE_OSCRIPT_PROPERTY=17
+val SCE_OSCRIPT_METHOD=18
+# Lexical states for SCLEX_VISUALPROLOG
+lex VisualProlog=SCLEX_VISUALPROLOG SCE_VISUALPROLOG_
+val SCE_VISUALPROLOG_DEFAULT=0
+val SCE_VISUALPROLOG_KEY_MAJOR=1
+val SCE_VISUALPROLOG_KEY_MINOR=2
+val SCE_VISUALPROLOG_KEY_DIRECTIVE=3
+val SCE_VISUALPROLOG_COMMENT_BLOCK=4
+val SCE_VISUALPROLOG_COMMENT_LINE=5
+val SCE_VISUALPROLOG_COMMENT_KEY=6
+val SCE_VISUALPROLOG_COMMENT_KEY_ERROR=7
+val SCE_VISUALPROLOG_IDENTIFIER=8
+val SCE_VISUALPROLOG_VARIABLE=9
+val SCE_VISUALPROLOG_ANONYMOUS=10
+val SCE_VISUALPROLOG_NUMBER=11
+val SCE_VISUALPROLOG_OPERATOR=12
+val SCE_VISUALPROLOG_CHARACTER=13
+val SCE_VISUALPROLOG_CHARACTER_TOO_MANY=14
+val SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR=15
+val SCE_VISUALPROLOG_STRING=16
+val SCE_VISUALPROLOG_STRING_ESCAPE=17
+val SCE_VISUALPROLOG_STRING_ESCAPE_ERROR=18
+val SCE_VISUALPROLOG_STRING_EOL_OPEN=19
+val SCE_VISUALPROLOG_STRING_VERBATIM=20
+val SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL=21
+val SCE_VISUALPROLOG_STRING_VERBATIM_EOL=22
# Events
evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers)
-evt void DoubleClick=2006(void)
-evt void UpdateUI=2007(void)
-evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
+evt void DoubleClick=2006(int modifiers, int position, int line)
+evt void UpdateUI=2007(int updated)
+evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
evt void MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void)
-evt void UserListSelection=2014(int listType, string text)
+evt void UserListSelection=2014(int listType, string text, int position)
evt void URIDropped=2015(string text)
-evt void DwellStart=2016(int position)
-evt void DwellEnd=2017(int position)
+evt void DwellStart=2016(int position, int x, int y)
+evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
-evt void AutoCSelection=2022(string text)
+evt void AutoCSelection=2022(string text, int position)
evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void)
evt void AutoCCharDeleted=2026(void)
+evt void HotSpotReleaseClick=2027(int modifiers, int position)
+
+cat Deprecated
+
+# Deprecated in 2.21
+# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+val SC_CP_DBCS=1
+
+# Deprecated in 2.30
+
+# In palette mode?
+get bool GetUsePalette=2139(,)
+
+# In palette mode, Scintilla uses the environment's palette calls to display
+# more colours. This may lead to ugly displays.
+set void SetUsePalette=2039(bool usePalette,)
#ifndef SCINTILLAWIDGET_H
#define SCINTILLAWIDGET_H
-#if PLAT_GTK
+#if defined(GTK)
#ifdef __cplusplus
extern "C" {
#endif
-#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject)
+#define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject)
#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ())
void (* notify) (ScintillaObject *ttt);
};
-#if GLIB_MAJOR_VERSION < 2
-GtkType scintilla_get_type (void);
-#else
GType scintilla_get_type (void);
-#endif
GtkWidget* scintilla_new (void);
void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);
-#if GTK_MAJOR_VERSION < 2
-#define SCINTILLA_NOTIFY "notify"
-#else
#define SCINTILLA_NOTIFY "sci-notify"
-#endif
#ifdef __cplusplus
}
+++ /dev/null
-// Scintilla source code edit control
-/** @file WindowAccessor.h
- ** Implementation of BufferAccess and StylingAccess on a Scintilla
- ** rapid easy access to contents of a Scintilla.
- **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-/**
- */
-
-class WindowAccessor : public Accessor {
- // Private so WindowAccessor objects can not be copied
- WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
- WindowAccessor &operator=(const WindowAccessor &) { return *this; }
-protected:
- WindowID id;
- PropertyGet &props;
- int lenDoc;
-
- char styleBuf[bufferSize];
- int validLen;
- char chFlags;
- char chWhile;
- unsigned int startSeg;
-
- bool InternalIsLeadByte(char ch);
- void Fill(int position);
-public:
- WindowAccessor(WindowID id_, PropertyGet &props_) :
- Accessor(), id(id_), props(props_),
- lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
- }
- ~WindowAccessor();
- bool Match(int pos, const char *s);
- char StyleAt(int position);
- int GetLine(int position);
- int LineStart(int line);
- int LevelAt(int line);
- int Length();
- void Flush();
- int GetLineState(int line);
- int SetLineState(int line, int state);
- int GetPropertyInt(const char *key, int defaultValue=0) {
- return props.GetInt(key, defaultValue);
- }
- char *GetProperties() {
- return props.ToString();
- }
-
- void StartAt(unsigned int start, char chMask=31);
- void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
- unsigned int GetStartSegment() { return startSeg; }
- void StartSegment(unsigned int pos);
- void ColourTo(unsigned int pos, int chAttr);
- void SetLevel(int line, int level);
- int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
- void IndicatorFill(int start, int end, int indicator, int value);
-};
-
-#ifdef SCI_NAMESPACE
-}
-#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file LexA68k.cxx
+ ** Lexer for Assembler, just for the MASM syntax
+ ** Written by Martial Demolins AKA Folco
+ **/
+// Copyright 2010 Martial Demolins <mdemolins(a)gmail.com>
+// 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
+
+
+// Return values for GetOperatorType
+#define NO_OPERATOR 0
+#define OPERATOR_1CHAR 1
+#define OPERATOR_2CHAR 2
+
+
+/**
+ * IsIdentifierStart
+ *
+ * Return true if the given char is a valid identifier first char
+ */
+
+static inline bool IsIdentifierStart (const int ch)
+{
+ return (isalpha(ch) || (ch == '_') || (ch == '\\'));
+}
+
+
+/**
+ * IsIdentifierChar
+ *
+ * Return true if the given char is a valid identifier char
+ */
+
+static inline bool IsIdentifierChar (const int ch)
+{
+ return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.'));
+}
+
+
+/**
+ * GetOperatorType
+ *
+ * Return:
+ * NO_OPERATOR if char is not an operator
+ * OPERATOR_1CHAR if the operator is one char long
+ * OPERATOR_2CHAR if the operator is two chars long
+ */
+
+static inline int GetOperatorType (const int ch1, const int ch2)
+{
+ int OpType = NO_OPERATOR;
+
+ if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') ||
+ (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ','))
+ OpType = OPERATOR_1CHAR;
+
+ else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>'))
+ OpType = OPERATOR_2CHAR;
+
+ return OpType;
+}
+
+
+/**
+ * IsBin
+ *
+ * Return true if the given char is 0 or 1
+ */
+
+static inline bool IsBin (const int ch)
+{
+ return (ch == '0') || (ch == '1');
+}
+
+
+/**
+ * IsDoxygenChar
+ *
+ * Return true if the char may be part of a Doxygen keyword
+ */
+
+static inline bool IsDoxygenChar (const int ch)
+{
+ return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}');
+}
+
+
+/**
+ * ColouriseA68kDoc
+ *
+ * Main function, which colourises a 68k source
+ */
+
+static void ColouriseA68kDoc (unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
+{
+
+ // Get references to keywords lists
+ WordList &cpuInstruction = *keywordlists[0];
+ WordList ®isters = *keywordlists[1];
+ WordList &directive = *keywordlists[2];
+ WordList &extInstruction = *keywordlists[3];
+ WordList &commentSpecial = *keywordlists[4];
+ WordList &doxygenKeyword = *keywordlists[5];
+
+
+ // Instanciate a context for our source
+ StyleContext sc(startPos, length, initStyle, styler);
+
+
+ /************************************************************
+ *
+ * Parse the text
+ *
+ ************************************************************/
+
+ for ( ; sc.More(); sc.Forward())
+ {
+ char Buffer[100];
+ int OpType;
+
+ // Reset style at beginning of line
+ if (sc.atLineStart)
+ sc.SetState(SCE_A68K_DEFAULT);
+
+
+ /************************************************************
+ *
+ * Handle current state if we are not in the "default style"
+ *
+ ************************************************************/
+
+ if (sc.state != SCE_A68K_DEFAULT)
+ {
+ // Check if current style continue.
+ // If this case, we loop because there is nothing else to do
+ if (((sc.state == SCE_A68K_NUMBER_DEC) && isdigit(sc.ch)) // Decimal number
+ || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch)) // Binary number
+ || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch)) // Hexa number
+ || ((sc.state == SCE_A68K_MACRO_ARG) && isdigit(sc.ch)) // Arg of macro
+ || ((sc.state == SCE_A68K_STRING1) && (sc.ch != '\'')) // String single-quoted
+ || ((sc.state == SCE_A68K_STRING2) && (sc.ch != '\"')) // String double-quoted
+ || ((sc.state == SCE_A68K_MACRO_ARG) && isdigit(sc.ch)) // Macro argument
+ // Label. ' ' and '\t' are needed to handle macro declarations
+ || ((sc.state == SCE_A68K_LABEL) && (sc.ch != ':') && (sc.ch != ' ') && (sc.ch != '\t'))
+ || ((sc.state == SCE_A68K_IDENTIFIER) && (sc.ch < 0x80) && IsIdentifierChar(sc.ch)) // Identifier
+ || ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && IsDoxygenChar(sc.ch)) // Doxygen keyword
+ || ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && isalpha(sc.ch))) // Comment current word
+ {
+ continue;
+ }
+
+ // Check if some states terminate at the current char:
+ // we must include this char in the current style context
+ else if (((sc.state == SCE_A68K_STRING1) && (sc.ch < 0x80) && (sc.ch == '\'')) // String single-quoted
+ || ((sc.state == SCE_A68K_STRING2) && (sc.ch < 0x80) && (sc.ch == '\"')) // String double-quoted
+ || ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && (sc.ch == ':'))) // Label
+ {
+ sc.ForwardSetState(SCE_A68K_DEFAULT);
+ }
+
+ // Check for special words or Doxygen keywords in comments
+ else if (sc.state == SCE_A68K_COMMENT)
+ {
+ if (sc.ch == '\\') {
+ sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
+ }
+ else if ((sc.ch < 0x80) && isalpha(sc.ch)) {
+ sc.SetState(SCE_A68K_COMMENT_WORD);
+ }
+ continue;
+ }
+
+ // Check for special words in comment
+ else if ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && !isalpha(sc.ch))
+ {
+ sc.GetCurrent(Buffer, sizeof(Buffer));
+ if (commentSpecial.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_COMMENT_SPECIAL);
+ }
+ else {
+ sc.ChangeState(SCE_A68K_COMMENT);
+ }
+ sc.SetState(SCE_A68K_COMMENT);
+ continue;
+ }
+
+ // Check for Doxygen keywords
+ else if ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && !IsDoxygenChar(sc.ch))
+ {
+ sc.GetCurrentLowered(Buffer, sizeof(Buffer)); // Buffer the string of the current context
+ if (!doxygenKeyword.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_COMMENT);
+ }
+ sc.SetState(SCE_A68K_COMMENT);
+ continue;
+ }
+
+ // Check if we are in the case of a label which terminates without ':'
+ // It should be a macro declaration, not a label
+ else if ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && ((sc.ch == ' ') || (sc.ch == '\t')))
+ {
+ sc.ChangeState(SCE_A68K_MACRO_DECLARATION);
+ }
+
+ // Check if we are at the end of an identifier
+ // In this case, colourise it if was a keyword.
+ else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch))
+ {
+ sc.GetCurrentLowered(Buffer, sizeof(Buffer)); // Buffer the string of the current context
+ if (cpuInstruction.InList(Buffer)) { // And check if it belongs to a keyword list
+ sc.ChangeState(SCE_A68K_CPUINSTRUCTION);
+ }
+ else if (extInstruction.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_EXTINSTRUCTION);
+ }
+ else if (registers.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_REGISTER);
+ }
+ else if (directive.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_DIRECTIVE);
+ }
+ }
+
+ // All special contexts are now handled.Come back to default style
+ sc.SetState(SCE_A68K_DEFAULT);
+ }
+
+
+ /************************************************************
+ *
+ * Check if we must enter a new state
+ *
+ ************************************************************/
+
+ // Label and macro identifiers start at the beginning of a line
+ // We set both as a label, but if it wasn't one (no ':' at the end),
+ // it will be changed as a macro identifier.
+ if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {
+ sc.SetState(SCE_A68K_LABEL);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == ';')) { // Comment
+ sc.SetState(SCE_A68K_COMMENT);
+ }
+ else if ((sc.ch < 0x80) && isdigit(sc.ch)) { // Decimal numbers haven't prefix
+ sc.SetState(SCE_A68K_NUMBER_DEC);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '%')) { // Binary numbers are prefixed with '%'
+ sc.SetState(SCE_A68K_NUMBER_BIN);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '$')) { // Hexadecimal numbers are prefixed with '$'
+ sc.SetState(SCE_A68K_NUMBER_HEX);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '\'')) { // String (single-quoted)
+ sc.SetState(SCE_A68K_STRING1);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '\"')) { // String (double-quoted)
+ sc.SetState(SCE_A68K_STRING2);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '\\') && (isdigit(sc.chNext))) { // Replacement symbols in macro
+ sc.SetState(SCE_A68K_MACRO_ARG);
+ }
+ else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) { // An identifier: constant, label, etc...
+ sc.SetState(SCE_A68K_IDENTIFIER);
+ }
+ else {
+ if (sc.ch < 0x80) {
+ OpType = GetOperatorType(sc.ch, sc.chNext); // Check if current char is an operator
+ if (OpType != NO_OPERATOR) {
+ sc.SetState(SCE_A68K_OPERATOR);
+ if (OpType == OPERATOR_2CHAR) { // Check if the operator is 2 bytes long
+ sc.ForwardSetState(SCE_A68K_OPERATOR); // (>> or <<)
+ }
+ }
+ }
+ }
+ } // End of for()
+ sc.Complete();
+}
+
+
+// Names of the keyword lists
+
+static const char * const a68kWordListDesc[] =
+{
+ "CPU instructions",
+ "Registers",
+ "Directives",
+ "Extended instructions",
+ "Comment special words",
+ "Doxygen keywords",
+ 0
+};
+
+LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, "a68k", 0, a68kWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexAPDL.cxx
+ ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
+ ** By Hadar Raz.
+ **/
+// Copyright 1998-2003 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 IsAWordChar(const int ch) {
+ return (ch < 0x80 && (isalnum(ch) || ch == '_'));
+}
+
+static inline bool IsAnOperator(char ch) {
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
+ ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
+ ch == '$' || ch == ':' || ch == '%')
+ return true;
+ return false;
+}
+
+static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ int stringStart = ' ';
+
+ WordList &processors = *keywordlists[0];
+ WordList &commands = *keywordlists[1];
+ WordList &slashcommands = *keywordlists[2];
+ WordList &starcommands = *keywordlists[3];
+ WordList &arguments = *keywordlists[4];
+ WordList &functions = *keywordlists[5];
+
+ // Do not leak onto next line
+ initStyle = SCE_APDL_DEFAULT;
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_APDL_NUMBER) {
+ if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
+ ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ sc.SetState(SCE_APDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_APDL_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_APDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_APDL_COMMENTBLOCK) {
+ if (sc.atLineEnd) {
+ if (sc.ch == '\r') {
+ sc.Forward();
+ }
+ sc.ForwardSetState(SCE_APDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_APDL_STRING) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_APDL_DEFAULT);
+ } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
+ sc.ForwardSetState(SCE_APDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_APDL_WORD) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (processors.InList(s)) {
+ sc.ChangeState(SCE_APDL_PROCESSOR);
+ } else if (slashcommands.InList(s)) {
+ sc.ChangeState(SCE_APDL_SLASHCOMMAND);
+ } else if (starcommands.InList(s)) {
+ sc.ChangeState(SCE_APDL_STARCOMMAND);
+ } else if (commands.InList(s)) {
+ sc.ChangeState(SCE_APDL_COMMAND);
+ } else if (arguments.InList(s)) {
+ sc.ChangeState(SCE_APDL_ARGUMENT);
+ } else if (functions.InList(s)) {
+ sc.ChangeState(SCE_APDL_FUNCTION);
+ }
+ sc.SetState(SCE_APDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_APDL_OPERATOR) {
+ if (!IsAnOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_APDL_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_APDL_DEFAULT) {
+ if (sc.ch == '!' && sc.chNext == '!') {
+ sc.SetState(SCE_APDL_COMMENTBLOCK);
+ } else if (sc.ch == '!') {
+ sc.SetState(SCE_APDL_COMMENT);
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_APDL_NUMBER);
+ } else if (sc.ch == '\'' || sc.ch == '\"') {
+ sc.SetState(SCE_APDL_STRING);
+ stringStart = sc.ch;
+ } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
+ sc.SetState(SCE_APDL_WORD);
+ } else if (IsAnOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_APDL_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+//------------------------------------------------------------------------------
+// 06-27-07 Sergio Lucato
+// - Included code folding for Ansys APDL lexer
+// - Copyied from LexBasic.cxx and modified for APDL
+//------------------------------------------------------------------------------
+
+/* Bits:
+ * 1 - whitespace
+ * 2 - operator
+ * 4 - identifier
+ * 8 - decimal digit
+ * 16 - hex digit
+ * 32 - bin digit
+ */
+static int character_classification[128] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
+ 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
+};
+
+static bool IsSpace(int c) {
+ return c < 128 && (character_classification[c] & 1);
+}
+
+static bool IsIdentifier(int c) {
+ return c < 128 && (character_classification[c] & 4);
+}
+
+static int LowerCase(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+static int CheckAPDLFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "*if") ||
+ !strcmp(token, "*do") ||
+ !strcmp(token, "*dowhile") ) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "*endif") ||
+ !strcmp(token, "*enddo") ) {
+ return -1;
+ }
+ return 0;
+}
+
+static void FoldAPDLDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+
+ int line = styler.GetLine(startPos);
+ int level = styler.LevelAt(line);
+ int go = 0, done = 0;
+ int endPos = startPos + length;
+ char word[256];
+ int wordlen = 0;
+ int i;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ // Scan for tokens at the start of the line (they may include
+ // whitespace, for tokens like "End Function"
+ for (i = startPos; i < endPos; i++) {
+ int c = styler.SafeGetCharAt(i);
+ if (!done && !go) {
+ if (wordlen) { // are we scanning a token already?
+ word[wordlen] = static_cast<char>(LowerCase(c));
+ if (!IsIdentifier(c)) { // done with token
+ word[wordlen] = '\0';
+ go = CheckAPDLFoldPoint(word, level);
+ if (!go) {
+ // Treat any whitespace as single blank, for
+ // things like "End Function".
+ if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
+ word[wordlen] = ' ';
+ if (wordlen < 255)
+ wordlen++;
+ }
+ else // done with this line
+ done = 1;
+ }
+ } else if (wordlen < 255) {
+ wordlen++;
+ }
+ } else { // start scanning at first non-whitespace character
+ if (!IsSpace(c)) {
+ if (IsIdentifier(c)) {
+ word[0] = static_cast<char>(LowerCase(c));
+ wordlen = 1;
+ } else // done with this line
+ done = 1;
+ }
+ }
+ }
+ if (c == '\n') { // line end
+ if (!done && wordlen == 0 && foldCompact) // line was only space
+ level |= SC_FOLDLEVELWHITEFLAG;
+ if (level != styler.LevelAt(line))
+ styler.SetLevel(line, level);
+ level += go;
+ line++;
+ // reset state
+ wordlen = 0;
+ level &= ~SC_FOLDLEVELHEADERFLAG;
+ level &= ~SC_FOLDLEVELWHITEFLAG;
+ go = 0;
+ done = 0;
+ }
+ }
+}
+
+static const char * const apdlWordListDesc[] = {
+ "processors",
+ "commands",
+ "slashommands",
+ "starcommands",
+ "arguments",
+ "functions",
+ 0
+};
+
+LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+//Author: instanton (email: soft_share<at>126<dot>com)
+// 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 "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 void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+ int visibleChars = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart) {
+ if (sc.state == SCE_ASY_STRING) {
+ sc.SetState(SCE_ASY_STRING);
+ }
+ visibleChars = 0;
+ }
+
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+// continuationLine = true;
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_ASY_OPERATOR:
+ sc.SetState(SCE_ASY_DEFAULT);
+ break;
+ case SCE_ASY_NUMBER:
+ if (!setWord.Contains(sc.ch)) {
+ sc.SetState(SCE_ASY_DEFAULT);
+ }
+ break;
+ case SCE_ASY_IDENTIFIER:
+ if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_ASY_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_ASY_WORD2);
+ }
+ sc.SetState(SCE_ASY_DEFAULT);
+ }
+ break;
+ case SCE_ASY_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_ASY_DEFAULT);
+ }
+ break;
+ case SCE_ASY_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_ASY_DEFAULT);
+ }
+ break;
+ case SCE_ASY_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_ASY_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_ASY_DEFAULT);
+ }
+ break;
+ case SCE_ASY_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_ASY_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_ASY_DEFAULT);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_ASY_DEFAULT) {
+ if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
+ sc.SetState(SCE_ASY_IDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_ASY_COMMENT);
+ sc.Forward(); //
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_ASY_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_ASY_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_ASY_CHARACTER);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_ASY_DEFAULT);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_ASY_OPERATOR);
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+static bool IsAsyCommentStyle(int style) {
+ return style == SCE_ASY_COMMENT;
+}
+
+
+static inline bool isASYidentifier(int ch) {
+ return
+ ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ;
+}
+
+static int ParseASYWord(unsigned int pos, Accessor &styler, char *word)
+{
+ int length=0;
+ char ch=styler.SafeGetCharAt(pos);
+ *word=0;
+
+ while(isASYidentifier(ch) && length<100){
+ word[length]=ch;
+ length++;
+ ch=styler.SafeGetCharAt(pos+length);
+ }
+ word[length]=0;
+ return length;
+}
+
+static bool IsASYDrawingLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+
+ int startpos = pos;
+ char buffer[100]="";
+
+ while (startpos<eol_pos){
+ char ch = styler[startpos];
+ ParseASYWord(startpos,styler,buffer);
+ bool drawcommands = strncmp(buffer,"draw",4)==0||
+ strncmp(buffer,"pair",4)==0||strncmp(buffer,"label",5)==0;
+ if (!drawcommands && ch!=' ') return false;
+ else if (drawcommands) return true;
+ startpos++;
+ }
+ return false;
+}
+
+static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && IsAsyCommentStyle(style)) {
+ if (!IsAsyCommentStyle(stylePrev) && (stylePrev != SCE_ASY_COMMENTLINEDOC)) {
+ levelNext++;
+ } else if (!IsAsyCommentStyle(styleNext) && (styleNext != SCE_ASY_COMMENTLINEDOC) && !atEOL) {
+ levelNext--;
+ }
+ }
+ if (style == SCE_ASY_OPERATOR) {
+ if (ch == '{') {
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+
+ if (atEOL && IsASYDrawingLine(lineCurrent, styler)){
+ if (lineCurrent==0 && IsASYDrawingLine(lineCurrent + 1, styler))
+ levelNext++;
+ else if (lineCurrent!=0 && !IsASYDrawingLine(lineCurrent - 1, styler)
+ && IsASYDrawingLine(lineCurrent + 1, styler)
+ )
+ levelNext++;
+ else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&
+ !IsASYDrawingLine(lineCurrent+1, styler))
+ levelNext--;
+ }
+
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ }
+}
+
+static const char * const asyWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ 0,
+ };
+
+LexerModule lmASY(SCLEX_ASYMPTOTE, ColouriseAsyDoc, "asy", FoldAsyDoc, asyWordLists);
--- /dev/null
+// Scintilla source code edit control
+// @file LexAU3.cxx
+// Lexer for AutoIt3 http://www.hiddensoft.com/autoit3
+// by Jos van der Zande, jvdzande@yahoo.com
+//
+// Changes:
+// March 28, 2004 - Added the standard Folding code
+// April 21, 2004 - Added Preprosessor Table + Syntax Highlighting
+// Fixed Number highlighting
+// Changed default isoperator to IsAOperator to have a better match to AutoIt3
+// Fixed "#comments_start" -> "#comments-start"
+// Fixed "#comments_end" -> "#comments-end"
+// Fixed Sendkeys in Strings when not terminated with }
+// Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
+// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
+// Added logic for #include <xyz.au3> to treat the <> as string
+// Added underscore to IsAOperator.
+// May 17, 2004 - Changed the folding logic from indent to keyword folding.
+// Added Folding logic for blocks of single-commentlines or commentblock.
+// triggered by: fold.comment=1
+// Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1
+// Added Special for #region - #endregion syntax highlight and folding.
+// May 30, 2004 - Fixed issue with continuation lines on If statements.
+// June 5, 2004 - Added comma to Operators for better readability.
+// Added fold.compact support set with fold.compact=1
+// Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
+// it will now only happen when fold.comment=2.
+// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
+// Typed Characters now show as "default" till they match any table.
+// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
+// Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
+// Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
+// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
+// Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator.
+// Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account
+// - Added folding support for With...EndWith
+// - Added support for a DOT in variable names
+// - Fixed Underscore in CommentBlock
+// May 23, 2005 - Fixed the SentKey lexing in case of a missing }
+// Aug 11, 2005 - Fixed possible bug with s_save length > 100.
+// Aug 23, 2005 - Added Switch/endswitch support to the folding logic.
+// Sep 27, 2005 - Fixed the SentKey lexing logic in case of multiple sentkeys.
+// Mar 12, 2006 - Fixed issue with <> coloring as String in stead of Operator in rare occasions.
+// Apr 8, 2006 - Added support for AutoIt3 Standard UDF library (SCE_AU3_UDF)
+// Mar 9, 2007 - Fixed bug with + following a String getting the wrong Color.
+// Jun 20, 2007 - Fixed Commentblock issue when LF's are used as EOL.
+// Jul 26, 2007 - Fixed #endregion undetected bug.
+//
+// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+// Scintilla source code edit control
+
+#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 IsTypeCharacter(const int ch)
+{
+ return ch == '$';
+}
+static inline bool IsAWordChar(const int ch)
+{
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch)
+{
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
+}
+
+static inline bool IsAOperator(char ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
+ ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' ||
+ ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' )
+ return true;
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// GetSendKey() filters the portion before and after a/multiple space(s)
+// and return the first portion to be looked-up in the table
+// also check if the second portion is valid... (up,down.on.off,toggle or a number)
+///////////////////////////////////////////////////////////////////////////////
+
+static int GetSendKey(const char *szLine, char *szKey)
+{
+ int nFlag = 0;
+ int nStartFound = 0;
+ int nKeyPos = 0;
+ int nSpecPos= 0;
+ int nSpecNum= 1;
+ int nPos = 0;
+ char cTemp;
+ char szSpecial[100];
+
+ // split the portion of the sendkey in the part before and after the spaces
+ while ( ( (cTemp = szLine[nPos]) != '\0'))
+ {
+ // skip leading Ctrl/Shift/Alt state
+ if (cTemp == '{') {
+ nStartFound = 1;
+ }
+ //
+ if (nStartFound == 1) {
+ if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
+ {
+ nFlag = 1;
+ // Add } to the end of the first bit for table lookup later.
+ szKey[nKeyPos++] = '}';
+ }
+ else if (cTemp == ' ')
+ {
+ // skip other spaces
+ }
+ else if (nFlag == 0)
+ {
+ // save first portion into var till space or } is hit
+ szKey[nKeyPos++] = cTemp;
+ }
+ else if ((nFlag == 1) && (cTemp != '}'))
+ {
+ // Save second portion into var...
+ szSpecial[nSpecPos++] = cTemp;
+ // check if Second portion is all numbers for repeat fuction
+ if (isdigit(cTemp) == false) {nSpecNum = 0;}
+ }
+ }
+ nPos++; // skip to next char
+
+ } // End While
+
+
+ // Check if the second portion is either a number or one of these keywords
+ szKey[nKeyPos] = '\0';
+ szSpecial[nSpecPos] = '\0';
+ if (strcmp(szSpecial,"down")== 0 || strcmp(szSpecial,"up")== 0 ||
+ strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 ||
+ strcmp(szSpecial,"toggle")== 0 || nSpecNum == 1 )
+ {
+ nFlag = 0;
+ }
+ else
+ {
+ nFlag = 1;
+ }
+ return nFlag; // 1 is bad, 0 is good
+
+} // GetSendKey()
+
+//
+// Routine to check the last "none comment" character on a line to see if its a continuation
+//
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
+{
+ int nsPos = styler.LineStart(szLine);
+ int nePos = styler.LineStart(szLine+1) - 2;
+ //int stylech = styler.StyleAt(nsPos);
+ while (nsPos < nePos)
+ {
+ //stylech = styler.StyleAt(nePos);
+ int stylech = styler.StyleAt(nsPos);
+ if (!(stylech == SCE_AU3_COMMENT)) {
+ char ch = styler.SafeGetCharAt(nePos);
+ if (!isspacechar(ch)) {
+ if (ch == '_')
+ return true;
+ else
+ return false;
+ }
+ }
+ nePos--; // skip to next char
+ } // End While
+ return false;
+} // IsContinuationLine()
+
+//
+// syntax highlighting logic
+static void ColouriseAU3Doc(unsigned int startPos,
+ int length, int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+ // find the first previous line without continuation character at the end
+ int lineCurrent = styler.GetLine(startPos);
+ int s_startPos = startPos;
+ // When not inside a Block comment: find First line without _
+ if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
+ (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent); // get start position
+ initStyle = 0; // reset the start style to 0
+ }
+ }
+ // Set the new length to include it from the start and set the start position
+ length = length + s_startPos - startPos; // correct the total length to process
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ char si; // string indicator "=1 '=2
+ char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
+ char ci; // comment indicator 0=not linecomment(;)
+ char s_save[100];
+ si=0;
+ ni=0;
+ ci=0;
+ //$$$
+ for (; sc.More(); sc.Forward()) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ // **********************************************
+ // save the total current word for eof processing
+ if (IsAWordChar(sc.ch) || sc.ch == '}')
+ {
+ strcpy(s_save,s);
+ int tp = static_cast<int>(strlen(s_save));
+ if (tp < 99) {
+ s_save[tp] = static_cast<char>(tolower(sc.ch));
+ s_save[tp+1] = '\0';
+ }
+ }
+ // **********************************************
+ //
+ switch (sc.state)
+ {
+ case SCE_AU3_COMMENTBLOCK:
+ {
+ //Reset at line end
+ if (sc.atLineEnd) {
+ ci=0;
+ if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
+ if (sc.atLineEnd)
+ sc.SetState(SCE_AU3_DEFAULT);
+ else
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ break;
+ }
+ //skip rest of line when a ; is encountered
+ if (sc.chPrev == ';') {
+ ci=2;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ // skip rest of the line
+ if (ci==2)
+ break;
+ // check when first character is detected on the line
+ if (ci==0) {
+ if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
+ ci=1;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ break;
+ }
+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
+ if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
+ sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line
+ else
+ ci=2; // line doesn't begin with #CE so skip the rest of the line
+ }
+ break;
+ }
+ case SCE_AU3_COMMENT:
+ {
+ if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ break;
+ }
+ case SCE_AU3_OPERATOR:
+ {
+ // check if its a COMobject
+ if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_AU3_COMOBJ);
+ }
+ else {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ case SCE_AU3_SPECIAL:
+ {
+ if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
+ if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ break;
+ }
+ case SCE_AU3_KEYWORD:
+ {
+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0))))
+ {
+ if (!IsTypeCharacter(sc.ch))
+ {
+ if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 )
+ {
+ sc.ChangeState(SCE_AU3_COMMENTBLOCK);
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ break;
+ }
+ else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_AU3_KEYWORD);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_AU3_FUNCTION);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_AU3_MACRO);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_AU3_PREPROCESSOR);
+ sc.SetState(SCE_AU3_DEFAULT);
+ if (strcmp(s, "#include")== 0)
+ {
+ si = 3; // use to determine string start for #inlude <>
+ }
+ }
+ else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_AU3_SPECIAL);
+ sc.SetState(SCE_AU3_SPECIAL);
+ }
+ else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
+ sc.ChangeState(SCE_AU3_EXPAND);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ else if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_AU3_UDF);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ else if (strcmp(s, "_") == 0) {
+ sc.ChangeState(SCE_AU3_OPERATOR);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ else if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ }
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_AU3_DEFAULT);}
+ break;
+ }
+ case SCE_AU3_NUMBER:
+ {
+ // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
+ //
+ // test for Hex notation
+ if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
+ {
+ ni = 2;
+ break;
+ }
+ // test for E notation
+ if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
+ {
+ ni = 3;
+ break;
+ }
+ // Allow Hex characters inside hex numeric strings
+ if ((ni == 2) &&
+ (sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
+ sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
+ {
+ break;
+ }
+ // test for 1 dec point only
+ if (sc.ch == '.')
+ {
+ if (ni==0)
+ {
+ ni=1;
+ }
+ else
+ {
+ ni=9;
+ }
+ break;
+ }
+ // end of numeric string ?
+ if (!(IsADigit(sc.ch)))
+ {
+ if (ni==9)
+ {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ }
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ case SCE_AU3_VARIABLE:
+ {
+ // Check if its a COMObject
+ if (sc.ch == '.' && !IsADigit(sc.chNext)) {
+ sc.SetState(SCE_AU3_OPERATOR);
+ }
+ else if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ case SCE_AU3_COMOBJ:
+ {
+ if (!(IsAWordChar(sc.ch))) {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ case SCE_AU3_STRING:
+ {
+ // check for " to end a double qouted string or
+ // check for ' to end a single qouted string
+ if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
+ {
+ sc.ForwardSetState(SCE_AU3_DEFAULT);
+ si=0;
+ break;
+ }
+ if (sc.atLineEnd)
+ {
+ si=0;
+ // at line end and not found a continuation char then reset to default
+ int lineCurrent = styler.GetLine(sc.currentPos);
+ if (!IsContinuationLine(lineCurrent,styler))
+ {
+ sc.SetState(SCE_AU3_DEFAULT);
+ break;
+ }
+ }
+ // find Sendkeys in a STRING
+ if (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) {
+ sc.SetState(SCE_AU3_SENT);}
+ break;
+ }
+
+ case SCE_AU3_SENT:
+ {
+ // Send key string ended
+ if (sc.chPrev == '}' && sc.ch != '}')
+ {
+ // set color to SENDKEY when valid sendkey .. else set back to regular string
+ char sk[100];
+ // split {111 222} and return {111} and check if 222 is valid.
+ // if return code = 1 then invalid 222 so must be string
+ if (GetSendKey(s,sk))
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ // if single char between {?} then its ok as sendkey for a single character
+ else if (strlen(sk) == 3)
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ // if sendkey {111} is in table then ok as sendkey
+ else if (keywords4.InList(sk))
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ else
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ sc.SetState(SCE_AU3_STRING);
+ }
+ else
+ {
+ // check if the start is a valid SendKey start
+ int nPos = 0;
+ int nState = 1;
+ char cTemp;
+ while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
+ {
+ if (cTemp == '{' && nState == 1)
+ {
+ nState = 2;
+ }
+ if (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' ))
+ {
+ nState = 0;
+ }
+ nPos++;
+ }
+ //Verify characters infront of { ... if not assume regular string
+ if (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.SetState(SCE_AU3_STRING);
+ }
+ // If invalid character found then assume its a regular string
+ if (nState == 0) {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.SetState(SCE_AU3_STRING);
+ }
+ }
+ // check if next portion is again a sendkey
+ if (sc.atLineEnd)
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.SetState(SCE_AU3_DEFAULT);
+ si = 0; // reset string indicator
+ }
+ //* check in next characters following a sentkey are again a sent key
+ // Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{}
+ if (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) {
+ sc.SetState(SCE_AU3_SENT);}
+ // check to see if the string ended...
+ // Sendkey string isn't complete but the string ended....
+ if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\''))
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.ForwardSetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ } //switch (sc.state)
+
+ // Determine if a new state should be entered:
+
+ if (sc.state == SCE_AU3_DEFAULT)
+ {
+ if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
+ else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
+ else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
+ else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
+ else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
+ //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
+ else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
+ else if (sc.ch == '\"') {
+ sc.SetState(SCE_AU3_STRING);
+ si = 1; }
+ else if (sc.ch == '\'') {
+ sc.SetState(SCE_AU3_STRING);
+ si = 2; }
+ else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+ {
+ sc.SetState(SCE_AU3_NUMBER);
+ ni = 0;
+ }
+ else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
+ else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
+ else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ }
+ } //for (; sc.More(); sc.Forward())
+
+ //*************************************
+ // Colourize the last word correctly
+ //*************************************
+ if (sc.state == SCE_AU3_KEYWORD)
+ {
+ if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
+ {
+ sc.ChangeState(SCE_AU3_COMMENTBLOCK);
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ else if (keywords.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_KEYWORD);
+ sc.SetState(SCE_AU3_KEYWORD);
+ }
+ else if (keywords2.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_FUNCTION);
+ sc.SetState(SCE_AU3_FUNCTION);
+ }
+ else if (keywords3.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_MACRO);
+ sc.SetState(SCE_AU3_MACRO);
+ }
+ else if (keywords5.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_PREPROCESSOR);
+ sc.SetState(SCE_AU3_PREPROCESSOR);
+ }
+ else if (keywords6.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_SPECIAL);
+ sc.SetState(SCE_AU3_SPECIAL);
+ }
+ else if (keywords7.InList(s_save) && sc.atLineEnd) {
+ sc.ChangeState(SCE_AU3_EXPAND);
+ sc.SetState(SCE_AU3_EXPAND);
+ }
+ else if (keywords8.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_UDF);
+ sc.SetState(SCE_AU3_UDF);
+ }
+ else {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ if (sc.state == SCE_AU3_SENT)
+ {
+ // Send key string ended
+ if (sc.chPrev == '}' && sc.ch != '}')
+ {
+ // set color to SENDKEY when valid sendkey .. else set back to regular string
+ char sk[100];
+ // split {111 222} and return {111} and check if 222 is valid.
+ // if return code = 1 then invalid 222 so must be string
+ if (GetSendKey(s_save,sk))
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ // if single char between {?} then its ok as sendkey for a single character
+ else if (strlen(sk) == 3)
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ // if sendkey {111} is in table then ok as sendkey
+ else if (keywords4.InList(sk))
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ else
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ sc.SetState(SCE_AU3_STRING);
+ }
+ // check if next portion is again a sendkey
+ if (sc.atLineEnd)
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ //*************************************
+ sc.Complete();
+}
+
+//
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK;
+}
+
+//
+// Routine to find first none space on the current line and return its Style
+// needed for comment lines not starting on pos 1
+static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
+{
+ int nsPos = styler.LineStart(szLine);
+ int nePos = styler.LineStart(szLine+1) - 1;
+ while (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)
+ {
+ nsPos++; // skip to next char
+
+ } // End While
+ return styler.StyleAt(nsPos);
+
+} // GetStyleFirstWord()
+
+
+//
+static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ int endPos = startPos + length;
+ // get settings from the config files for folding comments and preprocessor lines
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ // vars for style of previous/current/next lines
+ int style = GetStyleFirstWord(lineCurrent,styler);
+ int stylePrev = 0;
+ // find the first previous line without continuation character at the end
+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
+ (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ if (lineCurrent > 0) {
+ stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
+ }
+ // vars for getting first word to check for keywords
+ bool FirstWordStart = false;
+ bool FirstWordEnd = false;
+ char szKeyword[11]="";
+ int szKeywordlen = 0;
+ char szThen[5]="";
+ int szThenlen = 0;
+ bool ThenFoundLast = false;
+ // var for indentlevel
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+ //
+ int visibleChars = 0;
+ char chNext = styler.SafeGetCharAt(startPos);
+ char chPrev = ' ';
+ //
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (IsAWordChar(ch)) {
+ visibleChars++;
+ }
+ // get the syle for the current character neede to check in comment
+ int stylech = styler.StyleAt(i);
+ // get first word for the line for indent check max 9 characters
+ if (FirstWordStart && (!(FirstWordEnd))) {
+ if (!IsAWordChar(ch)) {
+ FirstWordEnd = true;
+ szKeyword[szKeywordlen] = '\0';
+ }
+ else {
+ if (szKeywordlen < 10) {
+ szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+ }
+ }
+ }
+ // start the capture of the first word
+ if (!(FirstWordStart)) {
+ if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
+ FirstWordStart = true;
+ szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+ }
+ }
+ // only process this logic when not in comment section
+ if (!(stylech == SCE_AU3_COMMENT)) {
+ if (ThenFoundLast) {
+ if (IsAWordChar(ch)) {
+ ThenFoundLast = false;
+ }
+ }
+ // find out if the word "then" is the last on a "if" line
+ if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
+ if (szThenlen == 4) {
+ szThen[0] = szThen[1];
+ szThen[1] = szThen[2];
+ szThen[2] = szThen[3];
+ szThen[3] = static_cast<char>(tolower(ch));
+ if (strcmp(szThen,"then") == 0 ) {
+ ThenFoundLast = true;
+ }
+ }
+ else {
+ szThen[szThenlen++] = static_cast<char>(tolower(ch));
+ if (szThenlen == 5) {
+ szThen[4] = '\0';
+ }
+ }
+ }
+ }
+ // End of Line found so process the information
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ // **************************
+ // Folding logic for Keywords
+ // **************************
+ // if a keyword is found on the current line and the line doesn't end with _ (continuation)
+ // and we are not inside a commentblock.
+ if (szKeywordlen > 0 && (!(chPrev == '_')) &&
+ ((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
+ szKeyword[szKeywordlen] = '\0';
+ // only fold "if" last keyword is "then" (else its a one line if)
+ if (strcmp(szKeyword,"if") == 0 && ThenFoundLast) {
+ levelNext++;
+ }
+ // create new fold for these words
+ if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
+ strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
+ strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
+ levelNext++;
+ }
+ // create double Fold for select&switch because Case will subtract one of the current level
+ if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
+ levelNext++;
+ levelNext++;
+ }
+ // end the fold for these words before the current line
+ if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
+ strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
+ strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
+ levelNext--;
+ levelCurrent--;
+ }
+ // end the fold for these words before the current line and Start new fold
+ if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 ||
+ strcmp(szKeyword,"elseif") == 0 ) {
+ levelCurrent--;
+ }
+ // end the double fold for this word before the current line
+ if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
+ levelNext--;
+ levelNext--;
+ levelCurrent--;
+ levelCurrent--;
+ }
+ // end the fold for these words on the current line
+ if (strcmp(szKeyword,"#endregion") == 0 ) {
+ levelNext--;
+ }
+ }
+ // Preprocessor and Comment folding
+ int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
+ // *************************************
+ // Folding logic for preprocessor blocks
+ // *************************************
+ // process preprosessor line
+ if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {
+ if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {
+ levelNext++;
+ }
+ // fold till the last line for normal comment lines
+ else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {
+ levelNext--;
+ }
+ }
+ // *********************************
+ // Folding logic for Comment blocks
+ // *********************************
+ if (foldComment && IsStreamCommentStyle(style)) {
+ // Start of a comment block
+ if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
+ levelNext++;
+ }
+ // fold till the last line for normal comment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && !(styleNext == SCE_AU3_COMMENT)
+ && stylePrev == SCE_AU3_COMMENT
+ && style == SCE_AU3_COMMENT) {
+ levelNext--;
+ }
+ // fold till the one but last line for Blockcomment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && !(styleNext == SCE_AU3_COMMENTBLOCK)
+ && style == SCE_AU3_COMMENTBLOCK) {
+ levelNext--;
+ levelCurrent--;
+ }
+ }
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ // reset values for the next line
+ lineCurrent++;
+ stylePrev = style;
+ style = styleNext;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+ // if the last character is an Underscore then don't reset since the line continues on the next line.
+ if (!(chPrev == '_')) {
+ szKeywordlen = 0;
+ szThenlen = 0;
+ FirstWordStart = false;
+ FirstWordEnd = false;
+ ThenFoundLast = false;
+ }
+ }
+ // save the last processed character
+ if (!isspacechar(ch)) {
+ chPrev = ch;
+ visibleChars++;
+ }
+ }
+}
+
+
+//
+
+static const char * const AU3WordLists[] = {
+ "#autoit keywords",
+ "#autoit functions",
+ "#autoit macros",
+ "#autoit Sent keys",
+ "#autoit Pre-processors",
+ "#autoit Special",
+ "#autoit Expand",
+ "#autoit UDF",
+ 0
+};
+LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
--- /dev/null
+// SciTE - Scintilla based Text Editor
+/** @file LexAVE.cxx
+ ** Lexer for Avenue.
+ **
+ ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
+ **/
+// Copyright 1998-2002 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+static inline bool IsEnumChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch)|| ch == '_');
+}
+static inline bool IsANumberChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' );
+}
+
+inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+inline bool isAveOperator(char ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' ||
+ ch == '{' || ch == '}' ||
+ ch == '[' || ch == ']' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' ||
+ ch == '.' )
+ return true;
+ return false;
+}
+
+static void ColouriseAveDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_AVE_STRINGEOL) {
+ initStyle = SCE_AVE_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ int currentLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(currentLine, 0);
+ }
+ if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
+ // Prevent SCE_AVE_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_AVE_STRING);
+ }
+
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_AVE_OPERATOR) {
+ sc.SetState(SCE_AVE_DEFAULT);
+ } else if (sc.state == SCE_AVE_NUMBER) {
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_AVE_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVE_ENUM) {
+ if (!IsEnumChar(sc.ch)) {
+ sc.SetState(SCE_AVE_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVE_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[100];
+ //sc.GetCurrent(s, sizeof(s));
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_AVE_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_AVE_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_AVE_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_AVE_WORD4);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_AVE_WORD5);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_AVE_WORD6);
+ }
+ sc.SetState(SCE_AVE_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVE_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_AVE_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVE_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_AVE_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_AVE_STRINGEOL);
+ sc.ForwardSetState(SCE_AVE_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_AVE_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_AVE_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_AVE_IDENTIFIER);
+ } else if (sc.Match('\"')) {
+ sc.SetState(SCE_AVE_STRING);
+ } else if (sc.Match('\'')) {
+ sc.SetState(SCE_AVE_COMMENT);
+ sc.Forward();
+ } else if (isAveOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_AVE_OPERATOR);
+ } else if (sc.Match('#')) {
+ sc.SetState(SCE_AVE_ENUM);
+ sc.Forward();
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = static_cast<char>(tolower(styler[startPos]));
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ int styleNext = styler.StyleAt(startPos);
+ char s[10];
+
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = static_cast<char>(tolower(chNext));
+ chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_AVE_WORD) {
+ if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
+ for (unsigned int j = 0; j < 6; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = static_cast<char>(tolower(styler[i + j]));
+ s[j + 1] = '\0';
+ }
+
+ if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
+ levelCurrent++;
+ }
+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
+ // Normally "elseif" and "then" will be on the same line and will cancel
+ // each other out. // As implemented, this does not support fold.at.else.
+ levelCurrent--;
+ }
+ }
+ } else if (style == SCE_AVE_OPERATOR) {
+ if (ch == '{' || ch == '(') {
+ levelCurrent++;
+ } else if (ch == '}' || ch == ')') {
+ levelCurrent--;
+ }
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact) {
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ }
+ if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch)) {
+ visibleChars++;
+ }
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexAVS.cxx
+ ** Lexer for AviSynth.
+ **/
+// Copyright 2012 by Bruno Barbieri <brunorex@gmail.com>
+// Heavily based on LexPOV by Neil Hodgson
+// 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return isalpha(ch) || (ch != ' ' && ch != '\n' && ch != '(' && ch != '.' && ch != ',');
+}
+
+static inline bool IsANumberChar(int ch) {
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases.
+ return (ch < 0x80) &&
+ (isdigit(ch) || ch == '.' || ch == '-' || ch == '+');
+}
+
+static void ColouriseAvsDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &filters = *keywordlists[1];
+ WordList &plugins = *keywordlists[2];
+ WordList &functions = *keywordlists[3];
+ WordList &clipProperties = *keywordlists[4];
+ WordList &userDefined = *keywordlists[5];
+
+ int currentLine = styler.GetLine(startPos);
+ // Initialize the block comment nesting level, if we are inside such a comment.
+ int blockCommentLevel = 0;
+ if (initStyle == SCE_AVS_COMMENTBLOCK || initStyle == SCE_AVS_COMMENTBLOCKN) {
+ blockCommentLevel = styler.GetLineState(currentLine - 1);
+ }
+
+ // Do not leak onto next line
+ if (initStyle == SCE_AVS_COMMENTLINE) {
+ initStyle = SCE_AVS_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ currentLine = styler.GetLine(sc.currentPos);
+ if (sc.state == SCE_AVS_COMMENTBLOCK || sc.state == SCE_AVS_COMMENTBLOCKN) {
+ // Inside a block comment, we set the line state
+ styler.SetLineState(currentLine, blockCommentLevel);
+ } else {
+ // Reset the line state
+ styler.SetLineState(currentLine, 0);
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_AVS_OPERATOR) {
+ sc.SetState(SCE_AVS_DEFAULT);
+ } else if (sc.state == SCE_AVS_NUMBER) {
+ // We stop the number definition on non-numerical non-dot non-sign char
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_AVS_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVS_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_AVS_KEYWORD);
+ } else if (filters.InList(s)) {
+ sc.ChangeState(SCE_AVS_FILTER);
+ } else if (plugins.InList(s)) {
+ sc.ChangeState(SCE_AVS_PLUGIN);
+ } else if (functions.InList(s)) {
+ sc.ChangeState(SCE_AVS_FUNCTION);
+ } else if (clipProperties.InList(s)) {
+ sc.ChangeState(SCE_AVS_CLIPPROP);
+ } else if (userDefined.InList(s)) {
+ sc.ChangeState(SCE_AVS_USERDFN);
+ }
+ sc.SetState(SCE_AVS_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVS_COMMENTBLOCK) {
+ if (sc.Match('/', '*')) {
+ blockCommentLevel++;
+ sc.Forward();
+ } else if (sc.Match('*', '/') && blockCommentLevel > 0) {
+ blockCommentLevel--;
+ sc.Forward();
+ if (blockCommentLevel == 0) {
+ sc.ForwardSetState(SCE_AVS_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_AVS_COMMENTBLOCKN) {
+ if (sc.Match('[', '*')) {
+ blockCommentLevel++;
+ sc.Forward();
+ } else if (sc.Match('*', ']') && blockCommentLevel > 0) {
+ blockCommentLevel--;
+ sc.Forward();
+ if (blockCommentLevel == 0) {
+ sc.ForwardSetState(SCE_AVS_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_AVS_COMMENTLINE) {
+ if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_AVS_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVS_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_AVS_DEFAULT);
+ }
+ } else if (sc.state == SCE_AVS_TRIPLESTRING) {
+ if (sc.Match("\"\"\"")) {
+ sc.Forward();
+ sc.Forward();
+ sc.ForwardSetState(SCE_AVS_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_AVS_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_AVS_NUMBER);
+ } else if (IsADigit(sc.ch) || (sc.ch == ',' && IsADigit(sc.chNext))) {
+ sc.Forward();
+ sc.SetState(SCE_AVS_NUMBER);
+ } else if (sc.Match('/', '*')) {
+ blockCommentLevel = 1;
+ sc.SetState(SCE_AVS_COMMENTBLOCK);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('[', '*')) {
+ blockCommentLevel = 1;
+ sc.SetState(SCE_AVS_COMMENTBLOCKN);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_AVS_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ if (sc.Match("\"\"\"")) {
+ sc.SetState(SCE_AVS_TRIPLESTRING);
+ } else {
+ sc.SetState(SCE_AVS_STRING);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_AVS_OPERATOR);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_AVS_IDENTIFIER);
+ }
+ }
+ }
+
+ // End of file: complete any pending changeState
+ if (sc.state == SCE_AVS_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_AVS_KEYWORD);
+ } else if (filters.InList(s)) {
+ sc.ChangeState(SCE_AVS_FILTER);
+ } else if (plugins.InList(s)) {
+ sc.ChangeState(SCE_AVS_PLUGIN);
+ } else if (functions.InList(s)) {
+ sc.ChangeState(SCE_AVS_FUNCTION);
+ } else if (clipProperties.InList(s)) {
+ sc.ChangeState(SCE_AVS_CLIPPROP);
+ } else if (userDefined.InList(s)) {
+ sc.ChangeState(SCE_AVS_USERDFN);
+ }
+ sc.SetState(SCE_AVS_DEFAULT);
+ }
+ }
+
+ sc.Complete();
+}
+
+static void FoldAvsDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *[],
+ Accessor &styler) {
+
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && style == SCE_AVS_COMMENTBLOCK) {
+ if (stylePrev != SCE_AVS_COMMENTBLOCK) {
+ levelCurrent++;
+ } else if ((styleNext != SCE_AVS_COMMENTBLOCK) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+
+ if (foldComment && style == SCE_AVS_COMMENTBLOCKN) {
+ if (stylePrev != SCE_AVS_COMMENTBLOCKN) {
+ levelCurrent++;
+ } else if ((styleNext != SCE_AVS_COMMENTBLOCKN) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+
+ if (style == SCE_AVS_OPERATOR) {
+ if (ch == '{') {
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const avsWordLists[] = {
+ "Keywords",
+ "Filters",
+ "Plugins",
+ "Functions",
+ "Clip properties",
+ "User defined functions",
+ 0,
+};
+
+LexerModule lmAVS(SCLEX_AVS, ColouriseAvsDoc, "avs", FoldAvsDoc, avsWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexABAQUS.cxx
+ ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
+ ** By Sergio Lucato.
+ ** Sort of completely rewritten by Gertjan Kloosterman
+ **/
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// Code folding copyied and modified from LexBasic.cxx
+
+#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 IsAWordChar(const int ch) {
+ return (ch < 0x80 && (isalnum(ch) || (ch == '_')));
+}
+
+static inline bool IsAKeywordChar(const int ch) {
+ return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
+}
+
+static inline bool IsASetChar(const int ch) {
+ return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
+}
+
+static inline bool IsAnOperator(char ch) {
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
+ ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
+ ch == '$' || ch == ':' || ch == '%')
+ return true;
+ return false;
+}
+
+static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */,
+ Accessor &styler) {
+ enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
+ DAT_LINE_VAL, DAT_LINE_COMMA,\
+ COMMENT_LINE,\
+ ST_ERROR, LINE_END } state ;
+
+ // Do not leak onto next line
+ state = LINE_END ;
+ initStyle = SCE_ABAQUS_DEFAULT;
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ // Things are actually quite simple
+ // we have commentlines
+ // keywordlines and datalines
+ // On a data line there will only be colouring of numbers
+ // a keyword line is constructed as
+ // *word,[ paramname[=paramvalue]]*
+ // if the line ends with a , the keyword line continues onto the new line
+
+ for (; sc.More(); sc.Forward()) {
+ switch ( state ) {
+ case KW_LINE_KW :
+ if ( sc.atLineEnd ) {
+ // finished the line in keyword state, switch to LINE_END
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ } else if ( IsAKeywordChar(sc.ch) ) {
+ // nothing changes
+ state = KW_LINE_KW ;
+ } else if ( sc.ch == ',' ) {
+ // Well well we say a comma, arguments *MUST* follow
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = KW_LINE_COMMA ;
+ } else {
+ // Flag an error
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ // Done with processing
+ break ;
+ case KW_LINE_COMMA :
+ // acomma on a keywordline was seen
+ if ( IsAKeywordChar(sc.ch)) {
+ sc.SetState(SCE_ABAQUS_ARGUMENT) ;
+ state = KW_LINE_PAR ;
+ } else if ( sc.atLineEnd || (sc.ch == ',') ) {
+ // we remain in keyword mode
+ state = KW_LINE_COMMA ;
+ } else if ( sc.ch == ' ' ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = KW_LINE_COMMA ;
+ } else {
+ // Anything else constitutes an error
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ break ;
+ case KW_LINE_PAR :
+ if ( sc.atLineEnd ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
+ // remain in this state
+ state = KW_LINE_PAR ;
+ } else if ( sc.ch == ',' ) {
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = KW_LINE_COMMA ;
+ } else if ( sc.ch == '=' ) {
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = KW_LINE_EQ ;
+ } else {
+ // Anything else constitutes an error
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ break ;
+ case KW_LINE_EQ :
+ if ( sc.ch == ' ' ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ // remain in this state
+ state = KW_LINE_EQ ;
+ } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
+ sc.SetState(SCE_ABAQUS_NUMBER) ;
+ state = KW_LINE_VAL ;
+ } else if ( IsAKeywordChar(sc.ch) ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = KW_LINE_VAL ;
+ } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
+ sc.SetState(SCE_ABAQUS_STRING) ;
+ state = KW_LINE_VAL ;
+ } else {
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ break ;
+ case KW_LINE_VAL :
+ if ( sc.atLineEnd ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
+ // nothing changes
+ state = KW_LINE_VAL ;
+ } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
+ ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
+ (sc.state == SCE_ABAQUS_NUMBER)) {
+ // remain in number mode
+ state = KW_LINE_VAL ;
+ } else if (sc.state == SCE_ABAQUS_STRING) {
+ // accept everything until a closing quote
+ if ( sc.ch == '\'' || sc.ch == '\"' ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = KW_LINE_VAL ;
+ }
+ } else if ( sc.ch == ',' ) {
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = KW_LINE_COMMA ;
+ } else {
+ // anything else is an error
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ break ;
+ case DAT_LINE_VAL :
+ if ( sc.atLineEnd ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
+ // nothing changes
+ state = DAT_LINE_VAL ;
+ } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
+ ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
+ (sc.state == SCE_ABAQUS_NUMBER)) {
+ // remain in number mode
+ state = DAT_LINE_VAL ;
+ } else if (sc.state == SCE_ABAQUS_STRING) {
+ // accept everything until a closing quote
+ if ( sc.ch == '\'' || sc.ch == '\"' ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = DAT_LINE_VAL ;
+ }
+ } else if ( sc.ch == ',' ) {
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = DAT_LINE_COMMA ;
+ } else {
+ // anything else is an error
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ break ;
+ case DAT_LINE_COMMA :
+ // a comma on a data line was seen
+ if ( sc.atLineEnd ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ } else if ( sc.ch == ' ' ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = DAT_LINE_COMMA ;
+ } else if (sc.ch == ',') {
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = DAT_LINE_COMMA ;
+ } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
+ sc.SetState(SCE_ABAQUS_NUMBER) ;
+ state = DAT_LINE_VAL ;
+ } else if ( IsAKeywordChar(sc.ch) ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = DAT_LINE_VAL ;
+ } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
+ sc.SetState(SCE_ABAQUS_STRING) ;
+ state = DAT_LINE_VAL ;
+ } else {
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ break ;
+ case COMMENT_LINE :
+ if ( sc.atLineEnd ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ }
+ break ;
+ case ST_ERROR :
+ if ( sc.atLineEnd ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = LINE_END ;
+ }
+ break ;
+ case LINE_END :
+ if ( sc.atLineEnd || sc.ch == ' ' ) {
+ // nothing changes
+ state = LINE_END ;
+ } else if ( sc.ch == '*' ) {
+ if ( sc.chNext == '*' ) {
+ state = COMMENT_LINE ;
+ sc.SetState(SCE_ABAQUS_COMMENT) ;
+ } else {
+ state = KW_LINE_KW ;
+ sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
+ }
+ } else {
+ // it must be a data line, things are as if we are in DAT_LINE_COMMA
+ if ( sc.ch == ',' ) {
+ sc.SetState(SCE_ABAQUS_OPERATOR) ;
+ state = DAT_LINE_COMMA ;
+ } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
+ sc.SetState(SCE_ABAQUS_NUMBER) ;
+ state = DAT_LINE_VAL ;
+ } else if ( IsAKeywordChar(sc.ch) ) {
+ sc.SetState(SCE_ABAQUS_DEFAULT) ;
+ state = DAT_LINE_VAL ;
+ } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
+ sc.SetState(SCE_ABAQUS_STRING) ;
+ state = DAT_LINE_VAL ;
+ } else {
+ sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+ state = ST_ERROR ;
+ }
+ }
+ break ;
+ }
+ }
+ sc.Complete();
+}
+
+//------------------------------------------------------------------------------
+// This copyied and modified from LexBasic.cxx
+//------------------------------------------------------------------------------
+
+/* Bits:
+ * 1 - whitespace
+ * 2 - operator
+ * 4 - identifier
+ * 8 - decimal digit
+ * 16 - hex digit
+ * 32 - bin digit
+ */
+static int character_classification[128] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
+ 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
+};
+
+static bool IsSpace(int c) {
+ return c < 128 && (character_classification[c] & 1);
+}
+
+static bool IsIdentifier(int c) {
+ return c < 128 && (character_classification[c] & 4);
+}
+
+static int LowerCase(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+static int LineEnd(int line, Accessor &styler)
+{
+ const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
+ int eol_pos ;
+ // if the line is the last line, the eol_pos is styler.Length()
+ // eol will contain a new line, or a virtual new line
+ if ( docLines == line )
+ eol_pos = styler.Length() ;
+ else
+ eol_pos = styler.LineStart(line + 1) - 1;
+ return eol_pos ;
+}
+
+static int LineStart(int line, Accessor &styler)
+{
+ return styler.LineStart(line) ;
+}
+
+// LineType
+//
+// bits determines the line type
+// 1 : data line
+// 2 : only whitespace
+// 3 : data line with only whitespace
+// 4 : keyword line
+// 5 : block open keyword line
+// 6 : block close keyword line
+// 7 : keyword line in error
+// 8 : comment line
+static int LineType(int line, Accessor &styler) {
+ int pos = LineStart(line, styler) ;
+ int eol_pos = LineEnd(line, styler) ;
+
+ int c ;
+ char ch = ' ';
+
+ int i = pos ;
+ while ( i < eol_pos ) {
+ c = styler.SafeGetCharAt(i);
+ ch = static_cast<char>(LowerCase(c));
+ // We can say something as soon as no whitespace
+ // was encountered
+ if ( !IsSpace(c) )
+ break ;
+ i++ ;
+ }
+
+ if ( i >= eol_pos ) {
+ // This is a whitespace line, currently
+ // classifies as data line
+ return 3 ;
+ }
+
+ if ( ch != '*' ) {
+ // This is a data line
+ return 1 ;
+ }
+
+ if ( i == eol_pos - 1 ) {
+ // Only a single *, error but make keyword line
+ return 4+3 ;
+ }
+
+ // This means we can have a second character
+ // if that is also a * this means a comment
+ // otherwise it is a keyword.
+ c = styler.SafeGetCharAt(i+1);
+ ch = static_cast<char>(LowerCase(c));
+ if ( ch == '*' ) {
+ return 8 ;
+ }
+
+ // At this point we know this is a keyword line
+ // the character at position i is a *
+ // it is not a comment line
+ char word[256] ;
+ int wlen = 0;
+
+ word[wlen] = '*' ;
+ wlen++ ;
+
+ i++ ;
+ while ( (i < eol_pos) && (wlen < 255) ) {
+ c = styler.SafeGetCharAt(i);
+ ch = static_cast<char>(LowerCase(c));
+
+ if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
+ break ;
+
+ if ( IsIdentifier(c) ) {
+ word[wlen] = ch ;
+ wlen++ ;
+ }
+
+ i++ ;
+ }
+
+ word[wlen] = 0 ;
+
+ // Make a comparison
+ if ( !strcmp(word, "*step") ||
+ !strcmp(word, "*part") ||
+ !strcmp(word, "*instance") ||
+ !strcmp(word, "*assembly")) {
+ return 4+1 ;
+ }
+
+ if ( !strcmp(word, "*endstep") ||
+ !strcmp(word, "*endpart") ||
+ !strcmp(word, "*endinstance") ||
+ !strcmp(word, "*endassembly")) {
+ return 4+2 ;
+ }
+
+ return 4 ;
+}
+
+static void SafeSetLevel(int line, int level, Accessor &styler)
+{
+ if ( line < 0 )
+ return ;
+
+ int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
+
+ if ( (level & mask) < 0 )
+ return ;
+
+ if ( styler.LevelAt(line) != level )
+ styler.SetLevel(line, level) ;
+}
+
+static void FoldABAQUSDoc(unsigned int startPos, int length, int,
+WordList *[], Accessor &styler) {
+ int startLine = styler.GetLine(startPos) ;
+ int endLine = styler.GetLine(startPos+length-1) ;
+
+ // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ // We want to deal with all the cases
+ // To know the correct indentlevel, we need to look back to the
+ // previous command line indentation level
+ // order of formatting keyline datalines commentlines
+ int beginData = -1 ;
+ int beginComment = -1 ;
+ int prvKeyLine = startLine ;
+ int prvKeyLineTp = 0 ;
+
+ // Scan until we find the previous keyword line
+ // this will give us the level reference that we need
+ while ( prvKeyLine > 0 ) {
+ prvKeyLine-- ;
+ prvKeyLineTp = LineType(prvKeyLine, styler) ;
+ if ( prvKeyLineTp & 4 )
+ break ;
+ }
+
+ // Determine the base line level of all lines following
+ // the previous keyword
+ // new keyword lines are placed on this level
+ //if ( prvKeyLineTp & 4 ) {
+ int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
+ //}
+
+ // uncomment line below if weird behaviour continues
+ prvKeyLine = -1 ;
+
+ // Now start scanning over the lines.
+ for ( int line = startLine; line <= endLine; line++ ) {
+ int lineType = LineType(line, styler) ;
+
+ // Check for comment line
+ if ( lineType == 8 ) {
+ if ( beginComment < 0 ) {
+ beginComment = line ;
+ }
+ }
+
+ // Check for data line
+ if ( (lineType == 1) || (lineType == 3) ) {
+ if ( beginData < 0 ) {
+ if ( beginComment >= 0 ) {
+ beginData = beginComment ;
+ } else {
+ beginData = line ;
+ }
+ }
+ beginComment = -1 ;
+ }
+
+ // Check for keywordline.
+ // As soon as a keyword line is encountered, we can set the
+ // levels of everything from the previous keyword line to this one
+ if ( lineType & 4 ) {
+ // this is a keyword, we can now place the previous keyword
+ // all its data lines and the remainder
+
+ // Write comments and data line
+ if ( beginComment < 0 ) {
+ beginComment = line ;
+ }
+
+ if ( beginData < 0 ) {
+ beginData = beginComment ;
+ if ( prvKeyLineTp != 5 )
+ SafeSetLevel(prvKeyLine, level, styler) ;
+ else
+ SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+ } else {
+ SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+ }
+
+ int datLevel = level + 1 ;
+ if ( !(prvKeyLineTp & 4) ) {
+ datLevel = level ;
+ }
+
+ for ( int ll = beginData; ll < beginComment; ll++ )
+ SafeSetLevel(ll, datLevel, styler) ;
+
+ // The keyword we just found is going to be written at another level
+ // if we have a type 5 and type 6
+ if ( prvKeyLineTp == 5 ) {
+ level += 1 ;
+ }
+
+ if ( prvKeyLineTp == 6 ) {
+ level -= 1 ;
+ if ( level < 0 ) {
+ level = 0 ;
+ }
+ }
+
+ for ( int lll = beginComment; lll < line; lll++ )
+ SafeSetLevel(lll, level, styler) ;
+
+ // wrap and reset
+ beginComment = -1 ;
+ beginData = -1 ;
+ prvKeyLine = line ;
+ prvKeyLineTp = lineType ;
+ }
+
+ }
+
+ if ( beginComment < 0 ) {
+ beginComment = endLine + 1 ;
+ } else {
+ // We need to find out whether this comment block is followed by
+ // a data line or a keyword line
+ const int docLines = styler.GetLine(styler.Length() - 1);
+
+ for ( int line = endLine + 1; line <= docLines; line++ ) {
+ int lineType = LineType(line, styler) ;
+
+ if ( lineType != 8 ) {
+ if ( !(lineType & 4) ) {
+ beginComment = endLine + 1 ;
+ }
+ break ;
+ }
+ }
+ }
+
+ if ( beginData < 0 ) {
+ beginData = beginComment ;
+ if ( prvKeyLineTp != 5 )
+ SafeSetLevel(prvKeyLine, level, styler) ;
+ else
+ SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+ } else {
+ SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+ }
+
+ int datLevel = level + 1 ;
+ if ( !(prvKeyLineTp & 4) ) {
+ datLevel = level ;
+ }
+
+ for ( int ll = beginData; ll < beginComment; ll++ )
+ SafeSetLevel(ll, datLevel, styler) ;
+
+ if ( prvKeyLineTp == 5 ) {
+ level += 1 ;
+ }
+
+ if ( prvKeyLineTp == 6 ) {
+ level -= 1 ;
+ }
+ for ( int m = beginComment; m <= endLine; m++ )
+ SafeSetLevel(m, level, styler) ;
+}
+
+static const char * const abaqusWordListDesc[] = {
+ "processors",
+ "commands",
+ "slashommands",
+ "starcommands",
+ "arguments",
+ "functions",
+ 0
+};
+
+LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexAda.cxx
+ ** Lexer for Ada 95
+ **/
+// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
+// 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 <string>
+
+#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
+
+/*
+ * Interface
+ */
+
+static void ColouriseDocument(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static const char * const adaWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
+
+/*
+ * Implementation
+ */
+
+// Functions that have apostropheStartsAttribute as a parameter set it according to whether
+// an apostrophe encountered after processing the current token will start an attribute or
+// a character literal.
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+
+static inline bool IsDelimiterCharacter(int ch);
+static inline bool IsNumberStartCharacter(int ch);
+static inline bool IsNumberCharacter(int ch);
+static inline bool IsSeparatorOrDelimiterCharacter(int ch);
+static bool IsValidIdentifier(const std::string& identifier);
+static bool IsValidNumber(const std::string& number);
+static inline bool IsWordStartCharacter(int ch);
+static inline bool IsWordCharacter(int ch);
+
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = true;
+
+ sc.SetState(SCE_ADA_CHARACTER);
+
+ // Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
+ // is handled correctly)
+ sc.Forward();
+ sc.Forward();
+
+ ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
+}
+
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
+ while (!sc.atLineEnd && !sc.Match(chEnd)) {
+ sc.Forward();
+ }
+
+ if (!sc.atLineEnd) {
+ sc.ForwardSetState(SCE_ADA_DEFAULT);
+ } else {
+ sc.ChangeState(stateEOL);
+ }
+}
+
+static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+ // Apostrophe meaning is not changed, but the parameter is present for uniformity
+
+ sc.SetState(SCE_ADA_COMMENTLINE);
+
+ while (!sc.atLineEnd) {
+ sc.Forward();
+ }
+}
+
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = sc.Match (')');
+ sc.SetState(SCE_ADA_DELIMITER);
+ sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = false;
+
+ sc.SetState(SCE_ADA_LABEL);
+
+ // Skip "<<"
+ sc.Forward();
+ sc.Forward();
+
+ std::string identifier;
+
+ while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ identifier += static_cast<char>(tolower(sc.ch));
+ sc.Forward();
+ }
+
+ // Skip ">>"
+ if (sc.Match('>', '>')) {
+ sc.Forward();
+ sc.Forward();
+ } else {
+ sc.ChangeState(SCE_ADA_ILLEGAL);
+ }
+
+ // If the name is an invalid identifier or a keyword, then make it invalid label
+ if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
+ sc.ChangeState(SCE_ADA_ILLEGAL);
+ }
+
+ sc.SetState(SCE_ADA_DEFAULT);
+
+}
+
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = true;
+
+ std::string number;
+ sc.SetState(SCE_ADA_NUMBER);
+
+ // Get all characters up to a delimiter or a separator, including points, but excluding
+ // double points (ranges).
+ while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward();
+ }
+
+ // Special case: exponent with sign
+ if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+ (sc.ch == '+' || sc.ch == '-')) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward ();
+
+ while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward();
+ }
+ }
+
+ if (!IsValidNumber(number)) {
+ sc.ChangeState(SCE_ADA_ILLEGAL);
+ }
+
+ sc.SetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = true;
+
+ sc.SetState(SCE_ADA_STRING);
+ sc.Forward();
+
+ ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
+}
+
+static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+ // Apostrophe meaning is not changed, but the parameter is present for uniformity
+ sc.SetState(SCE_ADA_DEFAULT);
+ sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = true;
+ sc.SetState(SCE_ADA_IDENTIFIER);
+
+ std::string word;
+
+ while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ word += static_cast<char>(tolower(sc.ch));
+ sc.Forward();
+ }
+
+ if (!IsValidIdentifier(word)) {
+ sc.ChangeState(SCE_ADA_ILLEGAL);
+
+ } else if (keywords.InList(word.c_str())) {
+ sc.ChangeState(SCE_ADA_WORD);
+
+ if (word != "all") {
+ apostropheStartsAttribute = false;
+ }
+ }
+
+ sc.SetState(SCE_ADA_DEFAULT);
+}
+
+//
+// ColouriseDocument
+//
+
+static void ColouriseDocument(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+ WordList &keywords = *keywordlists[0];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ int lineCurrent = styler.GetLine(startPos);
+ bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
+
+ while (sc.More()) {
+ if (sc.atLineEnd) {
+ // Go to the next line
+ sc.Forward();
+ lineCurrent++;
+
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, apostropheStartsAttribute);
+
+ // Don't continue any styles on the next line
+ sc.SetState(SCE_ADA_DEFAULT);
+ }
+
+ // Comments
+ if (sc.Match('-', '-')) {
+ ColouriseComment(sc, apostropheStartsAttribute);
+
+ // Strings
+ } else if (sc.Match('"')) {
+ ColouriseString(sc, apostropheStartsAttribute);
+
+ // Characters
+ } else if (sc.Match('\'') && !apostropheStartsAttribute) {
+ ColouriseCharacter(sc, apostropheStartsAttribute);
+
+ // Labels
+ } else if (sc.Match('<', '<')) {
+ ColouriseLabel(sc, keywords, apostropheStartsAttribute);
+
+ // Whitespace
+ } else if (IsASpace(sc.ch)) {
+ ColouriseWhiteSpace(sc, apostropheStartsAttribute);
+
+ // Delimiters
+ } else if (IsDelimiterCharacter(sc.ch)) {
+ ColouriseDelimiter(sc, apostropheStartsAttribute);
+
+ // Numbers
+ } else if (IsADigit(sc.ch) || sc.ch == '#') {
+ ColouriseNumber(sc, apostropheStartsAttribute);
+
+ // Keywords or identifiers
+ } else {
+ ColouriseWord(sc, keywords, apostropheStartsAttribute);
+ }
+ }
+
+ sc.Complete();
+}
+
+static inline bool IsDelimiterCharacter(int ch) {
+ switch (ch) {
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case '-':
+ case '.':
+ case '/':
+ case ':':
+ case ';':
+ case '<':
+ case '=':
+ case '>':
+ case '|':
+ return true;
+ default:
+ return false;
+ }
+}
+
+static inline bool IsNumberCharacter(int ch) {
+ return IsNumberStartCharacter(ch) ||
+ ch == '_' ||
+ ch == '.' ||
+ ch == '#' ||
+ (ch >= 'a' && ch <= 'f') ||
+ (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool IsNumberStartCharacter(int ch) {
+ return IsADigit(ch);
+}
+
+static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
+ return IsASpace(ch) || IsDelimiterCharacter(ch);
+}
+
+static bool IsValidIdentifier(const std::string& identifier) {
+ // First character can't be '_', so initialize the flag to true
+ bool lastWasUnderscore = true;
+
+ size_t length = identifier.length();
+
+ // Zero-length identifiers are not valid (these can occur inside labels)
+ if (length == 0) {
+ return false;
+ }
+
+ // Check for valid character at the start
+ if (!IsWordStartCharacter(identifier[0])) {
+ return false;
+ }
+
+ // Check for only valid characters and no double underscores
+ for (size_t i = 0; i < length; i++) {
+ if (!IsWordCharacter(identifier[i]) ||
+ (identifier[i] == '_' && lastWasUnderscore)) {
+ return false;
+ }
+ lastWasUnderscore = identifier[i] == '_';
+ }
+
+ // Check for underscore at the end
+ if (lastWasUnderscore == true) {
+ return false;
+ }
+
+ // All checks passed
+ return true;
+}
+
+static bool IsValidNumber(const std::string& number) {
+ size_t hashPos = number.find("#");
+ bool seenDot = false;
+
+ size_t i = 0;
+ size_t length = number.length();
+
+ if (length == 0)
+ return false; // Just in case
+
+ // Decimal number
+ if (hashPos == std::string::npos) {
+ bool canBeSpecial = false;
+
+ for (; i < length; i++) {
+ if (number[i] == '_') {
+ if (!canBeSpecial) {
+ return false;
+ }
+ canBeSpecial = false;
+ } else if (number[i] == '.') {
+ if (!canBeSpecial || seenDot) {
+ return false;
+ }
+ canBeSpecial = false;
+ seenDot = true;
+ } else if (IsADigit(number[i])) {
+ canBeSpecial = true;
+ } else {
+ break;
+ }
+ }
+
+ if (!canBeSpecial)
+ return false;
+ } else {
+ // Based number
+ bool canBeSpecial = false;
+ int base = 0;
+
+ // Parse base
+ for (; i < length; i++) {
+ int ch = number[i];
+ if (ch == '_') {
+ if (!canBeSpecial)
+ return false;
+ canBeSpecial = false;
+ } else if (IsADigit(ch)) {
+ base = base * 10 + (ch - '0');
+ if (base > 16)
+ return false;
+ canBeSpecial = true;
+ } else if (ch == '#' && canBeSpecial) {
+ break;
+ } else {
+ return false;
+ }
+ }
+
+ if (base < 2)
+ return false;
+ if (i == length)
+ return false;
+
+ i++; // Skip over '#'
+
+ // Parse number
+ canBeSpecial = false;
+
+ for (; i < length; i++) {
+ int ch = tolower(number[i]);
+
+ if (ch == '_') {
+ if (!canBeSpecial) {
+ return false;
+ }
+ canBeSpecial = false;
+
+ } else if (ch == '.') {
+ if (!canBeSpecial || seenDot) {
+ return false;
+ }
+ canBeSpecial = false;
+ seenDot = true;
+
+ } else if (IsADigit(ch)) {
+ if (ch - '0' >= base) {
+ return false;
+ }
+ canBeSpecial = true;
+
+ } else if (ch >= 'a' && ch <= 'f') {
+ if (ch - 'a' + 10 >= base) {
+ return false;
+ }
+ canBeSpecial = true;
+
+ } else if (ch == '#' && canBeSpecial) {
+ break;
+
+ } else {
+ return false;
+ }
+ }
+
+ if (i == length) {
+ return false;
+ }
+
+ i++;
+ }
+
+ // Exponent (optional)
+ if (i < length) {
+ if (number[i] != 'e' && number[i] != 'E')
+ return false;
+
+ i++; // Move past 'E'
+
+ if (i == length) {
+ return false;
+ }
+
+ if (number[i] == '+')
+ i++;
+ else if (number[i] == '-') {
+ if (seenDot) {
+ i++;
+ } else {
+ return false; // Integer literals should not have negative exponents
+ }
+ }
+
+ if (i == length) {
+ return false;
+ }
+
+ bool canBeSpecial = false;
+
+ for (; i < length; i++) {
+ if (number[i] == '_') {
+ if (!canBeSpecial) {
+ return false;
+ }
+ canBeSpecial = false;
+ } else if (IsADigit(number[i])) {
+ canBeSpecial = true;
+ } else {
+ return false;
+ }
+ }
+
+ if (!canBeSpecial)
+ return false;
+ }
+
+ // if i == length, number was parsed successfully.
+ return i == length;
+}
+
+static inline bool IsWordCharacter(int ch) {
+ return IsWordStartCharacter(ch) || IsADigit(ch);
+}
+
+static inline bool IsWordStartCharacter(int ch) {
+ return (isascii(ch) && isalpha(ch)) || ch == '_';
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file LexAsm.cxx
+ ** Lexer for Assembler, just for the MASM syntax
+ ** Written by The Black Horus
+ ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
+ ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
+ **/
+// Copyright 1998-2003 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 <string>
+#include <map>
+#include <set>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+ ch == '_' || ch == '?');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
+ ch == '%' || ch == '@' || ch == '$' || ch == '?');
+}
+
+static inline bool IsAsmOperator(const int ch) {
+ if ((ch < 0x80) && (isalnum(ch)))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
+ ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
+ ch == '%' || ch == ':')
+ return true;
+ return false;
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;
+}
+
+static inline int LowerCase(int c) {
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerAsm
+struct OptionsAsm {
+ std::string delimiter;
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldCommentMultiline;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldCompact;
+ OptionsAsm() {
+ delimiter = "";
+ fold = false;
+ foldSyntaxBased = true;
+ foldCommentMultiline = false;
+ foldCommentExplicit = false;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldCompact = true;
+ }
+};
+
+static const char * const asmWordListDesc[] = {
+ "CPU instructions",
+ "FPU instructions",
+ "Registers",
+ "Directives",
+ "Directive operands",
+ "Extended instructions",
+ "Directives4Foldstart",
+ "Directives4Foldend",
+ 0
+};
+
+struct OptionSetAsm : public OptionSet<OptionsAsm> {
+ OptionSetAsm() {
+ DefineProperty("lexer.asm.comment.delimiter", &OptionsAsm::delimiter,
+ "Character used for COMMENT directive's delimiter, replacing the standard \"~\".");
+
+ DefineProperty("fold", &OptionsAsm::fold);
+
+ DefineProperty("fold.asm.syntax.based", &OptionsAsm::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.asm.comment.multiline", &OptionsAsm::foldCommentMultiline,
+ "Set this property to 1 to enable folding multi-line comments.");
+
+ DefineProperty("fold.asm.comment.explicit", &OptionsAsm::foldCommentExplicit,
+ "This option enables folding explicit fold points when using the Asm lexer. "
+ "Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} "
+ "at the end of a section that should fold.");
+
+ DefineProperty("fold.asm.explicit.start", &OptionsAsm::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard ;{.");
+
+ DefineProperty("fold.asm.explicit.end", &OptionsAsm::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard ;}.");
+
+ DefineProperty("fold.asm.explicit.anywhere", &OptionsAsm::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.compact", &OptionsAsm::foldCompact);
+
+ DefineWordListSets(asmWordListDesc);
+ }
+};
+
+class LexerAsm : public ILexer {
+ WordList cpuInstruction;
+ WordList mathInstruction;
+ WordList registers;
+ WordList directive;
+ WordList directiveOperand;
+ WordList extInstruction;
+ WordList directives4foldstart;
+ WordList directives4foldend;
+ OptionsAsm options;
+ OptionSetAsm osAsm;
+public:
+ LexerAsm() {
+ }
+ virtual ~LexerAsm() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osAsm.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osAsm.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osAsm.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osAsm.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryAsm() {
+ return new LexerAsm();
+ }
+};
+
+int SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) {
+ if (osAsm.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &cpuInstruction;
+ break;
+ case 1:
+ wordListN = &mathInstruction;
+ break;
+ case 2:
+ wordListN = ®isters;
+ break;
+ case 3:
+ wordListN = &directive;
+ break;
+ case 4:
+ wordListN = &directiveOperand;
+ break;
+ case 5:
+ wordListN = &extInstruction;
+ break;
+ case 6:
+ wordListN = &directives4foldstart;
+ break;
+ case 7:
+ wordListN = &directives4foldend;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerAsm::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
+ // Do not leak onto next line
+ if (initStyle == SCE_ASM_STRINGEOL)
+ initStyle = SCE_ASM_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+
+ // Prevent SCE_ASM_STRINGEOL from leaking back to previous line
+ if (sc.atLineStart && (sc.state == SCE_ASM_STRING)) {
+ sc.SetState(SCE_ASM_STRING);
+ } else if (sc.atLineStart && (sc.state == SCE_ASM_CHARACTER)) {
+ sc.SetState(SCE_ASM_CHARACTER);
+ }
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_ASM_OPERATOR) {
+ if (!IsAsmOperator(sc.ch)) {
+ sc.SetState(SCE_ASM_DEFAULT);
+ }
+ } else if (sc.state == SCE_ASM_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_ASM_DEFAULT);
+ }
+ } else if (sc.state == SCE_ASM_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ bool IsDirective = false;
+
+ if (cpuInstruction.InList(s)) {
+ sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
+ } else if (mathInstruction.InList(s)) {
+ sc.ChangeState(SCE_ASM_MATHINSTRUCTION);
+ } else if (registers.InList(s)) {
+ sc.ChangeState(SCE_ASM_REGISTER);
+ } else if (directive.InList(s)) {
+ sc.ChangeState(SCE_ASM_DIRECTIVE);
+ IsDirective = true;
+ } else if (directiveOperand.InList(s)) {
+ sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
+ } else if (extInstruction.InList(s)) {
+ sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
+ }
+ sc.SetState(SCE_ASM_DEFAULT);
+ if (IsDirective && !strcmp(s, "comment")) {
+ char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
+ sc.ForwardSetState(SCE_ASM_DEFAULT);
+ }
+ if (sc.ch == delimiter) {
+ sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
+ }
+ }
+ }
+ } else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
+ char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+ if (sc.ch == delimiter) {
+ while (!sc.atLineEnd) {
+ sc.Forward();
+ }
+ sc.SetState(SCE_ASM_DEFAULT);
+ }
+ } else if (sc.state == SCE_ASM_COMMENT ) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_ASM_DEFAULT);
+ }
+ } else if (sc.state == SCE_ASM_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_ASM_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_ASM_STRINGEOL);
+ sc.ForwardSetState(SCE_ASM_DEFAULT);
+ }
+ } else if (sc.state == SCE_ASM_CHARACTER) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_ASM_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_ASM_STRINGEOL);
+ sc.ForwardSetState(SCE_ASM_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_ASM_DEFAULT) {
+ if (sc.ch == ';'){
+ sc.SetState(SCE_ASM_COMMENT);
+ } else if (isascii(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && isascii(sc.chNext) && isdigit(sc.chNext)))) {
+ sc.SetState(SCE_ASM_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_ASM_IDENTIFIER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_ASM_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_ASM_CHARACTER);
+ } else if (IsAsmOperator(sc.ch)) {
+ sc.SetState(SCE_ASM_OPERATOR);
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "else".
+
+void SCI_METHOD LexerAsm::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char word[100];
+ int wordlen = 0;
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (options.foldCommentMultiline && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ levelNext++;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ levelNext--;
+ }
+ } else {
+ if (ch == ';') {
+ if (chNext == '{') {
+ levelNext++;
+ } else if (chNext == '}') {
+ levelNext--;
+ }
+ }
+ }
+ }
+ if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
+ word[wordlen++] = static_cast<char>(LowerCase(ch));
+ if (wordlen == 100) { // prevent overflow
+ word[0] = '\0';
+ wordlen = 1;
+ }
+ if (styleNext != SCE_ASM_DIRECTIVE) { // reading directive ready
+ word[wordlen] = '\0';
+ wordlen = 0;
+ if (directives4foldstart.InList(word)) {
+ levelNext++;
+ } else if (directives4foldend.InList(word)){
+ levelNext--;
+ }
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && options.foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+ // There is an empty line at end of file so give it same level and empty
+ styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+ }
+ visibleChars = 0;
+ }
+ }
+}
+
+LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexAsn1.cxx
+ ** Lexer for ASN.1
+ **/
+// Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de
+// Last Updated: 20/07/2004
+// 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 "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
+
+// Some char test functions
+static bool isAsn1Number(int ch)
+{
+ return (ch >= '0' && ch <= '9');
+}
+
+static bool isAsn1Letter(int ch)
+{
+ return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+static bool isAsn1Char(int ch)
+{
+ return (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch);
+}
+
+//
+// Function determining the color of a given code portion
+// Based on a "state"
+//
+static void ColouriseAsn1Doc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[], Accessor &styler)
+{
+ // The keywords
+ WordList &Keywords = *keywordLists[0];
+ WordList &Attributes = *keywordLists[1];
+ WordList &Descriptors = *keywordLists[2];
+ WordList &Types = *keywordLists[3];
+
+ // Parse the whole buffer character by character using StyleContext
+ StyleContext sc(startPos, length, initStyle, styler);
+ for (; sc.More(); sc.Forward())
+ {
+ // The state engine
+ switch (sc.state)
+ {
+ case SCE_ASN1_DEFAULT: // Plain characters
+asn1_default:
+ if (sc.ch == '-' && sc.chNext == '-')
+ // A comment begins here
+ sc.SetState(SCE_ASN1_COMMENT);
+ else if (sc.ch == '"')
+ // A string begins here
+ sc.SetState(SCE_ASN1_STRING);
+ else if (isAsn1Number (sc.ch))
+ // A number starts here (identifier should start with a letter in ASN.1)
+ sc.SetState(SCE_ASN1_SCALAR);
+ else if (isAsn1Char (sc.ch))
+ // An identifier starts here (identifier always start with a letter)
+ sc.SetState(SCE_ASN1_IDENTIFIER);
+ else if (sc.ch == ':')
+ // A ::= operator starts here
+ sc.SetState(SCE_ASN1_OPERATOR);
+ break;
+ case SCE_ASN1_COMMENT: // A comment
+ if (sc.ch == '\r' || sc.ch == '\n')
+ // A comment ends here
+ sc.SetState(SCE_ASN1_DEFAULT);
+ break;
+ case SCE_ASN1_IDENTIFIER: // An identifier (keyword, attribute, descriptor or type)
+ if (!isAsn1Char (sc.ch))
+ {
+ // The end of identifier is here: we can look for it in lists by now and change its state
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (Keywords.InList(s))
+ // It's a keyword, change its state
+ sc.ChangeState(SCE_ASN1_KEYWORD);
+ else if (Attributes.InList(s))
+ // It's an attribute, change its state
+ sc.ChangeState(SCE_ASN1_ATTRIBUTE);
+ else if (Descriptors.InList(s))
+ // It's a descriptor, change its state
+ sc.ChangeState(SCE_ASN1_DESCRIPTOR);
+ else if (Types.InList(s))
+ // It's a type, change its state
+ sc.ChangeState(SCE_ASN1_TYPE);
+
+ // Set to default now
+ sc.SetState(SCE_ASN1_DEFAULT);
+ }
+ break;
+ case SCE_ASN1_STRING: // A string delimited by ""
+ if (sc.ch == '"')
+ {
+ // A string ends here
+ sc.ForwardSetState(SCE_ASN1_DEFAULT);
+
+ // To correctly manage a char sticking to the string quote
+ goto asn1_default;
+ }
+ break;
+ case SCE_ASN1_SCALAR: // A plain number
+ if (!isAsn1Number (sc.ch))
+ // A number ends here
+ sc.SetState(SCE_ASN1_DEFAULT);
+ break;
+ case SCE_ASN1_OPERATOR: // The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap)
+ if (sc.ch == '{')
+ {
+ // An OID definition starts here: enter the sub loop
+ for (; sc.More(); sc.Forward())
+ {
+ if (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev)))
+ // The OID number is highlighted
+ sc.SetState(SCE_ASN1_OID);
+ else if (isAsn1Char (sc.ch))
+ // The OID parent identifier is plain
+ sc.SetState(SCE_ASN1_IDENTIFIER);
+ else
+ sc.SetState(SCE_ASN1_DEFAULT);
+
+ if (sc.ch == '}')
+ // Here ends the OID and the operator sub loop: go back to main loop
+ break;
+ }
+ }
+ else if (isAsn1Number (sc.ch))
+ {
+ // A trap number definition starts here: enter the sub loop
+ for (; sc.More(); sc.Forward())
+ {
+ if (isAsn1Number (sc.ch))
+ // The trap number is highlighted
+ sc.SetState(SCE_ASN1_OID);
+ else
+ {
+ // The number ends here: go back to main loop
+ sc.SetState(SCE_ASN1_DEFAULT);
+ break;
+ }
+ }
+ }
+ else if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ')
+ // The operator doesn't imply an OID definition nor a trap, back to main loop
+ goto asn1_default; // To be sure to handle actually the state change
+ break;
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldAsn1Doc(unsigned int, int, int, WordList *[], Accessor &styler)
+{
+ // No folding enabled, no reason to continue...
+ if( styler.GetPropertyInt("fold") == 0 )
+ return;
+
+ // No folding implemented: doesn't make sense for ASN.1
+}
+
+static const char * const asn1WordLists[] = {
+ "Keywords",
+ "Attributes",
+ "Descriptors",
+ "Types",
+ 0, };
+
+
+LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexBaan.cxx
+ ** Lexer for Baan.
+ ** Based heavily on LexCPP.cxx
+ **/
+// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>
+// 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$' || ch == ':');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static void ColouriseBaanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
+
+ if (initStyle == SCE_BAAN_STRINGEOL) // Does not leak onto next line
+ initStyle = SCE_BAAN_DEFAULT;
+
+ int visibleChars = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_BAAN_OPERATOR) {
+ sc.SetState(SCE_BAAN_DEFAULT);
+ } else if (sc.state == SCE_BAAN_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_BAAN_DEFAULT);
+ }
+ } else if (sc.state == SCE_BAAN_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_BAAN_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_BAAN_WORD2);
+ }
+ sc.SetState(SCE_BAAN_DEFAULT);
+ }
+ } else if (sc.state == SCE_BAAN_PREPROCESSOR) {
+ if (stylingWithinPreprocessor) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_BAAN_DEFAULT);
+ }
+ } else {
+ if (sc.atLineEnd && (sc.chNext != '^')) {
+ sc.SetState(SCE_BAAN_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_BAAN_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_BAAN_DEFAULT);
+ }
+ } else if (sc.state == SCE_BAAN_COMMENTDOC) {
+ if (sc.MatchIgnoreCase("enddllusage")) {
+ for (unsigned int i = 0; i < 10; i++){
+ sc.Forward();
+ }
+ sc.ForwardSetState(SCE_BAAN_DEFAULT);
+ }
+ } else if (sc.state == SCE_BAAN_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_BAAN_DEFAULT);
+ } else if ((sc.atLineEnd) && (sc.chNext != '^')) {
+ sc.ChangeState(SCE_BAAN_STRINGEOL);
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ visibleChars = 0;
+ }
+ }
+
+ if (sc.state == SCE_BAAN_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_BAAN_NUMBER);
+ } else if (sc.MatchIgnoreCase("dllusage")){
+ sc.SetState(SCE_BAAN_COMMENTDOC);
+ do {
+ sc.Forward();
+ } while ((!sc.atLineEnd) && sc.More());
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_BAAN_IDENTIFIER);
+ } else if (sc.Match('|')){
+ sc.SetState(SCE_BAAN_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_BAAN_STRING);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_BAAN_PREPROCESSOR);
+ // Skip whitespace between # and preprocessor word
+ do {
+ sc.Forward();
+ } while (IsASpace(sc.ch) && sc.More());
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_BAAN_OPERATOR);
+ }
+ }
+ if (sc.atLineEnd) {
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldBaanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment &&
+ (style == SCE_BAAN_COMMENT || style == SCE_BAAN_COMMENTDOC)) {
+ if (style != stylePrev) {
+ levelCurrent++;
+ } else if ((style != styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+ if (style == SCE_BAAN_OPERATOR) {
+ if (ch == '{') {
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+LexerModule lmBaan(SCLEX_BAAN, ColouriseBaanDoc, "baan", FoldBaanDoc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexBash.cxx
+ ** Lexer for Bash.
+ **/
+// Copyright 2004-2010 by Neil Hodgson <neilh@scintilla.org>
+// Adapted from LexPerl by Kein-Hong Man 2004
+// 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 "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
+
+#define HERE_DELIM_MAX 256
+
+// define this if you want 'invalid octals' to be marked as errors
+// usually, this is not a good idea, permissive lexing is better
+#undef PEDANTIC_OCTAL
+
+#define BASH_BASE_ERROR 65
+#define BASH_BASE_DECIMAL 66
+#define BASH_BASE_HEX 67
+#ifdef PEDANTIC_OCTAL
+#define BASH_BASE_OCTAL 68
+#define BASH_BASE_OCTAL_ERROR 69
+#endif
+
+// state constants for parts of a bash command segment
+#define BASH_CMD_BODY 0
+#define BASH_CMD_START 1
+#define BASH_CMD_WORD 2
+#define BASH_CMD_TEST 3
+#define BASH_CMD_ARITH 4
+#define BASH_CMD_DELIM 5
+
+static inline int translateBashDigit(int ch) {
+ if (ch >= '0' && ch <= '9') {
+ return ch - '0';
+ } else if (ch >= 'a' && ch <= 'z') {
+ return ch - 'a' + 10;
+ } else if (ch >= 'A' && ch <= 'Z') {
+ return ch - 'A' + 36;
+ } else if (ch == '@') {
+ return 62;
+ } else if (ch == '_') {
+ return 63;
+ }
+ return BASH_BASE_ERROR;
+}
+
+static inline int getBashNumberBase(char *s) {
+ int i = 0;
+ int base = 0;
+ while (*s) {
+ base = base * 10 + (*s++ - '0');
+ i++;
+ }
+ if (base > 64 || i > 2) {
+ return BASH_BASE_ERROR;
+ }
+ return base;
+}
+
+static int opposite(int ch) {
+ if (ch == '(') return ')';
+ if (ch == '[') return ']';
+ if (ch == '{') return '}';
+ if (ch == '<') return '>';
+ return ch;
+}
+
+static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList cmdDelimiter, bashStruct, bashStruct_in;
+ cmdDelimiter.Set("| || |& & && ; ;; ( ) { }");
+ bashStruct.Set("if elif fi while until else then do done esac eval");
+ bashStruct_in.Set("for case select");
+
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_");
+ // note that [+-] are often parts of identifiers in shell scripts
+ CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
+ CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@");
+ CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
+ CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
+ CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
+ CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!");
+ CharacterSet setLeftShift(CharacterSet::setDigits, "=$");
+
+ class HereDocCls { // Class to manage HERE document elements
+ public:
+ int State; // 0: '<<' encountered
+ // 1: collect the delimiter
+ // 2: here doc text (lines after the delimiter)
+ int Quote; // the char after '<<'
+ bool Quoted; // true if Quote in ('\'','"','`')
+ bool Indent; // indented delimiter (for <<-)
+ int DelimiterLength; // strlen(Delimiter)
+ char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
+ HereDocCls() {
+ State = 0;
+ Quote = 0;
+ Quoted = false;
+ Indent = 0;
+ DelimiterLength = 0;
+ Delimiter = new char[HERE_DELIM_MAX];
+ Delimiter[0] = '\0';
+ }
+ void Append(int ch) {
+ Delimiter[DelimiterLength++] = static_cast<char>(ch);
+ Delimiter[DelimiterLength] = '\0';
+ }
+ ~HereDocCls() {
+ delete []Delimiter;
+ }
+ };
+ HereDocCls HereDoc;
+
+ class QuoteCls { // Class to manage quote pairs (simplified vs LexPerl)
+ public:
+ int Count;
+ int Up, Down;
+ QuoteCls() {
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ }
+ void Open(int u) {
+ Count++;
+ Up = u;
+ Down = opposite(Up);
+ }
+ void Start(int u) {
+ Count = 0;
+ Open(u);
+ }
+ };
+ QuoteCls Quote;
+
+ int numBase = 0;
+ int digit;
+ unsigned int endPos = startPos + length;
+ int cmdState = BASH_CMD_START;
+ int testExprType = 0;
+
+ // Always backtracks to the start of a line that is not a continuation
+ // of the previous line (i.e. start of a bash command segment)
+ int ln = styler.GetLine(startPos);
+ for (;;) {
+ startPos = styler.LineStart(ln);
+ if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
+ break;
+ ln--;
+ }
+ initStyle = SCE_SH_DEFAULT;
+
+ StyleContext sc(startPos, endPos - startPos, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ // handle line continuation, updates per-line stored state
+ if (sc.atLineStart) {
+ ln = styler.GetLine(sc.currentPos);
+ if (sc.state == SCE_SH_STRING
+ || sc.state == SCE_SH_BACKTICKS
+ || sc.state == SCE_SH_CHARACTER
+ || sc.state == SCE_SH_HERE_Q
+ || sc.state == SCE_SH_COMMENTLINE
+ || sc.state == SCE_SH_PARAM) {
+ // force backtrack while retaining cmdState
+ styler.SetLineState(ln, BASH_CMD_BODY);
+ } else {
+ if (ln > 0) {
+ if ((sc.GetRelative(-3) == '\\' && sc.GetRelative(-2) == '\r' && sc.chPrev == '\n')
+ || sc.GetRelative(-2) == '\\') { // handle '\' line continuation
+ // retain last line's state
+ } else
+ cmdState = BASH_CMD_START;
+ }
+ styler.SetLineState(ln, cmdState);
+ }
+ }
+
+ // controls change of cmdState at the end of a non-whitespace element
+ // states BODY|TEST|ARITH persist until the end of a command segment
+ // state WORD persist, but ends with 'in' or 'do' construct keywords
+ int cmdStateNew = BASH_CMD_BODY;
+ if (cmdState == BASH_CMD_TEST || cmdState == BASH_CMD_ARITH || cmdState == BASH_CMD_WORD)
+ cmdStateNew = cmdState;
+ int stylePrev = sc.state;
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_SH_OPERATOR:
+ sc.SetState(SCE_SH_DEFAULT);
+ if (cmdState == BASH_CMD_DELIM) // if command delimiter, start new command
+ cmdStateNew = BASH_CMD_START;
+ else if (sc.chPrev == '\\') // propagate command state if line continued
+ cmdStateNew = cmdState;
+ break;
+ case SCE_SH_WORD:
+ // "." never used in Bash variable names but used in file names
+ if (!setWord.Contains(sc.ch)) {
+ char s[500];
+ char s2[10];
+ sc.GetCurrent(s, sizeof(s));
+ // allow keywords ending in a whitespace or command delimiter
+ s2[0] = static_cast<char>(sc.ch);
+ s2[1] = '\0';
+ bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2);
+ // 'in' or 'do' may be construct keywords
+ if (cmdState == BASH_CMD_WORD) {
+ if (strcmp(s, "in") == 0 && keywordEnds)
+ cmdStateNew = BASH_CMD_BODY;
+ else if (strcmp(s, "do") == 0 && keywordEnds)
+ cmdStateNew = BASH_CMD_START;
+ else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ sc.SetState(SCE_SH_DEFAULT);
+ break;
+ }
+ // a 'test' keyword starts a test expression
+ if (strcmp(s, "test") == 0) {
+ if (cmdState == BASH_CMD_START && keywordEnds) {
+ cmdStateNew = BASH_CMD_TEST;
+ testExprType = 0;
+ } else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // detect bash construct keywords
+ else if (bashStruct.InList(s)) {
+ if (cmdState == BASH_CMD_START && keywordEnds)
+ cmdStateNew = BASH_CMD_START;
+ else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // 'for'|'case'|'select' needs 'in'|'do' to be highlighted later
+ else if (bashStruct_in.InList(s)) {
+ if (cmdState == BASH_CMD_START && keywordEnds)
+ cmdStateNew = BASH_CMD_WORD;
+ else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // disambiguate option items and file test operators
+ else if (s[0] == '-') {
+ if (cmdState != BASH_CMD_TEST)
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // disambiguate keywords and identifiers
+ else if (cmdState != BASH_CMD_START
+ || !(keywords.InList(s) && keywordEnds)) {
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ sc.SetState(SCE_SH_DEFAULT);
+ }
+ break;
+ case SCE_SH_IDENTIFIER:
+ if (sc.chPrev == '\\') { // for escaped chars
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ } else if (!setWord.Contains(sc.ch)) {
+ sc.SetState(SCE_SH_DEFAULT);
+ }
+ break;
+ case SCE_SH_NUMBER:
+ digit = translateBashDigit(sc.ch);
+ if (numBase == BASH_BASE_DECIMAL) {
+ if (sc.ch == '#') {
+ char s[10];
+ sc.GetCurrent(s, sizeof(s));
+ numBase = getBashNumberBase(s);
+ if (numBase != BASH_BASE_ERROR)
+ break;
+ } else if (IsADigit(sc.ch))
+ break;
+ } else if (numBase == BASH_BASE_HEX) {
+ if (IsADigit(sc.ch, 16))
+ break;
+#ifdef PEDANTIC_OCTAL
+ } else if (numBase == BASH_BASE_OCTAL ||
+ numBase == BASH_BASE_OCTAL_ERROR) {
+ if (digit <= 7)
+ break;
+ if (digit <= 9) {
+ numBase = BASH_BASE_OCTAL_ERROR;
+ break;
+ }
+#endif
+ } else if (numBase == BASH_BASE_ERROR) {
+ if (digit <= 9)
+ break;
+ } else { // DD#DDDD number style handling
+ if (digit != BASH_BASE_ERROR) {
+ if (numBase <= 36) {
+ // case-insensitive if base<=36
+ if (digit >= 36) digit -= 26;
+ }
+ if (digit < numBase)
+ break;
+ if (digit <= 9) {
+ numBase = BASH_BASE_ERROR;
+ break;
+ }
+ }
+ }
+ // fallthrough when number is at an end or error
+ if (numBase == BASH_BASE_ERROR
+#ifdef PEDANTIC_OCTAL
+ || numBase == BASH_BASE_OCTAL_ERROR
+#endif
+ ) {
+ sc.ChangeState(SCE_SH_ERROR);
+ }
+ sc.SetState(SCE_SH_DEFAULT);
+ break;
+ case SCE_SH_COMMENTLINE:
+ if (sc.atLineEnd && sc.chPrev != '\\') {
+ sc.SetState(SCE_SH_DEFAULT);
+ }
+ break;
+ case SCE_SH_HERE_DELIM:
+ // From Bash info:
+ // ---------------
+ // Specifier format is: <<[-]WORD
+ // Optional '-' is for removal of leading tabs from here-doc.
+ // Whitespace acceptable after <<[-] operator
+ //
+ if (HereDoc.State == 0) { // '<<' encountered
+ HereDoc.Quote = sc.chNext;
+ HereDoc.Quoted = false;
+ HereDoc.DelimiterLength = 0;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ if (sc.chNext == '\'' || sc.chNext == '\"') { // a quoted here-doc delimiter (' or ")
+ sc.Forward();
+ HereDoc.Quoted = true;
+ HereDoc.State = 1;
+ } else if (!HereDoc.Indent && sc.chNext == '-') { // <<- indent case
+ HereDoc.Indent = true;
+ } else if (setHereDoc.Contains(sc.chNext)) {
+ // an unquoted here-doc delimiter, no special handling
+ // TODO check what exactly bash considers part of the delim
+ HereDoc.State = 1;
+ } else if (sc.chNext == '<') { // HERE string <<<
+ sc.Forward();
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ } else if (IsASpace(sc.chNext)) {
+ // eat whitespace
+ } else if (setLeftShift.Contains(sc.chNext)) {
+ // left shift << or <<= operator cases
+ sc.ChangeState(SCE_SH_OPERATOR);
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ } else {
+ // symbols terminates; deprecated zero-length delimiter
+ HereDoc.State = 1;
+ }
+ } else if (HereDoc.State == 1) { // collect the delimiter
+ if (setHereDoc2.Contains(sc.ch) || sc.chPrev == '\\') {
+ HereDoc.Append(sc.ch);
+ } else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ } else if (sc.ch == '\\') {
+ // skip escape prefix
+ } else {
+ sc.SetState(SCE_SH_DEFAULT);
+ }
+ if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup
+ sc.SetState(SCE_SH_ERROR);
+ HereDoc.State = 0;
+ }
+ }
+ break;
+ case SCE_SH_HERE_Q:
+ // HereDoc.State == 2
+ if (sc.atLineStart) {
+ sc.SetState(SCE_SH_HERE_Q);
+ int prefixws = 0;
+ while (IsASpace(sc.ch) && !sc.atLineEnd) { // whitespace prefix
+ sc.Forward();
+ prefixws++;
+ }
+ if (prefixws > 0)
+ sc.SetState(SCE_SH_HERE_Q);
+ while (!sc.atLineEnd) {
+ sc.Forward();
+ }
+ char s[HERE_DELIM_MAX];
+ sc.GetCurrent(s, sizeof(s));
+ if (sc.LengthCurrent() == 0)
+ break;
+ if (s[strlen(s) - 1] == '\r')
+ s[strlen(s) - 1] = '\0';
+ if (strcmp(HereDoc.Delimiter, s) == 0) {
+ if ((prefixws == 0) || // indentation rule
+ (prefixws > 0 && HereDoc.Indent)) {
+ sc.SetState(SCE_SH_DEFAULT);
+ break;
+ }
+ }
+ }
+ break;
+ case SCE_SH_SCALAR: // variable names
+ if (!setParam.Contains(sc.ch)) {
+ if (sc.LengthCurrent() == 1) {
+ // Special variable: $(, $_ etc.
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ } else {
+ sc.SetState(SCE_SH_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SH_STRING: // delimited styles
+ case SCE_SH_BACKTICKS:
+ case SCE_SH_PARAM:
+ if (sc.ch == '\\' && Quote.Up != '\\') {
+ sc.Forward();
+ } else if (sc.ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ }
+ } else if (sc.ch == Quote.Up) {
+ Quote.Count++;
+ }
+ break;
+ case SCE_SH_CHARACTER: // singly-quoted strings
+ if (sc.ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ }
+ }
+ break;
+ }
+
+ // Must check end of HereDoc state 1 before default state is handled
+ if (HereDoc.State == 1 && sc.atLineEnd) {
+ // Begin of here-doc (the line after the here-doc delimiter):
+ // Lexically, the here-doc starts from the next line after the >>, but the
+ // first line of here-doc seem to follow the style of the last EOL sequence
+ HereDoc.State = 2;
+ if (HereDoc.Quoted) {
+ if (sc.state == SCE_SH_HERE_DELIM) {
+ // Missing quote at end of string! We are stricter than bash.
+ // Colour here-doc anyway while marking this bit as an error.
+ sc.ChangeState(SCE_SH_ERROR);
+ }
+ // HereDoc.Quote always == '\''
+ }
+ sc.SetState(SCE_SH_HERE_Q);
+ }
+
+ // update cmdState about the current command segment
+ if (stylePrev != SCE_SH_DEFAULT && sc.state == SCE_SH_DEFAULT) {
+ cmdState = cmdStateNew;
+ }
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_SH_DEFAULT) {
+ if (sc.ch == '\\') {
+ // Bash can escape any non-newline as a literal
+ sc.SetState(SCE_SH_IDENTIFIER);
+ if (sc.chNext == '\r' || sc.chNext == '\n')
+ sc.SetState(SCE_SH_OPERATOR);
+ } else if (IsADigit(sc.ch)) {
+ sc.SetState(SCE_SH_NUMBER);
+ numBase = BASH_BASE_DECIMAL;
+ if (sc.ch == '0') { // hex,octal
+ if (sc.chNext == 'x' || sc.chNext == 'X') {
+ numBase = BASH_BASE_HEX;
+ sc.Forward();
+ } else if (IsADigit(sc.chNext)) {
+#ifdef PEDANTIC_OCTAL
+ numBase = BASH_BASE_OCTAL;
+#else
+ numBase = BASH_BASE_HEX;
+#endif
+ }
+ }
+ } else if (setWordStart.Contains(sc.ch)) {
+ sc.SetState(SCE_SH_WORD);
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_SH_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_SH_STRING);
+ Quote.Start(sc.ch);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_SH_CHARACTER);
+ Quote.Start(sc.ch);
+ } else if (sc.ch == '`') {
+ sc.SetState(SCE_SH_BACKTICKS);
+ Quote.Start(sc.ch);
+ } else if (sc.ch == '$') {
+ if (sc.Match("$((")) {
+ sc.SetState(SCE_SH_OPERATOR); // handle '((' later
+ continue;
+ }
+ sc.SetState(SCE_SH_SCALAR);
+ sc.Forward();
+ if (sc.ch == '{') {
+ sc.ChangeState(SCE_SH_PARAM);
+ } else if (sc.ch == '\'') {
+ sc.ChangeState(SCE_SH_STRING);
+ } else if (sc.ch == '"') {
+ sc.ChangeState(SCE_SH_STRING);
+ } else if (sc.ch == '(' || sc.ch == '`') {
+ sc.ChangeState(SCE_SH_BACKTICKS);
+ } else {
+ continue; // scalar has no delimiter pair
+ }
+ // fallthrough, open delim for $[{'"(`]
+ Quote.Start(sc.ch);
+ } else if (sc.Match('<', '<')) {
+ sc.SetState(SCE_SH_HERE_DELIM);
+ HereDoc.State = 0;
+ HereDoc.Indent = false;
+ } else if (sc.ch == '-' && // one-char file test operators
+ setSingleCharOp.Contains(sc.chNext) &&
+ !setWord.Contains(sc.GetRelative(2)) &&
+ IsASpace(sc.chPrev)) {
+ sc.SetState(SCE_SH_WORD);
+ sc.Forward();
+ } else if (setBashOperator.Contains(sc.ch)) {
+ char s[10];
+ bool isCmdDelim = false;
+ sc.SetState(SCE_SH_OPERATOR);
+ // handle opening delimiters for test/arithmetic expressions - ((,[[,[
+ if (cmdState == BASH_CMD_START
+ || cmdState == BASH_CMD_BODY) {
+ if (sc.Match('(', '(')) {
+ cmdState = BASH_CMD_ARITH;
+ sc.Forward();
+ } else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) {
+ cmdState = BASH_CMD_TEST;
+ testExprType = 1;
+ sc.Forward();
+ } else if (sc.ch == '[' && IsASpace(sc.chNext)) {
+ cmdState = BASH_CMD_TEST;
+ testExprType = 2;
+ }
+ }
+ // special state -- for ((x;y;z)) in ... looping
+ if (cmdState == BASH_CMD_WORD && sc.Match('(', '(')) {
+ cmdState = BASH_CMD_ARITH;
+ sc.Forward();
+ continue;
+ }
+ // handle command delimiters in command START|BODY|WORD state, also TEST if 'test'
+ if (cmdState == BASH_CMD_START
+ || cmdState == BASH_CMD_BODY
+ || cmdState == BASH_CMD_WORD
+ || (cmdState == BASH_CMD_TEST && testExprType == 0)) {
+ s[0] = static_cast<char>(sc.ch);
+ if (setBashOperator.Contains(sc.chNext)) {
+ s[1] = static_cast<char>(sc.chNext);
+ s[2] = '\0';
+ isCmdDelim = cmdDelimiter.InList(s);
+ if (isCmdDelim)
+ sc.Forward();
+ }
+ if (!isCmdDelim) {
+ s[1] = '\0';
+ isCmdDelim = cmdDelimiter.InList(s);
+ }
+ if (isCmdDelim) {
+ cmdState = BASH_CMD_DELIM;
+ continue;
+ }
+ }
+ // handle closing delimiters for test/arithmetic expressions - )),]],]
+ if (cmdState == BASH_CMD_ARITH && sc.Match(')', ')')) {
+ cmdState = BASH_CMD_BODY;
+ sc.Forward();
+ } else if (cmdState == BASH_CMD_TEST && IsASpace(sc.chPrev)) {
+ if (sc.Match(']', ']') && testExprType == 1) {
+ sc.Forward();
+ cmdState = BASH_CMD_BODY;
+ } else if (sc.ch == ']' && testExprType == 2) {
+ cmdState = BASH_CMD_BODY;
+ }
+ }
+ }
+ }// sc.state
+ }
+ sc.Complete();
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ if (ch == '#')
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ // Comment folding
+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+ {
+ if (!IsCommentLine(lineCurrent - 1, styler)
+ && IsCommentLine(lineCurrent + 1, styler))
+ levelCurrent++;
+ else if (IsCommentLine(lineCurrent - 1, styler)
+ && !IsCommentLine(lineCurrent + 1, styler))
+ levelCurrent--;
+ }
+ if (style == SCE_SH_OPERATOR) {
+ if (ch == '{') {
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ }
+ // Here Document folding
+ if (style == SCE_SH_HERE_DELIM) {
+ if (ch == '<' && chNext == '<') {
+ levelCurrent++;
+ }
+ } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
+ levelCurrent--;
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const bashWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmBash(SCLEX_BASH, ColouriseBashDoc, "bash", FoldBashDoc, bashWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexBasic.cxx
+ ** Lexer for BlitzBasic and PureBasic.
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics
+// and derivatives. Once they diverge enough, might want to split it into multiple
+// lexers for more code clearity.
+//
+// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.
+
+// Folding only works for simple things like functions or types.
+
+// You may want to have a look at my ctags lexer as well, if you additionally to coloring
+// and folding need to extract things like label tags in your editor.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+#include <map>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/* Bits:
+ * 1 - whitespace
+ * 2 - operator
+ * 4 - identifier
+ * 8 - decimal digit
+ * 16 - hex digit
+ * 32 - bin digit
+ */
+static int character_classification[128] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
+ 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
+};
+
+static bool IsSpace(int c) {
+ return c < 128 && (character_classification[c] & 1);
+}
+
+static bool IsOperator(int c) {
+ return c < 128 && (character_classification[c] & 2);
+}
+
+static bool IsIdentifier(int c) {
+ return c < 128 && (character_classification[c] & 4);
+}
+
+static bool IsDigit(int c) {
+ return c < 128 && (character_classification[c] & 8);
+}
+
+static bool IsHexDigit(int c) {
+ return c < 128 && (character_classification[c] & 16);
+}
+
+static bool IsBinDigit(int c) {
+ return c < 128 && (character_classification[c] & 32);
+}
+
+static int LowerCase(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+static int CheckBlitzFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckPureFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "procedure") ||
+ !strcmp(token, "enumeration") ||
+ !strcmp(token, "interface") ||
+ !strcmp(token, "structure")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "endprocedure") ||
+ !strcmp(token, "endenumeration") ||
+ !strcmp(token, "endinterface") ||
+ !strcmp(token, "endstructure")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckFreeFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "sub") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end sub") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerBasic
+struct OptionsBasic {
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldCompact;
+ OptionsBasic() {
+ fold = false;
+ foldSyntaxBased = true;
+ foldCommentExplicit = false;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldCompact = true;
+ }
+};
+
+static const char * const blitzbasicWordListDesc[] = {
+ "BlitzBasic Keywords",
+ "user1",
+ "user2",
+ "user3",
+ 0
+};
+
+static const char * const purebasicWordListDesc[] = {
+ "PureBasic Keywords",
+ "PureBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+static const char * const freebasicWordListDesc[] = {
+ "FreeBasic Keywords",
+ "FreeBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+struct OptionSetBasic : public OptionSet<OptionsBasic> {
+ OptionSetBasic(const char * const wordListDescriptions[]) {
+ DefineProperty("fold", &OptionsBasic::fold);
+
+ DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
+ "This option enables folding explicit fold points when using the Basic lexer. "
+ "Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
+ "and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
+
+ DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
+
+ DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
+
+ DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.compact", &OptionsBasic::foldCompact);
+
+ DefineWordListSets(wordListDescriptions);
+ }
+};
+
+class LexerBasic : public ILexer {
+ char comment_char;
+ int (*CheckFoldPoint)(char const *, int &);
+ WordList keywordlists[4];
+ OptionsBasic options;
+ OptionSetBasic osBasic;
+public:
+ LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
+ comment_char(comment_char_),
+ CheckFoldPoint(CheckFoldPoint_),
+ osBasic(wordListDescriptions) {
+ }
+ virtual ~LexerBasic() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osBasic.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osBasic.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osBasic.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osBasic.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+ static ILexer *LexerFactoryBlitzBasic() {
+ return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
+ }
+ static ILexer *LexerFactoryPureBasic() {
+ return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
+ }
+ static ILexer *LexerFactoryFreeBasic() {
+ return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
+ }
+};
+
+int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
+ if (osBasic.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywordlists[0];
+ break;
+ case 1:
+ wordListN = &keywordlists[1];
+ break;
+ case 2:
+ wordListN = &keywordlists[2];
+ break;
+ case 3:
+ wordListN = &keywordlists[3];
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
+ bool wasfirst = true, isfirst = true; // true if first token in a line
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ // Can't use sc.More() here else we miss the last character
+ for (; ; sc.Forward()) {
+ if (sc.state == SCE_B_IDENTIFIER) {
+ if (!IsIdentifier(sc.ch)) {
+ // Labels
+ if (wasfirst && sc.Match(':')) {
+ sc.ChangeState(SCE_B_LABEL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else {
+ char s[100];
+ int kstates[4] = {
+ SCE_B_KEYWORD,
+ SCE_B_KEYWORD2,
+ SCE_B_KEYWORD3,
+ SCE_B_KEYWORD4,
+ };
+ sc.GetCurrentLowered(s, sizeof(s));
+ for (int i = 0; i < 4; i++) {
+ if (keywordlists[i].InList(s)) {
+ sc.ChangeState(kstates[i]);
+ }
+ }
+ // Types, must set them as operator else they will be
+ // matched as number/constant
+ if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||
+ sc.Match('#')) {
+ sc.SetState(SCE_B_OPERATOR);
+ } else {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+ }
+ } else if (sc.state == SCE_B_OPERATOR) {
+ if (!IsOperator(sc.ch) || sc.Match('#'))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_LABEL) {
+ if (!IsIdentifier(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_CONSTANT) {
+ if (!IsIdentifier(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_NUMBER) {
+ if (!IsDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_HEXNUMBER) {
+ if (!IsHexDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_BINNUMBER) {
+ if (!IsBinDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_STRING) {
+ if (sc.ch == '"') {
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_B_ERROR);
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+
+ if (sc.atLineStart)
+ isfirst = true;
+
+ if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
+ if (isfirst && sc.Match('.')) {
+ sc.SetState(SCE_B_LABEL);
+ } else if (isfirst && sc.Match('#')) {
+ wasfirst = isfirst;
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (sc.Match(comment_char)) {
+ // Hack to make deprecated QBASIC '$Include show
+ // up in freebasic with SCE_B_PREPROCESSOR.
+ if (comment_char == '\'' && sc.Match(comment_char, '$'))
+ sc.SetState(SCE_B_PREPROCESSOR);
+ else
+ sc.SetState(SCE_B_COMMENT);
+ } else if (sc.Match('"')) {
+ sc.SetState(SCE_B_STRING);
+ } else if (IsDigit(sc.ch)) {
+ sc.SetState(SCE_B_NUMBER);
+ } else if (sc.Match('$')) {
+ sc.SetState(SCE_B_HEXNUMBER);
+ } else if (sc.Match('%')) {
+ sc.SetState(SCE_B_BINNUMBER);
+ } else if (sc.Match('#')) {
+ sc.SetState(SCE_B_CONSTANT);
+ } else if (IsOperator(sc.ch)) {
+ sc.SetState(SCE_B_OPERATOR);
+ } else if (IsIdentifier(sc.ch)) {
+ wasfirst = isfirst;
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (!IsSpace(sc.ch)) {
+ sc.SetState(SCE_B_ERROR);
+ }
+ }
+
+ if (!IsSpace(sc.ch))
+ isfirst = false;
+
+ if (!sc.More())
+ break;
+ }
+ sc.Complete();
+}
+
+
+void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
+ int line = styler.GetLine(startPos);
+ int level = styler.LevelAt(line);
+ int go = 0, done = 0;
+ int endPos = startPos + length;
+ char word[256];
+ int wordlen = 0;
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+ int cNext = styler[startPos];
+
+ // Scan for tokens at the start of the line (they may include
+ // whitespace, for tokens like "End Function"
+ for (int i = startPos; i < endPos; i++) {
+ int c = cNext;
+ cNext = styler.SafeGetCharAt(i + 1);
+ bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
+ if (options.foldSyntaxBased && !done && !go) {
+ if (wordlen) { // are we scanning a token already?
+ word[wordlen] = static_cast<char>(LowerCase(c));
+ if (!IsIdentifier(c)) { // done with token
+ word[wordlen] = '\0';
+ go = CheckFoldPoint(word, level);
+ if (!go) {
+ // Treat any whitespace as single blank, for
+ // things like "End Function".
+ if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
+ word[wordlen] = ' ';
+ if (wordlen < 255)
+ wordlen++;
+ }
+ else // done with this line
+ done = 1;
+ }
+ } else if (wordlen < 255) {
+ wordlen++;
+ }
+ } else { // start scanning at first non-whitespace character
+ if (!IsSpace(c)) {
+ if (IsIdentifier(c)) {
+ word[0] = static_cast<char>(LowerCase(c));
+ wordlen = 1;
+ } else // done with this line
+ done = 1;
+ }
+ }
+ }
+ if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ go = 1;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ go = -1;
+ }
+ } else {
+ if (c == comment_char) {
+ if (cNext == '{') {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ go = 1;
+ } else if (cNext == '}') {
+ go = -1;
+ }
+ }
+ }
+ }
+ if (atEOL) { // line end
+ if (!done && wordlen == 0 && options.foldCompact) // line was only space
+ level |= SC_FOLDLEVELWHITEFLAG;
+ if (level != styler.LevelAt(line))
+ styler.SetLevel(line, level);
+ level += go;
+ line++;
+ // reset state
+ wordlen = 0;
+ level &= ~SC_FOLDLEVELHEADERFLAG;
+ level &= ~SC_FOLDLEVELWHITEFLAG;
+ go = 0;
+ done = 0;
+ }
+ }
+}
+
+LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
+
+LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
+
+LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);
--- /dev/null
+// SciTE - Scintilla based Text Editor
+// LexBullant.cxx - lexer for Bullant
+
+#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 int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+ char s[100];
+ s[0] = '\0';
+ for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ s[i + 1] = '\0';
+ }
+ int lev= 0;
+ char chAttr = SCE_C_IDENTIFIER;
+ if (isdigit(s[0]) || (s[0] == '.')){
+ chAttr = SCE_C_NUMBER;
+ }
+ else {
+ if (keywords.InList(s)) {
+ chAttr = SCE_C_WORD;
+ if (strcmp(s, "end") == 0)
+ lev = -1;
+ else if (strcmp(s, "method") == 0 ||
+ strcmp(s, "case") == 0 ||
+ strcmp(s, "class") == 0 ||
+ strcmp(s, "debug") == 0 ||
+ strcmp(s, "test") == 0 ||
+ strcmp(s, "if") == 0 ||
+ strcmp(s, "lock") == 0 ||
+ strcmp(s, "transaction") == 0 ||
+ strcmp(s, "trap") == 0 ||
+ strcmp(s, "until") == 0 ||
+ strcmp(s, "while") == 0)
+ lev = 1;
+ }
+ }
+ styler.ColourTo(end, chAttr);
+ return lev;
+}
+
+static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ WordList &keywords = *keywordlists[0];
+
+ styler.StartAt(startPos);
+
+ bool fold = styler.GetPropertyInt("fold") != 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+
+ int state = initStyle;
+ if (state == SCE_C_STRINGEOL) // Does not leak onto next line
+ state = SCE_C_DEFAULT;
+ char chPrev = ' ';
+ char chNext = styler[startPos];
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ styler.StartSegment(startPos);
+ int endFoundThisLine = 0;
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+ // Avoid triggering two times on Dos/Win
+ // End of line
+ endFoundThisLine = 0;
+ if (state == SCE_C_STRINGEOL) {
+ styler.ColourTo(i, state);
+ state = SCE_C_DEFAULT;
+ }
+ if (fold) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ }
+ visibleChars = 0;
+
+/* int indentBlock = GetLineIndentation(lineCurrent);
+ if (blockChange==1){
+ lineCurrent++;
+ int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);
+ } else if (blockChange==-1) {
+ indentBlock -= indentSize;
+ if (indentBlock < 0)
+ indentBlock = 0;
+ SetLineIndentation(lineCurrent, indentBlock);
+ lineCurrent++;
+ }
+ blockChange=0;
+*/ }
+ if (!(isascii(ch) && isspace(ch)))
+ visibleChars++;
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ if (state == SCE_C_DEFAULT) {
+ if (iswordstart(ch)) {
+ styler.ColourTo(i-1, state);
+ state = SCE_C_IDENTIFIER;
+ } else if (ch == '@' && chNext == 'o') {
+ if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {
+ styler.ColourTo(i-1, state);
+ state = SCE_C_COMMENT;
+ }
+ } else if (ch == '#') {
+ styler.ColourTo(i-1, state);
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '\"') {
+ styler.ColourTo(i-1, state);
+ state = SCE_C_STRING;
+ } else if (ch == '\'') {
+ styler.ColourTo(i-1, state);
+ state = SCE_C_CHARACTER;
+ } else if (isoperator(ch)) {
+ styler.ColourTo(i-1, state);
+ styler.ColourTo(i, SCE_C_OPERATOR);
+ }
+ } else if (state == SCE_C_IDENTIFIER) {
+ if (!iswordchar(ch)) {
+ int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);
+ state = SCE_C_DEFAULT;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (ch == '#') {
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '\"') {
+ state = SCE_C_STRING;
+ } else if (ch == '\'') {
+ state = SCE_C_CHARACTER;
+ } else if (isoperator(ch)) {
+ styler.ColourTo(i, SCE_C_OPERATOR);
+ }
+ if (endFoundThisLine == 0)
+ levelCurrent+=levelChange;
+ if (levelChange == -1)
+ endFoundThisLine=1;
+ }
+ } else if (state == SCE_C_COMMENT) {
+ if (ch == '@' && chNext == 'o') {
+ if (styler.SafeGetCharAt(i+2) == 'n') {
+ styler.ColourTo(i+2, state);
+ state = SCE_C_DEFAULT;
+ i+=2;
+ }
+ }
+ } else if (state == SCE_C_COMMENTLINE) {
+ if (ch == '\r' || ch == '\n') {
+ endFoundThisLine = 0;
+ styler.ColourTo(i-1, state);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_STRING) {
+ if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ } else if (ch == '\"') {
+ styler.ColourTo(i, state);
+ state = SCE_C_DEFAULT;
+ } else if (chNext == '\r' || chNext == '\n') {
+ endFoundThisLine = 0;
+ styler.ColourTo(i-1, SCE_C_STRINGEOL);
+ state = SCE_C_STRINGEOL;
+ }
+ } else if (state == SCE_C_CHARACTER) {
+ if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
+ endFoundThisLine = 0;
+ styler.ColourTo(i-1, SCE_C_STRINGEOL);
+ state = SCE_C_STRINGEOL;
+ } else if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ } else if (ch == '\'') {
+ styler.ColourTo(i, state);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ chPrev = ch;
+ }
+ styler.ColourTo(lengthDoc - 1, state);
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ if (fold) {
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+
+ }
+}
+
+static const char * const bullantWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexClw.cxx
+ ** Lexer for Clarion.
+ ** 2004/12/17 Updated Lexer
+ **/
+// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
+// 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
+
+// Is an end of line character
+inline bool IsEOL(const int ch) {
+
+ return(ch == '\n');
+}
+
+// Convert character to uppercase
+static char CharacterUpper(char chChar) {
+
+ if (chChar < 'a' || chChar > 'z') {
+ return(chChar);
+ }
+ else {
+ return(static_cast<char>(chChar - 'a' + 'A'));
+ }
+}
+
+// Convert string to uppercase
+static void StringUpper(char *szString) {
+
+ while (*szString) {
+ *szString = CharacterUpper(*szString);
+ szString++;
+ }
+}
+
+// Is a label start character
+inline bool IsALabelStart(const int iChar) {
+
+ return(isalpha(iChar) || iChar == '_');
+}
+
+// Is a label character
+inline bool IsALabelCharacter(const int iChar) {
+
+ return(isalnum(iChar) || iChar == '_' || iChar == ':');
+}
+
+// Is the character is a ! and the the next character is not a !
+inline bool IsACommentStart(const int iChar) {
+
+ return(iChar == '!');
+}
+
+// Is the character a Clarion hex character (ABCDEF)
+inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
+
+ // Case insensitive.
+ if (!bCaseSensitive) {
+ if (strchr("ABCDEFabcdef", iChar) != NULL) {
+ return(true);
+ }
+ }
+ // Case sensitive
+ else {
+ if (strchr("ABCDEF", iChar) != NULL) {
+ return(true);
+ }
+ }
+ return(false);
+}
+
+// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
+inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
+
+ // Case insensitive.
+ if (!bCaseSensitive) {
+ // If character is a numeric base character
+ if (strchr("BOHboh", iChar) != NULL) {
+ return(true);
+ }
+ }
+ // Case sensitive
+ else {
+ // If character is a numeric base character
+ if (strchr("BOH", iChar) != NULL) {
+ return(true);
+ }
+ }
+ return(false);
+}
+
+// Set the correct numeric constant state
+inline bool SetNumericConstantState(StyleContext &scDoc) {
+
+ int iPoints = 0; // Point counter
+ char cNumericString[512]; // Numeric string buffer
+
+ // Buffer the current numberic string
+ scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
+ // Loop through the string until end of string (NULL termination)
+ for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) {
+ // Depending on the character
+ switch (cNumericString[iIndex]) {
+ // Is a . (point)
+ case '.' :
+ // Increment point counter
+ iPoints++;
+ break;
+ default :
+ break;
+ }
+ }
+ // If points found (can be more than one for improper formatted number
+ if (iPoints > 0) {
+ return(true);
+ }
+ // Else no points found
+ else {
+ return(false);
+ }
+}
+
+// Get the next word in uppercase from the current position (keyword lookahead)
+inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
+
+ unsigned int iIndex = 0; // Buffer Index
+
+ // Loop through the remaining string from the current position
+ for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
+ // Get the character from the buffer using the offset
+ char cCharacter = styler[iOffset];
+ if (IsEOL(cCharacter)) {
+ break;
+ }
+ // If the character is alphabet character
+ if (isalpha(cCharacter)) {
+ // Add UPPERCASE character to the word buffer
+ cWord[iIndex++] = CharacterUpper(cCharacter);
+ }
+ }
+ // Add null termination
+ cWord[iIndex] = '\0';
+ // If no word was found
+ if (iIndex == 0) {
+ // Return failure
+ return(false);
+ }
+ // Else word was found
+ else {
+ // Return success
+ return(true);
+ }
+}
+
+// Clarion Language Colouring Procedure
+static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
+
+ int iParenthesesLevel = 0; // Parenthese Level
+ int iColumn1Label = false; // Label starts in Column 1
+
+ WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
+ WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
+ WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
+ WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
+ WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
+ WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
+ WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
+ WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
+ WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
+
+ const char wlProcReservedKeywordList[] =
+ "PROCEDURE FUNCTION";
+ WordList wlProcReservedKeywords;
+ wlProcReservedKeywords.Set(wlProcReservedKeywordList);
+
+ const char wlCompilerKeywordList[] =
+ "COMPILE OMIT";
+ WordList wlCompilerKeywords;
+ wlCompilerKeywords.Set(wlCompilerKeywordList);
+
+ const char wlLegacyStatementsList[] =
+ "BOF EOF FUNCTION POINTER SHARE";
+ WordList wlLegacyStatements;
+ wlLegacyStatements.Set(wlLegacyStatementsList);
+
+ StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
+
+ // lex source code
+ for (; scDoc.More(); scDoc.Forward())
+ {
+ //
+ // Determine if the current state should terminate.
+ //
+
+ // Label State Handling
+ if (scDoc.state == SCE_CLW_LABEL) {
+ // If the character is not a valid label
+ if (!IsALabelCharacter(scDoc.ch)) {
+ // If the character is a . (dot syntax)
+ if (scDoc.ch == '.') {
+ // Turn off column 1 label flag as label now cannot be reserved work
+ iColumn1Label = false;
+ // Uncolour the . (dot) to default state, move forward one character,
+ // and change back to the label state.
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ scDoc.Forward();
+ scDoc.SetState(SCE_CLW_LABEL);
+ }
+ // Else check label
+ else {
+ char cLabel[512]; // Label buffer
+ // Buffer the current label string
+ scDoc.GetCurrent(cLabel,sizeof(cLabel));
+ // If case insensitive, convert string to UPPERCASE to match passed keywords.
+ if (!bCaseSensitive) {
+ StringUpper(cLabel);
+ }
+ // Else if UPPERCASE label string is in the Clarion compiler keyword list
+ if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
+ // change the label to error state
+ scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
+ }
+ // Else if UPPERCASE label string is in the Clarion reserved keyword list
+ else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
+ // change the label to error state
+ scDoc.ChangeState(SCE_CLW_ERROR);
+ }
+ // Else if UPPERCASE label string is
+ else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
+ char cWord[512]; // Word buffer
+ // Get the next word from the current position
+ if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
+ // If the next word is a procedure reserved word
+ if (wlProcReservedKeywords.InList(cWord)) {
+ // Change the label to error state
+ scDoc.ChangeState(SCE_CLW_ERROR);
+ }
+ }
+ }
+ // Else if label string is in the compiler directive keyword list
+ else if (wlCompilerDirectives.InList(cLabel)) {
+ // change the state to compiler directive state
+ scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
+ }
+ // Terminate the label state and set to default state
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ }
+ }
+ // Keyword State Handling
+ else if (scDoc.state == SCE_CLW_KEYWORD) {
+ // If character is : (colon)
+ if (scDoc.ch == ':') {
+ char cEquate[512]; // Equate buffer
+ // Move forward to include : (colon) in buffer
+ scDoc.Forward();
+ // Buffer the equate string
+ scDoc.GetCurrent(cEquate,sizeof(cEquate));
+ // If case insensitive, convert string to UPPERCASE to match passed keywords.
+ if (!bCaseSensitive) {
+ StringUpper(cEquate);
+ }
+ // If statement string is in the equate list
+ if (wlStandardEquates.InList(cEquate)) {
+ // Change to equate state
+ scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
+ }
+ }
+ // If the character is not a valid label character
+ else if (!IsALabelCharacter(scDoc.ch)) {
+ char cStatement[512]; // Statement buffer
+ // Buffer the statement string
+ scDoc.GetCurrent(cStatement,sizeof(cStatement));
+ // If case insensitive, convert string to UPPERCASE to match passed keywords.
+ if (!bCaseSensitive) {
+ StringUpper(cStatement);
+ }
+ // If statement string is in the Clarion keyword list
+ if (wlClarionKeywords.InList(cStatement)) {
+ // Change the statement string to the Clarion keyword state
+ scDoc.ChangeState(SCE_CLW_KEYWORD);
+ }
+ // Else if statement string is in the compiler directive keyword list
+ else if (wlCompilerDirectives.InList(cStatement)) {
+ // Change the statement string to the compiler directive state
+ scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
+ }
+ // Else if statement string is in the runtime expressions keyword list
+ else if (wlRuntimeExpressions.InList(cStatement)) {
+ // Change the statement string to the runtime expressions state
+ scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
+ }
+ // Else if statement string is in the builtin procedures and functions keyword list
+ else if (wlBuiltInProcsFuncs.InList(cStatement)) {
+ // Change the statement string to the builtin procedures and functions state
+ scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
+ }
+ // Else if statement string is in the tructures and data types keyword list
+ else if (wlStructsDataTypes.InList(cStatement)) {
+ // Change the statement string to the structures and data types state
+ scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
+ }
+ // Else if statement string is in the procedure attribute keyword list
+ else if (wlAttributes.InList(cStatement)) {
+ // Change the statement string to the procedure attribute state
+ scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
+ }
+ // Else if statement string is in the standard equate keyword list
+ else if (wlStandardEquates.InList(cStatement)) {
+ // Change the statement string to the standard equate state
+ scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
+ }
+ // Else if statement string is in the deprecated or legacy keyword list
+ else if (wlLegacyStatements.InList(cStatement)) {
+ // Change the statement string to the standard equate state
+ scDoc.ChangeState(SCE_CLW_DEPRECATED);
+ }
+ // Else the statement string doesn't match any work list
+ else {
+ // Change the statement string to the default state
+ scDoc.ChangeState(SCE_CLW_DEFAULT);
+ }
+ // Terminate the keyword state and set to default state
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ }
+ // String State Handling
+ else if (scDoc.state == SCE_CLW_STRING) {
+ // If the character is an ' (single quote)
+ if (scDoc.ch == '\'') {
+ // Set the state to default and move forward colouring
+ // the ' (single quote) as default state
+ // terminating the string state
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ scDoc.Forward();
+ }
+ // If the next character is an ' (single quote)
+ if (scDoc.chNext == '\'') {
+ // Move forward one character and set to default state
+ // colouring the next ' (single quote) as default state
+ // terminating the string state
+ scDoc.ForwardSetState(SCE_CLW_DEFAULT);
+ scDoc.Forward();
+ }
+ }
+ // Picture String State Handling
+ else if (scDoc.state == SCE_CLW_PICTURE_STRING) {
+ // If the character is an ( (open parenthese)
+ if (scDoc.ch == '(') {
+ // Increment the parenthese level
+ iParenthesesLevel++;
+ }
+ // Else if the character is a ) (close parenthese)
+ else if (scDoc.ch == ')') {
+ // If the parenthese level is set to zero
+ // parentheses matched
+ if (!iParenthesesLevel) {
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ // Else parenthese level is greater than zero
+ // still looking for matching parentheses
+ else {
+ // Decrement the parenthese level
+ iParenthesesLevel--;
+ }
+ }
+ }
+ // Standard Equate State Handling
+ else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {
+ if (!isalnum(scDoc.ch)) {
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ }
+ // Integer Constant State Handling
+ else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {
+ // If the character is not a digit (0-9)
+ // or character is not a hexidecimal character (A-F)
+ // or character is not a . (point)
+ // or character is not a numberic base character (B,O,H)
+ if (!(isdigit(scDoc.ch)
+ || IsAHexCharacter(scDoc.ch, bCaseSensitive)
+ || scDoc.ch == '.'
+ || IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
+ // If the number was a real
+ if (SetNumericConstantState(scDoc)) {
+ // Colour the matched string to the real constant state
+ scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
+ }
+ // Else the number was an integer
+ else {
+ // Colour the matched string to an integer constant state
+ scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);
+ }
+ // Terminate the integer constant state and set to default state
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ }
+
+ //
+ // Determine if a new state should be entered.
+ //
+
+ // Beginning of Line Handling
+ if (scDoc.atLineStart) {
+ // Reset the column 1 label flag
+ iColumn1Label = false;
+ // If column 1 character is a label start character
+ if (IsALabelStart(scDoc.ch)) {
+ // Label character is found in column 1
+ // so set column 1 label flag and clear last column 1 label
+ iColumn1Label = true;
+ // Set the state to label
+ scDoc.SetState(SCE_CLW_LABEL);
+ }
+ // else if character is a space or tab
+ else if (IsASpace(scDoc.ch)){
+ // Set to default state
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ // else if comment start (!) or is an * (asterisk)
+ else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
+ // then set the state to comment.
+ scDoc.SetState(SCE_CLW_COMMENT);
+ }
+ // else the character is a ? (question mark)
+ else if (scDoc.ch == '?') {
+ // Change to the compiler directive state, move forward,
+ // colouring the ? (question mark), change back to default state.
+ scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
+ scDoc.Forward();
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ // else an invalid character in column 1
+ else {
+ // Set to error state
+ scDoc.SetState(SCE_CLW_ERROR);
+ }
+ }
+ // End of Line Handling
+ else if (scDoc.atLineEnd) {
+ // Reset to the default state at the end of each line.
+ scDoc.SetState(SCE_CLW_DEFAULT);
+ }
+ // Default Handling
+ else {
+ // If in default state
+ if (scDoc.state == SCE_CLW_DEFAULT) {
+ // If is a letter could be a possible statement
+ if (isalpha(scDoc.ch)) {
+ // Set the state to Clarion Keyword and verify later
+ scDoc.SetState(SCE_CLW_KEYWORD);
+ }
+ // else is a number
+ else if (isdigit(scDoc.ch)) {
+ // Set the state to Integer Constant and verify later
+ scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
+ }
+ // else if the start of a comment or a | (line continuation)
+ else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
+ // then set the state to comment.
+ scDoc.SetState(SCE_CLW_COMMENT);
+ }
+ // else if the character is a ' (single quote)
+ else if (scDoc.ch == '\'') {
+ // If the character is also a ' (single quote)
+ // Embedded Apostrophe
+ if (scDoc.chNext == '\'') {
+ // Move forward colouring it as default state
+ scDoc.ForwardSetState(SCE_CLW_DEFAULT);
+ }
+ else {
+ // move to the next character and then set the state to comment.
+ scDoc.ForwardSetState(SCE_CLW_STRING);
+ }
+ }
+ // else the character is an @ (ampersand)
+ else if (scDoc.ch == '@') {
+ // Case insensitive.
+ if (!bCaseSensitive) {
+ // If character is a valid picture token character
+ if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) {
+ // Set to the picture string state
+ scDoc.SetState(SCE_CLW_PICTURE_STRING);
+ }
+ }
+ // Case sensitive
+ else {
+ // If character is a valid picture token character
+ if (strchr("DEKNPST", scDoc.chNext) != NULL) {
+ // Set the picture string state
+ scDoc.SetState(SCE_CLW_PICTURE_STRING);
+ }
+ }
+ }
+ }
+ }
+ }
+ // lexing complete
+ scDoc.Complete();
+}
+
+// Clarion Language Case Sensitive Colouring Procedure
+static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+
+ ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
+}
+
+// Clarion Language Case Insensitive Colouring Procedure
+static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+
+ ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
+}
+
+// Fill Buffer
+
+static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
+
+ unsigned int uiPos = 0;
+
+ while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
+ szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
+ uiPos++;
+ }
+ szBuffer[uiPos] = '\0';
+}
+
+// Classify Clarion Fold Point
+
+static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
+
+ if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
+ if (strcmp(szString, "PROCEDURE") == 0) {
+ // iLevel = SC_FOLDLEVELBASE + 1;
+ }
+ else if (strcmp(szString, "MAP") == 0 ||
+ strcmp(szString,"ACCEPT") == 0 ||
+ strcmp(szString,"BEGIN") == 0 ||
+ strcmp(szString,"CASE") == 0 ||
+ strcmp(szString,"EXECUTE") == 0 ||
+ strcmp(szString,"IF") == 0 ||
+ strcmp(szString,"ITEMIZE") == 0 ||
+ strcmp(szString,"INTERFACE") == 0 ||
+ strcmp(szString,"JOIN") == 0 ||
+ strcmp(szString,"LOOP") == 0 ||
+ strcmp(szString,"MODULE") == 0 ||
+ strcmp(szString,"RECORD") == 0) {
+ iLevel++;
+ }
+ else if (strcmp(szString, "APPLICATION") == 0 ||
+ strcmp(szString, "CLASS") == 0 ||
+ strcmp(szString, "DETAIL") == 0 ||
+ strcmp(szString, "FILE") == 0 ||
+ strcmp(szString, "FOOTER") == 0 ||
+ strcmp(szString, "FORM") == 0 ||
+ strcmp(szString, "GROUP") == 0 ||
+ strcmp(szString, "HEADER") == 0 ||
+ strcmp(szString, "INTERFACE") == 0 ||
+ strcmp(szString, "MENU") == 0 ||
+ strcmp(szString, "MENUBAR") == 0 ||
+ strcmp(szString, "OLE") == 0 ||
+ strcmp(szString, "OPTION") == 0 ||
+ strcmp(szString, "QUEUE") == 0 ||
+ strcmp(szString, "REPORT") == 0 ||
+ strcmp(szString, "SHEET") == 0 ||
+ strcmp(szString, "TAB") == 0 ||
+ strcmp(szString, "TOOLBAR") == 0 ||
+ strcmp(szString, "VIEW") == 0 ||
+ strcmp(szString, "WINDOW") == 0) {
+ iLevel++;
+ }
+ else if (strcmp(szString, "END") == 0 ||
+ strcmp(szString, "UNTIL") == 0 ||
+ strcmp(szString, "WHILE") == 0) {
+ iLevel--;
+ }
+ }
+ return(iLevel);
+}
+
+// Clarion Language Folding Procedure
+static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
+
+ unsigned int uiEndPos = uiStartPos + iLength;
+ int iLineCurrent = accStyler.GetLine(uiStartPos);
+ int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int iLevelCurrent = iLevelPrev;
+ char chNext = accStyler[uiStartPos];
+ int iStyle = iInitStyle;
+ int iStyleNext = accStyler.StyleAt(uiStartPos);
+ int iVisibleChars = 0;
+ int iLastStart = 0;
+
+ for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
+
+ char chChar = chNext;
+ chNext = accStyler.SafeGetCharAt(uiPos + 1);
+ int iStylePrev = iStyle;
+ iStyle = iStyleNext;
+ iStyleNext = accStyler.StyleAt(uiPos + 1);
+ bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
+
+ if (iStylePrev == SCE_CLW_DEFAULT) {
+ if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
+ // Store last word start point.
+ iLastStart = uiPos;
+ }
+ }
+
+ if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
+ if(iswordchar(chChar) && !iswordchar(chNext)) {
+ char chBuffer[100];
+ FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
+ iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
+ // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
+ // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
+ // iLevelPrev = SC_FOLDLEVELBASE;
+ // }
+ }
+ }
+
+ if (bEOL) {
+ int iLevel = iLevelPrev;
+ if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
+ iLevel |= SC_FOLDLEVELHEADERFLAG;
+ if (iLevel != accStyler.LevelAt(iLineCurrent)) {
+ accStyler.SetLevel(iLineCurrent,iLevel);
+ }
+ iLineCurrent++;
+ iLevelPrev = iLevelCurrent;
+ iVisibleChars = 0;
+ }
+
+ if (!isspacechar(chChar))
+ iVisibleChars++;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags
+ // as they will be filled in later.
+ int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
+}
+
+// Word List Descriptions
+static const char * const rgWordListDescriptions[] = {
+ "Clarion Keywords",
+ "Compiler Directives",
+ "Built-in Procedures and Functions",
+ "Runtime Expressions",
+ "Structure and Data Types",
+ "Attributes",
+ "Standard Equates",
+ "Reserved Words (Labels)",
+ "Reserved Words (Procedure Labels)",
+ 0,
+};
+
+// Case Sensitive Clarion Language Lexer
+LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
+
+// Case Insensitive Clarion Language Lexer
+LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCOBOL.cxx
+ ** Lexer for COBOL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to COBOL
+ **/
+
+#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
+
+#define IN_DIVISION 0x01
+#define IN_DECLARATIVES 0x02
+#define IN_SECTION 0x04
+#define IN_PARAGRAPH 0x08
+#define IN_FLAGS 0xF
+#define NOT_HEADER 0x10
+
+inline bool isCOBOLoperator(char ch)
+ {
+ return isoperator(ch);
+ }
+
+inline bool isCOBOLwordchar(char ch)
+ {
+ return isascii(ch) && (isalnum(ch) || ch == '-');
+
+ }
+
+inline bool isCOBOLwordstart(char ch)
+ {
+ return isascii(ch) && isalnum(ch);
+ }
+
+static int CountBits(int nBits)
+ {
+ int count = 0;
+ for (int i = 0; i < 32; ++i)
+ {
+ count += nBits & 1;
+ nBits >>= 1;
+ }
+ return count;
+ }
+
+static void getRange(unsigned int start,
+ unsigned int end,
+ Accessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr) {
+ styler.ColourTo(end, attr);
+}
+
+
+static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
+ int ret = 0;
+
+ WordList& a_keywords = *keywordlists[0];
+ WordList& b_keywords = *keywordlists[1];
+ WordList& c_keywords = *keywordlists[2];
+
+ char s[100];
+ getRange(start, end, styler, s, sizeof(s));
+
+ char chAttr = SCE_C_IDENTIFIER;
+ if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {
+ chAttr = SCE_C_NUMBER;
+ char *p = s + 1;
+ while (*p) {
+ if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
+ chAttr = SCE_C_IDENTIFIER;
+ break;
+ }
+ ++p;
+ }
+ }
+ else {
+ if (a_keywords.InList(s)) {
+ chAttr = SCE_C_WORD;
+ }
+ else if (b_keywords.InList(s)) {
+ chAttr = SCE_C_WORD2;
+ }
+ else if (c_keywords.InList(s)) {
+ chAttr = SCE_C_UUID;
+ }
+ }
+ if (*bAarea) {
+ if (strcmp(s, "division") == 0) {
+ ret = IN_DIVISION;
+ // we've determined the containment, anything else is just ignored for those purposes
+ *bAarea = false;
+ } else if (strcmp(s, "declaratives") == 0) {
+ ret = IN_DIVISION | IN_DECLARATIVES;
+ if (nContainment & IN_DECLARATIVES)
+ ret |= NOT_HEADER | IN_SECTION;
+ // we've determined the containment, anything else is just ignored for those purposes
+ *bAarea = false;
+ } else if (strcmp(s, "section") == 0) {
+ ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;
+ // we've determined the containment, anything else is just ignored for those purposes
+ *bAarea = false;
+ } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) {
+ ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;
+ } else {
+ ret = nContainment | IN_PARAGRAPH;
+ }
+ }
+ ColourTo(styler, end, chAttr);
+ return ret;
+}
+
+static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ styler.StartAt(startPos);
+
+ int state = initStyle;
+ if (state == SCE_C_CHARACTER) // Does not leak onto next line
+ state = SCE_C_DEFAULT;
+ char chPrev = ' ';
+ char chNext = styler[startPos];
+ unsigned int lengthDoc = startPos + length;
+
+ int nContainment;
+
+ int currentLine = styler.GetLine(startPos);
+ if (currentLine > 0) {
+ styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+ nContainment = styler.GetLineState(currentLine);
+ nContainment &= ~NOT_HEADER;
+ } else {
+ styler.SetLineState(currentLine, 0);
+ nContainment = 0;
+ }
+
+ styler.StartSegment(startPos);
+ bool bNewLine = true;
+ bool bAarea = !isspacechar(chNext);
+ int column = 0;
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ ++column;
+
+ if (bNewLine) {
+ column = 0;
+ }
+ if (column <= 1 && !bAarea) {
+ bAarea = !isspacechar(ch);
+ }
+ bool bSetNewLine = false;
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+ // Avoid triggering two times on Dos/Win
+ // End of line
+ if (state == SCE_C_CHARACTER) {
+ ColourTo(styler, i, state);
+ state = SCE_C_DEFAULT;
+ }
+ styler.SetLineState(currentLine, nContainment);
+ currentLine++;
+ bSetNewLine = true;
+ if (nContainment & NOT_HEADER)
+ nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);
+ }
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ if (state == SCE_C_DEFAULT) {
+ if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_IDENTIFIER;
+ } else if (column == 6 && ch == '*') {
+ // Cobol comment line: asterisk in column 7.
+ ColourTo(styler, i-1, state);
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '*' && chNext == '>') {
+ // Cobol inline comment: asterisk, followed by greater than.
+ ColourTo(styler, i-1, state);
+ state = SCE_C_COMMENTLINE;
+ } else if (column == 0 && ch == '*' && chNext != '*') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_COMMENTLINE;
+ } else if (column == 0 && ch == '/' && chNext != '*') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_COMMENTLINE;
+ } else if (column == 0 && ch == '*' && chNext == '*') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_COMMENTDOC;
+ } else if (column == 0 && ch == '/' && chNext == '*') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_COMMENTDOC;
+ } else if (ch == '"') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_STRING;
+ } else if (ch == '\'') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_CHARACTER;
+ } else if (ch == '?' && column == 0) {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_PREPROCESSOR;
+ } else if (isCOBOLoperator(ch)) {
+ ColourTo(styler, i-1, state);
+ ColourTo(styler, i, SCE_C_OPERATOR);
+ }
+ } else if (state == SCE_C_IDENTIFIER) {
+ if (!isCOBOLwordchar(ch)) {
+ int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
+
+ if(lStateChange != 0) {
+ styler.SetLineState(currentLine, lStateChange);
+ nContainment = lStateChange;
+ }
+
+ state = SCE_C_DEFAULT;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (ch == '"') {
+ state = SCE_C_STRING;
+ } else if (ch == '\'') {
+ state = SCE_C_CHARACTER;
+ } else if (isCOBOLoperator(ch)) {
+ ColourTo(styler, i, SCE_C_OPERATOR);
+ }
+ }
+ } else {
+ if (state == SCE_C_PREPROCESSOR) {
+ if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_COMMENT) {
+ if (ch == '\r' || ch == '\n') {
+ ColourTo(styler, i, state);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_COMMENTDOC) {
+ if (ch == '\r' || ch == '\n') {
+ if (((i > styler.GetStartSegment() + 2) || (
+ (initStyle == SCE_C_COMMENTDOC) &&
+ (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+ ColourTo(styler, i, state);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ } else if (state == SCE_C_COMMENTLINE) {
+ if (ch == '\r' || ch == '\n') {
+ ColourTo(styler, i-1, state);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_STRING) {
+ if (ch == '"') {
+ ColourTo(styler, i, state);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_CHARACTER) {
+ if (ch == '\'') {
+ ColourTo(styler, i, state);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ }
+ chPrev = ch;
+ bNewLine = bSetNewLine;
+ if (bNewLine)
+ {
+ bAarea = false;
+ }
+ }
+ ColourTo(styler, lengthDoc - 1, state);
+}
+
+static void FoldCOBOLDoc(unsigned int startPos, int length, int, WordList *[],
+ Accessor &styler) {
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;
+ char chNext = styler[startPos];
+
+ bool bNewLine = true;
+ bool bAarea = !isspacechar(chNext);
+ int column = 0;
+ bool bComment = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ ++column;
+
+ if (bNewLine) {
+ column = 0;
+ bComment = (ch == '*' || ch == '/' || ch == '?');
+ }
+ if (column <= 1 && !bAarea) {
+ bAarea = !isspacechar(ch);
+ }
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (atEOL) {
+ int nContainment = styler.GetLineState(lineCurrent);
+ int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;
+ if (bAarea && !bComment)
+ --lev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {
+ // this level is at the same level or less than the previous line
+ // therefore these is nothing for the previous header to collapse, so remove the header
+ styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
+ }
+ levelPrev = lev;
+ visibleChars = 0;
+ bAarea = false;
+ bNewLine = true;
+ lineCurrent++;
+ } else {
+ bNewLine = false;
+ }
+
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const COBOLWordListDesc[] = {
+ "A Keywords",
+ "B Keywords",
+ "Extended Keywords",
+ 0
+};
+
+LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCPP.cxx
+ ** Lexer for C++, C, Java, and JavaScript.
+ ** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net>
+ **/
+// Copyright 1998-2005 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#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"
+#include "OptionSet.h"
+#include "SparseState.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static bool IsSpaceEquiv(int state) {
+ return (state <= SCE_C_COMMENTDOC) ||
+ // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
+ (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
+ (state == SCE_C_COMMENTDOCKEYWORDERROR);
+}
+
+// Preconditions: sc.currentPos points to a character after '+' or '-'.
+// The test for pos reaching 0 should be redundant,
+// and is in only for safety measures.
+// Limitation: this code will give the incorrect answer for code like
+// a = b+++/ptn/...
+// Putting a space between the '++' post-inc operator and the '+' binary op
+// fixes this, and is highly recommended for readability anyway.
+static bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) {
+ int pos = (int) sc.currentPos;
+ while (--pos > 0) {
+ char ch = styler[pos];
+ if (ch == '+' || ch == '-') {
+ return styler[pos - 1] == ch;
+ }
+ }
+ return false;
+}
+
+static bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) {
+ // Don't look at styles, so no need to flush.
+ int pos = (int) sc.currentPos;
+ int currentLine = styler.GetLine(pos);
+ int lineStartPos = styler.LineStart(currentLine);
+ char ch;
+ while (--pos > lineStartPos) {
+ ch = styler.SafeGetCharAt(pos);
+ if (ch != ' ' && ch != '\t') {
+ break;
+ }
+ }
+ const char *retBack = "nruter";
+ const char *s = retBack;
+ while (*s
+ && pos >= lineStartPos
+ && styler.SafeGetCharAt(pos) == *s) {
+ s++;
+ pos--;
+ }
+ return !*s;
+}
+
+static std::string GetRestOfLine(LexAccessor &styler, int start, bool allowSpace) {
+ std::string restOfLine;
+ int i =0;
+ char ch = styler.SafeGetCharAt(start, '\n');
+ while ((ch != '\r') && (ch != '\n')) {
+ if (allowSpace || (ch != ' '))
+ restOfLine += ch;
+ i++;
+ ch = styler.SafeGetCharAt(start + i, '\n');
+ }
+ return restOfLine;
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_C_COMMENT ||
+ style == SCE_C_COMMENTDOC ||
+ style == SCE_C_COMMENTDOCKEYWORD ||
+ style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static std::vector<std::string> Tokenize(const std::string &s) {
+ // Break into space separated tokens
+ std::string word;
+ std::vector<std::string> tokens;
+ for (const char *cp = s.c_str(); *cp; cp++) {
+ if ((*cp == ' ') || (*cp == '\t')) {
+ if (!word.empty()) {
+ tokens.push_back(word);
+ word = "";
+ }
+ } else {
+ word += *cp;
+ }
+ }
+ if (!word.empty()) {
+ tokens.push_back(word);
+ }
+ return tokens;
+}
+
+struct PPDefinition {
+ int line;
+ std::string key;
+ std::string value;
+ PPDefinition(int line_, const std::string &key_, const std::string &value_) :
+ line(line_), key(key_), value(value_) {
+ }
+};
+
+class LinePPState {
+ int state;
+ int ifTaken;
+ int level;
+ bool ValidLevel() const {
+ return level >= 0 && level < 32;
+ }
+ int maskLevel() const {
+ return 1 << level;
+ }
+public:
+ LinePPState() : state(0), ifTaken(0), level(-1) {
+ }
+ bool IsInactive() const {
+ return state != 0;
+ }
+ bool CurrentIfTaken() {
+ return (ifTaken & maskLevel()) != 0;
+ }
+ void StartSection(bool on) {
+ level++;
+ if (ValidLevel()) {
+ if (on) {
+ state &= ~maskLevel();
+ ifTaken |= maskLevel();
+ } else {
+ state |= maskLevel();
+ ifTaken &= ~maskLevel();
+ }
+ }
+ }
+ void EndSection() {
+ if (ValidLevel()) {
+ state &= ~maskLevel();
+ ifTaken &= ~maskLevel();
+ }
+ level--;
+ }
+ void InvertCurrentLevel() {
+ if (ValidLevel()) {
+ state ^= maskLevel();
+ ifTaken |= maskLevel();
+ }
+ }
+};
+
+// Hold the preprocessor state for each line seen.
+// Currently one entry per line but could become sparse with just one entry per preprocessor line.
+class PPStates {
+ std::vector<LinePPState> vlls;
+public:
+ LinePPState ForLine(int line) {
+ if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {
+ return vlls[line];
+ } else {
+ return LinePPState();
+ }
+ }
+ void Add(int line, LinePPState lls) {
+ vlls.resize(line+1);
+ vlls[line] = lls;
+ }
+};
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerCPP
+struct OptionsCPP {
+ bool stylingWithinPreprocessor;
+ bool identifiersAllowDollars;
+ bool trackPreprocessor;
+ bool updatePreprocessor;
+ bool triplequotedStrings;
+ bool hashquotedStrings;
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldComment;
+ bool foldCommentMultiline;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldPreprocessor;
+ bool foldCompact;
+ bool foldAtElse;
+ OptionsCPP() {
+ stylingWithinPreprocessor = false;
+ identifiersAllowDollars = true;
+ trackPreprocessor = true;
+ updatePreprocessor = true;
+ triplequotedStrings = false;
+ hashquotedStrings = false;
+ fold = false;
+ foldSyntaxBased = true;
+ foldComment = false;
+ foldCommentMultiline = true;
+ foldCommentExplicit = true;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldPreprocessor = false;
+ foldCompact = false;
+ foldAtElse = false;
+ }
+};
+
+static const char *const cppWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Global classes and typedefs",
+ "Preprocessor definitions",
+ 0,
+};
+
+struct OptionSetCPP : public OptionSet<OptionsCPP> {
+ OptionSetCPP() {
+ DefineProperty("styling.within.preprocessor", &OptionsCPP::stylingWithinPreprocessor,
+ "For C++ code, determines whether all preprocessor code is styled in the "
+ "preprocessor style (0, the default) or only from the initial # to the end "
+ "of the command word(1).");
+
+ DefineProperty("lexer.cpp.allow.dollars", &OptionsCPP::identifiersAllowDollars,
+ "Set to 0 to disallow the '$' character in identifiers with the cpp lexer.");
+
+ DefineProperty("lexer.cpp.track.preprocessor", &OptionsCPP::trackPreprocessor,
+ "Set to 1 to interpret #if/#else/#endif to grey out code that is not active.");
+
+ DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor,
+ "Set to 1 to update preprocessor definitions when #define found.");
+
+ DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings,
+ "Set to 1 to enable highlighting of triple-quoted strings.");
+
+ DefineProperty("lexer.cpp.hashquoted.strings", &OptionsCPP::hashquotedStrings,
+ "Set to 1 to enable highlighting of hash-quoted strings.");
+
+ DefineProperty("fold", &OptionsCPP::fold);
+
+ DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.comment", &OptionsCPP::foldComment,
+ "This option enables folding multi-line comments and explicit fold points when using the C++ lexer. "
+ "Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} "
+ "at the end of a section that should fold.");
+
+ DefineProperty("fold.cpp.comment.multiline", &OptionsCPP::foldCommentMultiline,
+ "Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+ DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit,
+ "Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+ DefineProperty("fold.cpp.explicit.start", &OptionsCPP::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard //{.");
+
+ DefineProperty("fold.cpp.explicit.end", &OptionsCPP::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard //}.");
+
+ DefineProperty("fold.cpp.explicit.anywhere", &OptionsCPP::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor,
+ "This option enables folding preprocessor directives when using the C++ lexer. "
+ "Includes C#'s explicit #region and #endregion folding directives.");
+
+ DefineProperty("fold.compact", &OptionsCPP::foldCompact);
+
+ DefineProperty("fold.at.else", &OptionsCPP::foldAtElse,
+ "This option enables C++ folding on a \"} else {\" line of an if statement.");
+
+ DefineWordListSets(cppWordLists);
+ }
+};
+
+class LexerCPP : public ILexer {
+ bool caseSensitive;
+ CharacterSet setWord;
+ CharacterSet setNegationOp;
+ CharacterSet setArithmethicOp;
+ CharacterSet setRelOp;
+ CharacterSet setLogicalOp;
+ PPStates vlls;
+ std::vector<PPDefinition> ppDefineHistory;
+ WordList keywords;
+ WordList keywords2;
+ WordList keywords3;
+ WordList keywords4;
+ WordList ppDefinitions;
+ std::map<std::string, std::string> preprocessorDefinitionsStart;
+ OptionsCPP options;
+ OptionSetCPP osCPP;
+ SparseState<std::string> rawStringTerminators;
+ enum { activeFlag = 0x40 };
+public:
+ LexerCPP(bool caseSensitive_) :
+ caseSensitive(caseSensitive_),
+ setWord(CharacterSet::setAlphaNum, "._", 0x80, true),
+ setNegationOp(CharacterSet::setNone, "!"),
+ setArithmethicOp(CharacterSet::setNone, "+-/*%"),
+ setRelOp(CharacterSet::setNone, "=!<>"),
+ setLogicalOp(CharacterSet::setNone, "|&") {
+ }
+ virtual ~LexerCPP() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osCPP.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osCPP.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osCPP.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osCPP.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryCPP() {
+ return new LexerCPP(true);
+ }
+ static ILexer *LexerFactoryCPPInsensitive() {
+ return new LexerCPP(false);
+ }
+ static int MaskActive(int style) {
+ return style & ~activeFlag;
+ }
+ void EvaluateTokens(std::vector<std::string> &tokens);
+ bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
+};
+
+int SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) {
+ if (osCPP.PropertySet(&options, key, val)) {
+ if (strcmp(key, "lexer.cpp.allow.dollars") == 0) {
+ setWord = CharacterSet(CharacterSet::setAlphaNum, "._", 0x80, true);
+ if (options.identifiersAllowDollars) {
+ setWord.Add('$');
+ }
+ }
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords;
+ break;
+ case 1:
+ wordListN = &keywords2;
+ break;
+ case 2:
+ wordListN = &keywords3;
+ break;
+ case 3:
+ wordListN = &keywords4;
+ break;
+ case 4:
+ wordListN = &ppDefinitions;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ if (n == 4) {
+ // Rebuild preprocessorDefinitions
+ preprocessorDefinitionsStart.clear();
+ for (int nDefinition = 0; nDefinition < ppDefinitions.len; nDefinition++) {
+ char *cpDefinition = ppDefinitions.words[nDefinition];
+ char *cpEquals = strchr(cpDefinition, '=');
+ if (cpEquals) {
+ std::string name(cpDefinition, cpEquals - cpDefinition);
+ std::string val(cpEquals+1);
+ preprocessorDefinitionsStart[name] = val;
+ } else {
+ std::string name(cpDefinition);
+ std::string val("1");
+ preprocessorDefinitionsStart[name] = val;
+ }
+ }
+ }
+ }
+ }
+ return firstModification;
+}
+
+// Functor used to truncate history
+struct After {
+ int line;
+ After(int line_) : line(line_) {}
+ bool operator()(PPDefinition &p) const {
+ return p.line > line;
+ }
+};
+
+void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
+ CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
+ CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
+
+ CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
+
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+
+ if (options.identifiersAllowDollars) {
+ setWordStart.Add('$');
+ }
+
+ int chPrevNonWhite = ' ';
+ int visibleChars = 0;
+ bool lastWordWasUUID = false;
+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
+ bool continuationLine = false;
+ bool isIncludePreprocessor = false;
+
+ int lineCurrent = styler.GetLine(startPos);
+ if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) ||
+ (MaskActive(initStyle) == SCE_C_COMMENTLINE) ||
+ (MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) {
+ // Set continuationLine if last character of previous line is '\'
+ if (lineCurrent > 0) {
+ int chBack = styler.SafeGetCharAt(startPos-1, 0);
+ int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
+ int lineEndChar = '!';
+ if (chBack2 == '\r' && chBack == '\n') {
+ lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
+ } else if (chBack == '\n' || chBack == '\r') {
+ lineEndChar = chBack2;
+ }
+ continuationLine = lineEndChar == '\\';
+ }
+ }
+
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (startPos > 0) {
+ int back = startPos;
+ while (--back && IsSpaceEquiv(MaskActive(styler.StyleAt(back))))
+ ;
+ if (MaskActive(styler.StyleAt(back)) == SCE_C_OPERATOR) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+ LinePPState preproc = vlls.ForLine(lineCurrent);
+
+ bool definitionsChanged = false;
+
+ // Truncate ppDefineHistory before current line
+
+ if (!options.updatePreprocessor)
+ ppDefineHistory.clear();
+
+ std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(lineCurrent-1));
+ if (itInvalid != ppDefineHistory.end()) {
+ ppDefineHistory.erase(itInvalid, ppDefineHistory.end());
+ definitionsChanged = true;
+ }
+
+ std::map<std::string, std::string> preprocessorDefinitions = preprocessorDefinitionsStart;
+ for (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) {
+ preprocessorDefinitions[itDef->key] = itDef->value;
+ }
+
+ std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
+ SparseState<std::string> rawSTNew(lineCurrent);
+
+ int activitySet = preproc.IsInactive() ? activeFlag : 0;
+
+ for (; sc.More();) {
+
+ if (sc.atLineStart) {
+ // Using MaskActive() is not needed in the following statement.
+ // Inside inactive preprocessor declaration, state will be reset anyway at the end of this block.
+ if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) {
+ // Prevent SCE_C_STRINGEOL from leaking back to previous line which
+ // ends with a line continuation by locking in the state upto this position.
+ sc.SetState(sc.state);
+ }
+ if ((MaskActive(sc.state) == SCE_C_PREPROCESSOR) && (!continuationLine)) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ lastWordWasUUID = false;
+ isIncludePreprocessor = false;
+ if (preproc.IsInactive()) {
+ activitySet = activeFlag;
+ sc.SetState(sc.state | activitySet);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ lineCurrent++;
+ vlls.Add(lineCurrent, preproc);
+ if (rawStringTerminator != "") {
+ rawSTNew.Set(lineCurrent-1, rawStringTerminator);
+ }
+ }
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ lineCurrent++;
+ vlls.Add(lineCurrent, preproc);
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continuationLine = true;
+ sc.Forward();
+ continue;
+ }
+ }
+
+ const bool atLineEndBeforeSwitch = sc.atLineEnd;
+
+ // Determine if the current state should terminate.
+ switch (MaskActive(sc.state)) {
+ case SCE_C_OPERATOR:
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ break;
+ case SCE_C_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (!(setWord.Contains(sc.ch) || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_IDENTIFIER:
+ if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
+ char s[1000];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (keywords.InList(s)) {
+ lastWordWasUUID = strcmp(s, "uuid") == 0;
+ sc.ChangeState(SCE_C_WORD|activitySet);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_C_WORD2|activitySet);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
+ }
+ const bool literalString = sc.ch == '\"';
+ if (literalString || sc.ch == '\'') {
+ size_t lenS = strlen(s);
+ const bool raw = literalString && sc.chPrev == 'R';
+ if (raw)
+ s[lenS--] = '\0';
+ bool valid =
+ (lenS == 0) ||
+ ((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||
+ ((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8'));
+ if (valid) {
+ if (literalString)
+ sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet);
+ else
+ sc.ChangeState(SCE_C_CHARACTER|activitySet);
+ }
+ }
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_PREPROCESSOR:
+ if (options.stylingWithinPreprocessor) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ } else {
+ if (sc.Match('/', '*')) {
+ sc.SetState(SCE_C_PREPROCESSORCOMMENT|activitySet);
+ sc.Forward(); // Eat the *
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ }
+ break;
+ case SCE_C_PREPROCESSORCOMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_PREPROCESSOR|activitySet);
+ continue; // Without advancing in case of '\'.
+ }
+ break;
+ case SCE_C_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_C_COMMENTDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
+ }
+ }
+ break;
+ case SCE_C_COMMENTLINE:
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_COMMENTLINEDOC:
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
+ }
+ }
+ break;
+ case SCE_C_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ } else if (!setDoxygen.Contains(sc.ch)) {
+ char s[100];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
+ }
+ sc.SetState(styleBeforeDCKeyword|activitySet);
+ }
+ break;
+ case SCE_C_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_C_STRINGEOL|activitySet);
+ } else if (isIncludePreprocessor) {
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ isIncludePreprocessor = false;
+ }
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_HASHQUOTEDSTRING:
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_STRINGRAW:
+ if (sc.Match(rawStringTerminator.c_str())) {
+ for (size_t termPos=rawStringTerminator.size(); termPos; termPos--)
+ sc.Forward();
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ rawStringTerminator = "";
+ }
+ break;
+ case SCE_C_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_C_STRINGEOL|activitySet);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_REGEX:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ } else if (sc.ch == '/') {
+ sc.Forward();
+ while ((sc.ch < 0x80) && islower(sc.ch))
+ sc.Forward(); // gobble regex flags
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ } else if (sc.ch == '\\') {
+ // Gobble up the quoted character
+ if (sc.chNext == '\\' || sc.chNext == '/') {
+ sc.Forward();
+ }
+ }
+ break;
+ case SCE_C_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_VERBATIM:
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ }
+ }
+ break;
+ case SCE_C_TRIPLEVERBATIM:
+ if (sc.Match("\"\"\"")) {
+ while (sc.Match('"')) {
+ sc.Forward();
+ }
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_UUID:
+ if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ }
+
+ if (sc.atLineEnd && !atLineEndBeforeSwitch) {
+ // State exit processing consumed characters up to end of line.
+ lineCurrent++;
+ vlls.Add(lineCurrent, preproc);
+ }
+
+ // Determine if a new state should be entered.
+ if (MaskActive(sc.state) == SCE_C_DEFAULT) {
+ if (sc.Match('@', '\"')) {
+ sc.SetState(SCE_C_VERBATIM|activitySet);
+ sc.Forward();
+ } else if (options.triplequotedStrings && sc.Match("\"\"\"")) {
+ sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
+ sc.Forward(2);
+ } else if (options.hashquotedStrings && sc.Match('#', '\"')) {
+ sc.SetState(SCE_C_HASHQUOTEDSTRING|activitySet);
+ sc.Forward();
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ if (lastWordWasUUID) {
+ sc.SetState(SCE_C_UUID|activitySet);
+ lastWordWasUUID = false;
+ } else {
+ sc.SetState(SCE_C_NUMBER|activitySet);
+ }
+ } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
+ if (lastWordWasUUID) {
+ sc.SetState(SCE_C_UUID|activitySet);
+ lastWordWasUUID = false;
+ } else {
+ sc.SetState(SCE_C_IDENTIFIER|activitySet);
+ }
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_C_COMMENTDOC|activitySet);
+ } else {
+ sc.SetState(SCE_C_COMMENT|activitySet);
+ }
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
+ // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_C_COMMENTLINEDOC|activitySet);
+ else
+ sc.SetState(SCE_C_COMMENTLINE|activitySet);
+ } else if (sc.ch == '/'
+ && (setOKBeforeRE.Contains(chPrevNonWhite)
+ || followsReturnKeyword(sc, styler))
+ && (!setCouldBePostOp.Contains(chPrevNonWhite)
+ || !FollowsPostfixOperator(sc, styler))) {
+ sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
+ } else if (sc.ch == '\"') {
+ if (sc.chPrev == 'R') {
+ styler.Flush();
+ if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) {
+ sc.SetState(SCE_C_STRINGRAW|activitySet);
+ rawStringTerminator = ")";
+ for (int termPos = sc.currentPos + 1;; termPos++) {
+ char chTerminator = styler.SafeGetCharAt(termPos, '(');
+ if (chTerminator == '(')
+ break;
+ rawStringTerminator += chTerminator;
+ }
+ rawStringTerminator += '\"';
+ } else {
+ sc.SetState(SCE_C_STRING|activitySet);
+ }
+ } else {
+ sc.SetState(SCE_C_STRING|activitySet);
+ }
+ isIncludePreprocessor = false; // ensure that '>' won't end the string
+ } else if (isIncludePreprocessor && sc.ch == '<') {
+ sc.SetState(SCE_C_STRING|activitySet);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_C_CHARACTER|activitySet);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_C_PREPROCESSOR|activitySet);
+ // Skip whitespace between # and preprocessor word
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ } else if (sc.Match("include")) {
+ isIncludePreprocessor = true;
+ } else {
+ if (options.trackPreprocessor) {
+ if (sc.Match("ifdef") || sc.Match("ifndef")) {
+ bool isIfDef = sc.Match("ifdef");
+ int i = isIfDef ? 5 : 6;
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false);
+ bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();
+ preproc.StartSection(isIfDef == foundDef);
+ } else if (sc.Match("if")) {
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
+ bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
+ preproc.StartSection(ifGood);
+ } else if (sc.Match("else")) {
+ if (!preproc.CurrentIfTaken()) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ } else if (!preproc.IsInactive()) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ }
+ } else if (sc.Match("elif")) {
+ // Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif
+ if (!preproc.CurrentIfTaken()) {
+ // Similar to #if
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
+ bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
+ if (ifGood) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ }
+ } else if (!preproc.IsInactive()) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ }
+ } else if (sc.Match("endif")) {
+ preproc.EndSection();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ } else if (sc.Match("define")) {
+ if (options.updatePreprocessor && !preproc.IsInactive()) {
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);
+ if (restOfLine.find(")") == std::string::npos) { // Don't handle macros with arguments
+ std::vector<std::string> tokens = Tokenize(restOfLine);
+ std::string key;
+ std::string value("1");
+ if (tokens.size() >= 1) {
+ key = tokens[0];
+ if (tokens.size() >= 2) {
+ value = tokens[1];
+ }
+ preprocessorDefinitions[key] = value;
+ ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value));
+ definitionsChanged = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_C_OPERATOR|activitySet);
+ }
+ }
+
+ if (!IsASpace(sc.ch) && !IsSpaceEquiv(MaskActive(sc.state))) {
+ chPrevNonWhite = sc.ch;
+ visibleChars++;
+ }
+ continuationLine = false;
+ sc.Forward();
+ }
+ const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
+ if (definitionsChanged || rawStringsChanged)
+ styler.ChangeLexerState(startPos, startPos + length);
+ sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+
+void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = MaskActive(styler.StyleAt(startPos));
+ int style = MaskActive(initStyle);
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = MaskActive(styler.StyleAt(i + 1));
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ levelNext++;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ levelNext--;
+ }
+ } else {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ }
+ if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+ if (ch == '#') {
+ unsigned int j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "region") || styler.Match(j, "if")) {
+ levelNext++;
+ } else if (styler.Match(j, "end")) {
+ levelNext--;
+ }
+ }
+ }
+ if (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ if (options.foldSyntaxBased && options.foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && options.foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+ // There is an empty line at end of file so give it same level and empty
+ styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+ }
+ visibleChars = 0;
+ }
+ }
+}
+
+void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens) {
+
+ // Evaluate defined() statements to either 0 or 1
+ for (size_t i=0; (i+2)<tokens.size();) {
+ if ((tokens[i] == "defined") && (tokens[i+1] == "(")) {
+ const char *val = "0";
+ if (tokens[i+2] == ")") {
+ // defined()
+ tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 3);
+ } else if (((i+3)<tokens.size()) && (tokens[i+3] == ")")) {
+ // defined(<int>)
+ tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 4);
+ val = "1";
+ }
+ tokens[i] = val;
+ } else {
+ i++;
+ }
+ }
+
+ // Find bracketed subexpressions and recurse on them
+ std::vector<std::string>::iterator itBracket = std::find(tokens.begin(), tokens.end(), "(");
+ std::vector<std::string>::iterator itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+ while ((itBracket != tokens.end()) && (itEndBracket != tokens.end()) && (itEndBracket > itBracket)) {
+ std::vector<std::string> inBracket(itBracket + 1, itEndBracket);
+ EvaluateTokens(inBracket);
+
+ // The insertion is done before the removal because there were failures with the opposite approach
+ tokens.insert(itBracket, inBracket.begin(), inBracket.end());
+ itBracket = std::find(tokens.begin(), tokens.end(), "(");
+ itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+ tokens.erase(itBracket, itEndBracket + 1);
+
+ itBracket = std::find(tokens.begin(), tokens.end(), "(");
+ itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+ }
+
+ // Evaluate logical negations
+ for (size_t j=0; (j+1)<tokens.size();) {
+ if (setNegationOp.Contains(tokens[j][0])) {
+ int isTrue = atoi(tokens[j+1].c_str());
+ if (tokens[j] == "!")
+ isTrue = !isTrue;
+ std::vector<std::string>::iterator itInsert =
+ tokens.erase(tokens.begin() + j, tokens.begin() + j + 2);
+ tokens.insert(itInsert, isTrue ? "1" : "0");
+ } else {
+ j++;
+ }
+ }
+
+ // Evaluate expressions in precedence order
+ enum precedence { precArithmetic, precRelative, precLogical };
+ for (int prec=precArithmetic; prec <= precLogical; prec++) {
+ // Looking at 3 tokens at a time so end at 2 before end
+ for (size_t k=0; (k+2)<tokens.size();) {
+ char chOp = tokens[k+1][0];
+ if (
+ ((prec==precArithmetic) && setArithmethicOp.Contains(chOp)) ||
+ ((prec==precRelative) && setRelOp.Contains(chOp)) ||
+ ((prec==precLogical) && setLogicalOp.Contains(chOp))
+ ) {
+ int valA = atoi(tokens[k].c_str());
+ int valB = atoi(tokens[k+2].c_str());
+ int result = 0;
+ if (tokens[k+1] == "+")
+ result = valA + valB;
+ else if (tokens[k+1] == "-")
+ result = valA - valB;
+ else if (tokens[k+1] == "*")
+ result = valA * valB;
+ else if (tokens[k+1] == "/")
+ result = valA / (valB ? valB : 1);
+ else if (tokens[k+1] == "%")
+ result = valA % (valB ? valB : 1);
+ else if (tokens[k+1] == "<")
+ result = valA < valB;
+ else if (tokens[k+1] == "<=")
+ result = valA <= valB;
+ else if (tokens[k+1] == ">")
+ result = valA > valB;
+ else if (tokens[k+1] == ">=")
+ result = valA >= valB;
+ else if (tokens[k+1] == "==")
+ result = valA == valB;
+ else if (tokens[k+1] == "!=")
+ result = valA != valB;
+ else if (tokens[k+1] == "||")
+ result = valA || valB;
+ else if (tokens[k+1] == "&&")
+ result = valA && valB;
+ char sResult[30];
+ sprintf(sResult, "%d", result);
+ std::vector<std::string>::iterator itInsert =
+ tokens.erase(tokens.begin() + k, tokens.begin() + k + 3);
+ tokens.insert(itInsert, sResult);
+ } else {
+ k++;
+ }
+ }
+ }
+}
+
+bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions) {
+ // Break into tokens, replacing with definitions
+ std::string word;
+ std::vector<std::string> tokens;
+ const char *cp = expr.c_str();
+ for (;;) {
+ if (setWord.Contains(*cp)) {
+ word += *cp;
+ } else {
+ std::map<std::string, std::string>::const_iterator it = preprocessorDefinitions.find(word);
+ if (it != preprocessorDefinitions.end()) {
+ tokens.push_back(it->second);
+ } else if (!word.empty() && ((word[0] >= '0' && word[0] <= '9') || (word == "defined"))) {
+ tokens.push_back(word);
+ }
+ word = "";
+ if (!*cp) {
+ break;
+ }
+ if ((*cp != ' ') && (*cp != '\t')) {
+ std::string op(cp, 1);
+ if (setRelOp.Contains(*cp)) {
+ if (setRelOp.Contains(cp[1])) {
+ op += cp[1];
+ cp++;
+ }
+ } else if (setLogicalOp.Contains(*cp)) {
+ if (setLogicalOp.Contains(cp[1])) {
+ op += cp[1];
+ cp++;
+ }
+ }
+ tokens.push_back(op);
+ }
+ }
+ cp++;
+ }
+
+ EvaluateTokens(tokens);
+
+ // "0" or "" -> false else true
+ bool isFalse = tokens.empty() ||
+ ((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0"));
+ return !isFalse;
+}
+
+LexerModule lmCPP(SCLEX_CPP, LexerCPP::LexerFactoryCPP, "cpp", cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, LexerCPP::LexerFactoryCPPInsensitive, "cppnocase", cppWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCSS.cxx
+ ** Lexer for Cascading Style Sheets
+ ** Written by Jakub Vrána
+ ** Improved by Philippe Lhoste (CSS2)
+ ** Improved by Ross McKay (SCSS mode; see http://sass-lang.com/ )
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// TODO: handle SCSS nested properties like font: { weight: bold; size: 1em; }
+// TODO: handle SCSS interpolation: #{}
+// TODO: add features for Less if somebody feels like contributing; http://lesscss.org/
+// TODO: refactor this monster so that the next poor slob can read it!
+
+#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 IsAWordChar(const unsigned int ch) {
+ /* FIXME:
+ * The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars.
+ * Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee
+ * that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher
+ */
+ return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
+}
+
+inline bool IsCssOperator(const int ch) {
+ if (!((ch < 0x80) && isalnum(ch)) &&
+ (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' ||
+ ch == '.' || ch == '#' || ch == '!' || ch == '@' ||
+ /* CSS2 */
+ ch == '*' || ch == '>' || ch == '+' || ch == '=' || ch == '~' || ch == '|' ||
+ ch == '[' || ch == ']' || ch == '(' || ch == ')')) {
+ return true;
+ }
+ return false;
+}
+
+// look behind (from start of document to our start position) to determine current nesting level
+inline int NestingLevelLookBehind(unsigned int startPos, Accessor &styler) {
+ int ch;
+ int nestingLevel = 0;
+
+ for (unsigned int i = 0; i < startPos; i++) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '{')
+ nestingLevel++;
+ else if (ch == '}')
+ nestingLevel--;
+ }
+
+ return nestingLevel;
+}
+
+static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+ WordList &css1Props = *keywordlists[0];
+ WordList &pseudoClasses = *keywordlists[1];
+ WordList &css2Props = *keywordlists[2];
+ WordList &css3Props = *keywordlists[3];
+ WordList &pseudoElements = *keywordlists[4];
+ WordList &exProps = *keywordlists[5];
+ WordList &exPseudoClasses = *keywordlists[6];
+ WordList &exPseudoElements = *keywordlists[7];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ int lastState = -1; // before operator
+ int lastStateC = -1; // before comment
+ int lastStateS = -1; // before single-quoted/double-quoted string
+ int lastStateVar = -1; // before variable (SCSS)
+ int lastStateVal = -1; // before value (SCSS)
+ int op = ' '; // last operator
+ int opPrev = ' '; // last operator
+ bool insideParentheses = false; // true if currently in a CSS url() or similar construct
+
+ // property lexer.css.scss.language
+ // Set to 1 for Sassy CSS (.scss)
+ bool isScssDocument = styler.GetPropertyInt("lexer.css.scss.language") != 0;
+
+ // property lexer.css.less.language
+ // Set to 1 for Less CSS (.less)
+ bool isLessDocument = styler.GetPropertyInt("lexer.css.less.language") != 0;
+
+ // property lexer.css.hss.language
+ // Set to 1 for HSS (.hss)
+ bool isHssDocument = styler.GetPropertyInt("lexer.css.hss.language") != 0;
+
+ // SCSS/LESS/HSS have the concept of variable
+ bool hasVariables = isScssDocument || isLessDocument || isHssDocument;
+ char varPrefix = 0;
+ if (hasVariables)
+ varPrefix = isLessDocument ? '@' : '$';
+
+ // SCSS/LESS/HSS support single-line comments
+ typedef enum _CommentModes { eCommentBlock = 0, eCommentLine = 1} CommentMode;
+ CommentMode comment_mode = eCommentBlock;
+ bool hasSingleLineComments = isScssDocument || isLessDocument || isHssDocument;
+
+ // must keep track of nesting level in document types that support it (SCSS/LESS/HSS)
+ bool hasNesting = false;
+ int nestingLevel = 0;
+ if (isScssDocument || isLessDocument || isHssDocument) {
+ hasNesting = true;
+ nestingLevel = NestingLevelLookBehind(startPos, styler);
+ }
+
+ // "the loop"
+ for (; sc.More(); sc.Forward()) {
+ if (sc.state == SCE_CSS_COMMENT && ((comment_mode == eCommentBlock && sc.Match('*', '/')) || (comment_mode == eCommentLine && sc.atLineEnd))) {
+ if (lastStateC == -1) {
+ // backtrack to get last state:
+ // comments are like whitespace, so we must return to the previous state
+ unsigned int i = startPos;
+ for (; i > 0; i--) {
+ if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
+ if (lastStateC == SCE_CSS_OPERATOR) {
+ op = styler.SafeGetCharAt(i-1);
+ opPrev = styler.SafeGetCharAt(i-2);
+ while (--i) {
+ lastState = styler.StyleAt(i-1);
+ if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
+ break;
+ }
+ if (i == 0)
+ lastState = SCE_CSS_DEFAULT;
+ }
+ break;
+ }
+ }
+ if (i == 0)
+ lastStateC = SCE_CSS_DEFAULT;
+ }
+ if (comment_mode == eCommentBlock) {
+ sc.Forward();
+ sc.ForwardSetState(lastStateC);
+ } else /* eCommentLine */ {
+ sc.SetState(lastStateC);
+ }
+ }
+
+ if (sc.state == SCE_CSS_COMMENT)
+ continue;
+
+ if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {
+ if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
+ continue;
+ unsigned int i = sc.currentPos;
+ while (i && styler[i-1] == '\\')
+ i--;
+ if ((sc.currentPos - i) % 2 == 1)
+ continue;
+ sc.ForwardSetState(lastStateS);
+ }
+
+ if (sc.state == SCE_CSS_OPERATOR) {
+ if (op == ' ') {
+ unsigned int i = startPos;
+ op = styler.SafeGetCharAt(i-1);
+ opPrev = styler.SafeGetCharAt(i-2);
+ while (--i) {
+ lastState = styler.StyleAt(i-1);
+ if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
+ break;
+ }
+ }
+ switch (op) {
+ case '@':
+ if (lastState == SCE_CSS_DEFAULT || hasNesting)
+ sc.SetState(SCE_CSS_DIRECTIVE);
+ break;
+ case '>':
+ case '+':
+ if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+ lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+ sc.SetState(SCE_CSS_DEFAULT);
+ break;
+ case '[':
+ if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+ lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+ sc.SetState(SCE_CSS_ATTRIBUTE);
+ break;
+ case ']':
+ if (lastState == SCE_CSS_ATTRIBUTE)
+ sc.SetState(SCE_CSS_TAG);
+ break;
+ case '{':
+ nestingLevel++;
+ switch (lastState) {
+ case SCE_CSS_MEDIA:
+ sc.SetState(SCE_CSS_DEFAULT);
+ break;
+ case SCE_CSS_TAG:
+ case SCE_CSS_DIRECTIVE:
+ sc.SetState(SCE_CSS_IDENTIFIER);
+ break;
+ }
+ break;
+ case '}':
+ if (--nestingLevel < 0)
+ nestingLevel = 0;
+ switch (lastState) {
+ case SCE_CSS_DEFAULT:
+ case SCE_CSS_VALUE:
+ case SCE_CSS_IMPORTANT:
+ case SCE_CSS_IDENTIFIER:
+ case SCE_CSS_IDENTIFIER2:
+ case SCE_CSS_IDENTIFIER3:
+ if (hasNesting)
+ sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);
+ else
+ sc.SetState(SCE_CSS_DEFAULT);
+ break;
+ }
+ break;
+ case '(':
+ if (lastState == SCE_CSS_PSEUDOCLASS)
+ sc.SetState(SCE_CSS_TAG);
+ else if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)
+ sc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS);
+ break;
+ case ')':
+ if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+ lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
+ lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
+ sc.SetState(SCE_CSS_TAG);
+ break;
+ case ':':
+ switch (lastState) {
+ case SCE_CSS_TAG:
+ case SCE_CSS_DEFAULT:
+ case SCE_CSS_CLASS:
+ case SCE_CSS_ID:
+ case SCE_CSS_PSEUDOCLASS:
+ case SCE_CSS_EXTENDED_PSEUDOCLASS:
+ case SCE_CSS_UNKNOWN_PSEUDOCLASS:
+ case SCE_CSS_PSEUDOELEMENT:
+ case SCE_CSS_EXTENDED_PSEUDOELEMENT:
+ sc.SetState(SCE_CSS_PSEUDOCLASS);
+ break;
+ case SCE_CSS_IDENTIFIER:
+ case SCE_CSS_IDENTIFIER2:
+ case SCE_CSS_IDENTIFIER3:
+ case SCE_CSS_EXTENDED_IDENTIFIER:
+ case SCE_CSS_UNKNOWN_IDENTIFIER:
+ case SCE_CSS_VARIABLE:
+ sc.SetState(SCE_CSS_VALUE);
+ lastStateVal = lastState;
+ break;
+ }
+ break;
+ case '.':
+ if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+ lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+ sc.SetState(SCE_CSS_CLASS);
+ break;
+ case '#':
+ if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+ lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+ sc.SetState(SCE_CSS_ID);
+ break;
+ case ',':
+ case '|':
+ case '~':
+ if (lastState == SCE_CSS_TAG)
+ sc.SetState(SCE_CSS_DEFAULT);
+ break;
+ case ';':
+ switch (lastState) {
+ case SCE_CSS_DIRECTIVE:
+ if (hasNesting) {
+ sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);
+ } else {
+ sc.SetState(SCE_CSS_DEFAULT);
+ }
+ break;
+ case SCE_CSS_VALUE:
+ case SCE_CSS_IMPORTANT:
+ // data URLs can have semicolons; simplistically check for wrapping parentheses and move along
+ if (insideParentheses) {
+ sc.SetState(lastState);
+ } else {
+ if (lastStateVal == SCE_CSS_VARIABLE) {
+ sc.SetState(SCE_CSS_DEFAULT);
+ } else {
+ sc.SetState(SCE_CSS_IDENTIFIER);
+ }
+ }
+ break;
+ case SCE_CSS_VARIABLE:
+ if (lastStateVar == SCE_CSS_VALUE) {
+ // data URLs can have semicolons; simplistically check for wrapping parentheses and move along
+ if (insideParentheses) {
+ sc.SetState(SCE_CSS_VALUE);
+ } else {
+ sc.SetState(SCE_CSS_IDENTIFIER);
+ }
+ } else {
+ sc.SetState(SCE_CSS_DEFAULT);
+ }
+ break;
+ }
+ break;
+ case '!':
+ if (lastState == SCE_CSS_VALUE)
+ sc.SetState(SCE_CSS_IMPORTANT);
+ break;
+ }
+ }
+
+ if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
+ sc.SetState(SCE_CSS_TAG);
+ continue;
+ }
+
+ // check for inside parentheses (whether part of an "operator" or not)
+ if (sc.ch == '(')
+ insideParentheses = true;
+ else if (sc.ch == ')')
+ insideParentheses = false;
+
+ // SCSS special modes
+ if (hasVariables) {
+ // variable name
+ if (sc.ch == varPrefix) {
+ switch (sc.state) {
+ case SCE_CSS_DEFAULT:
+ if (isLessDocument) // give priority to pseudo elements
+ break;
+ case SCE_CSS_VALUE:
+ lastStateVar = sc.state;
+ sc.SetState(SCE_CSS_VARIABLE);
+ continue;
+ }
+ }
+ if (sc.state == SCE_CSS_VARIABLE) {
+ if (IsAWordChar(sc.ch)) {
+ // still looking at the variable name
+ continue;
+ }
+ if (lastStateVar == SCE_CSS_VALUE) {
+ // not looking at the variable name any more, and it was part of a value
+ sc.SetState(SCE_CSS_VALUE);
+ }
+ }
+
+ // nested rule parent selector
+ if (sc.ch == '&') {
+ switch (sc.state) {
+ case SCE_CSS_DEFAULT:
+ case SCE_CSS_IDENTIFIER:
+ sc.SetState(SCE_CSS_TAG);
+ continue;
+ }
+ }
+ }
+
+ // nesting rules that apply to SCSS and Less
+ if (hasNesting) {
+ // check for nested rule selector
+ if (sc.state == SCE_CSS_IDENTIFIER && (IsAWordChar(sc.ch) || sc.ch == ':' || sc.ch == '.' || sc.ch == '#')) {
+ // look ahead to see whether { comes before next ; and }
+ unsigned int endPos = startPos + length;
+ int ch;
+
+ for (unsigned int i = sc.currentPos; i < endPos; i++) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == ';' || ch == '}')
+ break;
+ if (ch == '{') {
+ sc.SetState(SCE_CSS_DEFAULT);
+ continue;
+ }
+ }
+ }
+
+ }
+
+ if (IsAWordChar(sc.ch)) {
+ if (sc.state == SCE_CSS_DEFAULT)
+ sc.SetState(SCE_CSS_TAG);
+ continue;
+ }
+
+ if (IsAWordChar(sc.chPrev) && (
+ sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 ||
+ sc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER ||
+ sc.state == SCE_CSS_UNKNOWN_IDENTIFIER ||
+ sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
+ sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
+ sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
+ sc.state == SCE_CSS_IMPORTANT ||
+ sc.state == SCE_CSS_DIRECTIVE
+ )) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ char *s2 = s;
+ while (*s2 && !IsAWordChar(*s2))
+ s2++;
+ switch (sc.state) {
+ case SCE_CSS_IDENTIFIER:
+ case SCE_CSS_IDENTIFIER2:
+ case SCE_CSS_IDENTIFIER3:
+ case SCE_CSS_EXTENDED_IDENTIFIER:
+ case SCE_CSS_UNKNOWN_IDENTIFIER:
+ if (css1Props.InList(s2))
+ sc.ChangeState(SCE_CSS_IDENTIFIER);
+ else if (css2Props.InList(s2))
+ sc.ChangeState(SCE_CSS_IDENTIFIER2);
+ else if (css3Props.InList(s2))
+ sc.ChangeState(SCE_CSS_IDENTIFIER3);
+ else if (exProps.InList(s2))
+ sc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER);
+ else
+ sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
+ break;
+ case SCE_CSS_PSEUDOCLASS:
+ case SCE_CSS_PSEUDOELEMENT:
+ case SCE_CSS_EXTENDED_PSEUDOCLASS:
+ case SCE_CSS_EXTENDED_PSEUDOELEMENT:
+ case SCE_CSS_UNKNOWN_PSEUDOCLASS:
+ if (op == ':' && opPrev != ':' && pseudoClasses.InList(s2))
+ sc.ChangeState(SCE_CSS_PSEUDOCLASS);
+ else if (opPrev == ':' && pseudoElements.InList(s2))
+ sc.ChangeState(SCE_CSS_PSEUDOELEMENT);
+ else if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2))
+ sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS);
+ else if (opPrev == ':' && exPseudoElements.InList(s2))
+ sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT);
+ else
+ sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
+ break;
+ case SCE_CSS_IMPORTANT:
+ if (strcmp(s2, "important") != 0)
+ sc.ChangeState(SCE_CSS_VALUE);
+ break;
+ case SCE_CSS_DIRECTIVE:
+ if (op == '@' && strcmp(s2, "media") == 0)
+ sc.ChangeState(SCE_CSS_MEDIA);
+ break;
+ }
+ }
+
+ if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (
+ sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID ||
+ (sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */
+ sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
+ sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
+ sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
+ ))
+ ))
+ sc.SetState(SCE_CSS_TAG);
+
+ if (sc.Match('/', '*')) {
+ lastStateC = sc.state;
+ comment_mode = eCommentBlock;
+ sc.SetState(SCE_CSS_COMMENT);
+ sc.Forward();
+ } else if (hasSingleLineComments && sc.Match('/', '/') && !insideParentheses) {
+ // note that we've had to treat ([...]// as the start of a URL not a comment, e.g. url(http://example.com), url(//example.com)
+ lastStateC = sc.state;
+ comment_mode = eCommentLine;
+ sc.SetState(SCE_CSS_COMMENT);
+ sc.Forward();
+ } else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE)
+ && (sc.ch == '\"' || sc.ch == '\'')) {
+ lastStateS = sc.state;
+ sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
+ } else if (IsCssOperator(sc.ch)
+ && (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
+ && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
+ && ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_MEDIA) || sc.ch == ';' || sc.ch == '{')
+ ) {
+ if (sc.state != SCE_CSS_OPERATOR)
+ lastState = sc.state;
+ sc.SetState(SCE_CSS_OPERATOR);
+ op = sc.ch;
+ opPrev = sc.chPrev;
+ }
+ }
+
+ sc.Complete();
+}
+
+static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment) {
+ if (!inComment && (style == SCE_CSS_COMMENT))
+ levelCurrent++;
+ else if (inComment && (style != SCE_CSS_COMMENT))
+ levelCurrent--;
+ inComment = (style == SCE_CSS_COMMENT);
+ }
+ if (style == SCE_CSS_OPERATOR) {
+ if (ch == '{') {
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const cssWordListDesc[] = {
+ "CSS1 Properties",
+ "Pseudo-classes",
+ "CSS2 Properties",
+ "CSS3 Properties",
+ "Pseudo-elements",
+ "Browser-Specific CSS Properties",
+ "Browser-Specific Pseudo-classes",
+ "Browser-Specific Pseudo-elements",
+ 0
+};
+
+LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCaml.cxx
+ ** Lexer for Objective Caml.
+ **/
+// Copyright 2005-2009 by Robert Roessler <robertr@rftp.com>
+// The License.txt file describes the conditions under which this software may be distributed.
+/* Release History
+ 20050204 Initial release.
+ 20050205 Quick compiler standards/"cleanliness" adjustment.
+ 20050206 Added cast for IsLeadByte().
+ 20050209 Changes to "external" build support.
+ 20050306 Fix for 1st-char-in-doc "corner" case.
+ 20050502 Fix for [harmless] one-past-the-end coloring.
+ 20050515 Refined numeric token recognition logic.
+ 20051125 Added 2nd "optional" keywords class.
+ 20051129 Support "magic" (read-only) comments for RCaml.
+ 20051204 Swtich to using StyleContext infrastructure.
+ 20090629 Add full Standard ML '97 support.
+*/
+
+#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 "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+// Since the Microsoft __iscsym[f] funcs are not ANSI...
+inline int iscaml(int c) {return isalnum(c) || c == '_';}
+inline int iscamlf(int c) {return isalpha(c) || c == '_';}
+
+static const int baseT[24] = {
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A - L */
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
+};
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+/*
+ (actually seems to work!)
+*/
+#include <string>
+#include "WindowAccessor.h"
+#include "ExternalLexer.h"
+
+#undef EXT_LEXER_DECL
+#define EXT_LEXER_DECL __declspec( dllexport ) __stdcall
+
+#if PLAT_WIN
+#include <windows.h>
+#endif
+
+static void ColouriseCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static void FoldCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static void InternalLexOrFold(int lexOrFold, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props);
+
+static const char* LexerName = "caml";
+
+#ifdef TRACE
+void Platform::DebugPrintf(const char *format, ...) {
+ char buffer[2000];
+ va_list pArguments;
+ va_start(pArguments, format);
+ vsprintf(buffer,format,pArguments);
+ va_end(pArguments);
+ Platform::DebugDisplay(buffer);
+}
+#else
+void Platform::DebugPrintf(const char *, ...) {
+}
+#endif
+
+bool Platform::IsDBCSLeadByte(int codePage, char ch) {
+ return ::IsDBCSLeadByteEx(codePage, ch) != 0;
+}
+
+long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
+ return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam);
+}
+
+long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) {
+ return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam,
+ reinterpret_cast<LPARAM>(lParam));
+}
+
+void EXT_LEXER_DECL Fold(unsigned int lexer, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ lexer;
+ // build expected data structures and do the Fold
+ InternalLexOrFold(1, startPos, length, initStyle, words, window, props);
+
+}
+
+int EXT_LEXER_DECL GetLexerCount()
+{
+ return 1; // just us [Objective] Caml lexers here!
+}
+
+void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ Index;
+ // return as much of our lexer name as will fit (what's up with Index?)
+ if (buflength > 0) {
+ buflength--;
+ int n = strlen(LexerName);
+ if (n > buflength)
+ n = buflength;
+ memcpy(name, LexerName, n), name[n] = '\0';
+ }
+}
+
+void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ lexer;
+ // build expected data structures and do the Lex
+ InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
+}
+
+static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // create and initialize a WindowAccessor (including contained PropSet)
+ PropSetSimple ps;
+ ps.SetMultiple(props);
+ WindowAccessor wa(window, ps);
+ // create and initialize WordList(s)
+ int nWL = 0;
+ for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed
+ WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs
+ int i = 0;
+ for (; i < nWL; i++) {
+ wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION)
+ wl[i]->Set(words[i]);
+ }
+ wl[i] = 0;
+ // call our "internal" folder/lexer (... then do Flush!)
+ if (foldOrLex)
+ FoldCamlDoc(startPos, length, initStyle, wl, wa);
+ else
+ ColouriseCamlDoc(startPos, length, initStyle, wl, wa);
+ wa.Flush();
+ // clean up before leaving
+ for (i = nWL - 1; i >= 0; i--)
+ delete wl[i];
+ delete [] wl;
+}
+
+static
+#endif /* BUILD_AS_EXTERNAL_LEXER */
+
+void ColouriseCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ // initialize styler
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ int chBase = 0, chToken = 0, chLit = 0;
+ WordList& keywords = *keywordlists[0];
+ WordList& keywords2 = *keywordlists[1];
+ WordList& keywords3 = *keywordlists[2];
+ const bool isSML = keywords.InList("andalso");
+ const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
+
+ // set up [initial] state info (terminating states that shouldn't "bleed")
+ const int state_ = sc.state & 0x0f;
+ if (state_ <= SCE_CAML_CHAR
+ || (isSML && state_ == SCE_CAML_STRING))
+ sc.state = SCE_CAML_DEFAULT;
+ int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;
+
+ // foreach char in range...
+ while (sc.More()) {
+ // set up [per-char] state info
+ int state2 = -1; // (ASSUME no state change)
+ int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
+ bool advance = true; // (ASSUME scanner "eats" 1 char)
+
+ // step state machine
+ switch (sc.state & 0x0f) {
+ case SCE_CAML_DEFAULT:
+ chToken = sc.currentPos; // save [possible] token start (JIC)
+ // it's wide open; what do we have?
+ if (iscamlf(sc.ch))
+ state2 = SCE_CAML_IDENTIFIER;
+ else if (!isSML && sc.Match('`') && iscamlf(sc.chNext))
+ state2 = SCE_CAML_TAGNAME;
+ else if (!isSML && sc.Match('#') && isdigit(sc.chNext))
+ state2 = SCE_CAML_LINENUM;
+ else if (isdigit(sc.ch)) {
+ // it's a number, assume base 10
+ state2 = SCE_CAML_NUMBER, chBase = 10;
+ if (sc.Match('0')) {
+ // there MAY be a base specified...
+ const char* baseC = "bBoOxX";
+ if (isSML) {
+ if (sc.chNext == 'w')
+ sc.Forward(); // (consume SML "word" indicator)
+ baseC = "x";
+ }
+ // ... change to specified base AS REQUIRED
+ if (strchr(baseC, sc.chNext))
+ chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
+ }
+ } else if (!isSML && sc.Match('\'')) // (Caml char literal?)
+ state2 = SCE_CAML_CHAR, chLit = 0;
+ else if (isSML && sc.Match('#', '"')) // (SML char literal?)
+ state2 = SCE_CAML_CHAR, sc.Forward();
+ else if (sc.Match('"'))
+ state2 = SCE_CAML_STRING;
+ else if (sc.Match('(', '*'))
+ state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...
+ else if (strchr("!?~" /* Caml "prefix-symbol" */
+ "=<>@^|&+-*/$%" /* Caml "infix-symbol" */
+ "()[]{};,:.#", sc.ch) // Caml "bracket" or ;,:.#
+ // SML "extra" ident chars
+ || (isSML && (sc.Match('\\') || sc.Match('`'))))
+ state2 = SCE_CAML_OPERATOR;
+ break;
+
+ case SCE_CAML_IDENTIFIER:
+ // [try to] interpret as [additional] identifier char
+ if (!(iscaml(sc.ch) || sc.Match('\''))) {
+ const int n = sc.currentPos - chToken;
+ if (n < 24) {
+ // length is believable as keyword, [re-]construct token
+ char t[24];
+ for (int i = -n; i < 0; i++)
+ t[n + i] = static_cast<char>(sc.GetRelative(i));
+ t[n] = '\0';
+ // special-case "_" token as KEYWORD
+ if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD);
+ else if (keywords2.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD2);
+ else if (keywords3.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD3);
+ }
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ }
+ break;
+
+ case SCE_CAML_TAGNAME:
+ // [try to] interpret as [additional] tagname char
+ if (!(iscaml(sc.ch) || sc.Match('\'')))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;
+
+ /*case SCE_CAML_KEYWORD:
+ case SCE_CAML_KEYWORD2:
+ case SCE_CAML_KEYWORD3:
+ // [try to] interpret as [additional] keyword char
+ if (!iscaml(ch))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;*/
+
+ case SCE_CAML_LINENUM:
+ // [try to] interpret as [additional] linenum directive char
+ if (!isdigit(sc.ch))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;
+
+ case SCE_CAML_OPERATOR: {
+ // [try to] interpret as [additional] operator char
+ const char* o = 0;
+ if (iscaml(sc.ch) || isspace(sc.ch) // ident or whitespace
+ || (o = strchr(")]};,\'\"#", sc.ch),o) // "termination" chars
+ || (!isSML && sc.Match('`')) // Caml extra term char
+ || (!strchr("!$%&*+-./:<=>?@^|~", sc.ch)// "operator" chars
+ // SML extra ident chars
+ && !(isSML && (sc.Match('\\') || sc.Match('`'))))) {
+ // check for INCLUSIVE termination
+ if (o && strchr(")]};,", sc.ch)) {
+ if ((sc.Match(')') && sc.chPrev == '(')
+ || (sc.Match(']') && sc.chPrev == '['))
+ // special-case "()" and "[]" tokens as KEYWORDS
+ sc.ChangeState(SCE_CAML_KEYWORD);
+ chColor++;
+ } else
+ advance = false;
+ state2 = SCE_CAML_DEFAULT;
+ }
+ break;
+ }
+
+ case SCE_CAML_NUMBER:
+ // [try to] interpret as [additional] numeric literal char
+ if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))
+ break;
+ // how about an integer suffix?
+ if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))
+ && (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))
+ break;
+ // or a floating-point literal?
+ if (chBase == 10) {
+ // with a decimal point?
+ if (sc.Match('.')
+ && ((!isSML && sc.chPrev == '_')
+ || IsADigit(sc.chPrev, chBase)))
+ break;
+ // with an exponent? (I)
+ if ((sc.Match('e') || sc.Match('E'))
+ && ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))
+ || IsADigit(sc.chPrev, chBase)))
+ break;
+ // with an exponent? (II)
+ if (((!isSML && (sc.Match('+') || sc.Match('-')))
+ || (isSML && sc.Match('~')))
+ && (sc.chPrev == 'e' || sc.chPrev == 'E'))
+ break;
+ }
+ // it looks like we have run out of number
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;
+
+ case SCE_CAML_CHAR:
+ if (!isSML) {
+ // [try to] interpret as [additional] char literal char
+ if (sc.Match('\\')) {
+ chLit = 1; // (definitely IS a char literal)
+ if (sc.chPrev == '\\')
+ sc.ch = ' '; // (...\\')
+ // should we be terminating - one way or another?
+ } else if ((sc.Match('\'') && sc.chPrev != '\\')
+ || sc.atLineEnd) {
+ state2 = SCE_CAML_DEFAULT;
+ if (sc.Match('\''))
+ chColor++;
+ else
+ sc.ChangeState(SCE_CAML_IDENTIFIER);
+ // ... maybe a char literal, maybe not
+ } else if (chLit < 1 && sc.currentPos - chToken >= 2)
+ sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
+ break;
+ }/* else
+ // fall through for SML char literal (handle like string) */
+
+ case SCE_CAML_STRING:
+ // [try to] interpret as [additional] [SML char/] string literal char
+ if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext))
+ state2 = SCE_CAML_WHITE;
+ else if (sc.Match('\\') && sc.chPrev == '\\')
+ sc.ch = ' '; // (...\\")
+ // should we be terminating - one way or another?
+ else if ((sc.Match('"') && sc.chPrev != '\\')
+ || (isSML && sc.atLineEnd)) {
+ state2 = SCE_CAML_DEFAULT;
+ if (sc.Match('"'))
+ chColor++;
+ }
+ break;
+
+ case SCE_CAML_WHITE:
+ // [try to] interpret as [additional] SML embedded whitespace char
+ if (sc.Match('\\')) {
+ // style this puppy NOW...
+ state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++,
+ styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();
+ // ... then backtrack to determine original SML literal type
+ int p = chColor - 2;
+ for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;
+ if (p >= 0)
+ state2 = static_cast<int>(styler.StyleAt(p));
+ // take care of state change NOW
+ sc.ChangeState(state2), state2 = -1;
+ }
+ break;
+
+ case SCE_CAML_COMMENT:
+ case SCE_CAML_COMMENT1:
+ case SCE_CAML_COMMENT2:
+ case SCE_CAML_COMMENT3:
+ // we're IN a comment - does this start a NESTED comment?
+ if (sc.Match('(', '*'))
+ state2 = sc.state + 1, chToken = sc.currentPos,
+ sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;
+ // [try to] interpret as [additional] comment char
+ else if (sc.Match(')') && sc.chPrev == '*') {
+ if (nesting)
+ state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
+ else
+ state2 = SCE_CAML_DEFAULT;
+ chColor++;
+ // enable "magic" (read-only) comment AS REQUIRED
+ } else if (useMagic && sc.currentPos - chToken == 4
+ && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
+ sc.state |= 0x10; // (switch to read-only comment style)
+ break;
+ }
+
+ // handle state change and char coloring AS REQUIRED
+ if (state2 >= 0)
+ styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
+ // move to next char UNLESS re-scanning current char
+ if (advance)
+ sc.Forward();
+ }
+
+ // do any required terminal char coloring (JIC)
+ sc.Complete();
+}
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+static
+#endif /* BUILD_AS_EXTERNAL_LEXER */
+void FoldCamlDoc(
+ unsigned int, int,
+ int,
+ WordList *[],
+ Accessor &)
+{
+}
+
+static const char * const camlWordListDesc[] = {
+ "Keywords", // primary Objective Caml keywords
+ "Keywords2", // "optional" keywords (typically from Pervasives)
+ "Keywords3", // "optional" keywords (typically typenames)
+ 0
+};
+
+#ifndef BUILD_AS_EXTERNAL_LEXER
+LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc);
+#endif /* BUILD_AS_EXTERNAL_LEXER */
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCmake.cxx
+ ** Lexer for Cmake
+ **/
+// Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
+// based on the NSIS lexer
+// 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 bool isCmakeNumber(char ch)
+{
+ return(ch >= '0' && ch <= '9');
+}
+
+static bool isCmakeChar(char ch)
+{
+ return(ch == '.' ) || (ch == '_' ) || isCmakeNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+static bool isCmakeLetter(char ch)
+{
+ return(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+static bool CmakeNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
+{
+ int nNextLine = -1;
+ for ( unsigned int i = start; i < end; i++ ) {
+ char cNext = styler.SafeGetCharAt( i );
+ if ( cNext == '\n' ) {
+ nNextLine = i+1;
+ break;
+ }
+ }
+
+ if ( nNextLine == -1 ) // We never foudn the next line...
+ return false;
+
+ for ( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ ) {
+ char cNext = styler.SafeGetCharAt( firstChar );
+ if ( cNext == ' ' )
+ continue;
+ if ( cNext == '\t' )
+ continue;
+ if ( styler.Match(firstChar, "ELSE") || styler.Match(firstChar, "else"))
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+static int calculateFoldCmake(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse)
+{
+ // If the word is too long, it is not what we are looking for
+ if ( end - start > 20 )
+ return foldlevel;
+
+ int newFoldlevel = foldlevel;
+
+ char s[20]; // The key word we are looking for has atmost 13 characters
+ for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) {
+ s[i] = static_cast<char>( styler[ start + i ] );
+ s[i + 1] = '\0';
+ }
+
+ if ( CompareCaseInsensitive(s, "IF") == 0 || CompareCaseInsensitive(s, "WHILE") == 0
+ || CompareCaseInsensitive(s, "MACRO") == 0 || CompareCaseInsensitive(s, "FOREACH") == 0
+ || CompareCaseInsensitive(s, "ELSEIF") == 0 )
+ newFoldlevel++;
+ else if ( CompareCaseInsensitive(s, "ENDIF") == 0 || CompareCaseInsensitive(s, "ENDWHILE") == 0
+ || CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0)
+ newFoldlevel--;
+ else if ( bElse && CompareCaseInsensitive(s, "ELSEIF") == 0 )
+ newFoldlevel++;
+ else if ( bElse && CompareCaseInsensitive(s, "ELSE") == 0 )
+ newFoldlevel++;
+
+ return newFoldlevel;
+}
+
+static int classifyWordCmake(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
+{
+ char word[100] = {0};
+ char lowercaseWord[100] = {0};
+
+ WordList &Commands = *keywordLists[0];
+ WordList &Parameters = *keywordLists[1];
+ WordList &UserDefined = *keywordLists[2];
+
+ for (unsigned int i = 0; i < end - start + 1 && i < 99; i++) {
+ word[i] = static_cast<char>( styler[ start + i ] );
+ lowercaseWord[i] = static_cast<char>(tolower(word[i]));
+ }
+
+ // Check for special words...
+ if ( CompareCaseInsensitive(word, "MACRO") == 0 || CompareCaseInsensitive(word, "ENDMACRO") == 0 )
+ return SCE_CMAKE_MACRODEF;
+
+ if ( CompareCaseInsensitive(word, "IF") == 0 || CompareCaseInsensitive(word, "ENDIF") == 0 )
+ return SCE_CMAKE_IFDEFINEDEF;
+
+ if ( CompareCaseInsensitive(word, "ELSEIF") == 0 || CompareCaseInsensitive(word, "ELSE") == 0 )
+ return SCE_CMAKE_IFDEFINEDEF;
+
+ if ( CompareCaseInsensitive(word, "WHILE") == 0 || CompareCaseInsensitive(word, "ENDWHILE") == 0)
+ return SCE_CMAKE_WHILEDEF;
+
+ if ( CompareCaseInsensitive(word, "FOREACH") == 0 || CompareCaseInsensitive(word, "ENDFOREACH") == 0)
+ return SCE_CMAKE_FOREACHDEF;
+
+ if ( Commands.InList(lowercaseWord) )
+ return SCE_CMAKE_COMMANDS;
+
+ if ( Parameters.InList(word) )
+ return SCE_CMAKE_PARAMETERS;
+
+
+ if ( UserDefined.InList(word) )
+ return SCE_CMAKE_USERDEFINED;
+
+ if ( strlen(word) > 3 ) {
+ if ( word[1] == '{' && word[strlen(word)-1] == '}' )
+ return SCE_CMAKE_VARIABLE;
+ }
+
+ // To check for numbers
+ if ( isCmakeNumber( word[0] ) ) {
+ bool bHasSimpleCmakeNumber = true;
+ for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) {
+ if ( !isCmakeNumber( word[j] ) ) {
+ bHasSimpleCmakeNumber = false;
+ break;
+ }
+ }
+
+ if ( bHasSimpleCmakeNumber )
+ return SCE_CMAKE_NUMBER;
+ }
+
+ return SCE_CMAKE_DEFAULT;
+}
+
+static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
+{
+ int state = SCE_CMAKE_DEFAULT;
+ if ( startPos > 0 )
+ state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
+
+ styler.StartAt( startPos );
+ styler.GetLine( startPos );
+
+ unsigned int nLengthDoc = startPos + length;
+ styler.StartSegment( startPos );
+
+ char cCurrChar;
+ bool bVarInString = false;
+ bool bClassicVarInString = false;
+
+ unsigned int i;
+ for ( i = startPos; i < nLengthDoc; i++ ) {
+ cCurrChar = styler.SafeGetCharAt( i );
+ char cNextChar = styler.SafeGetCharAt(i+1);
+
+ switch (state) {
+ case SCE_CMAKE_DEFAULT:
+ if ( cCurrChar == '#' ) { // we have a comment line
+ styler.ColourTo(i-1, state );
+ state = SCE_CMAKE_COMMENT;
+ break;
+ }
+ if ( cCurrChar == '"' ) {
+ styler.ColourTo(i-1, state );
+ state = SCE_CMAKE_STRINGDQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ break;
+ }
+ if ( cCurrChar == '\'' ) {
+ styler.ColourTo(i-1, state );
+ state = SCE_CMAKE_STRINGRQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ break;
+ }
+ if ( cCurrChar == '`' ) {
+ styler.ColourTo(i-1, state );
+ state = SCE_CMAKE_STRINGLQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ break;
+ }
+
+ // CMake Variable
+ if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) {
+ styler.ColourTo(i-1,state);
+ state = SCE_CMAKE_VARIABLE;
+
+ // If it is a number, we must check and set style here first...
+ if ( isCmakeNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
+ styler.ColourTo( i, SCE_CMAKE_NUMBER);
+
+ break;
+ }
+
+ break;
+ case SCE_CMAKE_COMMENT:
+ if ( cNextChar == '\n' || cNextChar == '\r' ) {
+ // Special case:
+ if ( cCurrChar == '\\' ) {
+ styler.ColourTo(i-2,state);
+ styler.ColourTo(i,SCE_CMAKE_DEFAULT);
+ }
+ else {
+ styler.ColourTo(i,state);
+ state = SCE_CMAKE_DEFAULT;
+ }
+ }
+ break;
+ case SCE_CMAKE_STRINGDQ:
+ case SCE_CMAKE_STRINGLQ:
+ case SCE_CMAKE_STRINGRQ:
+
+ if ( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
+ break; // Ignore the next character, even if it is a quote of some sort
+
+ if ( cCurrChar == '"' && state == SCE_CMAKE_STRINGDQ ) {
+ styler.ColourTo(i,state);
+ state = SCE_CMAKE_DEFAULT;
+ break;
+ }
+
+ if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) {
+ styler.ColourTo(i,state);
+ state = SCE_CMAKE_DEFAULT;
+ break;
+ }
+
+ if ( cCurrChar == '\'' && state == SCE_CMAKE_STRINGRQ ) {
+ styler.ColourTo(i,state);
+ state = SCE_CMAKE_DEFAULT;
+ break;
+ }
+
+ if ( cNextChar == '\r' || cNextChar == '\n' ) {
+ int nCurLine = styler.GetLine(i+1);
+ int nBack = i;
+ // We need to check if the previous line has a \ in it...
+ bool bNextLine = false;
+
+ while ( nBack > 0 ) {
+ if ( styler.GetLine(nBack) != nCurLine )
+ break;
+
+ char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
+
+ if ( cTemp == '\\' ) {
+ bNextLine = true;
+ break;
+ }
+ if ( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
+ break;
+
+ nBack--;
+ }
+
+ if ( bNextLine ) {
+ styler.ColourTo(i+1,state);
+ }
+ if ( bNextLine == false ) {
+ styler.ColourTo(i,state);
+ state = SCE_CMAKE_DEFAULT;
+ }
+ }
+ break;
+
+ case SCE_CMAKE_VARIABLE:
+
+ // CMake Variable:
+ if ( cCurrChar == '$' )
+ state = SCE_CMAKE_DEFAULT;
+ else if ( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
+ state = SCE_CMAKE_DEFAULT;
+ else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) {
+ state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler );
+ styler.ColourTo( i, state);
+ state = SCE_CMAKE_DEFAULT;
+ }
+ else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) {
+ if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER )
+ styler.ColourTo( i-1, SCE_CMAKE_NUMBER );
+
+ state = SCE_CMAKE_DEFAULT;
+
+ if ( cCurrChar == '"' ) {
+ state = SCE_CMAKE_STRINGDQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ }
+ else if ( cCurrChar == '`' ) {
+ state = SCE_CMAKE_STRINGLQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ }
+ else if ( cCurrChar == '\'' ) {
+ state = SCE_CMAKE_STRINGRQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ }
+ else if ( cCurrChar == '#' ) {
+ state = SCE_CMAKE_COMMENT;
+ }
+ }
+ break;
+ }
+
+ if ( state == SCE_CMAKE_COMMENT) {
+ styler.ColourTo(i,state);
+ }
+ else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {
+ bool bIngoreNextDollarSign = false;
+
+ if ( bVarInString && cCurrChar == '$' ) {
+ bVarInString = false;
+ bIngoreNextDollarSign = true;
+ }
+ else if ( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) {
+ styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
+ bVarInString = false;
+ bIngoreNextDollarSign = false;
+ }
+
+ else if ( bVarInString && !isCmakeChar(cNextChar) ) {
+ int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler);
+ if ( nWordState == SCE_CMAKE_VARIABLE )
+ styler.ColourTo( i, SCE_CMAKE_STRINGVAR);
+ bVarInString = false;
+ }
+ // Covers "${TEST}..."
+ else if ( bClassicVarInString && cNextChar == '}' ) {
+ styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
+ bClassicVarInString = false;
+ }
+
+ // Start of var in string
+ if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) {
+ styler.ColourTo( i-1, state);
+ bClassicVarInString = true;
+ bVarInString = false;
+ }
+ else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) {
+ styler.ColourTo( i-1, state);
+ bVarInString = true;
+ bClassicVarInString = false;
+ }
+ }
+ }
+
+ // Colourise remaining document
+ styler.ColourTo(nLengthDoc-1,state);
+}
+
+static void FoldCmakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ // No folding enabled, no reason to continue...
+ if ( styler.GetPropertyInt("fold") == 0 )
+ return;
+
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
+
+ int lineCurrent = styler.GetLine(startPos);
+ unsigned int safeStartPos = styler.LineStart( lineCurrent );
+
+ bool bArg1 = true;
+ int nWordStart = -1;
+
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+
+ for (unsigned int i = safeStartPos; i < startPos + length; i++) {
+ char chCurr = styler.SafeGetCharAt(i);
+
+ if ( bArg1 ) {
+ if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) {
+ nWordStart = i;
+ }
+ else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) {
+ int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse);
+
+ if ( newLevel == levelNext ) {
+ if ( foldAtElse ) {
+ if ( CmakeNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+ }
+ else
+ levelNext = newLevel;
+ bArg1 = false;
+ }
+ }
+
+ if ( chCurr == '\n' ) {
+ if ( bArg1 && foldAtElse) {
+ if ( CmakeNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+
+ // If we are on a new line...
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (levelUse < levelNext )
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+
+ lineCurrent++;
+ levelCurrent = levelNext;
+ bArg1 = true; // New line, lets look at first argument again
+ nWordStart = -1;
+ }
+ }
+
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+}
+
+static const char * const cmakeWordLists[] = {
+ "Commands",
+ "Parameters",
+ "UserDefined",
+ 0,
+ 0,};
+
+LexerModule lmCmake(SCLEX_CMAKE, ColouriseCmakeDoc, "cmake", FoldCmakeDoc, cmakeWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCoffeeScript.cxx
+ ** Lexer for CoffeeScript.
+ **/
+// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
+// Based on the Scintilla C++ Lexer
+// Written by Eric Promislow <ericp@activestate.com> in 2011 for the Komodo IDE
+// 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 "Platform.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 bool IsSpaceEquiv(int state) {
+ return (state <= SCE_C_COMMENTDOC
+ // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
+ || state == SCE_C_COMMENTLINEDOC
+ || state == SCE_C_COMMENTDOCKEYWORD
+ || state == SCE_C_COMMENTDOCKEYWORDERROR
+ || state == SCE_COFFEESCRIPT_COMMENTBLOCK
+ || state == SCE_COFFEESCRIPT_VERBOSE_REGEX
+ || state == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT
+ || state == SCE_C_WORD
+ || state == SCE_C_REGEX);
+}
+
+// Preconditions: sc.currentPos points to a character after '+' or '-'.
+// The test for pos reaching 0 should be redundant,
+// and is in only for safety measures.
+// Limitation: this code will give the incorrect answer for code like
+// a = b+++/ptn/...
+// Putting a space between the '++' post-inc operator and the '+' binary op
+// fixes this, and is highly recommended for readability anyway.
+static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
+ int pos = (int) sc.currentPos;
+ while (--pos > 0) {
+ char ch = styler[pos];
+ if (ch == '+' || ch == '-') {
+ return styler[pos - 1] == ch;
+ }
+ }
+ return false;
+}
+
+static bool followsReturnKeyword(StyleContext &sc, Accessor &styler) {
+ // Don't look at styles, so no need to flush.
+ int pos = (int) sc.currentPos;
+ int currentLine = styler.GetLine(pos);
+ int lineStartPos = styler.LineStart(currentLine);
+ char ch;
+ while (--pos > lineStartPos) {
+ ch = styler.SafeGetCharAt(pos);
+ if (ch != ' ' && ch != '\t') {
+ break;
+ }
+ }
+ const char *retBack = "nruter";
+ const char *s = retBack;
+ while (*s
+ && pos >= lineStartPos
+ && styler.SafeGetCharAt(pos) == *s) {
+ s++;
+ pos--;
+ }
+ return !*s;
+}
+
+static void ColouriseCoffeeScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ // property styling.within.preprocessor
+ // For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default)
+ // or only from the initial # to the end of the command word(1).
+ bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
+
+ CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
+ CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
+
+ CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
+
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+ // property lexer.cpp.allow.dollars
+ // Set to 0 to disallow the '$' character in identifiers with the cpp lexer.
+ if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
+ setWordStart.Add('$');
+ setWord.Add('$');
+ }
+
+ int chPrevNonWhite = ' ';
+ int visibleChars = 0;
+ bool lastWordWasUUID = false;
+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
+ bool continuationLine = false;
+ bool isIncludePreprocessor = false;
+
+ if (initStyle == SCE_C_PREPROCESSOR) {
+ // Set continuationLine if last character of previous line is '\'
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ int chBack = styler.SafeGetCharAt(startPos-1, 0);
+ int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
+ int lineEndChar = '!';
+ if (chBack2 == '\r' && chBack == '\n') {
+ lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
+ } else if (chBack == '\n' || chBack == '\r') {
+ lineEndChar = chBack2;
+ }
+ continuationLine = lineEndChar == '\\';
+ }
+ }
+
+ // look back to set chPrevNonWhite properly for better regex colouring
+ int endPos = startPos + length;
+ if (startPos > 0) {
+ unsigned int back = startPos;
+ styler.Flush();
+ while (back > 0 && IsSpaceEquiv(styler.StyleAt(--back)))
+ ;
+ if (styler.StyleAt(back) == SCE_C_OPERATOR) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ if (startPos != back) {
+ initStyle = styler.StyleAt(back);
+ }
+ startPos = back;
+ }
+
+ StyleContext sc(startPos, endPos - startPos, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart) {
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ lastWordWasUUID = false;
+ isIncludePreprocessor = false;
+ }
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continuationLine = true;
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_C_OPERATOR:
+ sc.SetState(SCE_C_DEFAULT);
+ break;
+ case SCE_C_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (!setWord.Contains(sc.ch)) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_IDENTIFIER:
+ if (!setWord.Contains(sc.ch) || (sc.ch == '.') || (sc.ch == '$')) {
+ char s[1000];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords.InList(s)) {
+ lastWordWasUUID = strcmp(s, "uuid") == 0;
+ sc.ChangeState(SCE_C_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_C_WORD2);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_C_GLOBALCLASS);
+ }
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_PREPROCESSOR:
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (stylingWithinPreprocessor) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ } else {
+ if (sc.Match('/', '*') || sc.Match('/', '/')) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ }
+ break;
+ case SCE_C_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_C_COMMENTDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_C_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_COMMENTLINEDOC:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_C_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (!setDoxygen.Contains(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_C_STRING:
+ if (isIncludePreprocessor) {
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ isIncludePreprocessor = false;
+ }
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_CHARACTER:
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_REGEX:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '/') {
+ sc.Forward();
+ while ((sc.ch < 0x80) && islower(sc.ch))
+ sc.Forward(); // gobble regex flags
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '\\') {
+ // Gobble up the quoted character
+ if (sc.chNext == '\\' || sc.chNext == '/') {
+ sc.Forward();
+ }
+ }
+ break;
+ case SCE_C_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_VERBATIM:
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ }
+ break;
+ case SCE_C_UUID:
+ if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_COFFEESCRIPT_COMMENTBLOCK:
+ if (sc.Match("###")) {
+ sc.ChangeState(SCE_C_COMMENT);
+ sc.Forward();
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '\\') {
+ sc.Forward();
+ }
+ break;
+ case SCE_COFFEESCRIPT_VERBOSE_REGEX:
+ if (sc.Match("///")) {
+ sc.Forward();
+ sc.Forward();
+ sc.ChangeState(SCE_C_REGEX);
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (sc.Match('#')) {
+ sc.ChangeState(SCE_C_REGEX);
+ sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT);
+ } else if (sc.ch == '\\') {
+ sc.Forward();
+ }
+ break;
+ case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT:
+ if (sc.atLineStart) {
+ sc.ChangeState(SCE_C_COMMENT);
+ sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_C_DEFAULT) {
+ if (sc.Match('@', '\"')) {
+ sc.SetState(SCE_C_VERBATIM);
+ sc.Forward();
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ if (lastWordWasUUID) {
+ sc.SetState(SCE_C_UUID);
+ lastWordWasUUID = false;
+ } else {
+ sc.SetState(SCE_C_NUMBER);
+ }
+ } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@') || (sc.ch == '$')) {
+ if (lastWordWasUUID) {
+ sc.SetState(SCE_C_UUID);
+ lastWordWasUUID = false;
+ } else {
+ sc.SetState(SCE_C_IDENTIFIER);
+ }
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_C_COMMENTDOC);
+ } else {
+ sc.SetState(SCE_C_COMMENT);
+ }
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match("///")) {
+ sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
+ } else if (sc.ch == '/'
+ && (setOKBeforeRE.Contains(chPrevNonWhite)
+ || followsReturnKeyword(sc, styler))
+ && (!setCouldBePostOp.Contains(chPrevNonWhite)
+ || !FollowsPostfixOperator(sc, styler))) {
+ sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_C_STRING);
+ isIncludePreprocessor = false; // ensure that '>' won't end the string
+ } else if (isIncludePreprocessor && sc.ch == '<') {
+ sc.SetState(SCE_C_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_C_CHARACTER);
+ } else if (sc.ch == '#') {
+ if (sc.Match("###")) {
+ sc.SetState(SCE_COFFEESCRIPT_COMMENTBLOCK);
+ } else {
+ sc.SetState(SCE_C_COMMENTLINE);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_C_OPERATOR);
+ }
+ }
+
+ if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
+ chPrevNonWhite = sc.ch;
+ visibleChars++;
+ }
+ continuationLine = false;
+ }
+ // Change temporary coffeescript states into standard C ones.
+ switch (sc.state) {
+ case SCE_COFFEESCRIPT_COMMENTBLOCK:
+ sc.ChangeState(SCE_C_COMMENT);
+ break;
+ case SCE_COFFEESCRIPT_VERBOSE_REGEX:
+ sc.ChangeState(SCE_C_REGEX);
+ break;
+ case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT:
+ sc.ChangeState(SCE_C_COMMENTLINE);
+ break;
+ }
+ sc.Complete();
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ if (ch == '#')
+ return true;
+ else if (ch == '/'
+ && i < eol_pos - 1
+ && styler[i + 1] == '*')
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+static void FoldCoffeeScriptDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ // A simplified version of FoldPyDoc
+ 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
+
+ // property fold.coffeescript.comment
+ const bool foldComment = styler.GetPropertyInt("fold.coffeescript.comment") != 0;
+
+ const bool foldCompact = styler.GetPropertyInt("fold.compact") != 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 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));
+ const int comment_continue = (comment && prevComment);
+ if (!comment)
+ indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+ if (indentNext & SC_FOLDLEVELWHITEFLAG)
+ indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+ if (comment_start) {
+ // Place fold point at start of a block of comments
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (comment_continue) {
+ // Add level to rest of lines in the block
+ lev = lev + 1;
+ }
+
+ // Skip past any blank lines for next indent level info; we skip also
+ // comments (all comments, not just those starting in column 0)
+ // which effectively folds them into surrounding code rather
+ // than screwing up folding.
+
+ while ((lineNext < docLines) &&
+ ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
+ (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
+
+ lineNext++;
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ }
+
+ const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+ const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
+
+ // Now set all the indent levels on the lines we skipped
+ // Do this from end to start. Once we encounter one line
+ // which is indented more than the line after the end of
+ // the comment-block, use the level of the block before
+
+ int skipLine = lineNext;
+ int skipLevel = levelAfterComments;
+
+ while (--skipLine > lineCurrent) {
+ int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+ if (foldCompact) {
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+ skipLevel = levelBeforeComments;
+
+ int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+ styler.SetLevel(skipLine, skipLevel | whiteFlag);
+ } else {
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
+ !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
+ !IsCommentLine(skipLine, styler))
+ skipLevel = levelBeforeComments;
+
+ styler.SetLevel(skipLine, skipLevel);
+ }
+ }
+
+ // Set fold header on non-comment line
+ if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+
+ // Keep track of block comment state of previous line
+ prevComment = comment_start || comment_continue;
+
+ // Set fold level for this line and move to next line
+ styler.SetLevel(lineCurrent, lev);
+ indentCurrent = indentNext;
+ lineCurrent = lineNext;
+ }
+}
+
+static const char *const csWordLists[] = {
+ "Keywords",
+ 0,
+};
+
+LexerModule lmCoffeeScript(SCLEX_COFFEESCRIPT, ColouriseCoffeeScriptDoc, "coffeescript", FoldCoffeeScriptDoc, csWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexConf.cxx
+ ** Lexer for Apache Configuration Files.
+ **
+ ** First working version contributed by Ahmad Zawawi <ahmad.zawawi@gmail.com> on October 28, 2000.
+ ** i created this lexer because i needed something pretty when dealing
+ ** when Apache Configuration 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 void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
+{
+ int state = SCE_CONF_DEFAULT;
+ char chNext = styler[startPos];
+ int lengthDoc = startPos + length;
+ // create a buffer large enough to take the largest chunk...
+ char *buffer = new char[length];
+ int bufferCount = 0;
+
+ // this assumes that we have 2 keyword list in conf.properties
+ WordList &directives = *keywordLists[0];
+ WordList ¶ms = *keywordLists[1];
+
+ // go through all provided text segment
+ // using the hand-written state machine shown below
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ for (int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ i++;
+ continue;
+ }
+ switch(state) {
+ case SCE_CONF_DEFAULT:
+ if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
+ // whitespace is simply ignored here...
+ styler.ColourTo(i,SCE_CONF_DEFAULT);
+ break;
+ } else if( ch == '#' ) {
+ // signals the start of a comment...
+ state = SCE_CONF_COMMENT;
+ styler.ColourTo(i,SCE_CONF_COMMENT);
+ } else if( ch == '.' /*|| ch == '/'*/) {
+ // signals the start of a file...
+ state = SCE_CONF_EXTENSION;
+ styler.ColourTo(i,SCE_CONF_EXTENSION);
+ } else if( ch == '"') {
+ state = SCE_CONF_STRING;
+ styler.ColourTo(i,SCE_CONF_STRING);
+ } else if( isascii(ch) && ispunct(ch) ) {
+ // signals an operator...
+ // no state jump necessary for this
+ // simple case...
+ styler.ColourTo(i,SCE_CONF_OPERATOR);
+ } else if( isascii(ch) && isalpha(ch) ) {
+ // signals the start of an identifier
+ bufferCount = 0;
+ buffer[bufferCount++] = static_cast<char>(tolower(ch));
+ state = SCE_CONF_IDENTIFIER;
+ } else if( isascii(ch) && isdigit(ch) ) {
+ // signals the start of a number
+ bufferCount = 0;
+ buffer[bufferCount++] = ch;
+ //styler.ColourTo(i,SCE_CONF_NUMBER);
+ state = SCE_CONF_NUMBER;
+ } else {
+ // style it the default style..
+ styler.ColourTo(i,SCE_CONF_DEFAULT);
+ }
+ break;
+
+ case SCE_CONF_COMMENT:
+ // if we find a newline here,
+ // we simply go to default state
+ // else continue to work on it...
+ if( ch == '\n' || ch == '\r' ) {
+ state = SCE_CONF_DEFAULT;
+ } else {
+ styler.ColourTo(i,SCE_CONF_COMMENT);
+ }
+ break;
+
+ case SCE_CONF_EXTENSION:
+ // if we find a non-alphanumeric char,
+ // we simply go to default state
+ // else we're still dealing with an extension...
+ if( (isascii(ch) && isalnum(ch)) || (ch == '_') ||
+ (ch == '-') || (ch == '$') ||
+ (ch == '/') || (ch == '.') || (ch == '*') )
+ {
+ styler.ColourTo(i,SCE_CONF_EXTENSION);
+ } else {
+ state = SCE_CONF_DEFAULT;
+ chNext = styler[i--];
+ }
+ break;
+
+ case SCE_CONF_STRING:
+ // if we find the end of a string char, we simply go to default state
+ // else we're still dealing with an string...
+ if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
+ state = SCE_CONF_DEFAULT;
+ }
+ styler.ColourTo(i,SCE_CONF_STRING);
+ break;
+
+ case SCE_CONF_IDENTIFIER:
+ // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
+ if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
+ buffer[bufferCount++] = static_cast<char>(tolower(ch));
+ } else {
+ state = SCE_CONF_DEFAULT;
+ buffer[bufferCount] = '\0';
+
+ // check if the buffer contains a keyword, and highlight it if it is a keyword...
+ if(directives.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
+ } else if(params.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_CONF_PARAMETER );
+ } else if(strchr(buffer,'/') || strchr(buffer,'.')) {
+ styler.ColourTo(i-1,SCE_CONF_EXTENSION);
+ } else {
+ styler.ColourTo(i-1,SCE_CONF_DEFAULT);
+ }
+
+ // push back the faulty character
+ chNext = styler[i--];
+
+ }
+ break;
+
+ case SCE_CONF_NUMBER:
+ // stay in CONF_NUMBER state until we find a non-numeric
+ if( (isascii(ch) && isdigit(ch)) || ch == '.') {
+ buffer[bufferCount++] = ch;
+ } else {
+ state = SCE_CONF_DEFAULT;
+ buffer[bufferCount] = '\0';
+
+ // Colourize here...
+ if( strchr(buffer,'.') ) {
+ // it is an IP address...
+ styler.ColourTo(i-1,SCE_CONF_IP);
+ } else {
+ // normal number
+ styler.ColourTo(i-1,SCE_CONF_NUMBER);
+ }
+
+ // push back a character
+ chNext = styler[i--];
+ }
+ break;
+
+ }
+ }
+ delete []buffer;
+}
+
+static const char * const confWordListDesc[] = {
+ "Directives",
+ "Parameters",
+ 0
+};
+
+LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCrontab.cxx
+ ** Lexer to use with extended crontab files used by a powerful
+ ** Windows scheduler/event monitor/automation manager nnCron.
+ ** (http://nemtsev.eserv.ru/)
+ **/
+// 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 void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordList
+*keywordLists[], Accessor &styler)
+{
+ int state = SCE_NNCRONTAB_DEFAULT;
+ char chNext = styler[startPos];
+ int lengthDoc = startPos + length;
+ // create a buffer large enough to take the largest chunk...
+ char *buffer = new char[length];
+ int bufferCount = 0;
+ // used when highliting environment variables inside quoted string:
+ bool insideString = false;
+
+ // this assumes that we have 3 keyword list in conf.properties
+ WordList §ion = *keywordLists[0];
+ WordList &keyword = *keywordLists[1];
+ WordList &modifier = *keywordLists[2];
+
+ // go through all provided text segment
+ // using the hand-written state machine shown below
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ for (int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ i++;
+ continue;
+ }
+ switch(state) {
+ case SCE_NNCRONTAB_DEFAULT:
+ if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
+ // whitespace is simply ignored here...
+ styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
+ break;
+ } else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') {
+ // signals the start of a task...
+ state = SCE_NNCRONTAB_TASK;
+ styler.ColourTo(i,SCE_NNCRONTAB_TASK);
+ }
+ else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
+ styler.SafeGetCharAt(i+1) == '\t')) {
+ // signals the start of an extended comment...
+ state = SCE_NNCRONTAB_COMMENT;
+ styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
+ } else if( ch == '#' ) {
+ // signals the start of a plain comment...
+ state = SCE_NNCRONTAB_COMMENT;
+ styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
+ } else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') {
+ // signals the end of a task...
+ state = SCE_NNCRONTAB_TASK;
+ styler.ColourTo(i,SCE_NNCRONTAB_TASK);
+ } else if( ch == '"') {
+ state = SCE_NNCRONTAB_STRING;
+ styler.ColourTo(i,SCE_NNCRONTAB_STRING);
+ } else if( ch == '%') {
+ // signals environment variables
+ state = SCE_NNCRONTAB_ENVIRONMENT;
+ styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
+ } else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') {
+ // signals environment variables
+ state = SCE_NNCRONTAB_ENVIRONMENT;
+ styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
+ } else if( ch == '*' ) {
+ // signals an asterisk
+ // no state jump necessary for this simple case...
+ styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
+ } else if( (isascii(ch) && isalpha(ch)) || ch == '<' ) {
+ // signals the start of an identifier
+ bufferCount = 0;
+ buffer[bufferCount++] = ch;
+ state = SCE_NNCRONTAB_IDENTIFIER;
+ } else if( isascii(ch) && isdigit(ch) ) {
+ // signals the start of a number
+ bufferCount = 0;
+ buffer[bufferCount++] = ch;
+ state = SCE_NNCRONTAB_NUMBER;
+ } else {
+ // style it the default style..
+ styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
+ }
+ break;
+
+ case SCE_NNCRONTAB_COMMENT:
+ // if we find a newline here,
+ // we simply go to default state
+ // else continue to work on it...
+ if( ch == '\n' || ch == '\r' ) {
+ state = SCE_NNCRONTAB_DEFAULT;
+ } else {
+ styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
+ }
+ break;
+
+ case SCE_NNCRONTAB_TASK:
+ // if we find a newline here,
+ // we simply go to default state
+ // else continue to work on it...
+ if( ch == '\n' || ch == '\r' ) {
+ state = SCE_NNCRONTAB_DEFAULT;
+ } else {
+ styler.ColourTo(i,SCE_NNCRONTAB_TASK);
+ }
+ break;
+
+ case SCE_NNCRONTAB_STRING:
+ if( ch == '%' ) {
+ state = SCE_NNCRONTAB_ENVIRONMENT;
+ insideString = true;
+ styler.ColourTo(i-1,SCE_NNCRONTAB_STRING);
+ break;
+ }
+ // if we find the end of a string char, we simply go to default state
+ // else we're still dealing with an string...
+ if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') ||
+ (ch == '\n') || (ch == '\r') ) {
+ state = SCE_NNCRONTAB_DEFAULT;
+ }
+ styler.ColourTo(i,SCE_NNCRONTAB_STRING);
+ break;
+
+ case SCE_NNCRONTAB_ENVIRONMENT:
+ // if we find the end of a string char, we simply go to default state
+ // else we're still dealing with an string...
+ if( ch == '%' && insideString ) {
+ state = SCE_NNCRONTAB_STRING;
+ insideString = false;
+ break;
+ }
+ if( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\')
+ || (ch == '\n') || (ch == '\r') || (ch == '>') ) {
+ state = SCE_NNCRONTAB_DEFAULT;
+ styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
+ break;
+ }
+ styler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT);
+ break;
+
+ case SCE_NNCRONTAB_IDENTIFIER:
+ // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
+ if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||
+ (ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
+ (ch == '@') ) {
+ buffer[bufferCount++] = ch;
+ } else {
+ state = SCE_NNCRONTAB_DEFAULT;
+ buffer[bufferCount] = '\0';
+
+ // check if the buffer contains a keyword,
+ // and highlight it if it is a keyword...
+ if(section.InList(buffer)) {
+ styler.ColourTo(i,SCE_NNCRONTAB_SECTION );
+ } else if(keyword.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD );
+ } // else if(strchr(buffer,'/') || strchr(buffer,'.')) {
+ // styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);
+ // }
+ else if(modifier.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER );
+ } else {
+ styler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT);
+ }
+ // push back the faulty character
+ chNext = styler[i--];
+ }
+ break;
+
+ case SCE_NNCRONTAB_NUMBER:
+ // stay in CONF_NUMBER state until we find a non-numeric
+ if( isascii(ch) && isdigit(ch) /* || ch == '.' */ ) {
+ buffer[bufferCount++] = ch;
+ } else {
+ state = SCE_NNCRONTAB_DEFAULT;
+ buffer[bufferCount] = '\0';
+ // Colourize here... (normal number)
+ styler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER);
+ // push back a character
+ chNext = styler[i--];
+ }
+ break;
+ }
+ }
+ delete []buffer;
+}
+
+static const char * const cronWordListDesc[] = {
+ "Section keywords and Forth words",
+ "nnCrontab keywords",
+ "Modifiers",
+ 0
+};
+
+LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCsound.cxx
+ ** Lexer for Csound (Orchestra & Score)
+ ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
+ **/
+// Copyright 1998-2003 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+ ch == '_' || ch == '?');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
+ ch == '%' || ch == '@' || ch == '$' || ch == '?');
+}
+
+static inline bool IsCsoundOperator(char ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
+ ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
+ ch == '%' || ch == ':')
+ return true;
+ return false;
+}
+
+static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &opcode = *keywordlists[0];
+ WordList &headerStmt = *keywordlists[1];
+ WordList &otherKeyword = *keywordlists[2];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_CSOUND_STRINGEOL)
+ initStyle = SCE_CSOUND_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_CSOUND_OPERATOR) {
+ if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }else if (sc.state == SCE_CSOUND_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ } else if (sc.state == SCE_CSOUND_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+
+ if (opcode.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_OPCODE);
+ } else if (headerStmt.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_HEADERSTMT);
+ } else if (otherKeyword.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_USERKEYWORD);
+ } else if (s[0] == 'p') {
+ sc.ChangeState(SCE_CSOUND_PARAM);
+ } else if (s[0] == 'a') {
+ sc.ChangeState(SCE_CSOUND_ARATE_VAR);
+ } else if (s[0] == 'k') {
+ sc.ChangeState(SCE_CSOUND_KRATE_VAR);
+ } else if (s[0] == 'i') { // covers both i-rate variables and i-statements
+ sc.ChangeState(SCE_CSOUND_IRATE_VAR);
+ } else if (s[0] == 'g') {
+ sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
+ }
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_CSOUND_COMMENT ) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+ else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
+ (sc.state == SCE_CSOUND_KRATE_VAR) ||
+ (sc.state == SCE_CSOUND_IRATE_VAR)) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_CSOUND_DEFAULT) {
+ if (sc.ch == ';'){
+ sc.SetState(SCE_CSOUND_COMMENT);
+ } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+ sc.SetState(SCE_CSOUND_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_CSOUND_IDENTIFIER);
+ } else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_CSOUND_OPERATOR);
+ } else if (sc.ch == 'p') {
+ sc.SetState(SCE_CSOUND_PARAM);
+ } else if (sc.ch == 'a') {
+ sc.SetState(SCE_CSOUND_ARATE_VAR);
+ } else if (sc.ch == 'k') {
+ sc.SetState(SCE_CSOUND_KRATE_VAR);
+ } else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
+ sc.SetState(SCE_CSOUND_IRATE_VAR);
+ } else if (sc.ch == 'g') {
+ sc.SetState(SCE_CSOUND_GLOBAL_VAR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int stylePrev = 0;
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
+ char s[20];
+ unsigned int j = 0;
+ while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
+ s[j] = styler[i + j];
+ j++;
+ }
+ s[j] = '\0';
+
+ if (strcmp(s, "instr") == 0)
+ levelCurrent++;
+ if (strcmp(s, "endin") == 0)
+ levelCurrent--;
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ stylePrev = style;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+
+static const char * const csoundWordListDesc[] = {
+ "Opcodes",
+ "Header Statements",
+ "User keywords",
+ 0
+};
+
+LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);
--- /dev/null
+/** @file LexD.cxx
+ ** Lexer for D.
+ **
+ ** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com>
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
+ **/
+// Copyright 1998-2005 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 <string>
+#include <map>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/* Nested comments require keeping the value of the nesting level for every
+ position in the document. But since scintilla always styles line by line,
+ we only need to store one value per line. The non-negative number indicates
+ nesting level at the end of the line.
+*/
+
+// Underscore, letter, digit and universal alphas from C99 Appendix D.
+
+static bool IsWordStart(int ch) {
+ return (isascii(ch) && (isalpha(ch) || ch == '_')) || !isascii(ch);
+}
+
+static bool IsWord(int ch) {
+ return (isascii(ch) && (isalnum(ch) || ch == '_')) || !isascii(ch);
+}
+
+static bool IsDoxygen(int ch) {
+ if (isascii(ch) && islower(ch))
+ return true;
+ if (ch == '$' || ch == '@' || ch == '\\' ||
+ ch == '&' || ch == '#' || ch == '<' || ch == '>' ||
+ ch == '{' || ch == '}' || ch == '[' || ch == ']')
+ return true;
+ return false;
+}
+
+static bool IsStringSuffix(int ch) {
+ return ch == 'c' || ch == 'w' || ch == 'd';
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_D_COMMENT ||
+ style == SCE_D_COMMENTDOC ||
+ style == SCE_D_COMMENTDOCKEYWORD ||
+ style == SCE_D_COMMENTDOCKEYWORDERROR;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerD
+struct OptionsD {
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldComment;
+ bool foldCommentMultiline;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldCompact;
+ int foldAtElseInt;
+ bool foldAtElse;
+ OptionsD() {
+ fold = false;
+ foldSyntaxBased = true;
+ foldComment = false;
+ foldCommentMultiline = true;
+ foldCommentExplicit = true;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldCompact = true;
+ foldAtElseInt = -1;
+ foldAtElse = false;
+ }
+};
+
+static const char * const dWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Type definitions and aliases",
+ "Keywords 5",
+ "Keywords 6",
+ "Keywords 7",
+ 0,
+ };
+
+struct OptionSetD : public OptionSet<OptionsD> {
+ OptionSetD() {
+ DefineProperty("fold", &OptionsD::fold);
+
+ DefineProperty("fold.d.syntax.based", &OptionsD::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.comment", &OptionsD::foldComment);
+
+ DefineProperty("fold.d.comment.multiline", &OptionsD::foldCommentMultiline,
+ "Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+ DefineProperty("fold.d.comment.explicit", &OptionsD::foldCommentExplicit,
+ "Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+ DefineProperty("fold.d.explicit.start", &OptionsD::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard //{.");
+
+ DefineProperty("fold.d.explicit.end", &OptionsD::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard //}.");
+
+ DefineProperty("fold.d.explicit.anywhere", &OptionsD::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.compact", &OptionsD::foldCompact);
+
+ DefineProperty("lexer.d.fold.at.else", &OptionsD::foldAtElseInt,
+ "This option enables D folding on a \"} else {\" line of an if statement.");
+
+ DefineProperty("fold.at.else", &OptionsD::foldAtElse);
+
+ DefineWordListSets(dWordLists);
+ }
+};
+
+class LexerD : public ILexer {
+ bool caseSensitive;
+ WordList keywords;
+ WordList keywords2;
+ WordList keywords3;
+ WordList keywords4;
+ WordList keywords5;
+ WordList keywords6;
+ WordList keywords7;
+ OptionsD options;
+ OptionSetD osD;
+public:
+ LexerD(bool caseSensitive_) :
+ caseSensitive(caseSensitive_) {
+ }
+ virtual ~LexerD() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osD.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osD.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osD.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osD.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryD() {
+ return new LexerD(true);
+ }
+ static ILexer *LexerFactoryDInsensitive() {
+ return new LexerD(false);
+ }
+};
+
+int SCI_METHOD LexerD::PropertySet(const char *key, const char *val) {
+ if (osD.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerD::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords;
+ break;
+ case 1:
+ wordListN = &keywords2;
+ break;
+ case 2:
+ wordListN = &keywords3;
+ break;
+ case 3:
+ wordListN = &keywords4;
+ break;
+ case 4:
+ wordListN = &keywords5;
+ break;
+ case 5:
+ wordListN = &keywords6;
+ break;
+ case 6:
+ wordListN = &keywords7;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerD::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
+ int styleBeforeDCKeyword = SCE_D_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ int curLine = styler.GetLine(startPos);
+ int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
+ bool numFloat = false; // Float literals have '+' and '-' signs
+ bool numHex = false;
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart) {
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curNcLevel);
+ }
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_D_OPERATOR:
+ sc.SetState(SCE_D_DEFAULT);
+ break;
+ case SCE_D_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (isascii(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {
+ continue;
+ } else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {
+ // Don't parse 0..2 as number.
+ numFloat=true;
+ continue;
+ } else if ( ( sc.ch == '-' || sc.ch == '+' ) && ( /*sign and*/
+ ( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/
+ ( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) { /*hex*/
+ // Parse exponent sign in float literals: 2e+10 0x2e+10
+ continue;
+ } else {
+ sc.SetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_IDENTIFIER:
+ if (!IsWord(sc.ch)) {
+ char s[1000];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_D_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_D_WORD2);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_D_TYPEDEF);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_D_WORD5);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_D_WORD6);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_D_WORD7);
+ }
+ sc.SetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_D_COMMENTDOC;
+ sc.SetState(SCE_D_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_D_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_COMMENTLINEDOC:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_D_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
+ sc.SetState(SCE_D_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_D_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ } else if (!IsDoxygen(sc.ch)) {
+ char s[100];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+ sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_D_COMMENTNESTED:
+ if (sc.Match('+', '/')) {
+ if (curNcLevel > 0)
+ curNcLevel -= 1;
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curNcLevel);
+ sc.Forward();
+ if (curNcLevel == 0) {
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ }
+ } else if (sc.Match('/','+')) {
+ curNcLevel += 1;
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curNcLevel);
+ sc.Forward();
+ }
+ break;
+ case SCE_D_STRING:
+ if (sc.ch == '\\') {
+ if (sc.chNext == '"' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '"') {
+ if(IsStringSuffix(sc.chNext))
+ sc.Forward();
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_D_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ // Char has no suffixes
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_STRINGB:
+ if (sc.ch == '`') {
+ if(IsStringSuffix(sc.chNext))
+ sc.Forward();
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ }
+ break;
+ case SCE_D_STRINGR:
+ if (sc.ch == '"') {
+ if(IsStringSuffix(sc.chNext))
+ sc.Forward();
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_D_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_D_NUMBER);
+ numFloat = sc.ch == '.';
+ // Remember hex literal
+ numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );
+ } else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')
+ && sc.chNext == '"' ) {
+ // Limited support for hex and delimited strings: parse as r""
+ sc.SetState(SCE_D_STRINGR);
+ sc.Forward();
+ } else if (IsWordStart(sc.ch) || sc.ch == '$') {
+ sc.SetState(SCE_D_IDENTIFIER);
+ } else if (sc.Match('/','+')) {
+ curNcLevel += 1;
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curNcLevel);
+ sc.SetState(SCE_D_COMMENTNESTED);
+ sc.Forward();
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_D_COMMENTDOC);
+ } else {
+ sc.SetState(SCE_D_COMMENT);
+ }
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
+ // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_D_COMMENTLINEDOC);
+ else
+ sc.SetState(SCE_D_COMMENTLINE);
+ } else if (sc.ch == '"') {
+ sc.SetState(SCE_D_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_D_CHARACTER);
+ } else if (sc.ch == '`') {
+ sc.SetState(SCE_D_STRINGB);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_D_OPERATOR);
+ if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator
+ }
+ }
+ }
+ sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+
+void SCI_METHOD LexerD::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ bool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse;
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ levelNext++;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ levelNext--;
+ }
+ } else {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ }
+ if (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (atEOL || (i == endPos-1)) {
+ if (options.foldComment && options.foldCommentMultiline) { // Handle nested comments
+ int nc;
+ nc = styler.GetLineState(lineCurrent);
+ nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
+ levelNext += nc;
+ }
+ int levelUse = levelCurrent;
+ if (options.foldSyntaxBased && foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && options.foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ }
+}
+
+LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexECL.cxx
+ ** Lexer for ECL.
+ **/
+// 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+#ifdef __BORLANDC__
+// Borland C++ displays warnings in vector header without this
+#pragma option -w-ccc -w-rch
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
+#define SET_LOWER "abcdefghijklmnopqrstuvwxyz"
+#define SET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define SET_DIGITS "0123456789"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static bool IsSpaceEquiv(int state) {
+ return (state <= SCE_ECL_COMMENTDOC) ||
+ // including SCE_ECL_DEFAULT, SCE_ECL_COMMENT, SCE_ECL_COMMENTLINE
+ (state == SCE_ECL_COMMENTLINEDOC) || (state == SCE_ECL_COMMENTDOCKEYWORD) ||
+ (state == SCE_ECL_COMMENTDOCKEYWORDERROR);
+}
+
+static void ColouriseEclDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ WordList &keywords0 = *keywordlists[0];
+ WordList &keywords1 = *keywordlists[1];
+ WordList &keywords2 = *keywordlists[2];
+ WordList &keywords3 = *keywordlists[3]; //Value Types
+ WordList &keywords4 = *keywordlists[4];
+ WordList &keywords5 = *keywordlists[5];
+ WordList &keywords6 = *keywordlists[6]; //Javadoc Tags
+ WordList cplusplus;
+ cplusplus.Set("beginc endc");
+
+ bool stylingWithinPreprocessor = false;
+
+ CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,");
+ CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]");
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+ CharacterSet setQualified(CharacterSet::setNone, "uUxX");
+
+ int chPrevNonWhite = ' ';
+ int visibleChars = 0;
+ bool lastWordWasUUID = false;
+ int styleBeforeDCKeyword = SCE_ECL_DEFAULT;
+ bool continuationLine = false;
+
+ if (initStyle == SCE_ECL_PREPROCESSOR) {
+ // Set continuationLine if last character of previous line is '\'
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ int chBack = styler.SafeGetCharAt(startPos-1, 0);
+ int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
+ int lineEndChar = '!';
+ if (chBack2 == '\r' && chBack == '\n') {
+ lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
+ } else if (chBack == '\n' || chBack == '\r') {
+ lineEndChar = chBack2;
+ }
+ continuationLine = lineEndChar == '\\';
+ }
+ }
+
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (startPos > 0) {
+ int back = startPos;
+ while (--back && IsSpaceEquiv(styler.StyleAt(back)))
+ ;
+ if (styler.StyleAt(back) == SCE_ECL_OPERATOR) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineStart) {
+ if (sc.state == SCE_ECL_STRING) {
+ // Prevent SCE_ECL_STRINGEOL from leaking back to previous line which
+ // ends with a line continuation by locking in the state upto this position.
+ sc.SetState(SCE_ECL_STRING);
+ }
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ lastWordWasUUID = false;
+ }
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continuationLine = true;
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_ECL_ADDED:
+ case SCE_ECL_DELETED:
+ case SCE_ECL_CHANGED:
+ case SCE_ECL_MOVED:
+ if (sc.atLineStart)
+ sc.SetState(SCE_ECL_DEFAULT);
+ break;
+ case SCE_ECL_OPERATOR:
+ sc.SetState(SCE_ECL_DEFAULT);
+ break;
+ case SCE_ECL_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (!setWord.Contains(sc.ch)) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_IDENTIFIER:
+ if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords0.InList(s)) {
+ lastWordWasUUID = strcmp(s, "uuid") == 0;
+ sc.ChangeState(SCE_ECL_WORD0);
+ } else if (keywords1.InList(s)) {
+ sc.ChangeState(SCE_ECL_WORD1);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_ECL_WORD2);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_ECL_WORD4);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_ECL_WORD5);
+ }
+ else //Data types are of from KEYWORD##
+ {
+ int i = static_cast<int>(strlen(s)) - 1;
+ while(i >= 0 && (isdigit(s[i]) || s[i] == '_'))
+ --i;
+
+ char s2[1000];
+ strncpy(s2, s, i + 1);
+ s2[i + 1] = 0;
+ if (keywords3.InList(s2)) {
+ sc.ChangeState(SCE_ECL_WORD3);
+ }
+ }
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_PREPROCESSOR:
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ } else if (stylingWithinPreprocessor) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ } else {
+ if (sc.Match('/', '*') || sc.Match('/', '/')) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_ECL_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_ECL_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_ECL_COMMENTDOC;
+ sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_ECL_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_COMMENTLINEDOC:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC;
+ sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_ECL_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_ECL_DEFAULT);
+ } else if (!setDoxygen.Contains(sc.ch)) {
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!IsASpace(sc.ch) || !keywords6.InList(s+1)) {
+ sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_ECL_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_ECL_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_ECL_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_REGEX:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ } else if (sc.ch == '/') {
+ sc.Forward();
+ while ((sc.ch < 0x80) && islower(sc.ch))
+ sc.Forward(); // gobble regex flags
+ sc.SetState(SCE_ECL_DEFAULT);
+ } else if (sc.ch == '\\') {
+ // Gobble up the quoted character
+ if (sc.chNext == '\\' || sc.chNext == '/') {
+ sc.Forward();
+ }
+ }
+ break;
+ case SCE_ECL_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ case SCE_ECL_VERBATIM:
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_ECL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_ECL_UUID:
+ if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ int lineCurrent = styler.GetLine(sc.currentPos);
+ int lineState = styler.GetLineState(lineCurrent);
+ if (sc.state == SCE_ECL_DEFAULT) {
+ if (lineState) {
+ sc.SetState(lineState);
+ }
+ else if (sc.Match('@', '\"')) {
+ sc.SetState(SCE_ECL_VERBATIM);
+ sc.Forward();
+ } else if (setQualified.Contains(sc.ch) && sc.chNext == '\'') {
+ sc.SetState(SCE_ECL_CHARACTER);
+ sc.Forward();
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ if (lastWordWasUUID) {
+ sc.SetState(SCE_ECL_UUID);
+ lastWordWasUUID = false;
+ } else {
+ sc.SetState(SCE_ECL_NUMBER);
+ }
+ } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
+ if (lastWordWasUUID) {
+ sc.SetState(SCE_ECL_UUID);
+ lastWordWasUUID = false;
+ } else {
+ sc.SetState(SCE_ECL_IDENTIFIER);
+ }
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_ECL_COMMENTDOC);
+ } else {
+ sc.SetState(SCE_ECL_COMMENT);
+ }
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
+ // Support of Qt/Doxygen doc. style
+ sc.SetState(SCE_ECL_COMMENTLINEDOC);
+ else
+ sc.SetState(SCE_ECL_COMMENTLINE);
+ } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) {
+ sc.SetState(SCE_ECL_REGEX); // JavaScript's RegEx
+// } else if (sc.ch == '\"') {
+// sc.SetState(SCE_ECL_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_ECL_CHARACTER);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_ECL_PREPROCESSOR);
+ // Skip whitespace between # and preprocessor word
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_ECL_DEFAULT);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_ECL_OPERATOR);
+ }
+ }
+
+ if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
+ chPrevNonWhite = sc.ch;
+ visibleChars++;
+ }
+ continuationLine = false;
+ }
+ sc.Complete();
+
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_ECL_COMMENT ||
+ style == SCE_ECL_COMMENTDOC ||
+ style == SCE_ECL_COMMENTDOCKEYWORD ||
+ style == SCE_ECL_COMMENTDOCKEYWORDERROR;
+}
+
+bool MatchNoCase(Accessor & styler, unsigned int & pos, const char *s) {
+ int i=0;
+ for (; *s; i++) {
+ char compare_char = tolower(*s);
+ char styler_char = tolower(styler.SafeGetCharAt(pos+i));
+ if (compare_char != styler_char)
+ return false;
+ s++;
+ }
+ pos+=i-1;
+ return true;
+}
+
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldEclDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ bool foldComment = true;
+ bool foldPreprocessor = true;
+ bool foldCompact = true;
+ bool foldAtElse = true;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_ECL_COMMENTLINEDOC) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (foldComment && (style == SCE_ECL_COMMENTLINE)) {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ if (foldPreprocessor && (style == SCE_ECL_PREPROCESSOR)) {
+ if (ch == '#') {
+ unsigned int j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (MatchNoCase(styler, j, "region") || MatchNoCase(styler, j, "if")) {
+ levelNext++;
+ } else if (MatchNoCase(styler, j, "endregion") || MatchNoCase(styler, j, "end")) {
+ levelNext--;
+ }
+ }
+ }
+ if (style == SCE_ECL_OPERATOR) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (style == SCE_ECL_WORD2) {
+ if (MatchNoCase(styler, i, "record") || MatchNoCase(styler, i, "transform") || MatchNoCase(styler, i, "type") || MatchNoCase(styler, i, "function") ||
+ MatchNoCase(styler, i, "module") || MatchNoCase(styler, i, "service") || MatchNoCase(styler, i, "interface") || MatchNoCase(styler, i, "ifblock") ||
+ MatchNoCase(styler, i, "macro") || MatchNoCase(styler, i, "beginc++")) {
+ levelNext++;
+ } else if (MatchNoCase(styler, i, "endmacro") || MatchNoCase(styler, i, "endc++") || MatchNoCase(styler, i, "end")) {
+ levelNext--;
+ }
+ }
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+ // There is an empty line at end of file so give it same level and empty
+ styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+ }
+ visibleChars = 0;
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ }
+}
+
+static const char * const EclWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmECL(
+ SCLEX_ECL,
+ ColouriseEclDoc,
+ "ecl",
+ FoldEclDoc,
+ EclWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexESCRIPT.cxx
+ ** Lexer for ESCRIPT
+ **/
+// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+
+
+static void ColouriseESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+
+ // Do not leak onto next line
+ /*if (initStyle == SCE_ESCRIPT_STRINGEOL)
+ initStyle = SCE_ESCRIPT_DEFAULT;*/
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ bool caseSensitive = styler.GetPropertyInt("escript.case.sensitive", 0) != 0;
+
+ for (; sc.More(); sc.Forward()) {
+
+ /*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) {
+ // Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_ESCRIPT_STRING);
+ }*/
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) {
+ sc.SetState(SCE_ESCRIPT_DEFAULT);
+ } else if (sc.state == SCE_ESCRIPT_NUMBER) {
+ if (!IsADigit(sc.ch) || sc.ch != '.') {
+ sc.SetState(SCE_ESCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_ESCRIPT_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[100];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+
+// sc.GetCurrentLowered(s, sizeof(s));
+
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_ESCRIPT_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_ESCRIPT_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_ESCRIPT_WORD3);
+ // sc.state = SCE_ESCRIPT_IDENTIFIER;
+ }
+ sc.SetState(SCE_ESCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_ESCRIPT_COMMENT) {
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_ESCRIPT_COMMENTDOC) {
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_ESCRIPT_COMMENTLINE) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_ESCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_ESCRIPT_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_ESCRIPT_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_ESCRIPT_NUMBER);
+ } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
+ sc.SetState(SCE_ESCRIPT_IDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_ESCRIPT_COMMENT);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_ESCRIPT_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_ESCRIPT_STRING);
+ //} else if (isoperator(static_cast<char>(sc.ch))) {
+ } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
+ sc.SetState(SCE_ESCRIPT_OPERATOR);
+ } else if (sc.ch == '{' || sc.ch == '}') {
+ sc.SetState(SCE_ESCRIPT_BRACE);
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+
+static int classifyFoldPointESCRIPT(const char* s, const char* prevWord) {
+ int lev = 0;
+ if (strcmp(prevWord, "end") == 0) return lev;
+ if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
+ return -1;
+
+ if (strcmp(s, "for") == 0 || strcmp(s, "foreach") == 0
+ || strcmp(s, "program") == 0 || strcmp(s, "function") == 0
+ || strcmp(s, "while") == 0 || strcmp(s, "case") == 0
+ || strcmp(s, "if") == 0 ) {
+ lev = 1;
+ } else if ( strcmp(s, "endfor") == 0 || strcmp(s, "endforeach") == 0
+ || strcmp(s, "endprogram") == 0 || strcmp(s, "endfunction") == 0
+ || strcmp(s, "endwhile") == 0 || strcmp(s, "endcase") == 0
+ || strcmp(s, "endif") == 0 ) {
+ lev = -1;
+ }
+
+ return lev;
+}
+
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_ESCRIPT_COMMENT ||
+ style == SCE_ESCRIPT_COMMENTDOC ||
+ style == SCE_ESCRIPT_COMMENTLINE;
+}
+
+static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+ //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ // Do not know how to fold the comment at the moment.
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldComment = true;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+
+ int lastStart = 0;
+ char prevWord[32] = "";
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelCurrent++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+
+ if (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelCurrent++;
+ } else if (chNext2 == '}') {
+ levelCurrent--;
+ }
+ }
+ }
+
+ if (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3)
+ {
+ // Store last word start point.
+ lastStart = i;
+ }
+
+ if (style == SCE_ESCRIPT_WORD3) {
+ if(iswordchar(ch) && !iswordchar(chNext)) {
+ char s[32];
+ unsigned int j;
+ for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
+ s[j] = static_cast<char>(tolower(styler[lastStart + j]));
+ }
+ s[j] = '\0';
+ levelCurrent += classifyFoldPointESCRIPT(s, prevWord);
+ strcpy(prevWord, s);
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ strcpy(prevWord, "");
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+
+
+static const char * const ESCRIPTWordLists[] = {
+ "Primary keywords and identifiers",
+ "Intrinsic functions",
+ "Extended and user defined functions",
+ 0,
+};
+
+LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, "escript", FoldESCRIPTDoc, ESCRIPTWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexEiffel.cxx
+ ** Lexer for Eiffel.
+ **/
+// 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 isEiffelOperator(unsigned int ch) {
+ // '.' left out as it is used to make up numbers
+ return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' ||
+ ch == '{' || ch == '}' || ch == '~' ||
+ ch == '[' || ch == ']' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' ||
+ ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
+ ch == '!' || ch == '@' || ch == '?';
+}
+
+static inline bool IsAWordChar(unsigned int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(unsigned int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static void ColouriseEiffelDoc(unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_EIFFEL_STRINGEOL) {
+ if (sc.ch != '\r' && sc.ch != '\n') {
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ }
+ } else if (sc.state == SCE_EIFFEL_OPERATOR) {
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ } else if (sc.state == SCE_EIFFEL_WORD) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!keywords.InList(s)) {
+ sc.ChangeState(SCE_EIFFEL_IDENTIFIER);
+ }
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ }
+ } else if (sc.state == SCE_EIFFEL_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ }
+ } else if (sc.state == SCE_EIFFEL_COMMENTLINE) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ }
+ } else if (sc.state == SCE_EIFFEL_STRING) {
+ if (sc.ch == '%') {
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ sc.Forward();
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ }
+ } else if (sc.state == SCE_EIFFEL_CHARACTER) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_EIFFEL_STRINGEOL);
+ } else if (sc.ch == '%') {
+ sc.Forward();
+ } else if (sc.ch == '\'') {
+ sc.Forward();
+ sc.SetState(SCE_EIFFEL_DEFAULT);
+ }
+ }
+
+ if (sc.state == SCE_EIFFEL_DEFAULT) {
+ if (sc.ch == '-' && sc.chNext == '-') {
+ sc.SetState(SCE_EIFFEL_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_EIFFEL_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_EIFFEL_CHARACTER);
+ } else if (IsADigit(sc.ch) || (sc.ch == '.')) {
+ sc.SetState(SCE_EIFFEL_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_EIFFEL_WORD);
+ } else if (isEiffelOperator(sc.ch)) {
+ sc.SetState(SCE_EIFFEL_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static bool IsEiffelComment(Accessor &styler, int pos, int len) {
+ return len>1 && styler[pos]=='-' && styler[pos+1]=='-';
+}
+
+static void FoldEiffelDocIndent(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ int lengthDoc = startPos + length;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);
+ char chNext = styler[startPos];
+ for (int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ // Only non whitespace lines can be headers
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
+ // Line after is blank so check the next - maybe should continue further?
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int stylePrev = 0;
+ int styleNext = styler.StyleAt(startPos);
+ // lastDeferred should be determined by looking back to last keyword in case
+ // the "deferred" is on a line before "class"
+ bool lastDeferred = false;
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {
+ char s[20];
+ unsigned int j = 0;
+ while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
+ s[j] = styler[i + j];
+ j++;
+ }
+ s[j] = '\0';
+
+ if (
+ (strcmp(s, "check") == 0) ||
+ (strcmp(s, "debug") == 0) ||
+ (strcmp(s, "deferred") == 0) ||
+ (strcmp(s, "do") == 0) ||
+ (strcmp(s, "from") == 0) ||
+ (strcmp(s, "if") == 0) ||
+ (strcmp(s, "inspect") == 0) ||
+ (strcmp(s, "once") == 0)
+ )
+ levelCurrent++;
+ if (!lastDeferred && (strcmp(s, "class") == 0))
+ levelCurrent++;
+ if (strcmp(s, "end") == 0)
+ levelCurrent--;
+ lastDeferred = strcmp(s, "deferred") == 0;
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ stylePrev = style;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const eiffelWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc);
+LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+/** @file LexErlang.cxx
+ ** Lexer for Erlang.
+ ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
+ ** Originally wrote by Peter-Henry Mander,
+ ** based on Matlab lexer by José Fonseca.
+ **/
+
+#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 int is_radix(int radix, int ch) {
+ int digit;
+
+ if (36 < radix || 2 > radix)
+ return 0;
+
+ if (isdigit(ch)) {
+ digit = ch - '0';
+ } else if (isalnum(ch)) {
+ digit = toupper(ch) - 'A' + 10;
+ } else {
+ return 0;
+ }
+
+ return (digit < radix);
+}
+
+typedef enum {
+ STATE_NULL,
+ COMMENT,
+ COMMENT_FUNCTION,
+ COMMENT_MODULE,
+ COMMENT_DOC,
+ COMMENT_DOC_MACRO,
+ ATOM_UNQUOTED,
+ ATOM_QUOTED,
+ NODE_NAME_UNQUOTED,
+ NODE_NAME_QUOTED,
+ MACRO_START,
+ MACRO_UNQUOTED,
+ MACRO_QUOTED,
+ RECORD_START,
+ RECORD_UNQUOTED,
+ RECORD_QUOTED,
+ NUMERAL_START,
+ NUMERAL_BASE_VALUE,
+ NUMERAL_FLOAT,
+ NUMERAL_EXPONENT,
+ PREPROCESSOR
+} atom_parse_state_t;
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');
+}
+
+static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ WordList &reservedWords = *keywordlists[0];
+ WordList &erlangBIFs = *keywordlists[1];
+ WordList &erlangPreproc = *keywordlists[2];
+ WordList &erlangModulesAtt = *keywordlists[3];
+ WordList &erlangDoc = *keywordlists[4];
+ WordList &erlangDocMacro = *keywordlists[5];
+ int radix_digits = 0;
+ int exponent_digits = 0;
+ atom_parse_state_t parse_state = STATE_NULL;
+ atom_parse_state_t old_parse_state = STATE_NULL;
+ bool to_late_to_comment = false;
+ char cur[100];
+ int old_style = SCE_ERLANG_DEFAULT;
+
+ styler.StartAt(startPos);
+
+ for (; sc.More(); sc.Forward()) {
+ int style = SCE_ERLANG_DEFAULT;
+ if (STATE_NULL != parse_state) {
+
+ switch (parse_state) {
+
+ case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;
+
+ /* COMMENTS ------------------------------------------------------*/
+ case COMMENT : {
+ if (sc.ch != '%') {
+ to_late_to_comment = true;
+ } else if (!to_late_to_comment && sc.ch == '%') {
+ // Switch to comment level 2 (Function)
+ sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
+ old_style = SCE_ERLANG_COMMENT_FUNCTION;
+ parse_state = COMMENT_FUNCTION;
+ sc.Forward();
+ }
+ }
+ // V--- Falling through!
+ case COMMENT_FUNCTION : {
+ if (sc.ch != '%') {
+ to_late_to_comment = true;
+ } else if (!to_late_to_comment && sc.ch == '%') {
+ // Switch to comment level 3 (Module)
+ sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
+ old_style = SCE_ERLANG_COMMENT_MODULE;
+ parse_state = COMMENT_MODULE;
+ sc.Forward();
+ }
+ }
+ // V--- Falling through!
+ case COMMENT_MODULE : {
+ if (parse_state != COMMENT) {
+ // Search for comment documentation
+ if (sc.chNext == '@') {
+ old_parse_state = parse_state;
+ parse_state = ('{' == sc.ch)
+ ? COMMENT_DOC_MACRO
+ : COMMENT_DOC;
+ sc.ForwardSetState(sc.state);
+ }
+ }
+
+ // All comments types fall here.
+ if (sc.atLineEnd) {
+ to_late_to_comment = false;
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case COMMENT_DOC :
+ // V--- Falling through!
+ case COMMENT_DOC_MACRO : {
+
+ if (!isalnum(sc.ch)) {
+ // Try to match documentation comment
+ sc.GetCurrent(cur, sizeof(cur));
+
+ if (parse_state == COMMENT_DOC_MACRO
+ && erlangDocMacro.InList(cur)) {
+ sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
+ while (sc.ch != '}' && !sc.atLineEnd)
+ sc.Forward();
+ } else if (erlangDoc.InList(cur)) {
+ sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
+ } else {
+ sc.ChangeState(old_style);
+ }
+
+ // Switch back to old state
+ sc.SetState(old_style);
+ parse_state = old_parse_state;
+ }
+
+ if (sc.atLineEnd) {
+ to_late_to_comment = false;
+ sc.ChangeState(old_style);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Atoms ---------------------------------------------------------*/
+ case ATOM_UNQUOTED : {
+ if ('@' == sc.ch){
+ parse_state = NODE_NAME_UNQUOTED;
+ } else if (sc.ch == ':') {
+ // Searching for module name
+ if (sc.chNext == ' ') {
+ // error
+ sc.ChangeState(SCE_ERLANG_UNKNOWN);
+ parse_state = STATE_NULL;
+ } else {
+ sc.Forward();
+ if (isalnum(sc.ch)) {
+ sc.GetCurrent(cur, sizeof(cur));
+ sc.ChangeState(SCE_ERLANG_MODULES);
+ sc.SetState(SCE_ERLANG_MODULES);
+ }
+ }
+ } else if (!IsAWordChar(sc.ch)) {
+
+ sc.GetCurrent(cur, sizeof(cur));
+ if (reservedWords.InList(cur)) {
+ style = SCE_ERLANG_KEYWORD;
+ } else if (erlangBIFs.InList(cur)
+ && strcmp(cur,"erlang:")){
+ style = SCE_ERLANG_BIFS;
+ } else if (sc.ch == '(' || '/' == sc.ch){
+ style = SCE_ERLANG_FUNCTION_NAME;
+ } else {
+ style = SCE_ERLANG_ATOM;
+ }
+
+ sc.ChangeState(style);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+
+ } break;
+
+ case ATOM_QUOTED : {
+ if ( '@' == sc.ch ){
+ parse_state = NODE_NAME_QUOTED;
+ } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_ATOM);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Node names ----------------------------------------------------*/
+ case NODE_NAME_UNQUOTED : {
+ if ('@' == sc.ch) {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_NODE_NAME);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case NODE_NAME_QUOTED : {
+ if ('@' == sc.ch) {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Records -------------------------------------------------------*/
+ case RECORD_START : {
+ if ('\'' == sc.ch) {
+ parse_state = RECORD_QUOTED;
+ } else if (isalpha(sc.ch) && islower(sc.ch)) {
+ parse_state = RECORD_UNQUOTED;
+ } else { // error
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case RECORD_UNQUOTED : {
+ if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_RECORD);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case RECORD_QUOTED : {
+ if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Macros --------------------------------------------------------*/
+ case MACRO_START : {
+ if ('\'' == sc.ch) {
+ parse_state = MACRO_QUOTED;
+ } else if (isalpha(sc.ch)) {
+ parse_state = MACRO_UNQUOTED;
+ } else { // error
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case MACRO_UNQUOTED : {
+ if (!IsAWordChar(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_MACRO);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ case MACRO_QUOTED : {
+ if ('\'' == sc.ch && '\\' != sc.chPrev) {
+ sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Numerics ------------------------------------------------------*/
+ /* Simple integer */
+ case NUMERAL_START : {
+ if (isdigit(sc.ch)) {
+ radix_digits *= 10;
+ radix_digits += sc.ch - '0'; // Assuming ASCII here!
+ } else if ('#' == sc.ch) {
+ if (2 > radix_digits || 36 < radix_digits) {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else {
+ parse_state = NUMERAL_BASE_VALUE;
+ }
+ } else if ('.' == sc.ch && isdigit(sc.chNext)) {
+ radix_digits = 0;
+ parse_state = NUMERAL_FLOAT;
+ } else if ('e' == sc.ch || 'E' == sc.ch) {
+ exponent_digits = 0;
+ parse_state = NUMERAL_EXPONENT;
+ } else {
+ radix_digits = 0;
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* Integer in other base than 10 (x#yyy) */
+ case NUMERAL_BASE_VALUE : {
+ if (!is_radix(radix_digits,sc.ch)) {
+ radix_digits = 0;
+
+ if (!isalnum(sc.ch))
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* Float (x.yyy) */
+ case NUMERAL_FLOAT : {
+ if ('e' == sc.ch || 'E' == sc.ch) {
+ exponent_digits = 0;
+ parse_state = NUMERAL_EXPONENT;
+ } else if (!isdigit(sc.ch)) {
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ /* Exponent, either integer or float (xEyy, x.yyEzzz) */
+ case NUMERAL_EXPONENT : {
+ if (('-' == sc.ch || '+' == sc.ch)
+ && (isdigit(sc.chNext))) {
+ sc.Forward();
+ } else if (!isdigit(sc.ch)) {
+ if (0 < exponent_digits)
+ sc.ChangeState(SCE_ERLANG_NUMBER);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ } else {
+ ++exponent_digits;
+ }
+ } break;
+
+ /* -------------------------------------------------------------- */
+ /* Preprocessor --------------------------------------------------*/
+ case PREPROCESSOR : {
+ if (!IsAWordChar(sc.ch)) {
+
+ sc.GetCurrent(cur, sizeof(cur));
+ if (erlangPreproc.InList(cur)) {
+ style = SCE_ERLANG_PREPROC;
+ } else if (erlangModulesAtt.InList(cur)) {
+ style = SCE_ERLANG_MODULES_ATT;
+ }
+
+ sc.ChangeState(style);
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ parse_state = STATE_NULL;
+ }
+ } break;
+
+ }
+
+ } /* End of : STATE_NULL != parse_state */
+ else
+ {
+ switch (sc.state) {
+ case SCE_ERLANG_VARIABLE : {
+ if (!IsAWordChar(sc.ch))
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ } break;
+ case SCE_ERLANG_STRING : {
+ if (sc.ch == '\"' && sc.chPrev != '\\')
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } break;
+ case SCE_ERLANG_COMMENT : {
+ if (sc.atLineEnd)
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ } break;
+ case SCE_ERLANG_CHARACTER : {
+ if (sc.chPrev == '\\') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } else if (sc.ch != '\\') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ }
+ } break;
+ case SCE_ERLANG_OPERATOR : {
+ if (sc.chPrev == '.') {
+ if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
+ || sc.ch == '^') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+ } else {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ }
+ } else {
+ sc.SetState(SCE_ERLANG_DEFAULT);
+ }
+ } break;
+ }
+ }
+
+ if (sc.state == SCE_ERLANG_DEFAULT) {
+ bool no_new_state = false;
+
+ switch (sc.ch) {
+ case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
+ case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
+ case '%' : {
+ parse_state = COMMENT;
+ sc.SetState(SCE_ERLANG_COMMENT);
+ } break;
+ case '#' : {
+ parse_state = RECORD_START;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } break;
+ case '?' : {
+ parse_state = MACRO_START;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } break;
+ case '\'' : {
+ parse_state = ATOM_QUOTED;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } break;
+ case '+' :
+ case '-' : {
+ if (IsADigit(sc.chNext)) {
+ parse_state = NUMERAL_START;
+ radix_digits = 0;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } else if (sc.ch != '+') {
+ parse_state = PREPROCESSOR;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ }
+ } break;
+ default : no_new_state = true;
+ }
+
+ if (no_new_state) {
+ if (isdigit(sc.ch)) {
+ parse_state = NUMERAL_START;
+ radix_digits = sc.ch - '0';
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } else if (isupper(sc.ch) || '_' == sc.ch) {
+ sc.SetState(SCE_ERLANG_VARIABLE);
+ } else if (isalpha(sc.ch)) {
+ parse_state = ATOM_UNQUOTED;
+ sc.SetState(SCE_ERLANG_UNKNOWN);
+ } else if (isoperator(static_cast<char>(sc.ch))
+ || sc.ch == '\\') {
+ sc.SetState(SCE_ERLANG_OPERATOR);
+ }
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+static int ClassifyErlangFoldPoint(
+ Accessor &styler,
+ int styleNext,
+ int keyword_start
+) {
+ int lev = 0;
+ if (styler.Match(keyword_start,"case")
+ || (
+ styler.Match(keyword_start,"fun")
+ && (SCE_ERLANG_FUNCTION_NAME != styleNext)
+ )
+ || styler.Match(keyword_start,"if")
+ || styler.Match(keyword_start,"query")
+ || styler.Match(keyword_start,"receive")
+ ) {
+ ++lev;
+ } else if (styler.Match(keyword_start,"end")) {
+ --lev;
+ }
+
+ return lev;
+}
+
+static void FoldErlangDoc(
+ unsigned int startPos, int length, int initStyle,
+ WordList** /*keywordlists*/, Accessor &styler
+) {
+ unsigned int endPos = startPos + length;
+ int currentLine = styler.GetLine(startPos);
+ int lev;
+ int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
+ int currentLevel = previousLevel;
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ int stylePrev;
+ int keyword_start = 0;
+ char ch;
+ char chNext = styler.SafeGetCharAt(startPos);
+ bool atEOL;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ // Get styles
+ stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');
+
+ if (stylePrev != SCE_ERLANG_KEYWORD
+ && style == SCE_ERLANG_KEYWORD) {
+ keyword_start = i;
+ }
+
+ // Fold on keywords
+ if (stylePrev == SCE_ERLANG_KEYWORD
+ && style != SCE_ERLANG_KEYWORD
+ && style != SCE_ERLANG_ATOM
+ ) {
+ currentLevel += ClassifyErlangFoldPoint(styler,
+ styleNext,
+ keyword_start);
+ }
+
+ // Fold on comments
+ if (style == SCE_ERLANG_COMMENT
+ || style == SCE_ERLANG_COMMENT_MODULE
+ || style == SCE_ERLANG_COMMENT_FUNCTION) {
+
+ if (ch == '%' && chNext == '{') {
+ currentLevel++;
+ } else if (ch == '%' && chNext == '}') {
+ currentLevel--;
+ }
+ }
+
+ // Fold on braces
+ if (style == SCE_ERLANG_OPERATOR) {
+ if (ch == '{' || ch == '(' || ch == '[') {
+ currentLevel++;
+ } else if (ch == '}' || ch == ')' || ch == ']') {
+ currentLevel--;
+ }
+ }
+
+
+ if (atEOL) {
+ lev = previousLevel;
+
+ if (currentLevel > previousLevel)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+
+ if (lev != styler.LevelAt(currentLine))
+ styler.SetLevel(currentLine, lev);
+
+ currentLine++;
+ previousLevel = currentLevel;
+ }
+
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ styler.SetLevel(currentLine,
+ previousLevel
+ | (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
+}
+
+static const char * const erlangWordListDesc[] = {
+ "Erlang Reserved words",
+ "Erlang BIFs",
+ "Erlang Preprocessor",
+ "Erlang Module Attributes",
+ "Erlang Documentation",
+ "Erlang Documentation Macro",
+ 0
+};
+
+LexerModule lmErlang(
+ SCLEX_ERLANG,
+ ColouriseErlangDoc,
+ "erlang",
+ FoldErlangDoc,
+ erlangWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexFlagShip.cxx
+ ** Lexer for Harbour and FlagShip.
+ ** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)
+ **/
+// Copyright 2005 by Randy Butler
+// Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour)
+// Copyright 1998-2003 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
+
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch)
+{
+ return ch >= 0x80 ||
+ (isalnum(ch) || ch == '_');
+}
+
+static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler)
+{
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+
+ // property lexer.flagship.styling.within.preprocessor
+ // For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the
+ // initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.
+ bool stylingWithinPreprocessor = styler.GetPropertyInt("lexer.flagship.styling.within.preprocessor", 1) != 0;
+
+ CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
+
+ int visibleChars = 0;
+ int closeStringChar = 0;
+ int styleBeforeDCKeyword = SCE_FS_DEFAULT;
+ bool bEnableCode = initStyle < SCE_FS_DISABLEDCODE;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_FS_OPERATOR:
+ case SCE_FS_OPERATOR_C:
+ case SCE_FS_WORDOPERATOR:
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ break;
+ case SCE_FS_IDENTIFIER:
+ case SCE_FS_IDENTIFIER_C:
+ if (!IsAWordChar(sc.ch)) {
+ char s[64];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C);
+ } else if (bEnableCode && keywords3.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD3);
+ } else if (bEnableCode && keywords4.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD4);
+ }// Else, it is really an identifier...
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_NUMBER:
+ if (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ break;
+ case SCE_FS_NUMBER_C:
+ if (!IsAWordChar(sc.ch) && sc.ch != '.') {
+ sc.SetState(SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_CONSTANT:
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ break;
+ case SCE_FS_STRING:
+ case SCE_FS_STRING_C:
+ if (sc.ch == closeStringChar) {
+ sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C);
+ }
+ break;
+ case SCE_FS_STRINGEOL:
+ case SCE_FS_STRINGEOL_C:
+ if (sc.atLineStart) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_COMMENTDOC:
+ case SCE_FS_COMMENTDOC_C:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C;
+ sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_FS_COMMENT:
+ case SCE_FS_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ break;
+ case SCE_FS_COMMENTLINEDOC:
+ case SCE_FS_COMMENTLINEDOC_C:
+ if (sc.atLineStart) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C;
+ sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_FS_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) &&
+ sc.Match('*', '/')) {
+ sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (!setDoxygen.Contains(sc.ch)) {
+ char s[64];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) {
+ sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_FS_PREPROCESSOR:
+ case SCE_FS_PREPROCESSOR_C:
+ if (sc.atLineEnd) {
+ if (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ } else if (stylingWithinPreprocessor) {
+ if (IsASpaceOrTab(sc.ch)) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ } else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_DISABLEDCODE:
+ if (sc.ch == '#' && visibleChars == 0) {
+ sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
+ do { // Skip whitespace between # and preprocessor word
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.MatchIgnoreCase("pragma")) {
+ sc.Forward(6);
+ do { // Skip more whitespace until keyword
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
+ bEnableCode = true;
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ sc.Forward(sc.ch == '_' ? 8 : 6);
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ } else {
+ sc.ChangeState(SCE_FS_DISABLEDCODE);
+ }
+ } else {
+ sc.ChangeState(SCE_FS_DISABLEDCODE);
+ }
+ }
+ break;
+ case SCE_FS_DATE:
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_FS_STRINGEOL);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) {
+ if (bEnableCode &&
+ (sc.MatchIgnoreCase(".and.") || sc.MatchIgnoreCase(".not."))) {
+ sc.SetState(SCE_FS_WORDOPERATOR);
+ sc.Forward(4);
+ } else if (bEnableCode && sc.MatchIgnoreCase(".or.")) {
+ sc.SetState(SCE_FS_WORDOPERATOR);
+ sc.Forward(3);
+ } else if (bEnableCode &&
+ (sc.MatchIgnoreCase(".t.") || sc.MatchIgnoreCase(".f.") ||
+ (!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase("nil")))) {
+ sc.SetState(SCE_FS_CONSTANT);
+ sc.Forward(2);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C);
+ sc.Forward();
+ } else if (bEnableCode && sc.Match('&', '&')) {
+ sc.SetState(SCE_FS_COMMENTLINE);
+ sc.Forward();
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C);
+ sc.Forward();
+ } else if (bEnableCode && sc.ch == '*' && visibleChars == 0) {
+ sc.SetState(SCE_FS_COMMENT);
+ } else if (sc.ch == '\"' || sc.ch == '\'') {
+ sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
+ closeStringChar = sc.ch;
+ } else if (closeStringChar == '>' && sc.ch == '<') {
+ sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
+ do { // Skip whitespace between # and preprocessor word
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.MatchIgnoreCase("include")) {
+ if (stylingWithinPreprocessor) {
+ closeStringChar = '>';
+ }
+ } else if (sc.MatchIgnoreCase("pragma")) {
+ sc.Forward(6);
+ do { // Skip more whitespace until keyword
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.MatchIgnoreCase("begindump") || sc.MatchIgnoreCase("__cstream")) {
+ bEnableCode = false;
+ if (stylingWithinPreprocessor) {
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ sc.Forward(8);
+ sc.ForwardSetState(SCE_FS_DEFAULT_C);
+ } else {
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ }
+ } else if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
+ bEnableCode = true;
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ sc.Forward(sc.ch == '_' ? 8 : 6);
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ }
+ }
+ } else if (bEnableCode && sc.ch == '{') {
+ int p = 0;
+ int chSeek;
+ unsigned int endPos(startPos + length);
+ do { // Skip whitespace
+ chSeek = sc.GetRelative(++p);
+ } while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos));
+ if (chSeek == '^') {
+ sc.SetState(SCE_FS_DATE);
+ } else {
+ sc.SetState(SCE_FS_OPERATOR);
+ }
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C);
+ } else if (IsAWordChar(sc.ch)) {
+ sc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C);
+ } else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) {
+ sc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ closeStringChar = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldFlagShipDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler)
+{
+
+ int endPos = startPos + length;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0 && lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
+ char chNext = styler[startPos];
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+static const char * const FSWordListDesc[] = {
+ "Keywords Commands",
+ "Std Library Functions",
+ "Procedure, return, exit",
+ "Class (oop)",
+ "Doxygen keywords",
+ 0
+};
+
+LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexForth.cxx
+ ** Lexer for FORTH
+ **/
+// Copyright 1998-2003 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 IsAWordChar(int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+ ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
+ ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
+ ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
+ ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
+ ch == ')' );
+}
+
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+}
+
+static inline bool IsANumChar(int ch) {
+ return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
+}
+
+static inline bool IsASpaceChar(int ch) {
+ return (ch < 0x80) && isspace(ch);
+}
+
+static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
+ Accessor &styler) {
+
+ WordList &control = *keywordLists[0];
+ WordList &keyword = *keywordLists[1];
+ WordList &defword = *keywordLists[2];
+ WordList &preword1 = *keywordLists[3];
+ WordList &preword2 = *keywordLists[4];
+ WordList &strings = *keywordLists[5];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_FORTH_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_FORTH_DEFAULT);
+ }
+ }else if (sc.state == SCE_FORTH_COMMENT_ML) {
+ if (sc.ch == ')') {
+ sc.ForwardSetState(SCE_FORTH_DEFAULT);
+ }
+ }else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
+ // handle numbers here too, because what we thought was a number might
+ // turn out to be a keyword e.g. 2DUP
+ if (IsASpaceChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
+ if (control.InList(s)) {
+ sc.ChangeState(SCE_FORTH_CONTROL);
+ } else if (keyword.InList(s)) {
+ sc.ChangeState(SCE_FORTH_KEYWORD);
+ } else if (defword.InList(s)) {
+ sc.ChangeState(SCE_FORTH_DEFWORD);
+ } else if (preword1.InList(s)) {
+ sc.ChangeState(SCE_FORTH_PREWORD1);
+ } else if (preword2.InList(s)) {
+ sc.ChangeState(SCE_FORTH_PREWORD2);
+ } else if (strings.InList(s)) {
+ sc.ChangeState(SCE_FORTH_STRING);
+ newState = SCE_FORTH_STRING;
+ }
+ sc.SetState(newState);
+ }
+ if (sc.state == SCE_FORTH_NUMBER) {
+ if (IsASpaceChar(sc.ch)) {
+ sc.SetState(SCE_FORTH_DEFAULT);
+ } else if (!IsANumChar(sc.ch)) {
+ sc.ChangeState(SCE_FORTH_IDENTIFIER);
+ }
+ }
+ }else if (sc.state == SCE_FORTH_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_FORTH_DEFAULT);
+ }
+ }else if (sc.state == SCE_FORTH_LOCALE) {
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_FORTH_DEFAULT);
+ }
+ }else if (sc.state == SCE_FORTH_DEFWORD) {
+ if (IsASpaceChar(sc.ch)) {
+ sc.SetState(SCE_FORTH_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_FORTH_DEFAULT) {
+ if (sc.ch == '\\'){
+ sc.SetState(SCE_FORTH_COMMENT);
+ } else if (sc.ch == '(' &&
+ (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
+ (sc.atLineEnd || IsASpaceChar(sc.chNext))) {
+ sc.SetState(SCE_FORTH_COMMENT_ML);
+ } else if ( (sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
+ // number starting with $ is a hex number
+ sc.SetState(SCE_FORTH_NUMBER);
+ while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
+ sc.Forward();
+ } else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
+ // number starting with % is binary
+ sc.SetState(SCE_FORTH_NUMBER);
+ while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
+ sc.Forward();
+ } else if ( isascii(sc.ch) &&
+ (isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
+ ){
+ sc.SetState(SCE_FORTH_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_FORTH_IDENTIFIER);
+ } else if (sc.ch == '{') {
+ sc.SetState(SCE_FORTH_LOCALE);
+ } else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
+ // highlight word definitions e.g. : GCD ( n n -- n ) ..... ;
+ // ^ ^^^
+ sc.SetState(SCE_FORTH_DEFWORD);
+ while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
+ sc.Forward();
+ } else if (sc.ch == ';' &&
+ (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
+ (sc.atLineEnd || IsASpaceChar(sc.chNext)) ) {
+ // mark the ';' that ends a word
+ sc.SetState(SCE_FORTH_DEFWORD);
+ sc.ForwardSetState(SCE_FORTH_DEFAULT);
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+static void FoldForthDoc(unsigned int, int, int, WordList *[],
+ Accessor &) {
+}
+
+static const char * const forthWordLists[] = {
+ "control keywords",
+ "keywords",
+ "definition words",
+ "prewords with one argument",
+ "prewords with two arguments",
+ "string definition keywords",
+ 0,
+ };
+
+LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
+
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexFortran.cxx
+ ** Lexer for Fortran.
+ ** Writen by Chuan-jian Shen, Last changed Sep. 2003
+ **/
+// 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
+}
+/**********************************************/
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch));
+}
+/***************************************/
+inline bool IsABlank(unsigned int ch) {
+ return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
+}
+/***************************************/
+inline bool IsALineEnd(char ch) {
+ return ((ch == '\n') || (ch == '\r')) ;
+}
+/***************************************/
+unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) {
+ while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;
+ if (styler.SafeGetCharAt(pos) == '\n') pos++;
+ while (IsABlank(styler.SafeGetCharAt(pos++))) continue;
+ char chCur = styler.SafeGetCharAt(pos);
+ if (chCur == '&') {
+ while (IsABlank(styler.SafeGetCharAt(++pos))) continue;
+ return pos;
+ } else {
+ return pos;
+ }
+}
+/***************************************/
+static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler, bool isFixFormat) {
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ /***************************************/
+ int posLineStart = 0, numNonBlank = 0, prevState = 0;
+ int endPos = startPos + length;
+ /***************************************/
+ // backtrack to the nearest keyword
+ while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
+ startPos--;
+ }
+ startPos = styler.LineStart(styler.GetLine(startPos));
+ initStyle = styler.StyleAt(startPos - 1);
+ StyleContext sc(startPos, endPos-startPos, initStyle, styler);
+ /***************************************/
+ for (; sc.More(); sc.Forward()) {
+ // remember the start position of the line
+ if (sc.atLineStart) {
+ posLineStart = sc.currentPos;
+ numNonBlank = 0;
+ sc.SetState(SCE_F_DEFAULT);
+ }
+ if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
+ /***********************************************/
+ // Handle the fix format generically
+ int toLineStart = sc.currentPos - posLineStart;
+ if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) {
+ if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
+ if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
+ sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
+ sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") ||
+ sc.chNext == '$') {
+ sc.SetState(SCE_F_PREPROCESSOR);
+ } else {
+ sc.SetState(SCE_F_COMMENT);
+ }
+
+ while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
+ } else if (toLineStart >= 72) {
+ sc.SetState(SCE_F_COMMENT);
+ while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
+ } else if (toLineStart < 5) {
+ if (IsADigit(sc.ch))
+ sc.SetState(SCE_F_LABEL);
+ else
+ sc.SetState(SCE_F_DEFAULT);
+ } else if (toLineStart == 5) {
+ //if (!IsASpace(sc.ch) && sc.ch != '0') {
+ if (sc.ch != '\r' && sc.ch != '\n') {
+ sc.SetState(SCE_F_CONTINUATION);
+ if (!IsASpace(sc.ch) && sc.ch != '0')
+ sc.ForwardSetState(prevState);
+ } else
+ sc.SetState(SCE_F_DEFAULT);
+ }
+ continue;
+ }
+ /***************************************/
+ // Hanndle preprocessor directives
+ if (sc.ch == '#' && numNonBlank == 1)
+ {
+ sc.SetState(SCE_F_PREPROCESSOR);
+ while (!sc.atLineEnd && sc.More())
+ sc.Forward(); // Until line end
+ }
+ /***************************************/
+ // Handle line continuation generically.
+ if (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) {
+ char chTemp = ' ';
+ int j = 1;
+ while (IsABlank(chTemp) && j<132) {
+ chTemp = static_cast<char>(sc.GetRelative(j));
+ j++;
+ }
+ if (chTemp == '!') {
+ sc.SetState(SCE_F_CONTINUATION);
+ if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
+ } else if (chTemp == '\r' || chTemp == '\n') {
+ int currentState = sc.state;
+ sc.SetState(SCE_F_CONTINUATION);
+ sc.ForwardSetState(SCE_F_DEFAULT);
+ while (IsASpace(sc.ch) && sc.More()) sc.Forward();
+ if (sc.ch == '&') {
+ sc.SetState(SCE_F_CONTINUATION);
+ sc.Forward();
+ }
+ sc.SetState(currentState);
+ }
+ }
+ /***************************************/
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_F_OPERATOR) {
+ sc.SetState(SCE_F_DEFAULT);
+ } else if (sc.state == SCE_F_NUMBER) {
+ if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) {
+ sc.SetState(SCE_F_DEFAULT);
+ }
+ } else if (sc.state == SCE_F_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_F_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_F_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_F_WORD3);
+ }
+ sc.SetState(SCE_F_DEFAULT);
+ }
+ } else if (sc.state == SCE_F_COMMENT || sc.state == SCE_F_PREPROCESSOR) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_F_DEFAULT);
+ }
+ } else if (sc.state == SCE_F_STRING1) {
+ prevState = sc.state;
+ if (sc.ch == '\'') {
+ if (sc.chNext == '\'') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_F_DEFAULT);
+ prevState = SCE_F_DEFAULT;
+ }
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_F_STRINGEOL);
+ sc.ForwardSetState(SCE_F_DEFAULT);
+ }
+ } else if (sc.state == SCE_F_STRING2) {
+ prevState = sc.state;
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_F_STRINGEOL);
+ sc.ForwardSetState(SCE_F_DEFAULT);
+ } else if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_F_DEFAULT);
+ prevState = SCE_F_DEFAULT;
+ }
+ }
+ } else if (sc.state == SCE_F_OPERATOR2) {
+ if (sc.ch == '.') {
+ sc.ForwardSetState(SCE_F_DEFAULT);
+ }
+ } else if (sc.state == SCE_F_CONTINUATION) {
+ sc.SetState(SCE_F_DEFAULT);
+ } else if (sc.state == SCE_F_LABEL) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_F_DEFAULT);
+ } else {
+ if (isFixFormat && sc.currentPos-posLineStart > 4)
+ sc.SetState(SCE_F_DEFAULT);
+ else if (numNonBlank > 5)
+ sc.SetState(SCE_F_DEFAULT);
+ }
+ }
+ /***************************************/
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_F_DEFAULT) {
+ if (sc.ch == '!') {
+ if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
+ sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
+ sc.SetState(SCE_F_PREPROCESSOR);
+ } else {
+ sc.SetState(SCE_F_COMMENT);
+ }
+ } else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) {
+ sc.SetState(SCE_F_LABEL);
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_F_NUMBER);
+ } else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
+ tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
+ sc.SetState(SCE_F_NUMBER);
+ sc.Forward();
+ } else if (sc.ch == '.' && isalpha(sc.chNext)) {
+ sc.SetState(SCE_F_OPERATOR2);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_F_IDENTIFIER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_F_STRING2);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_F_STRING1);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_F_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+/***************************************/
+// To determine the folding level depending on keywords
+static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
+ int lev = 0;
+ if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
+ return -1;
+ if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
+ || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
+ || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
+ || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
+ || strcmp(s, "module") == 0 || strcmp(s, "program") == 0
+ || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
+ || (strcmp(s, "type") == 0 && chNextNonBlank != '(')
+ || strcmp(s, "critical") == 0){
+ if (strcmp(prevWord, "end") == 0)
+ lev = 0;
+ else
+ lev = 1;
+ } else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
+ || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
+ || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
+ || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
+ || strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0
+ || strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
+ || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
+ || strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
+ || strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0
+ || (strcmp(s, "procedure") == 0 && strcmp(prevWord, "module") == 0) ) { // Take care of the "module procedure" statement
+ lev = -1;
+ } else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
+ lev = 0;
+ } else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is
+ lev = -1;
+ }
+ return lev;
+}
+// Folding the code
+static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
+ Accessor &styler, bool isFixFormat) {
+ //
+ // bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ // Do not know how to fold the comment at the moment.
+ //
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ char chNextNonBlank;
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ /***************************************/
+ int lastStart = 0;
+ char prevWord[32] = "";
+ char Label[6] = "";
+ // Variables for do label folding.
+ static int doLabels[100];
+ static int posLabel=-1;
+ /***************************************/
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ chNextNonBlank = chNext;
+ unsigned int j=i+1;
+ while(IsABlank(chNextNonBlank) && j<endPos) {
+ j ++ ;
+ chNextNonBlank = styler.SafeGetCharAt(j);
+ }
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ //
+ if (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT || stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
+ // Store last word and label start point.
+ lastStart = i;
+ }
+ /***************************************/
+ if (style == SCE_F_WORD) {
+ if(iswordchar(ch) && !iswordchar(chNext)) {
+ char s[32];
+ unsigned int k;
+ for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
+ s[k] = static_cast<char>(tolower(styler[lastStart+k]));
+ }
+ s[k] = '\0';
+ // Handle the forall and where statement and structure.
+ if (strcmp(s, "forall") == 0 || strcmp(s, "where") == 0) {
+ if (strcmp(prevWord, "end") != 0) {
+ j = i + 1;
+ char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j);
+ // Find the position of the first (
+ while (ch1 != chBrace && j<endPos) {
+ j++;
+ ch1 = styler.SafeGetCharAt(j);
+ }
+ char styBrace = styler.StyleAt(j);
+ int depth = 1;
+ char chAtPos;
+ char styAtPos;
+ while (j<endPos) {
+ j++;
+ chAtPos = styler.SafeGetCharAt(j);
+ styAtPos = styler.StyleAt(j);
+ if (styAtPos == styBrace) {
+ if (chAtPos == chBrace) depth++;
+ if (chAtPos == chSeek) depth--;
+ if (depth == 0) break;
+ }
+ }
+ while (j<endPos) {
+ j++;
+ chAtPos = styler.SafeGetCharAt(j);
+ styAtPos = styler.StyleAt(j);
+ if (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos)) continue;
+ if (isFixFormat) {
+ if (!IsALineEnd(chAtPos)) {
+ break;
+ } else {
+ if (lineCurrent < styler.GetLine(styler.Length()-1)) {
+ j = styler.LineStart(lineCurrent+1);
+ if (styler.StyleAt(j+5) == SCE_F_CONTINUATION) {
+ j += 5;
+ continue;
+ } else {
+ levelCurrent++;
+ break;
+ }
+ }
+ }
+ } else {
+ if (chAtPos == '&' && styler.StyleAt(j) == SCE_F_CONTINUATION) {
+ j = GetContinuedPos(j+1, styler);
+ continue;
+ } else if (IsALineEnd(chAtPos)) {
+ levelCurrent ++;
+ break;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ levelCurrent += classifyFoldPointFortran(s, prevWord, chNextNonBlank);
+ // Store the do Labels into array
+ if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) {
+ unsigned int k = 0;
+ for (i=j; (i<j+5 && i<endPos); i++) {
+ ch = styler.SafeGetCharAt(i);
+ if (IsADigit(ch))
+ Label[k++] = ch;
+ else
+ break;
+ }
+ Label[k] = '\0';
+ posLabel ++;
+ doLabels[posLabel] = atoi(Label);
+ }
+ }
+ strcpy(prevWord, s);
+ }
+ } else if (style == SCE_F_LABEL) {
+ if(IsADigit(ch) && !IsADigit(chNext)) {
+ for(j = 0; ( j < 5 ) && ( j < i-lastStart+1 ); j++) {
+ ch = styler.SafeGetCharAt(lastStart + j);
+ if (IsADigit(ch) && styler.StyleAt(lastStart+j) == SCE_F_LABEL)
+ Label[j] = ch;
+ else
+ break;
+ }
+ Label[j] = '\0';
+ while (doLabels[posLabel] == atoi(Label) && posLabel > -1) {
+ levelCurrent--;
+ posLabel--;
+ }
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ strcpy(prevWord, "");
+ }
+ /***************************************/
+ if (!isspacechar(ch)) visibleChars++;
+ }
+ /***************************************/
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+/***************************************/
+static const char * const FortranWordLists[] = {
+ "Primary keywords and identifiers",
+ "Intrinsic functions",
+ "Extended and user defined functions",
+ 0,
+};
+/***************************************/
+static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+/***************************************/
+static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+/***************************************/
+static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ FoldFortranDoc(startPos, length, initStyle,styler, false);
+}
+/***************************************/
+static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ FoldFortranDoc(startPos, length, initStyle,styler, true);
+}
+/***************************************/
+LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists);
+LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexGAP.cxx
+ ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
+ ** http://www.gap-system.org
+ **/
+// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
+// 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 IsGAPOperator(char ch) {
+ if (isascii(ch) && isalnum(ch)) return false;
+ if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
+ ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
+ ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
+ ch == ')' || ch == ';' || ch == '[' || ch == ']' ||
+ ch == '{' || ch == '}' || ch == ':' )
+ return true;
+ return false;
+}
+
+static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(styler[start + i]);
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static void ColouriseGAPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords1 = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ // Prevent SCE_GAP_STRINGEOL from leaking back to previous line
+ if ( sc.atLineStart ) {
+ if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);
+ if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);
+ }
+
+ // Handle line continuation generically
+ if (sc.ch == '\\' ) {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate
+ switch (sc.state) {
+ case SCE_GAP_OPERATOR :
+ sc.SetState(SCE_GAP_DEFAULT);
+ break;
+
+ case SCE_GAP_NUMBER :
+ if (!IsADigit(sc.ch)) {
+ if (sc.ch == '\\') {
+ if (!sc.atLineEnd) {
+ if (!IsADigit(sc.chNext)) {
+ sc.Forward();
+ sc.ChangeState(SCE_GAP_IDENTIFIER);
+ }
+ }
+ } else if (isalpha(sc.ch) || sc.ch == '_') {
+ sc.ChangeState(SCE_GAP_IDENTIFIER);
+ }
+ else sc.SetState(SCE_GAP_DEFAULT);
+ }
+ break;
+
+ case SCE_GAP_IDENTIFIER :
+ if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {
+ if (sc.ch == '\\') sc.Forward();
+ else {
+ char s[1000];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords1.InList(s)) {
+ sc.ChangeState(SCE_GAP_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_GAP_KEYWORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_GAP_KEYWORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_GAP_KEYWORD4);
+ }
+ sc.SetState(SCE_GAP_DEFAULT);
+ }
+ }
+ break;
+
+ case SCE_GAP_COMMENT :
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_GAP_DEFAULT);
+ }
+ break;
+
+ case SCE_GAP_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_GAP_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_GAP_DEFAULT);
+ }
+ break;
+
+ case SCE_GAP_CHAR:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_GAP_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_GAP_DEFAULT);
+ }
+ break;
+
+ case SCE_GAP_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_GAP_DEFAULT);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered
+ if (sc.state == SCE_GAP_DEFAULT) {
+ if (IsGAPOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_GAP_OPERATOR);
+ }
+ else if (IsADigit(sc.ch)) {
+ sc.SetState(SCE_GAP_NUMBER);
+ } else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') {
+ sc.SetState(SCE_GAP_IDENTIFIER);
+ if (sc.ch == '\\') sc.Forward();
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_GAP_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_GAP_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_GAP_CHAR);
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+static int ClassifyFoldPointGAP(const char* s) {
+ int level = 0;
+ if (strcmp(s, "function") == 0 ||
+ strcmp(s, "do") == 0 ||
+ strcmp(s, "if") == 0 ||
+ strcmp(s, "repeat") == 0 ) {
+ level = 1;
+ } else if (strcmp(s, "end") == 0 ||
+ strcmp(s, "od") == 0 ||
+ strcmp(s, "fi") == 0 ||
+ strcmp(s, "until") == 0 ) {
+ level = -1;
+ }
+ return level;
+}
+
+static void FoldGAPDoc( unsigned int startPos, int length, int initStyle, WordList** , Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+
+ int lastStart = 0;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) {
+ // Store last word start point.
+ lastStart = i;
+ }
+
+ if (stylePrev == SCE_GAP_KEYWORD) {
+ if(iswordchar(ch) && !iswordchar(chNext)) {
+ char s[100];
+ GetRange(lastStart, i, styler, s, sizeof(s));
+ levelCurrent += ClassifyFoldPointGAP(s);
+ }
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const GAPWordListDesc[] = {
+ "Keywords 1",
+ "Keywords 2",
+ "Keywords 3 (unused)",
+ "Keywords 4 (unused)",
+ 0
+};
+
+LexerModule lmGAP(
+ SCLEX_GAP,
+ ColouriseGAPDoc,
+ "gap",
+ FoldGAPDoc,
+ GAPWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+/*
+This is the Lexer for Gui4Cli, included in SciLexer.dll
+- by d. Keletsekis, 2/10/2003
+
+To add to SciLexer.dll:
+1. Add the values below to INCLUDE\Scintilla.iface
+2. Run the include/HFacer.py script
+3. Run the src/lexGen.py script
+
+val SCE_GC_DEFAULT=0
+val SCE_GC_COMMENTLINE=1
+val SCE_GC_COMMENTBLOCK=2
+val SCE_GC_GLOBAL=3
+val SCE_GC_EVENT=4
+val SCE_GC_ATTRIBUTE=5
+val SCE_GC_CONTROL=6
+val SCE_GC_COMMAND=7
+val SCE_GC_STRING=8
+val SCE_GC_OPERATOR=9
+*/
+
+#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
+
+#define debug Platform::DebugPrintf
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+}
+
+inline bool isGCOperator(int ch)
+{ if (isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '%' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '>' ||
+ ch == ',' || ch == ';' || ch == ':')
+ return true;
+ return false;
+}
+
+#define isSpace(x) ((x)==' ' || (x)=='\t')
+#define isNL(x) ((x)=='\n' || (x)=='\r')
+#define isSpaceOrNL(x) (isSpace(x) || isNL(x))
+#define BUFFSIZE 500
+#define isFoldPoint(x) ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)
+
+static void colorFirstWord(WordList *keywordlists[], Accessor &styler,
+ StyleContext *sc, char *buff, int length, int)
+{
+ int c = 0;
+ while (sc->More() && isSpaceOrNL(sc->ch))
+ { sc->Forward();
+ }
+ styler.ColourTo(sc->currentPos - 1, sc->state);
+
+ if (!IsAWordChar(sc->ch)) // comment, marker, etc..
+ return;
+
+ while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))
+ { buff[c] = static_cast<char>(sc->ch);
+ ++c; sc->Forward();
+ }
+ buff[c] = '\0';
+ char *p = buff;
+ while (*p) // capitalize..
+ { if (islower(*p)) *p = static_cast<char>(toupper(*p));
+ ++p;
+ }
+
+ WordList &kGlobal = *keywordlists[0]; // keyword lists set by the user
+ WordList &kEvent = *keywordlists[1];
+ WordList &kAttribute = *keywordlists[2];
+ WordList &kControl = *keywordlists[3];
+ WordList &kCommand = *keywordlists[4];
+
+ int state = 0;
+ // int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
+ // debug ("line = %d, level = %d", line, level);
+
+ if (kGlobal.InList(buff)) state = SCE_GC_GLOBAL;
+ else if (kAttribute.InList(buff)) state = SCE_GC_ATTRIBUTE;
+ else if (kControl.InList(buff)) state = SCE_GC_CONTROL;
+ else if (kCommand.InList(buff)) state = SCE_GC_COMMAND;
+ else if (kEvent.InList(buff)) state = SCE_GC_EVENT;
+
+ if (state)
+ { sc->ChangeState(state);
+ styler.ColourTo(sc->currentPos - 1, sc->state);
+ sc->ChangeState(SCE_GC_DEFAULT);
+ }
+ else
+ { sc->ChangeState(SCE_GC_DEFAULT);
+ styler.ColourTo(sc->currentPos - 1, sc->state);
+ }
+}
+
+// Main colorizing function called by Scintilla
+static void
+ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler)
+{
+ styler.StartAt(startPos);
+
+ int quotestart = 0, oldstate, currentline = styler.GetLine(startPos);
+ styler.StartSegment(startPos);
+ bool noforward;
+ char buff[BUFFSIZE+1]; // buffer for command name
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ buff[0] = '\0'; // cbuff = 0;
+
+ if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..
+ colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
+
+ while (sc.More())
+ { noforward = 0;
+
+ switch (sc.ch)
+ {
+ case '/':
+ if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)
+ break;
+ if (sc.chNext == '/') // line comment
+ { sc.SetState (SCE_GC_COMMENTLINE);
+ sc.Forward();
+ styler.ColourTo(sc.currentPos, sc.state);
+ }
+ else if (sc.chNext == '*') // block comment
+ { sc.SetState(SCE_GC_COMMENTBLOCK);
+ sc.Forward();
+ styler.ColourTo(sc.currentPos, sc.state);
+ }
+ else
+ styler.ColourTo(sc.currentPos, sc.state);
+ break;
+
+ case '*': // end of comment block, or operator..
+ if (sc.state == SCE_GC_STRING)
+ break;
+ if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')
+ { sc.Forward();
+ styler.ColourTo(sc.currentPos, sc.state);
+ sc.ChangeState (SCE_GC_DEFAULT);
+ }
+ else
+ styler.ColourTo(sc.currentPos, sc.state);
+ break;
+
+ case '\'': case '\"': // strings..
+ if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)
+ break;
+ if (sc.state == SCE_GC_STRING)
+ { if (sc.ch == quotestart) // match same quote char..
+ { styler.ColourTo(sc.currentPos, sc.state);
+ sc.ChangeState(SCE_GC_DEFAULT);
+ quotestart = 0;
+ } }
+ else
+ { styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_GC_STRING);
+ quotestart = sc.ch;
+ }
+ break;
+
+ case ';': // end of commandline character
+ if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
+ sc.state != SCE_GC_STRING)
+ {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
+ sc.ChangeState(SCE_GC_DEFAULT);
+ sc.Forward();
+ colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
+ noforward = 1; // don't move forward - already positioned at next char..
+ }
+ break;
+
+ case '+': case '-': case '=': case '!': // operators..
+ case '<': case '>': case '&': case '|': case '$':
+ if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
+ sc.state != SCE_GC_STRING)
+ {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
+ sc.ChangeState(SCE_GC_DEFAULT);
+ }
+ break;
+
+ case '\\': // escape - same as operator, but also mark in strings..
+ if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)
+ {
+ oldstate = sc.state;
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward(); // mark also the next char..
+ styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
+ sc.ChangeState(oldstate);
+ }
+ break;
+
+ case '\n': case '\r':
+ ++currentline;
+ if (sc.state == SCE_GC_COMMENTLINE)
+ { styler.ColourTo(sc.currentPos, sc.state);
+ sc.ChangeState (SCE_GC_DEFAULT);
+ }
+ else if (sc.state != SCE_GC_COMMENTBLOCK)
+ { colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
+ noforward = 1; // don't move forward - already positioned at next char..
+ }
+ break;
+
+// case ' ': case '\t':
+// default :
+ }
+
+ if (!noforward) sc.Forward();
+
+ }
+ sc.Complete();
+}
+
+// Main folding function called by Scintilla - (based on props (.ini) files function)
+static void FoldGui4Cli(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler)
+{
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ bool headerPoint = false;
+
+ for (unsigned int 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_GC_EVENT || style == SCE_GC_GLOBAL)
+ { headerPoint = true; // fold at events and globals
+ }
+
+ if (atEOL)
+ { int lev = SC_FOLDLEVELBASE+1;
+
+ if (headerPoint)
+ lev = SC_FOLDLEVELBASE;
+
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+
+ if (headerPoint)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+
+ if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct
+ { styler.SetLevel(lineCurrent, lev);
+ }
+
+ lineCurrent++; // re-initialize our flags
+ visibleChars = 0;
+ headerPoint = false;
+ }
+
+ if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))
+ visibleChars++;
+ }
+
+ int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, lev | flagsNext);
+}
+
+// I have no idea what these are for.. probably accessible by some message.
+static const char * const gui4cliWordListDesc[] = {
+ "Globals", "Events", "Attributes", "Control", "Commands",
+ 0
+};
+
+// Declare language & pass our function pointers to Scintilla
+LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc);
+
+#undef debug
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexHTML.cxx
+ ** Lexer for HTML.
+ **/
+// Copyright 1998-2005 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
+
+#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
+#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
+#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
+
+enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };
+enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+inline bool IsOperator(int ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
+ ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
+ ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
+ ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
+ ch == '?' || ch == '!' || ch == '.' || ch == '~')
+ return true;
+ return false;
+}
+
+static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
+ unsigned int i = 0;
+ for (; (i < end - start + 1) && (i < len-1); i++) {
+ s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
+ }
+ s[i] = '\0';
+}
+
+static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
+
+ unsigned int i = 0;
+ for (; i < sLen-1; i++) {
+ char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
+ if ((i == 0) && !IsAWordStart(ch))
+ break;
+ if ((i > 0) && !IsAWordChar(ch))
+ break;
+ s[i] = ch;
+ }
+ s[i] = '\0';
+
+ return s;
+}
+
+static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
+ //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
+ if (strstr(s, "src")) // External script
+ return eScriptNone;
+ if (strstr(s, "vbs"))
+ return eScriptVBS;
+ if (strstr(s, "pyth"))
+ return eScriptPython;
+ if (strstr(s, "javas"))
+ return eScriptJS;
+ if (strstr(s, "jscr"))
+ return eScriptJS;
+ if (strstr(s, "php"))
+ return eScriptPHP;
+ if (strstr(s, "xml")) {
+ const char *xml = strstr(s, "xml");
+ for (const char *t=s; t<xml; t++) {
+ if (!IsASpace(*t)) {
+ return prevValue;
+ }
+ }
+ return eScriptXML;
+ }
+
+ return prevValue;
+}
+
+static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) {
+ int iResult = 0;
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
+ if (0 == strncmp(s, "php", 3)) {
+ iResult = 3;
+ }
+
+ return iResult;
+}
+
+static script_type ScriptOfState(int state) {
+ if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
+ return eScriptPython;
+ } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
+ return eScriptVBS;
+ } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
+ return eScriptJS;
+ } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) {
+ return eScriptPHP;
+ } else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
+ return eScriptSGML;
+ } else if (state == SCE_H_SGML_BLOCK_DEFAULT) {
+ return eScriptSGMLblock;
+ } else {
+ return eScriptNone;
+ }
+}
+
+static int statePrintForState(int state, script_mode inScriptType) {
+ int StateToPrint = state;
+
+ if (state >= SCE_HJ_START) {
+ if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
+ StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
+ } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
+ StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
+ } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
+ StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
+ }
+ }
+
+ return StateToPrint;
+}
+
+static int stateForPrintState(int StateToPrint) {
+ int state;
+
+ if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) {
+ state = StateToPrint - SCE_HA_PYTHON;
+ } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {
+ state = StateToPrint - SCE_HA_VBS;
+ } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) {
+ state = StateToPrint - SCE_HA_JS;
+ } else {
+ state = StateToPrint;
+ }
+
+ return state;
+}
+
+static inline bool IsNumber(unsigned int start, Accessor &styler) {
+ return IsADigit(styler[start]) || (styler[start] == '.') ||
+ (styler[start] == '-') || (styler[start] == '#');
+}
+
+static inline bool isStringState(int state) {
+ bool bResult;
+
+ switch (state) {
+ case SCE_HJ_DOUBLESTRING:
+ case SCE_HJ_SINGLESTRING:
+ case SCE_HJA_DOUBLESTRING:
+ case SCE_HJA_SINGLESTRING:
+ case SCE_HB_STRING:
+ case SCE_HBA_STRING:
+ case SCE_HP_STRING:
+ case SCE_HP_CHARACTER:
+ case SCE_HP_TRIPLE:
+ case SCE_HP_TRIPLEDOUBLE:
+ case SCE_HPA_STRING:
+ case SCE_HPA_CHARACTER:
+ case SCE_HPA_TRIPLE:
+ case SCE_HPA_TRIPLEDOUBLE:
+ case SCE_HPHP_HSTRING:
+ case SCE_HPHP_SIMPLESTRING:
+ case SCE_HPHP_HSTRING_VARIABLE:
+ case SCE_HPHP_COMPLEX_VARIABLE:
+ bResult = true;
+ break;
+ default :
+ bResult = false;
+ break;
+ }
+ return bResult;
+}
+
+static inline bool stateAllowsTermination(int state) {
+ bool allowTermination = !isStringState(state);
+ if (allowTermination) {
+ switch (state) {
+ case SCE_HB_COMMENTLINE:
+ case SCE_HPHP_COMMENT:
+ case SCE_HP_COMMENTLINE:
+ case SCE_HPA_COMMENTLINE:
+ allowTermination = false;
+ }
+ }
+ return allowTermination;
+}
+
+// not really well done, since it's only comments that should lex the %> and <%
+static inline bool isCommentASPState(int state) {
+ bool bResult;
+
+ switch (state) {
+ case SCE_HJ_COMMENT:
+ case SCE_HJ_COMMENTLINE:
+ case SCE_HJ_COMMENTDOC:
+ case SCE_HB_COMMENTLINE:
+ case SCE_HP_COMMENTLINE:
+ case SCE_HPHP_COMMENT:
+ case SCE_HPHP_COMMENTLINE:
+ bResult = true;
+ break;
+ default :
+ bResult = false;
+ break;
+ }
+ return bResult;
+}
+
+static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+ bool wordIsNumber = IsNumber(start, styler);
+ char chAttr = SCE_H_ATTRIBUTEUNKNOWN;
+ if (wordIsNumber) {
+ chAttr = SCE_H_NUMBER;
+ } else {
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
+ if (keywords.InList(s))
+ chAttr = SCE_H_ATTRIBUTE;
+ }
+ if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords)
+ // No keywords -> all are known
+ chAttr = SCE_H_ATTRIBUTE;
+ styler.ColourTo(end, chAttr);
+}
+
+static int classifyTagHTML(unsigned int start, unsigned int end,
+ WordList &keywords, Accessor &styler, bool &tagDontFold,
+ bool caseSensitive, bool isXml, bool allowScripts) {
+ char withSpace[30 + 2] = " ";
+ const char *s = withSpace + 1;
+ // Copy after the '<'
+ unsigned int i = 1;
+ for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
+ char ch = styler[cPos];
+ if ((ch != '<') && (ch != '/')) {
+ withSpace[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch));
+ }
+ }
+
+ //The following is only a quick hack, to see if this whole thing would work
+ //we first need the tagname with a trailing space...
+ withSpace[i] = ' ';
+ withSpace[i+1] = '\0';
+
+ // if the current language is XML, I can fold any tag
+ // if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)
+ //...to find it in the list of no-container-tags
+ tagDontFold = (!isXml) && (NULL != strstr(" area base basefont br col command embed frame hr img input isindex keygen link meta param source track wbr ", withSpace));
+
+ //now we can remove the trailing space
+ withSpace[i] = '\0';
+
+ // No keywords -> all are known
+ char chAttr = SCE_H_TAGUNKNOWN;
+ if (s[0] == '!') {
+ chAttr = SCE_H_SGML_DEFAULT;
+ } else if (!keywords || keywords.InList(s)) {
+ chAttr = SCE_H_TAG;
+ }
+ styler.ColourTo(end, chAttr);
+ if (chAttr == SCE_H_TAG) {
+ if (allowScripts && 0 == strcmp(s, "script")) {
+ // check to see if this is a self-closing tag by sniffing ahead
+ bool isSelfClose = false;
+ for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
+ char ch = styler.SafeGetCharAt(cPos, '\0');
+ if (ch == '\0' || ch == '>')
+ break;
+ else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') {
+ isSelfClose = true;
+ break;
+ }
+ }
+
+ // do not enter a script state if the tag self-closed
+ if (!isSelfClose)
+ chAttr = SCE_H_SCRIPT;
+ } else if (!isXml && 0 == strcmp(s, "comment")) {
+ chAttr = SCE_H_COMMENT;
+ }
+ }
+ return chAttr;
+}
+
+static void classifyWordHTJS(unsigned int start, unsigned int end,
+ WordList &keywords, Accessor &styler, script_mode inScriptType) {
+ char s[30 + 1];
+ unsigned int i = 0;
+ for (; i < end - start + 1 && i < 30; i++) {
+ s[i] = styler[start + i];
+ }
+ s[i] = '\0';
+
+ char chAttr = SCE_HJ_WORD;
+ bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
+ if (wordIsNumber) {
+ chAttr = SCE_HJ_NUMBER;
+ } else if (keywords.InList(s)) {
+ chAttr = SCE_HJ_KEYWORD;
+ }
+ styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
+}
+
+static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) {
+ char chAttr = SCE_HB_IDENTIFIER;
+ bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
+ if (wordIsNumber)
+ chAttr = SCE_HB_NUMBER;
+ else {
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
+ if (keywords.InList(s)) {
+ chAttr = SCE_HB_WORD;
+ if (strcmp(s, "rem") == 0)
+ chAttr = SCE_HB_COMMENTLINE;
+ }
+ }
+ styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
+ if (chAttr == SCE_HB_COMMENTLINE)
+ return SCE_HB_COMMENTLINE;
+ else
+ return SCE_HB_DEFAULT;
+}
+
+static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType, bool isMako) {
+ bool wordIsNumber = IsADigit(styler[start]);
+ char s[30 + 1];
+ unsigned int i = 0;
+ for (; i < end - start + 1 && i < 30; i++) {
+ s[i] = styler[start + i];
+ }
+ s[i] = '\0';
+ char chAttr = SCE_HP_IDENTIFIER;
+ if (0 == strcmp(prevWord, "class"))
+ chAttr = SCE_HP_CLASSNAME;
+ else if (0 == strcmp(prevWord, "def"))
+ chAttr = SCE_HP_DEFNAME;
+ else if (wordIsNumber)
+ chAttr = SCE_HP_NUMBER;
+ else if (keywords.InList(s))
+ chAttr = SCE_HP_WORD;
+ else if (isMako && 0 == strcmp(s, "block"))
+ chAttr = SCE_HP_WORD;
+ styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
+ strcpy(prevWord, s);
+}
+
+// Update the word colour to default or keyword
+// Called when in a PHP word
+static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+ char chAttr = SCE_HPHP_DEFAULT;
+ bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1]));
+ if (wordIsNumber)
+ chAttr = SCE_HPHP_NUMBER;
+ else {
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
+ if (keywords.InList(s))
+ chAttr = SCE_HPHP_WORD;
+ }
+ styler.ColourTo(end, chAttr);
+}
+
+static bool isWordHSGML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+ char s[30 + 1];
+ unsigned int i = 0;
+ for (; i < end - start + 1 && i < 30; i++) {
+ s[i] = styler[start + i];
+ }
+ s[i] = '\0';
+ return keywords.InList(s);
+}
+
+static bool isWordCdata(unsigned int start, unsigned int end, Accessor &styler) {
+ char s[30 + 1];
+ unsigned int i = 0;
+ for (; i < end - start + 1 && i < 30; i++) {
+ s[i] = styler[start + i];
+ }
+ s[i] = '\0';
+ return (0 == strcmp(s, "[CDATA["));
+}
+
+// Return the first state to reach when entering a scripting language
+static int StateForScript(script_type scriptLanguage) {
+ int Result;
+ switch (scriptLanguage) {
+ case eScriptVBS:
+ Result = SCE_HB_START;
+ break;
+ case eScriptPython:
+ Result = SCE_HP_START;
+ break;
+ case eScriptPHP:
+ Result = SCE_HPHP_DEFAULT;
+ break;
+ case eScriptXML:
+ Result = SCE_H_TAGUNKNOWN;
+ break;
+ case eScriptSGML:
+ Result = SCE_H_SGML_DEFAULT;
+ break;
+ case eScriptComment:
+ Result = SCE_H_COMMENT;
+ break;
+ default :
+ Result = SCE_HJ_START;
+ break;
+ }
+ return Result;
+}
+
+static inline bool ishtmlwordchar(int ch) {
+ return !isascii(ch) ||
+ (isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
+}
+
+static inline bool issgmlwordchar(int ch) {
+ return !isascii(ch) ||
+ (isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
+}
+
+static inline bool IsPhpWordStart(int ch) {
+ return (isascii(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f);
+}
+
+static inline bool IsPhpWordChar(int ch) {
+ return IsADigit(ch) || IsPhpWordStart(ch);
+}
+
+static bool InTagState(int state) {
+ return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
+ state == SCE_H_SCRIPT ||
+ state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN ||
+ state == SCE_H_NUMBER || state == SCE_H_OTHER ||
+ state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING;
+}
+
+static bool IsCommentState(const int state) {
+ return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
+}
+
+static bool IsScriptCommentState(const int state) {
+ return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT ||
+ state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
+}
+
+static bool isLineEnd(int ch) {
+ return ch == '\r' || ch == '\n';
+}
+
+static bool isOKBeforeRE(int ch) {
+ return (ch == '(') || (ch == '=') || (ch == ',');
+}
+
+static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
+ if (strlen(blockType) == 0) {
+ return ((ch == '%') && (chNext == '>'));
+ } else if ((0 == strcmp(blockType, "inherit")) ||
+ (0 == strcmp(blockType, "namespace")) ||
+ (0 == strcmp(blockType, "include")) ||
+ (0 == strcmp(blockType, "page"))) {
+ return ((ch == '/') && (chNext == '>'));
+ } else if (0 == strcmp(blockType, "%")) {
+ if (ch == '/' && isLineEnd(chNext))
+ return 1;
+ else
+ return isLineEnd(ch);
+ } else if (0 == strcmp(blockType, "{")) {
+ return ch == '}';
+ } else {
+ return (ch == '>');
+ }
+}
+
+static bool isDjangoBlockEnd(const int ch, const int chNext, const char *blockType) {
+ if (strlen(blockType) == 0) {
+ return 0;
+ } else if (0 == strcmp(blockType, "%")) {
+ return ((ch == '%') && (chNext == '}'));
+ } else if (0 == strcmp(blockType, "{")) {
+ return ((ch == '}') && (chNext == '}'));
+ } else {
+ return 0;
+ }
+}
+
+static bool isPHPStringState(int state) {
+ return
+ (state == SCE_HPHP_HSTRING) ||
+ (state == SCE_HPHP_SIMPLESTRING) ||
+ (state == SCE_HPHP_HSTRING_VARIABLE) ||
+ (state == SCE_HPHP_COMPLEX_VARIABLE);
+}
+
+static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler, bool &isSimpleString) {
+ int j;
+ const int beginning = i - 1;
+ bool isValidSimpleString = false;
+
+ while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
+ i++;
+
+ char ch = styler.SafeGetCharAt(i);
+ const char chNext = styler.SafeGetCharAt(i + 1);
+ if (!IsPhpWordStart(ch)) {
+ if (ch == '\'' && IsPhpWordStart(chNext)) {
+ i++;
+ ch = chNext;
+ isSimpleString = true;
+ } else {
+ phpStringDelimiter[0] = '\0';
+ return beginning;
+ }
+ }
+ phpStringDelimiter[0] = ch;
+ i++;
+
+ for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) {
+ if (!IsPhpWordChar(styler[j])) {
+ if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) {
+ isValidSimpleString = true;
+ j++;
+ break;
+ } else {
+ phpStringDelimiter[0] = '\0';
+ return beginning;
+ }
+ }
+ if (j - i < phpStringDelimiterSize - 2)
+ phpStringDelimiter[j-i+1] = styler[j];
+ else
+ i++;
+ }
+ if (isSimpleString && !isValidSimpleString) {
+ phpStringDelimiter[0] = '\0';
+ return beginning;
+ }
+ phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0';
+ return j - 1;
+}
+
+static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler, bool isXml) {
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords
+
+ // Lexer for HTML requires more lexical states (8 bits worth) than most lexers
+ styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
+ char prevWord[200];
+ prevWord[0] = '\0';
+ char phpStringDelimiter[200]; // PHP is not limited in length, we are
+ phpStringDelimiter[0] = '\0';
+ int StateToPrint = initStyle;
+ int state = stateForPrintState(StateToPrint);
+ char makoBlockType[200];
+ makoBlockType[0] = '\0';
+ int makoComment = 0;
+ char djangoBlockType[2];
+ djangoBlockType[0] = '\0';
+
+ // If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen
+ if (InTagState(state)) {
+ while ((startPos > 0) && (InTagState(styler.StyleAt(startPos - 1)))) {
+ int backLineStart = styler.LineStart(styler.GetLine(startPos-1));
+ length += startPos - backLineStart;
+ startPos = backLineStart;
+ }
+ state = SCE_H_DEFAULT;
+ }
+ // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
+ if (isPHPStringState(state)) {
+ while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
+ startPos--;
+ length++;
+ state = styler.StyleAt(startPos);
+ }
+ if (startPos == 0)
+ state = SCE_H_DEFAULT;
+ }
+ styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
+
+ int lineCurrent = styler.GetLine(startPos);
+ int lineState;
+ if (lineCurrent > 0) {
+ lineState = styler.GetLineState(lineCurrent-1);
+ } else {
+ // Default client and ASP scripting language is JavaScript
+ lineState = eScriptJS << 8;
+
+ // property asp.default.language
+ // Script in ASP code is initially assumed to be in JavaScript.
+ // To change this to VBScript set asp.default.language to 2. Python is 3.
+ lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
+ }
+ script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
+ bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag
+ bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag
+ bool tagDontFold = false; //some HTML tags should not be folded
+ script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name
+ script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name
+ int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
+
+ script_type scriptLanguage = ScriptOfState(state);
+ // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
+ if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
+ scriptLanguage = eScriptComment;
+ }
+ script_type beforeLanguage = ScriptOfState(beforePreProc);
+
+ // property fold.html
+ // Folding is turned on or off for HTML and XML files with this option.
+ // The fold option must also be on for folding to occur.
+ const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
+
+ const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
+
+ // property fold.html.preprocessor
+ // Folding is turned on or off for scripts embedded in HTML files with this option.
+ // The default is on.
+ const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
+
+ const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+ // property fold.hypertext.comment
+ // Allow folding for comments in scripts embedded in HTML.
+ // The default is off.
+ const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
+
+ // property fold.hypertext.heredoc
+ // Allow folding for heredocs in scripts embedded in HTML.
+ // The default is off.
+ const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
+
+ // property html.tags.case.sensitive
+ // For XML and HTML, setting this property to 1 will make tags match in a case
+ // sensitive way which is the expected behaviour for XML and XHTML.
+ const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
+
+ // property lexer.xml.allow.scripts
+ // Set to 0 to disable scripts in XML.
+ const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
+
+ // property lexer.html.mako
+ // Set to 1 to enable the mako template language.
+ const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
+
+ // property lexer.html.django
+ // Set to 1 to enable the django template language.
+ const bool isDjango = styler.GetPropertyInt("lexer.html.django", 0) != 0;
+
+ const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
+ const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
+ const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
+
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ int visibleChars = 0;
+ int lineStartVisibleChars = 0;
+
+ int chPrev = ' ';
+ int ch = ' ';
+ int chPrevNonWhite = ' ';
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (scriptLanguage == eScriptJS && startPos > 0) {
+ int back = startPos;
+ int style = 0;
+ while (--back) {
+ style = styler.StyleAt(back);
+ if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)
+ // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
+ break;
+ }
+ if (style == SCE_HJ_SYMBOLS) {
+ chPrevNonWhite = static_cast<unsigned char>(styler.SafeGetCharAt(back));
+ }
+ }
+
+ styler.StartSegment(startPos);
+ const int lengthDoc = startPos + length;
+ for (int i = startPos; i < lengthDoc; i++) {
+ const int chPrev2 = chPrev;
+ chPrev = ch;
+ if (!IsASpace(ch) && state != SCE_HJ_COMMENT &&
+ state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
+ chPrevNonWhite = ch;
+ ch = static_cast<unsigned char>(styler[i]);
+ int chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ const int chNext2 = static_cast<unsigned char>(styler.SafeGetCharAt(i + 2));
+
+ // Handle DBCS codepages
+ if (styler.IsLeadByte(static_cast<char>(ch))) {
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ if ((!IsASpace(ch) || !foldCompact) && fold)
+ visibleChars++;
+ if (!IsASpace(ch))
+ lineStartVisibleChars++;
+
+ // decide what is the current state to print (depending of the script tag)
+ StateToPrint = statePrintForState(state, inScriptType);
+
+ // handle script folding
+ if (fold) {
+ switch (scriptLanguage) {
+ case eScriptJS:
+ case eScriptPHP:
+ //not currently supported case eScriptVBS:
+
+ if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
+ //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
+ //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
+ if (ch == '#') {
+ int j = i + 1;
+ while ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "region") || styler.Match(j, "if")) {
+ levelCurrent++;
+ } else if (styler.Match(j, "end")) {
+ levelCurrent--;
+ }
+ } else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
+ levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
+ }
+ } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
+ levelCurrent--;
+ }
+ break;
+ case eScriptPython:
+ if (state != SCE_HP_COMMENTLINE && !isMako) {
+ if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) {
+ levelCurrent++;
+ } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) {
+ // check if the number of tabs is lower than the level
+ int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8;
+ for (int j = 0; Findlevel > 0; j++) {
+ char chTmp = styler.SafeGetCharAt(i + j + 1);
+ if (chTmp == '\t') {
+ Findlevel -= 8;
+ } else if (chTmp == ' ') {
+ Findlevel--;
+ } else {
+ break;
+ }
+ }
+
+ if (Findlevel > 0) {
+ levelCurrent -= Findlevel / 8;
+ if (Findlevel % 8)
+ levelCurrent--;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+ // Avoid triggering two times on Dos/Win
+ // New line -> record any line state onto /next/ line
+ if (fold) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+
+ styler.SetLevel(lineCurrent, lev);
+ visibleChars = 0;
+ levelPrev = levelCurrent;
+ }
+ styler.SetLineState(lineCurrent,
+ ((inScriptType & 0x03) << 0) |
+ ((tagOpened & 0x01) << 2) |
+ ((tagClosing & 0x01) << 3) |
+ ((aspScript & 0x0F) << 4) |
+ ((clientScript & 0x0F) << 8) |
+ ((beforePreProc & 0xFF) << 12));
+ lineCurrent++;
+ lineStartVisibleChars = 0;
+ }
+
+ // handle start of Mako comment line
+ if (isMako && ch == '#' && chNext == '#') {
+ makoComment = 1;
+ }
+
+ // handle end of Mako comment line
+ else if (isMako && makoComment && (ch == '\r' || ch == '\n')) {
+ makoComment = 0;
+ styler.ColourTo(i, SCE_HP_COMMENTLINE);
+ state = SCE_HP_DEFAULT;
+ }
+
+ // Allow falling through to mako handling code if newline is going to end a block
+ if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
+ (!isMako || (0 != strcmp(makoBlockType, "%")))) {
+ }
+
+ // generic end of script processing
+ else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
+ // Check if it's the end of the script tag (or any other HTML tag)
+ switch (state) {
+ // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
+ case SCE_H_DOUBLESTRING:
+ case SCE_H_SINGLESTRING:
+ case SCE_HJ_COMMENT:
+ case SCE_HJ_COMMENTDOC:
+ //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
+ // the end of script marker from some JS interpreters.
+ case SCE_HB_COMMENTLINE:
+ case SCE_HBA_COMMENTLINE:
+ case SCE_HJ_DOUBLESTRING:
+ case SCE_HJ_SINGLESTRING:
+ case SCE_HJ_REGEX:
+ case SCE_HB_STRING:
+ case SCE_HBA_STRING:
+ case SCE_HP_STRING:
+ case SCE_HP_TRIPLE:
+ case SCE_HP_TRIPLEDOUBLE:
+ case SCE_HPHP_HSTRING:
+ case SCE_HPHP_SIMPLESTRING:
+ case SCE_HPHP_COMMENT:
+ case SCE_HPHP_COMMENTLINE:
+ break;
+ default :
+ // check if the closing tag is a script tag
+ if (const char *tag =
+ state == SCE_HJ_COMMENTLINE || isXml ? "script" :
+ state == SCE_H_COMMENT ? "comment" : 0) {
+ int j = i + 2;
+ int chr;
+ do {
+ chr = static_cast<int>(*tag++);
+ } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++)));
+ if (chr != 0) break;
+ }
+ // closing tag of the script (it's a closing HTML tag anyway)
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_TAGUNKNOWN;
+ inScriptType = eHtml;
+ scriptLanguage = eScriptNone;
+ clientScript = eScriptJS;
+ i += 2;
+ visibleChars += 2;
+ tagClosing = true;
+ continue;
+ }
+ }
+
+ /////////////////////////////////////
+ // handle the start of PHP pre-processor = Non-HTML
+ else if ((state != SCE_H_ASPAT) &&
+ !isPHPStringState(state) &&
+ (state != SCE_HPHP_COMMENT) &&
+ (state != SCE_HPHP_COMMENTLINE) &&
+ (ch == '<') &&
+ (chNext == '?') &&
+ !IsScriptCommentState(state)) {
+ beforeLanguage = scriptLanguage;
+ scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP);
+ if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ i++;
+ visibleChars++;
+ i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6);
+ if (scriptLanguage == eScriptXML)
+ styler.ColourTo(i, SCE_H_XMLSTART);
+ else
+ styler.ColourTo(i, SCE_H_QUESTION);
+ state = StateForScript(scriptLanguage);
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+ // Fold whole script, but not if the XML first tag (all XML-like tags in this case)
+ if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
+ levelCurrent++;
+ }
+ // should be better
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ }
+
+ // handle the start Mako template Python code
+ else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
+ (lineStartVisibleChars == 1 && ch == '%') ||
+ (lineStartVisibleChars == 1 && ch == '/' && chNext == '%') ||
+ (ch == '$' && chNext == '{') ||
+ (ch == '<' && chNext == '/' && chNext2 == '%'))) {
+ if (ch == '%' || ch == '/')
+ strcpy(makoBlockType, "%");
+ else if (ch == '$')
+ strcpy(makoBlockType, "{");
+ else if (chNext == '/')
+ GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
+ else
+ GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType));
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+
+ if (chNext == '/') {
+ i += 2;
+ visibleChars += 2;
+ } else if (ch != '%') {
+ i++;
+ visibleChars++;
+ }
+ state = SCE_HP_START;
+ scriptLanguage = eScriptPython;
+ styler.ColourTo(i, SCE_H_ASP);
+
+ if (ch != '%' && ch != '$' && ch != '/') {
+ i += static_cast<int>(strlen(makoBlockType));
+ visibleChars += static_cast<int>(strlen(makoBlockType));
+ if (keywords4.InList(makoBlockType))
+ styler.ColourTo(i, SCE_HP_WORD);
+ else
+ styler.ColourTo(i, SCE_H_TAGUNKNOWN);
+ }
+
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ }
+
+ // handle the start/end of Django comment
+ else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ beforeLanguage = scriptLanguage;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+ i += 1;
+ visibleChars += 1;
+ scriptLanguage = eScriptComment;
+ state = SCE_H_COMMENT;
+ styler.ColourTo(i, SCE_H_ASP);
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ } else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ i += 1;
+ visibleChars += 1;
+ styler.ColourTo(i, SCE_H_ASP);
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ scriptLanguage = beforeLanguage;
+ continue;
+ }
+
+ // handle the start Django template code
+ else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
+ if (chNext == '%')
+ strcpy(djangoBlockType, "%");
+ else
+ strcpy(djangoBlockType, "{");
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+
+ i += 1;
+ visibleChars += 1;
+ state = SCE_HP_START;
+ beforeLanguage = scriptLanguage;
+ scriptLanguage = eScriptPython;
+ styler.ColourTo(i, SCE_H_ASP);
+
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ }
+
+ // handle the start of ASP pre-processor = Non-HTML
+ else if (!isMako && !isDjango && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+
+ if (chNext2 == '@') {
+ i += 2; // place as if it was the second next char treated
+ visibleChars += 2;
+ state = SCE_H_ASPAT;
+ } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) {
+ styler.ColourTo(i + 3, SCE_H_ASP);
+ state = SCE_H_XCCOMMENT;
+ scriptLanguage = eScriptVBS;
+ continue;
+ } else {
+ if (chNext2 == '=') {
+ i += 2; // place as if it was the second next char treated
+ visibleChars += 2;
+ } else {
+ i++; // place as if it was the next char treated
+ visibleChars++;
+ }
+
+ state = StateForScript(aspScript);
+ }
+ scriptLanguage = eScriptVBS;
+ styler.ColourTo(i, SCE_H_ASP);
+ // fold whole script
+ if (foldHTMLPreprocessor)
+ levelCurrent++;
+ // should be better
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ }
+
+ /////////////////////////////////////
+ // handle the start of SGML language (DTD)
+ else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
+ (chPrev == '<') &&
+ (ch == '!') &&
+ (StateToPrint != SCE_H_CDATA) &&
+ (!IsCommentState(StateToPrint)) &&
+ (!IsScriptCommentState(StateToPrint))) {
+ beforePreProc = state;
+ styler.ColourTo(i - 2, StateToPrint);
+ if ((chNext == '-') && (chNext2 == '-')) {
+ state = SCE_H_COMMENT; // wait for a pending command
+ styler.ColourTo(i + 2, SCE_H_COMMENT);
+ i += 2; // follow styling after the --
+ } else if (isWordCdata(i + 1, i + 7, styler)) {
+ state = SCE_H_CDATA;
+ } else {
+ styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
+ scriptLanguage = eScriptSGML;
+ state = SCE_H_SGML_COMMAND; // wait for a pending command
+ }
+ // fold whole tag (-- when closing the tag)
+ if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA)
+ levelCurrent++;
+ continue;
+ }
+
+ // handle the end of Mako Python code
+ else if (isMako &&
+ ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
+ isMakoBlockEnd(ch, chNext, makoBlockType)) {
+ if (state == SCE_H_ASPAT) {
+ aspScript = segIsScriptingIndicator(styler,
+ styler.GetStartSegment(), i - 1, aspScript);
+ }
+ if (state == SCE_HP_WORD) {
+ classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ }
+ if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') {
+ i++;
+ visibleChars++;
+ }
+ else if (0 == strcmp(makoBlockType, "%") && ch == '/') {
+ i++;
+ visibleChars++;
+ }
+ if (0 != strcmp(makoBlockType, "%") || ch == '/') {
+ styler.ColourTo(i, SCE_H_ASP);
+ }
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ scriptLanguage = eScriptNone;
+ continue;
+ }
+
+ // handle the end of Django template code
+ else if (isDjango &&
+ ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
+ isDjangoBlockEnd(ch, chNext, djangoBlockType)) {
+ if (state == SCE_H_ASPAT) {
+ aspScript = segIsScriptingIndicator(styler,
+ styler.GetStartSegment(), i - 1, aspScript);
+ }
+ if (state == SCE_HP_WORD) {
+ classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ }
+ i += 1;
+ visibleChars += 1;
+ styler.ColourTo(i, SCE_H_ASP);
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ scriptLanguage = beforeLanguage;
+ continue;
+ }
+
+ // handle the end of a pre-processor = Non-HTML
+ else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
+ (((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
+ ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
+ if (state == SCE_H_ASPAT) {
+ aspScript = segIsScriptingIndicator(styler,
+ styler.GetStartSegment(), i - 1, aspScript);
+ }
+ // Bounce out of any ASP mode
+ switch (state) {
+ case SCE_HJ_WORD:
+ classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
+ break;
+ case SCE_HB_WORD:
+ classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
+ break;
+ case SCE_HP_WORD:
+ classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
+ break;
+ case SCE_HPHP_WORD:
+ classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
+ break;
+ case SCE_H_XCCOMMENT:
+ styler.ColourTo(i - 1, state);
+ break;
+ default :
+ styler.ColourTo(i - 1, StateToPrint);
+ break;
+ }
+ if (scriptLanguage != eScriptSGML) {
+ i++;
+ visibleChars++;
+ }
+ if (ch == '%')
+ styler.ColourTo(i, SCE_H_ASP);
+ else if (scriptLanguage == eScriptXML)
+ styler.ColourTo(i, SCE_H_XMLEND);
+ else if (scriptLanguage == eScriptSGML)
+ styler.ColourTo(i, SCE_H_SGML_DEFAULT);
+ else
+ styler.ColourTo(i, SCE_H_QUESTION);
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ // Unfold all scripting languages, except for XML tag
+ if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
+ levelCurrent--;
+ }
+ scriptLanguage = beforeLanguage;
+ continue;
+ }
+ /////////////////////////////////////
+
+ switch (state) {
+ case SCE_H_DEFAULT:
+ if (ch == '<') {
+ // in HTML, fold on tag open and unfold on tag close
+ tagOpened = true;
+ tagClosing = (chNext == '/');
+ styler.ColourTo(i - 1, StateToPrint);
+ if (chNext != '!')
+ state = SCE_H_TAGUNKNOWN;
+ } else if (ch == '&') {
+ styler.ColourTo(i - 1, SCE_H_DEFAULT);
+ state = SCE_H_ENTITY;
+ }
+ break;
+ case SCE_H_SGML_DEFAULT:
+ case SCE_H_SGML_BLOCK_DEFAULT:
+// if (scriptLanguage == eScriptSGMLblock)
+// StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
+
+ if (ch == '\"') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_SGML_DOUBLESTRING;
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_SGML_SIMPLESTRING;
+ } else if ((ch == '-') && (chPrev == '-')) {
+ if (static_cast<int>(styler.GetStartSegment()) <= (i - 2)) {
+ styler.ColourTo(i - 2, StateToPrint);
+ }
+ state = SCE_H_SGML_COMMENT;
+ } else if (isascii(ch) && isalpha(ch) && (chPrev == '%')) {
+ styler.ColourTo(i - 2, StateToPrint);
+ state = SCE_H_SGML_ENTITY;
+ } else if (ch == '#') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_SGML_SPECIAL;
+ } else if (ch == '[') {
+ styler.ColourTo(i - 1, StateToPrint);
+ scriptLanguage = eScriptSGMLblock;
+ state = SCE_H_SGML_BLOCK_DEFAULT;
+ } else if (ch == ']') {
+ if (scriptLanguage == eScriptSGMLblock) {
+ styler.ColourTo(i, StateToPrint);
+ scriptLanguage = eScriptSGML;
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i, SCE_H_SGML_ERROR);
+ }
+ state = SCE_H_SGML_DEFAULT;
+ } else if (scriptLanguage == eScriptSGMLblock) {
+ if ((ch == '!') && (chPrev == '<')) {
+ styler.ColourTo(i - 2, StateToPrint);
+ styler.ColourTo(i, SCE_H_SGML_DEFAULT);
+ state = SCE_H_SGML_COMMAND;
+ } else if (ch == '>') {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i, SCE_H_SGML_DEFAULT);
+ }
+ }
+ break;
+ case SCE_H_SGML_COMMAND:
+ if ((ch == '-') && (chPrev == '-')) {
+ styler.ColourTo(i - 2, StateToPrint);
+ state = SCE_H_SGML_COMMENT;
+ } else if (!issgmlwordchar(ch)) {
+ if (isWordHSGML(styler.GetStartSegment(), i - 1, keywords6, styler)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_SGML_1ST_PARAM;
+ } else {
+ state = SCE_H_SGML_ERROR;
+ }
+ }
+ break;
+ case SCE_H_SGML_1ST_PARAM:
+ // wait for the beginning of the word
+ if ((ch == '-') && (chPrev == '-')) {
+ if (scriptLanguage == eScriptSGMLblock) {
+ styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT);
+ } else {
+ styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
+ }
+ state = SCE_H_SGML_1ST_PARAM_COMMENT;
+ } else if (issgmlwordchar(ch)) {
+ if (scriptLanguage == eScriptSGMLblock) {
+ styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT);
+ } else {
+ styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
+ }
+ // find the length of the word
+ int size = 1;
+ while (setHTMLWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(i + size))))
+ size++;
+ styler.ColourTo(i + size - 1, StateToPrint);
+ i += size - 1;
+ visibleChars += size - 1;
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ if (scriptLanguage == eScriptSGMLblock) {
+ state = SCE_H_SGML_BLOCK_DEFAULT;
+ } else {
+ state = SCE_H_SGML_DEFAULT;
+ }
+ continue;
+ }
+ break;
+ case SCE_H_SGML_ERROR:
+ if ((ch == '-') && (chPrev == '-')) {
+ styler.ColourTo(i - 2, StateToPrint);
+ state = SCE_H_SGML_COMMENT;
+ }
+ case SCE_H_SGML_DOUBLESTRING:
+ if (ch == '\"') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_SGML_DEFAULT;
+ }
+ break;
+ case SCE_H_SGML_SIMPLESTRING:
+ if (ch == '\'') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_SGML_DEFAULT;
+ }
+ break;
+ case SCE_H_SGML_COMMENT:
+ if ((ch == '-') && (chPrev == '-')) {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_SGML_DEFAULT;
+ }
+ break;
+ case SCE_H_CDATA:
+ if ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_DEFAULT;
+ levelCurrent--;
+ }
+ break;
+ case SCE_H_COMMENT:
+ if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_DEFAULT;
+ levelCurrent--;
+ }
+ break;
+ case SCE_H_SGML_1ST_PARAM_COMMENT:
+ if ((ch == '-') && (chPrev == '-')) {
+ styler.ColourTo(i, SCE_H_SGML_COMMENT);
+ state = SCE_H_SGML_1ST_PARAM;
+ }
+ break;
+ case SCE_H_SGML_SPECIAL:
+ if (!(isascii(ch) && isupper(ch))) {
+ styler.ColourTo(i - 1, StateToPrint);
+ if (isalnum(ch)) {
+ state = SCE_H_SGML_ERROR;
+ } else {
+ state = SCE_H_SGML_DEFAULT;
+ }
+ }
+ break;
+ case SCE_H_SGML_ENTITY:
+ if (ch == ';') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_SGML_DEFAULT;
+ } else if (!(isascii(ch) && isalnum(ch)) && ch != '-' && ch != '.') {
+ styler.ColourTo(i, SCE_H_SGML_ERROR);
+ state = SCE_H_SGML_DEFAULT;
+ }
+ break;
+ case SCE_H_ENTITY:
+ if (ch == ';') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_DEFAULT;
+ }
+ if (ch != '#' && !(isascii(ch) && isalnum(ch)) // Should check that '#' follows '&', but it is unlikely anyway...
+ && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML
+ if (!isascii(ch)) // Possibly start of a multibyte character so don't allow this byte to be in entity style
+ styler.ColourTo(i-1, SCE_H_TAGUNKNOWN);
+ else
+ styler.ColourTo(i, SCE_H_TAGUNKNOWN);
+ state = SCE_H_DEFAULT;
+ }
+ break;
+ case SCE_H_TAGUNKNOWN:
+ if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) {
+ int eClass = classifyTagHTML(styler.GetStartSegment(),
+ i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts);
+ if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) {
+ if (!tagClosing) {
+ inScriptType = eNonHtmlScript;
+ scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment;
+ } else {
+ scriptLanguage = eScriptNone;
+ }
+ eClass = SCE_H_TAG;
+ }
+ if (ch == '>') {
+ styler.ColourTo(i, eClass);
+ if (inScriptType == eNonHtmlScript) {
+ state = StateForScript(scriptLanguage);
+ } else {
+ state = SCE_H_DEFAULT;
+ }
+ tagOpened = false;
+ if (!tagDontFold) {
+ if (tagClosing) {
+ levelCurrent--;
+ } else {
+ levelCurrent++;
+ }
+ }
+ tagClosing = false;
+ } else if (ch == '/' && chNext == '>') {
+ if (eClass == SCE_H_TAGUNKNOWN) {
+ styler.ColourTo(i + 1, SCE_H_TAGUNKNOWN);
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i + 1, SCE_H_TAGEND);
+ }
+ i++;
+ ch = chNext;
+ state = SCE_H_DEFAULT;
+ tagOpened = false;
+ } else {
+ if (eClass != SCE_H_TAGUNKNOWN) {
+ if (eClass == SCE_H_SGML_DEFAULT) {
+ state = SCE_H_SGML_DEFAULT;
+ } else {
+ state = SCE_H_OTHER;
+ }
+ }
+ }
+ }
+ break;
+ case SCE_H_ATTRIBUTE:
+ if (!setAttributeContinue.Contains(ch)) {
+ if (inScriptType == eNonHtmlScript) {
+ int scriptLanguagePrev = scriptLanguage;
+ clientScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, scriptLanguage);
+ scriptLanguage = clientScript;
+ if ((scriptLanguagePrev != scriptLanguage) && (scriptLanguage == eScriptNone))
+ inScriptType = eHtml;
+ }
+ classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler);
+ if (ch == '>') {
+ styler.ColourTo(i, SCE_H_TAG);
+ if (inScriptType == eNonHtmlScript) {
+ state = StateForScript(scriptLanguage);
+ } else {
+ state = SCE_H_DEFAULT;
+ }
+ tagOpened = false;
+ if (!tagDontFold) {
+ if (tagClosing) {
+ levelCurrent--;
+ } else {
+ levelCurrent++;
+ }
+ }
+ tagClosing = false;
+ } else if (ch == '=') {
+ styler.ColourTo(i, SCE_H_OTHER);
+ state = SCE_H_VALUE;
+ } else {
+ state = SCE_H_OTHER;
+ }
+ }
+ break;
+ case SCE_H_OTHER:
+ if (ch == '>') {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i, SCE_H_TAG);
+ if (inScriptType == eNonHtmlScript) {
+ state = StateForScript(scriptLanguage);
+ } else {
+ state = SCE_H_DEFAULT;
+ }
+ tagOpened = false;
+ if (!tagDontFold) {
+ if (tagClosing) {
+ levelCurrent--;
+ } else {
+ levelCurrent++;
+ }
+ }
+ tagClosing = false;
+ } else if (ch == '\"') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_DOUBLESTRING;
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_SINGLESTRING;
+ } else if (ch == '=') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_H_VALUE;
+ } else if (ch == '/' && chNext == '>') {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i + 1, SCE_H_TAGEND);
+ i++;
+ ch = chNext;
+ state = SCE_H_DEFAULT;
+ tagOpened = false;
+ } else if (ch == '?' && chNext == '>') {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i + 1, SCE_H_XMLEND);
+ i++;
+ ch = chNext;
+ state = SCE_H_DEFAULT;
+ } else if (setHTMLWord.Contains(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_H_ATTRIBUTE;
+ }
+ break;
+ case SCE_H_DOUBLESTRING:
+ if (ch == '\"') {
+ if (inScriptType == eNonHtmlScript) {
+ scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
+ }
+ styler.ColourTo(i, SCE_H_DOUBLESTRING);
+ state = SCE_H_OTHER;
+ }
+ break;
+ case SCE_H_SINGLESTRING:
+ if (ch == '\'') {
+ if (inScriptType == eNonHtmlScript) {
+ scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
+ }
+ styler.ColourTo(i, SCE_H_SINGLESTRING);
+ state = SCE_H_OTHER;
+ }
+ break;
+ case SCE_H_VALUE:
+ if (!setHTMLWord.Contains(ch)) {
+ if (ch == '\"' && chPrev == '=') {
+ // Should really test for being first character
+ state = SCE_H_DOUBLESTRING;
+ } else if (ch == '\'' && chPrev == '=') {
+ state = SCE_H_SINGLESTRING;
+ } else {
+ if (IsNumber(styler.GetStartSegment(), styler)) {
+ styler.ColourTo(i - 1, SCE_H_NUMBER);
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ }
+ if (ch == '>') {
+ styler.ColourTo(i, SCE_H_TAG);
+ if (inScriptType == eNonHtmlScript) {
+ state = StateForScript(scriptLanguage);
+ } else {
+ state = SCE_H_DEFAULT;
+ }
+ tagOpened = false;
+ if (!tagDontFold) {
+ if (tagClosing) {
+ levelCurrent--;
+ } else {
+ levelCurrent++;
+ }
+ }
+ tagClosing = false;
+ } else {
+ state = SCE_H_OTHER;
+ }
+ }
+ }
+ break;
+ case SCE_HJ_DEFAULT:
+ case SCE_HJ_START:
+ case SCE_HJ_SYMBOLS:
+ if (IsAWordStart(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_WORD;
+ } else if (ch == '/' && chNext == '*') {
+ styler.ColourTo(i - 1, StateToPrint);
+ if (chNext2 == '*')
+ state = SCE_HJ_COMMENTDOC;
+ else
+ state = SCE_HJ_COMMENT;
+ if (chNext2 == '/') {
+ // Eat the * so it isn't used for the end of the comment
+ i++;
+ }
+ } else if (ch == '/' && chNext == '/') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_COMMENTLINE;
+ } else if (ch == '/' && isOKBeforeRE(chPrevNonWhite)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_REGEX;
+ } else if (ch == '\"') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_DOUBLESTRING;
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_SINGLESTRING;
+ } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
+ styler.SafeGetCharAt(i + 3) == '-') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_COMMENTLINE;
+ } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_COMMENTLINE;
+ i += 2;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
+ state = SCE_HJ_DEFAULT;
+ } else if ((ch == ' ') || (ch == '\t')) {
+ if (state == SCE_HJ_START) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_DEFAULT;
+ }
+ }
+ break;
+ case SCE_HJ_WORD:
+ if (!IsAWordChar(ch)) {
+ classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
+ //styler.ColourTo(i - 1, eHTJSKeyword);
+ state = SCE_HJ_DEFAULT;
+ if (ch == '/' && chNext == '*') {
+ if (chNext2 == '*')
+ state = SCE_HJ_COMMENTDOC;
+ else
+ state = SCE_HJ_COMMENT;
+ } else if (ch == '/' && chNext == '/') {
+ state = SCE_HJ_COMMENTLINE;
+ } else if (ch == '\"') {
+ state = SCE_HJ_DOUBLESTRING;
+ } else if (ch == '\'') {
+ state = SCE_HJ_SINGLESTRING;
+ } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_COMMENTLINE;
+ i += 2;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
+ state = SCE_HJ_DEFAULT;
+ }
+ }
+ break;
+ case SCE_HJ_COMMENT:
+ case SCE_HJ_COMMENTDOC:
+ if (ch == '/' && chPrev == '*') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HJ_DEFAULT;
+ ch = ' ';
+ }
+ break;
+ case SCE_HJ_COMMENTLINE:
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));
+ state = SCE_HJ_DEFAULT;
+ ch = ' ';
+ }
+ break;
+ case SCE_HJ_DOUBLESTRING:
+ if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ }
+ } else if (ch == '\"') {
+ styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType));
+ state = SCE_HJ_DEFAULT;
+ } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_COMMENTLINE;
+ i += 2;
+ } else if (isLineEnd(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_STRINGEOL;
+ }
+ break;
+ case SCE_HJ_SINGLESTRING:
+ if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ }
+ } else if (ch == '\'') {
+ styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType));
+ state = SCE_HJ_DEFAULT;
+ } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_COMMENTLINE;
+ i += 2;
+ } else if (isLineEnd(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) {
+ state = SCE_HJ_STRINGEOL;
+ }
+ }
+ break;
+ case SCE_HJ_STRINGEOL:
+ if (!isLineEnd(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HJ_DEFAULT;
+ } else if (!isLineEnd(chNext)) {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HJ_DEFAULT;
+ }
+ break;
+ case SCE_HJ_REGEX:
+ if (ch == '\r' || ch == '\n' || ch == '/') {
+ if (ch == '/') {
+ while (isascii(chNext) && islower(chNext)) { // gobble regex flags
+ i++;
+ ch = chNext;
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ }
+ }
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HJ_DEFAULT;
+ } else if (ch == '\\') {
+ // Gobble up the quoted character
+ if (chNext == '\\' || chNext == '/') {
+ i++;
+ ch = chNext;
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ }
+ }
+ break;
+ case SCE_HB_DEFAULT:
+ case SCE_HB_START:
+ if (IsAWordStart(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_WORD;
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_COMMENTLINE;
+ } else if (ch == '\"') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_STRING;
+ } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
+ styler.SafeGetCharAt(i + 3) == '-') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_COMMENTLINE;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
+ state = SCE_HB_DEFAULT;
+ } else if ((ch == ' ') || (ch == '\t')) {
+ if (state == SCE_HB_START) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_DEFAULT;
+ }
+ }
+ break;
+ case SCE_HB_WORD:
+ if (!IsAWordChar(ch)) {
+ state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
+ if (state == SCE_HB_DEFAULT) {
+ if (ch == '\"') {
+ state = SCE_HB_STRING;
+ } else if (ch == '\'') {
+ state = SCE_HB_COMMENTLINE;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
+ state = SCE_HB_DEFAULT;
+ }
+ }
+ }
+ break;
+ case SCE_HB_STRING:
+ if (ch == '\"') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HB_DEFAULT;
+ } else if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_STRINGEOL;
+ }
+ break;
+ case SCE_HB_COMMENTLINE:
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_DEFAULT;
+ }
+ break;
+ case SCE_HB_STRINGEOL:
+ if (!isLineEnd(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HB_DEFAULT;
+ } else if (!isLineEnd(chNext)) {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HB_DEFAULT;
+ }
+ break;
+ case SCE_HP_DEFAULT:
+ case SCE_HP_START:
+ if (IsAWordStart(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HP_WORD;
+ } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
+ styler.SafeGetCharAt(i + 3) == '-') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HP_COMMENTLINE;
+ } else if (ch == '#') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HP_COMMENTLINE;
+ } else if (ch == '\"') {
+ styler.ColourTo(i - 1, StateToPrint);
+ if (chNext == '\"' && chNext2 == '\"') {
+ i += 2;
+ state = SCE_HP_TRIPLEDOUBLE;
+ ch = ' ';
+ chPrev = ' ';
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ } else {
+ // state = statePrintForState(SCE_HP_STRING,inScriptType);
+ state = SCE_HP_STRING;
+ }
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, StateToPrint);
+ if (chNext == '\'' && chNext2 == '\'') {
+ i += 2;
+ state = SCE_HP_TRIPLE;
+ ch = ' ';
+ chPrev = ' ';
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ } else {
+ state = SCE_HP_CHARACTER;
+ }
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
+ } else if ((ch == ' ') || (ch == '\t')) {
+ if (state == SCE_HP_START) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HP_DEFAULT;
+ }
+ }
+ break;
+ case SCE_HP_WORD:
+ if (!IsAWordChar(ch)) {
+ classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
+ state = SCE_HP_DEFAULT;
+ if (ch == '#') {
+ state = SCE_HP_COMMENTLINE;
+ } else if (ch == '\"') {
+ if (chNext == '\"' && chNext2 == '\"') {
+ i += 2;
+ state = SCE_HP_TRIPLEDOUBLE;
+ ch = ' ';
+ chPrev = ' ';
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ } else {
+ state = SCE_HP_STRING;
+ }
+ } else if (ch == '\'') {
+ if (chNext == '\'' && chNext2 == '\'') {
+ i += 2;
+ state = SCE_HP_TRIPLE;
+ ch = ' ';
+ chPrev = ' ';
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ } else {
+ state = SCE_HP_CHARACTER;
+ }
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
+ }
+ }
+ break;
+ case SCE_HP_COMMENTLINE:
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HP_DEFAULT;
+ }
+ break;
+ case SCE_HP_STRING:
+ if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ ch = chNext;
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ }
+ } else if (ch == '\"') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HP_DEFAULT;
+ }
+ break;
+ case SCE_HP_CHARACTER:
+ if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ ch = chNext;
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
+ }
+ } else if (ch == '\'') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HP_DEFAULT;
+ }
+ break;
+ case SCE_HP_TRIPLE:
+ if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HP_DEFAULT;
+ }
+ break;
+ case SCE_HP_TRIPLEDOUBLE:
+ if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HP_DEFAULT;
+ }
+ break;
+ ///////////// start - PHP state handling
+ case SCE_HPHP_WORD:
+ if (!IsAWordChar(ch)) {
+ classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
+ if (ch == '/' && chNext == '*') {
+ i++;
+ state = SCE_HPHP_COMMENT;
+ } else if (ch == '/' && chNext == '/') {
+ i++;
+ state = SCE_HPHP_COMMENTLINE;
+ } else if (ch == '#') {
+ state = SCE_HPHP_COMMENTLINE;
+ } else if (ch == '\"') {
+ state = SCE_HPHP_HSTRING;
+ strcpy(phpStringDelimiter, "\"");
+ } else if (styler.Match(i, "<<<")) {
+ bool isSimpleString = false;
+ i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
+ if (strlen(phpStringDelimiter)) {
+ state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
+ if (foldHeredoc) levelCurrent++;
+ }
+ } else if (ch == '\'') {
+ state = SCE_HPHP_SIMPLESTRING;
+ strcpy(phpStringDelimiter, "\'");
+ } else if (ch == '$' && IsPhpWordStart(chNext)) {
+ state = SCE_HPHP_VARIABLE;
+ } else if (IsOperator(ch)) {
+ state = SCE_HPHP_OPERATOR;
+ } else {
+ state = SCE_HPHP_DEFAULT;
+ }
+ }
+ break;
+ case SCE_HPHP_NUMBER:
+ // recognize bases 8,10 or 16 integers OR floating-point numbers
+ if (!IsADigit(ch)
+ && strchr(".xXabcdefABCDEF", ch) == NULL
+ && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) {
+ styler.ColourTo(i - 1, SCE_HPHP_NUMBER);
+ if (IsOperator(ch))
+ state = SCE_HPHP_OPERATOR;
+ else
+ state = SCE_HPHP_DEFAULT;
+ }
+ break;
+ case SCE_HPHP_VARIABLE:
+ if (!IsPhpWordChar(chNext)) {
+ styler.ColourTo(i, SCE_HPHP_VARIABLE);
+ state = SCE_HPHP_DEFAULT;
+ }
+ break;
+ case SCE_HPHP_COMMENT:
+ if (ch == '/' && chPrev == '*') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ }
+ break;
+ case SCE_HPHP_COMMENTLINE:
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ }
+ break;
+ case SCE_HPHP_HSTRING:
+ if (ch == '\\' && (phpStringDelimiter[0] == '\"' || chNext == '$' || chNext == '{')) {
+ // skip the next char
+ i++;
+ } else if (((ch == '{' && chNext == '$') || (ch == '$' && chNext == '{'))
+ && IsPhpWordStart(chNext2)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HPHP_COMPLEX_VARIABLE;
+ } else if (ch == '$' && IsPhpWordStart(chNext)) {
+ styler.ColourTo(i - 1, StateToPrint);
+ state = SCE_HPHP_HSTRING_VARIABLE;
+ } else if (styler.Match(i, phpStringDelimiter)) {
+ if (phpStringDelimiter[0] == '\"') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ } else if (isLineEnd(chPrev)) {
+ const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
+ const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
+ const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
+ if (isLineEnd(chAfterPsd) ||
+ (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
+ i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ if (foldHeredoc) levelCurrent--;
+ }
+ }
+ }
+ break;
+ case SCE_HPHP_SIMPLESTRING:
+ if (phpStringDelimiter[0] == '\'') {
+ if (ch == '\\') {
+ // skip the next char
+ i++;
+ } else if (ch == '\'') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ }
+ } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
+ const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
+ const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
+ const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
+ if (isLineEnd(chAfterPsd) ||
+ (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
+ i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ if (foldHeredoc) levelCurrent--;
+ }
+ }
+ break;
+ case SCE_HPHP_HSTRING_VARIABLE:
+ if (!IsPhpWordChar(chNext)) {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_HSTRING;
+ }
+ break;
+ case SCE_HPHP_COMPLEX_VARIABLE:
+ if (ch == '}') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_HSTRING;
+ }
+ break;
+ case SCE_HPHP_OPERATOR:
+ case SCE_HPHP_DEFAULT:
+ styler.ColourTo(i - 1, StateToPrint);
+ if (IsADigit(ch) || (ch == '.' && IsADigit(chNext))) {
+ state = SCE_HPHP_NUMBER;
+ } else if (IsAWordStart(ch)) {
+ state = SCE_HPHP_WORD;
+ } else if (ch == '/' && chNext == '*') {
+ i++;
+ state = SCE_HPHP_COMMENT;
+ } else if (ch == '/' && chNext == '/') {
+ i++;
+ state = SCE_HPHP_COMMENTLINE;
+ } else if (ch == '#') {
+ state = SCE_HPHP_COMMENTLINE;
+ } else if (ch == '\"') {
+ state = SCE_HPHP_HSTRING;
+ strcpy(phpStringDelimiter, "\"");
+ } else if (styler.Match(i, "<<<")) {
+ bool isSimpleString = false;
+ i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
+ if (strlen(phpStringDelimiter)) {
+ state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
+ if (foldHeredoc) levelCurrent++;
+ }
+ } else if (ch == '\'') {
+ state = SCE_HPHP_SIMPLESTRING;
+ strcpy(phpStringDelimiter, "\'");
+ } else if (ch == '$' && IsPhpWordStart(chNext)) {
+ state = SCE_HPHP_VARIABLE;
+ } else if (IsOperator(ch)) {
+ state = SCE_HPHP_OPERATOR;
+ } else if ((state == SCE_HPHP_OPERATOR) && (IsASpace(ch))) {
+ state = SCE_HPHP_DEFAULT;
+ }
+ break;
+ ///////////// end - PHP state handling
+ }
+
+ // Some of the above terminated their lexeme but since the same character starts
+ // the same class again, only reenter if non empty segment.
+
+ bool nonEmptySegment = i >= static_cast<int>(styler.GetStartSegment());
+ if (state == SCE_HB_DEFAULT) { // One of the above succeeded
+ if ((ch == '\"') && (nonEmptySegment)) {
+ state = SCE_HB_STRING;
+ } else if (ch == '\'') {
+ state = SCE_HB_COMMENTLINE;
+ } else if (IsAWordStart(ch)) {
+ state = SCE_HB_WORD;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i, SCE_HB_DEFAULT);
+ }
+ } else if (state == SCE_HBA_DEFAULT) { // One of the above succeeded
+ if ((ch == '\"') && (nonEmptySegment)) {
+ state = SCE_HBA_STRING;
+ } else if (ch == '\'') {
+ state = SCE_HBA_COMMENTLINE;
+ } else if (IsAWordStart(ch)) {
+ state = SCE_HBA_WORD;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i, SCE_HBA_DEFAULT);
+ }
+ } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded
+ if (ch == '/' && chNext == '*') {
+ if (styler.SafeGetCharAt(i + 2) == '*')
+ state = SCE_HJ_COMMENTDOC;
+ else
+ state = SCE_HJ_COMMENT;
+ } else if (ch == '/' && chNext == '/') {
+ state = SCE_HJ_COMMENTLINE;
+ } else if ((ch == '\"') && (nonEmptySegment)) {
+ state = SCE_HJ_DOUBLESTRING;
+ } else if ((ch == '\'') && (nonEmptySegment)) {
+ state = SCE_HJ_SINGLESTRING;
+ } else if (IsAWordStart(ch)) {
+ state = SCE_HJ_WORD;
+ } else if (IsOperator(ch)) {
+ styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
+ }
+ }
+ }
+
+ switch (state) {
+ case SCE_HJ_WORD:
+ classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType);
+ break;
+ case SCE_HB_WORD:
+ classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
+ break;
+ case SCE_HP_WORD:
+ classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType, isMako);
+ break;
+ case SCE_HPHP_WORD:
+ classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);
+ break;
+ default:
+ StateToPrint = statePrintForState(state, inScriptType);
+ if (static_cast<int>(styler.GetStartSegment()) < lengthDoc)
+ styler.ColourTo(lengthDoc - 1, StateToPrint);
+ break;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ if (fold) {
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+ }
+}
+
+static void ColouriseXMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ // Passing in true because we're lexing XML
+ ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ // Passing in false because we're notlexing XML
+ ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ if (startPos == 0)
+ initStyle = SCE_HPHP_DEFAULT;
+ ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler);
+}
+
+static const char * const htmlWordListDesc[] = {
+ "HTML elements and attributes",
+ "JavaScript keywords",
+ "VBScript keywords",
+ "Python keywords",
+ "PHP keywords",
+ "SGML and DTD keywords",
+ 0,
+};
+
+static const char * const phpscriptWordListDesc[] = {
+ "", //Unused
+ "", //Unused
+ "", //Unused
+ "", //Unused
+ "PHP keywords",
+ "", //Unused
+ 0,
+};
+
+LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, 8);
+LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, 8);
+LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 8);
--- /dev/null
+/******************************************************************
+ * LexHaskell.cxx
+ *
+ * A haskell lexer for the scintilla code control.
+ * Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
+ * External lexer stuff inspired from the caml external lexer.
+ *
+ * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
+ *
+ * Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
+ *
+ * TODO:
+ * * Implement a folder :)
+ * * Nice Character-lexing (stuff inside '\''), LexPython has
+ * this.
+ *
+ *
+ *****************************************************************/
+
+#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 "PropSetSimple.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
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+
+#include "ExternalLexer.h"
+#include "WindowAccessor.h"
+
+#define BUILD_EXTERNAL_LEXER 0
+
+#endif
+
+#define HA_MODE_DEFAULT 0
+#define HA_MODE_IMPORT1 1
+#define HA_MODE_IMPORT2 2
+#define HA_MODE_IMPORT3 3
+#define HA_MODE_MODULE 4
+#define HA_MODE_FFI 5
+#define HA_MODE_TYPE 6
+
+static inline bool IsNewline(const int ch) {
+ return (ch == '\n' || ch == '\r');
+}
+
+static inline bool IsWhitespace(const int ch) {
+ return ( ch == ' '
+ || ch == '\t'
+ || IsNewline(ch) );
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
+}
+
+static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &ffi = *keywordlists[1];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ int lineCurrent = styler.GetLine(startPos);
+ int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
+ : HA_MODE_DEFAULT;
+ int mode = state & 0xF;
+ int xmode = state >> 4;
+
+ while (sc.More()) {
+ // Check for state end
+
+ // Operator
+ if (sc.state == SCE_HA_OPERATOR) {
+ if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
+ sc.Forward();
+ } else {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ }
+ }
+ // String
+ else if (sc.state == SCE_HA_STRING) {
+ if (sc.ch == '\"') {
+ sc.Forward();
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else if (sc.ch == '\\') {
+ sc.Forward(2);
+ } else if (sc.atLineEnd) {
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
+ }
+ // Char
+ else if (sc.state == SCE_HA_CHARACTER) {
+ if (sc.ch == '\'') {
+ sc.Forward();
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else if (sc.ch == '\\') {
+ sc.Forward(2);
+ } else if (sc.atLineEnd) {
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
+ }
+ // Number
+ else if (sc.state == SCE_HA_NUMBER) {
+ if (IsADigit(sc.ch, xmode)) {
+ sc.Forward();
+ } else if ((xmode == 10) &&
+ (sc.ch == 'e' || sc.ch == 'E') &&
+ (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
+ sc.Forward();
+ if (sc.ch == '+' || sc.ch == '-')
+ sc.Forward();
+ } else {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ }
+ }
+ // Identifier
+ else if (sc.state == SCE_HA_IDENTIFIER) {
+ if (IsAWordChar(sc.ch)) {
+ sc.Forward();
+ } else {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ int style = sc.state;
+ int new_mode = 0;
+ if (keywords.InList(s)) {
+ style = SCE_HA_KEYWORD;
+ } else if (isupper(s[0])) {
+ if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
+ style = SCE_HA_MODULE;
+ new_mode = HA_MODE_IMPORT2;
+ } else if (mode == HA_MODE_MODULE)
+ style = SCE_HA_MODULE;
+ else
+ style = SCE_HA_CAPITAL;
+ } else if (mode == HA_MODE_IMPORT1 &&
+ strcmp(s,"qualified") == 0) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_IMPORT1;
+ } else if (mode == HA_MODE_IMPORT2) {
+ if (strcmp(s,"as") == 0) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_IMPORT3;
+ } else if (strcmp(s,"hiding") == 0) {
+ style = SCE_HA_KEYWORD;
+ }
+ } else if (mode == HA_MODE_FFI) {
+ if (ffi.InList(s)) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_FFI;
+ }
+ }
+ else if (mode == HA_MODE_TYPE) {
+ if (strcmp(s,"family") == 0)
+ style = SCE_HA_KEYWORD;
+ }
+ styler.ColourTo(sc.currentPos - 1, style);
+ if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
+ new_mode = HA_MODE_IMPORT1;
+ else if (strcmp(s,"module") == 0)
+ new_mode = HA_MODE_MODULE;
+ else if (strcmp(s,"foreign") == 0)
+ new_mode = HA_MODE_FFI;
+ else if (strcmp(s,"type") == 0)
+ new_mode = HA_MODE_TYPE;
+ sc.ChangeState(SCE_HA_DEFAULT);
+ mode = new_mode;
+ }
+ }
+
+ // Comments
+ // Oneliner
+ else if (sc.state == SCE_HA_COMMENTLINE) {
+ if (sc.atLineEnd) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
+ }
+ // Nested
+ else if (sc.state == SCE_HA_COMMENTBLOCK) {
+ if (sc.Match("{-")) {
+ sc.Forward(2);
+ xmode++;
+ }
+ else if (sc.Match("-}")) {
+ sc.Forward(2);
+ xmode--;
+ if (xmode == 0) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ }
+ } else {
+ if (sc.atLineEnd) {
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+ lineCurrent++;
+ }
+ sc.Forward();
+ }
+ }
+ // New state?
+ if (sc.state == SCE_HA_DEFAULT) {
+ // Digit
+ if (IsADigit(sc.ch) ||
+ (sc.ch == '.' && IsADigit(sc.chNext)) ||
+ (sc.ch == '-' && IsADigit(sc.chNext))) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_NUMBER);
+ if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
+ // Match anything starting with "0x" or "0X", too
+ sc.Forward(2);
+ xmode = 16;
+ } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
+ // Match anything starting with "0x" or "0X", too
+ sc.Forward(2);
+ xmode = 8;
+ } else {
+ sc.Forward();
+ xmode = 10;
+ }
+ mode = HA_MODE_DEFAULT;
+ }
+ // Comment line
+ else if (sc.Match("--")) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward(2);
+ sc.ChangeState(SCE_HA_COMMENTLINE);
+ // Comment block
+ }
+ else if (sc.Match("{-")) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward(2);
+ sc.ChangeState(SCE_HA_COMMENTBLOCK);
+ xmode = 1;
+ }
+ // String
+ else if (sc.Match('\"')) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_STRING);
+ }
+ // Character
+ else if (sc.Match('\'')) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_CHARACTER);
+ }
+ else if (sc.ch == '(' || sc.ch == ')' ||
+ sc.ch == '{' || sc.ch == '}' ||
+ sc.ch == '[' || sc.ch == ']') {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR);
+ mode = HA_MODE_DEFAULT;
+ }
+ // Operator
+ else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_OPERATOR);
+ mode = HA_MODE_DEFAULT;
+ }
+ // Keyword
+ else if (IsAWordStart(sc.ch)) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_IDENTIFIER);
+ } else {
+ if (sc.atLineEnd) {
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+ lineCurrent++;
+ }
+ sc.Forward();
+ }
+ }
+ }
+ sc.Complete();
+}
+
+// External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
+// Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
+#ifdef BUILD_EXTERNAL_LEXER
+static const char* LexerName = "haskell";
+
+void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
+ char *words[], WindowID window, char *props)
+{
+ PropSetSimple ps;
+ ps.SetMultiple(props);
+ WindowAccessor wa(window, ps);
+
+ int nWL = 0;
+ for (; words[nWL]; nWL++) ;
+ WordList** wl = new WordList* [nWL + 1];
+ int i = 0;
+ for (; i<nWL; i++)
+ {
+ wl[i] = new WordList();
+ wl[i]->Set(words[i]);
+ }
+ wl[i] = 0;
+
+ ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
+ wa.Flush();
+ for (i=nWL-1;i>=0;i--)
+ delete wl[i];
+ delete [] wl;
+}
+
+void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
+ char *words[], WindowID window, char *props)
+{
+
+}
+
+int EXT_LEXER_DECL GetLexerCount()
+{
+ return 1;
+}
+
+void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
+{
+ if (buflength > 0) {
+ buflength--;
+ int n = strlen(LexerName);
+ if (n > buflength)
+ n = buflength;
+ memcpy(name, LexerName, n), name[n] = '\0';
+ }
+}
+#endif
+
+LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
--- /dev/null
+// Scintilla source code edit control
+/** @file LexInno.cxx
+ ** Lexer for Inno Setup scripts.
+ **/
+// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
+// 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 void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
+ int state = SCE_INNO_DEFAULT;
+ char chPrev;
+ char ch = 0;
+ char chNext = styler[startPos];
+ int lengthDoc = startPos + length;
+ char *buffer = new char[length];
+ int bufferCount = 0;
+ bool isBOL, isEOL, isWS, isBOLWS = 0;
+ bool isCStyleComment = false;
+
+ WordList §ionKeywords = *keywordLists[0];
+ WordList &standardKeywords = *keywordLists[1];
+ WordList ¶meterKeywords = *keywordLists[2];
+ WordList &preprocessorKeywords = *keywordLists[3];
+ WordList &pascalKeywords = *keywordLists[4];
+ WordList &userKeywords = *keywordLists[5];
+
+ int curLine = styler.GetLine(startPos);
+ int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+ bool isCode = (curLineState == 1);
+
+ // Go through all provided text segment
+ // using the hand-written state machine shown below
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ for (int i = startPos; i < lengthDoc; i++) {
+ chPrev = ch;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ i++;
+ continue;
+ }
+
+ isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
+ isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
+ isEOL = (ch == '\n' || ch == '\r');
+ isWS = (ch == ' ' || ch == '\t');
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Remember the line state for future incremental lexing
+ curLine = styler.GetLine(i);
+ styler.SetLineState(curLine, (isCode ? 1 : 0));
+ }
+
+ switch(state) {
+ case SCE_INNO_DEFAULT:
+ if (!isCode && ch == ';' && isBOLWS) {
+ // Start of a comment
+ state = SCE_INNO_COMMENT;
+ } else if (ch == '[' && isBOLWS) {
+ // Start of a section name
+ bufferCount = 0;
+ state = SCE_INNO_SECTION;
+ } else if (ch == '#' && isBOLWS) {
+ // Start of a preprocessor directive
+ state = SCE_INNO_PREPROC;
+ } else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
+ // Start of an inline expansion
+ state = SCE_INNO_INLINE_EXPANSION;
+ } else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
+ // Start of a Pascal comment
+ state = SCE_INNO_COMMENT_PASCAL;
+ isCStyleComment = false;
+ } else if (isCode && ch == '/' && chNext == '/') {
+ // Apparently, C-style comments are legal, too
+ state = SCE_INNO_COMMENT_PASCAL;
+ isCStyleComment = true;
+ } else if (ch == '"') {
+ // Start of a double-quote string
+ state = SCE_INNO_STRING_DOUBLE;
+ } else if (ch == '\'') {
+ // Start of a single-quote string
+ state = SCE_INNO_STRING_SINGLE;
+ } else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {
+ // Start of an identifier
+ bufferCount = 0;
+ buffer[bufferCount++] = static_cast<char>(tolower(ch));
+ state = SCE_INNO_IDENTIFIER;
+ } else {
+ // Style it the default style
+ styler.ColourTo(i,SCE_INNO_DEFAULT);
+ }
+ break;
+
+ case SCE_INNO_COMMENT:
+ if (isEOL) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_COMMENT);
+ }
+ break;
+
+ case SCE_INNO_IDENTIFIER:
+ if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
+ buffer[bufferCount++] = static_cast<char>(tolower(ch));
+ } else {
+ state = SCE_INNO_DEFAULT;
+ buffer[bufferCount] = '\0';
+
+ // Check if the buffer contains a keyword
+ if (!isCode && standardKeywords.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_INNO_KEYWORD);
+ } else if (!isCode && parameterKeywords.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_INNO_PARAMETER);
+ } else if (isCode && pascalKeywords.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
+ } else if (!isCode && userKeywords.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
+ } else {
+ styler.ColourTo(i-1,SCE_INNO_DEFAULT);
+ }
+
+ // Push back the faulty character
+ chNext = styler[i--];
+ ch = chPrev;
+ }
+ break;
+
+ case SCE_INNO_SECTION:
+ if (ch == ']') {
+ state = SCE_INNO_DEFAULT;
+ buffer[bufferCount] = '\0';
+
+ // Check if the buffer contains a section name
+ if (sectionKeywords.InList(buffer)) {
+ styler.ColourTo(i,SCE_INNO_SECTION);
+ isCode = !CompareCaseInsensitive(buffer, "code");
+ } else {
+ styler.ColourTo(i,SCE_INNO_DEFAULT);
+ }
+ } else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
+ buffer[bufferCount++] = static_cast<char>(tolower(ch));
+ } else {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_DEFAULT);
+ }
+ break;
+
+ case SCE_INNO_PREPROC:
+ if (isWS || isEOL) {
+ if (isascii(chPrev) && isalpha(chPrev)) {
+ state = SCE_INNO_DEFAULT;
+ buffer[bufferCount] = '\0';
+
+ // Check if the buffer contains a preprocessor directive
+ if (preprocessorKeywords.InList(buffer)) {
+ styler.ColourTo(i-1,SCE_INNO_PREPROC);
+ } else {
+ styler.ColourTo(i-1,SCE_INNO_DEFAULT);
+ }
+
+ // Push back the faulty character
+ chNext = styler[i--];
+ ch = chPrev;
+ }
+ } else if (isascii(ch) && isalpha(ch)) {
+ if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
+ bufferCount = 0;
+ buffer[bufferCount++] = static_cast<char>(tolower(ch));
+ }
+ break;
+
+ case SCE_INNO_STRING_DOUBLE:
+ if (ch == '"' || isEOL) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
+ }
+ break;
+
+ case SCE_INNO_STRING_SINGLE:
+ if (ch == '\'' || isEOL) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
+ }
+ break;
+
+ case SCE_INNO_INLINE_EXPANSION:
+ if (ch == '}') {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
+ } else if (isEOL) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_DEFAULT);
+ }
+ break;
+
+ case SCE_INNO_COMMENT_PASCAL:
+ if (isCStyleComment) {
+ if (isEOL) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
+ }
+ } else {
+ if (ch == '}' || (ch == ')' && chPrev == '*')) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
+ } else if (isEOL) {
+ state = SCE_INNO_DEFAULT;
+ styler.ColourTo(i,SCE_INNO_DEFAULT);
+ }
+ }
+ break;
+
+ }
+ }
+ delete []buffer;
+}
+
+static const char * const innoWordListDesc[] = {
+ "Sections",
+ "Keywords",
+ "Parameters",
+ "Preprocessor directives",
+ "Pascal keywords",
+ "User defined keywords",
+ 0
+};
+
+static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ char chNext = styler[startPos];
+
+ int lineCurrent = styler.GetLine(startPos);
+
+ bool sectionFlag = false;
+ int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
+ int level;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler[i+1];
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ int style = styler.StyleAt(i);
+
+ if (style == SCE_INNO_SECTION)
+ sectionFlag = true;
+
+ if (atEOL || i == endPos - 1) {
+ if (sectionFlag) {
+ level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ if (level == levelPrev)
+ styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
+ } else {
+ level = levelPrev & SC_FOLDLEVELNUMBERMASK;
+ if (levelPrev & SC_FOLDLEVELHEADERFLAG)
+ level++;
+ }
+
+ styler.SetLevel(lineCurrent, level);
+
+ levelPrev = level;
+ lineCurrent++;
+ sectionFlag = false;
+ }
+ }
+}
+
+LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexKix.cxx
+ ** Lexer for KIX-Scripts.
+ **/
+// Copyright 2004 by Manfred Becker <manfred@becker-trdf.de>
+// 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
+
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+ return ch >= 0x80 || isalnum(ch) || ch == '_';
+}
+
+static inline bool IsOperator(const int ch) {
+ return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '=');
+}
+
+static void ColouriseKixDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+// WordList &keywords4 = *keywordlists[3];
+
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_KIX_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_STRING1) {
+ // This is a doubles quotes string
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_STRING2) {
+ // This is a single quote string
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_NUMBER) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_VAR) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_MACRO) {
+ if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+
+ if (!keywords3.InList(&s[1])) {
+ sc.ChangeState(SCE_KIX_DEFAULT);
+ }
+ sc.SetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_OPERATOR) {
+ if (!IsOperator(sc.ch)) {
+ sc.SetState(SCE_KIX_DEFAULT);
+ }
+ } else if (sc.state == SCE_KIX_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_KIX_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_KIX_FUNCTIONS);
+ }
+ sc.SetState(SCE_KIX_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_KIX_DEFAULT) {
+ if (sc.ch == ';') {
+ sc.SetState(SCE_KIX_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_KIX_STRING1);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_KIX_STRING2);
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_KIX_VAR);
+ } else if (sc.ch == '@') {
+ sc.SetState(SCE_KIX_MACRO);
+ } else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_KIX_NUMBER);
+ } else if (IsOperator(sc.ch)) {
+ sc.SetState(SCE_KIX_OPERATOR);
+ } else if (IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_KIX_IDENTIFIER);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+
+LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, "kix");
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexLisp.cxx
+ ** Lexer for Lisp.
+ ** Written by Alexey Yutkin.
+ **/
+// 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
+
+#define SCE_LISP_CHARACTER 29
+#define SCE_LISP_MACRO 30
+#define SCE_LISP_MACRO_DISPATCH 31
+
+static inline bool isLispoperator(char ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
+ return true;
+ return false;
+}
+
+static inline bool isLispwordstart(char ch) {
+ return isascii(ch) && ch != ';' && !isspacechar(ch) && !isLispoperator(ch) &&
+ ch != '\n' && ch != '\r' && ch != '\"';
+}
+
+
+static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
+ assert(end >= start);
+ char s[100];
+ unsigned int i;
+ bool digit_flag = true;
+ for (i = 0; (i < end - start + 1) && (i < 99); i++) {
+ s[i] = styler[start + i];
+ s[i + 1] = '\0';
+ if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
+ }
+ char chAttr = SCE_LISP_IDENTIFIER;
+
+ if(digit_flag) chAttr = SCE_LISP_NUMBER;
+ else {
+ if (keywords.InList(s)) {
+ chAttr = SCE_LISP_KEYWORD;
+ } else if (keywords_kw.InList(s)) {
+ chAttr = SCE_LISP_KEYWORD_KW;
+ } else if ((s[0] == '*' && s[i-1] == '*') ||
+ (s[0] == '+' && s[i-1] == '+')) {
+ chAttr = SCE_LISP_SPECIAL;
+ }
+ }
+ styler.ColourTo(end, chAttr);
+ return;
+}
+
+
+static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords_kw = *keywordlists[1];
+
+ styler.StartAt(startPos);
+
+ int state = initStyle, radix = -1;
+ char chNext = styler[startPos];
+ unsigned int lengthDoc = startPos + length;
+ styler.StartSegment(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ i += 1;
+ continue;
+ }
+
+ if (state == SCE_LISP_DEFAULT) {
+ if (ch == '#') {
+ styler.ColourTo(i - 1, state);
+ radix = -1;
+ state = SCE_LISP_MACRO_DISPATCH;
+ } else if (ch == ':' && isLispwordstart(chNext)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_SYMBOL;
+ } else if (isLispwordstart(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_IDENTIFIER;
+ }
+ else if (ch == ';') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_COMMENT;
+ }
+ else if (isLispoperator(ch) || ch=='\'') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
+ }
+ else if (ch == '\"') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_STRING;
+ }
+ } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
+ if (!isLispwordstart(ch)) {
+ if (state == SCE_LISP_IDENTIFIER) {
+ classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
+ } else {
+ styler.ColourTo(i - 1, state);
+ }
+ state = SCE_LISP_DEFAULT;
+ } /*else*/
+ if (isLispoperator(ch) || ch=='\'') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
+ }
+ } else if (state == SCE_LISP_MACRO_DISPATCH) {
+ if (!(isascii(ch) && isdigit(ch))) {
+ if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
+ state = SCE_LISP_DEFAULT;
+ } else {
+ switch (ch) {
+ case '|': state = SCE_LISP_MULTI_COMMENT; break;
+ case 'o':
+ case 'O': radix = 8; state = SCE_LISP_MACRO; break;
+ case 'x':
+ case 'X': radix = 16; state = SCE_LISP_MACRO; break;
+ case 'b':
+ case 'B': radix = 2; state = SCE_LISP_MACRO; break;
+ case '\\': state = SCE_LISP_CHARACTER; break;
+ case ':':
+ case '-':
+ case '+': state = SCE_LISP_MACRO; break;
+ case '\'': if (isLispwordstart(chNext)) {
+ state = SCE_LISP_SPECIAL;
+ } else {
+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ state = SCE_LISP_DEFAULT;
+ }
+ break;
+ default: if (isLispoperator(ch)) {
+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ }
+ state = SCE_LISP_DEFAULT;
+ break;
+ }
+ }
+ }
+ } else if (state == SCE_LISP_MACRO) {
+ if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
+ state = SCE_LISP_SPECIAL;
+ } else {
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_CHARACTER) {
+ if (isLispoperator(ch)) {
+ styler.ColourTo(i, SCE_LISP_SPECIAL);
+ state = SCE_LISP_DEFAULT;
+ } else if (isLispwordstart(ch)) {
+ styler.ColourTo(i, SCE_LISP_SPECIAL);
+ state = SCE_LISP_SPECIAL;
+ } else {
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_SPECIAL) {
+ if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_DEFAULT;
+ }
+ if (isLispoperator(ch) || ch=='\'') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
+ }
+ } else {
+ if (state == SCE_LISP_COMMENT) {
+ if (atEOL) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_MULTI_COMMENT) {
+ if (ch == '|' && chNext == '#') {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ styler.ColourTo(i, state);
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_STRING) {
+ if (ch == '\\') {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ } else if (ch == '\"') {
+ styler.ColourTo(i, state);
+ state = SCE_LISP_DEFAULT;
+ }
+ }
+ }
+
+ }
+ styler.ColourTo(lengthDoc - 1, state);
+}
+
+static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_LISP_OPERATOR) {
+ if (ch == '(' || ch == '[' || ch == '{') {
+ levelCurrent++;
+ } else if (ch == ')' || ch == ']' || ch == '}') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const lispWordListDesc[] = {
+ "Functions and special operators",
+ "Keywords",
+ 0
+};
+
+LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexLout.cxx
+ ** Lexer for the Basser Lout (>= version 3) typesetting language
+ **/
+// Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>
+// 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
+}
+
+static inline bool IsAnOther(const int ch) {
+ return (ch < 0x80) && (ch == '{' || ch == '}' ||
+ ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
+ ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
+ ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
+ ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
+ ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
+}
+
+static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+
+ int visibleChars = 0;
+ int firstWordInLine = 0;
+ int leadingAtSign = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
+ // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_LOUT_STRING);
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_LOUT_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_LOUT_DEFAULT);
+ visibleChars = 0;
+ }
+ } else if (sc.state == SCE_LOUT_NUMBER) {
+ if (!IsADigit(sc.ch) && sc.ch != '.') {
+ sc.SetState(SCE_LOUT_DEFAULT);
+ }
+ } else if (sc.state == SCE_LOUT_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_LOUT_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_LOUT_STRINGEOL);
+ sc.ForwardSetState(SCE_LOUT_DEFAULT);
+ visibleChars = 0;
+ }
+ } else if (sc.state == SCE_LOUT_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+
+ if (leadingAtSign) {
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_LOUT_WORD);
+ } else {
+ sc.ChangeState(SCE_LOUT_WORD4);
+ }
+ } else if (firstWordInLine && keywords3.InList(s)) {
+ sc.ChangeState(SCE_LOUT_WORD3);
+ }
+ sc.SetState(SCE_LOUT_DEFAULT);
+ }
+ } else if (sc.state == SCE_LOUT_OPERATOR) {
+ if (!IsAnOther(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+
+ if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_LOUT_WORD2);
+ }
+ sc.SetState(SCE_LOUT_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_LOUT_DEFAULT) {
+ if (sc.ch == '#') {
+ sc.SetState(SCE_LOUT_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_LOUT_STRING);
+ } else if (IsADigit(sc.ch) ||
+ (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_LOUT_NUMBER);
+ } else if (IsAWordChar(sc.ch)) {
+ firstWordInLine = (visibleChars == 0);
+ leadingAtSign = (sc.ch == '@');
+ sc.SetState(SCE_LOUT_IDENTIFIER);
+ } else if (IsAnOther(sc.ch)) {
+ sc.SetState(SCE_LOUT_OPERATOR);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[],
+ Accessor &styler) {
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ int styleNext = styler.StyleAt(startPos);
+ char s[10];
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (style == SCE_LOUT_WORD) {
+ if (ch == '@') {
+ for (unsigned int j = 0; j < 8; j++) {
+ if (!IsAWordChar(styler[i + j])) {
+ break;
+ }
+ s[j] = styler[i + j];
+ s[j + 1] = '\0';
+ }
+ if (strcmp(s, "@Begin") == 0) {
+ levelCurrent++;
+ } else if (strcmp(s, "@End") == 0) {
+ levelCurrent--;
+ }
+ }
+ } else if (style == SCE_LOUT_OPERATOR) {
+ if (ch == '{') {
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact) {
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ }
+ if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const loutWordLists[] = {
+ "Predefined identifiers",
+ "Predefined delimiters",
+ "Predefined keywords",
+ 0,
+ };
+
+LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexLua.cxx
+ ** Lexer for Lua language.
+ **
+ ** Written by Paul Winwood.
+ ** Folder by Alexey Yutkin.
+ ** Modified by Marcos E. Wurzius & Philippe Lhoste
+ **/
+
+#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
+
+// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],
+// return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.
+// The maximum number of '=' characters allowed is 254.
+static int LongDelimCheck(StyleContext &sc) {
+ int sep = 1;
+ while (sc.GetRelative(sep) == '=' && sep < 0xFF)
+ sep++;
+ if (sc.GetRelative(sep) == sc.ch)
+ return sep;
+ return 0;
+}
+
+static void ColouriseLuaDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+
+ // Accepts accented characters
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases. [pP] is for hex floats.
+ CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
+ CharacterSet setExponent(CharacterSet::setNone, "eEpP");
+ CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
+ CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
+
+ int currentLine = styler.GetLine(startPos);
+ // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
+ // if we are inside such a string. Block comment was introduced in Lua 5.0,
+ // blocks with separators [=[ ... ]=] in Lua 5.1.
+ // Continuation of a string (\z whitespace escaping) is controlled by stringWs.
+ int nestLevel = 0;
+ int sepCount = 0;
+ int stringWs = 0;
+ if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
+ initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
+ int lineState = styler.GetLineState(currentLine - 1);
+ nestLevel = lineState >> 9;
+ sepCount = lineState & 0xFF;
+ stringWs = lineState & 0x100;
+ }
+
+ // Do not leak onto next line
+ if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
+ initStyle = SCE_LUA_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ if (startPos == 0 && sc.ch == '#') {
+ // shbang line: # is a comment only if first char of the script
+ sc.SetState(SCE_LUA_COMMENTLINE);
+ }
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ currentLine = styler.GetLine(sc.currentPos);
+ switch (sc.state) {
+ case SCE_LUA_LITERALSTRING:
+ case SCE_LUA_COMMENT:
+ case SCE_LUA_STRING:
+ case SCE_LUA_CHARACTER:
+ // Inside a literal string, block comment or string, we set the line state
+ styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
+ break;
+ default:
+ // Reset the line state
+ styler.SetLineState(currentLine, 0);
+ break;
+ }
+ }
+ if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {
+ // Prevent SCE_LUA_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_LUA_STRING);
+ }
+
+ // Handle string line continuation
+ if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&
+ sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_LUA_OPERATOR) {
+ if (sc.ch == ':' && sc.chPrev == ':') { // :: <label> :: forward scan
+ sc.Forward();
+ int ln = 0, maxln = startPos + length - sc.currentPos;
+ int c;
+ while (ln < maxln) { // determine line extent
+ c = sc.GetRelative(ln);
+ if (c == '\r' || c == '\n')
+ break;
+ ln++;
+ }
+ maxln = ln; ln = 0;
+ while (ln < maxln) { // skip over spaces/tabs
+ if (!IsASpaceOrTab(sc.GetRelative(ln)))
+ break;
+ ln++;
+ }
+ int ws1 = ln;
+ if (setWordStart.Contains(sc.GetRelative(ln))) {
+ int i = 0;
+ char s[100];
+ while (ln < maxln) { // get potential label
+ c = sc.GetRelative(ln);
+ if (!setWord.Contains(c))
+ break;
+ if (i < 90)
+ s[i++] = c;
+ ln++;
+ }
+ s[i] = '\0'; int lbl = ln;
+ if (!keywords.InList(s)) {
+ while (ln < maxln) { // skip over spaces/tabs
+ if (!IsASpaceOrTab(sc.GetRelative(ln)))
+ break;
+ ln++;
+ }
+ int ws2 = ln - lbl;
+ if (sc.GetRelative(ln) == ':' && sc.GetRelative(ln + 1) == ':') {
+ // final :: found, complete valid label construct
+ sc.ChangeState(SCE_LUA_LABEL);
+ if (ws1) {
+ sc.SetState(SCE_LUA_DEFAULT);
+ sc.Forward(ws1);
+ }
+ sc.SetState(SCE_LUA_LABEL);
+ sc.Forward(lbl - ws1);
+ if (ws2) {
+ sc.SetState(SCE_LUA_DEFAULT);
+ sc.Forward(ws2);
+ }
+ sc.SetState(SCE_LUA_LABEL);
+ sc.Forward(2);
+ }
+ }
+ }
+ }
+ sc.SetState(SCE_LUA_DEFAULT);
+ } else if (sc.state == SCE_LUA_NUMBER) {
+ // We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
+ if (!setNumber.Contains(sc.ch)) {
+ sc.SetState(SCE_LUA_DEFAULT);
+ } else if (sc.ch == '-' || sc.ch == '+') {
+ if (!setExponent.Contains(sc.chPrev))
+ sc.SetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sc.state == SCE_LUA_IDENTIFIER) {
+ if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD);
+ if (strcmp(s, "goto") == 0) { // goto <label> forward scan
+ sc.SetState(SCE_LUA_DEFAULT);
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+ sc.Forward();
+ if (setWordStart.Contains(sc.ch)) {
+ sc.SetState(SCE_LUA_LABEL);
+ sc.Forward();
+ while (setWord.Contains(sc.ch))
+ sc.Forward();
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords.InList(s))
+ sc.ChangeState(SCE_LUA_WORD);
+ }
+ sc.SetState(SCE_LUA_DEFAULT);
+ }
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD4);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD5);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD6);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD7);
+ } else if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD8);
+ }
+ sc.SetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sc.state == SCE_LUA_COMMENTLINE || sc.state == SCE_LUA_PREPROCESSOR) {
+ if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sc.state == SCE_LUA_STRING) {
+ if (stringWs) {
+ if (!IsASpace(sc.ch))
+ stringWs = 0;
+ }
+ if (sc.ch == '\\') {
+ if (setEscapeSkip.Contains(sc.chNext)) {
+ sc.Forward();
+ } else if (sc.chNext == 'z') {
+ sc.Forward();
+ stringWs = 0x100;
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ } else if (stringWs == 0 && sc.atLineEnd) {
+ sc.ChangeState(SCE_LUA_STRINGEOL);
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sc.state == SCE_LUA_CHARACTER) {
+ if (stringWs) {
+ if (!IsASpace(sc.ch))
+ stringWs = 0;
+ }
+ if (sc.ch == '\\') {
+ if (setEscapeSkip.Contains(sc.chNext)) {
+ sc.Forward();
+ } else if (sc.chNext == 'z') {
+ sc.Forward();
+ stringWs = 0x100;
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ } else if (stringWs == 0 && sc.atLineEnd) {
+ sc.ChangeState(SCE_LUA_STRINGEOL);
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) {
+ if (sc.ch == '[') {
+ int sep = LongDelimCheck(sc);
+ if (sep == 1 && sepCount == 1) { // [[-only allowed to nest
+ nestLevel++;
+ sc.Forward();
+ }
+ } else if (sc.ch == ']') {
+ int sep = LongDelimCheck(sc);
+ if (sep == 1 && sepCount == 1) { // un-nest with ]]-only
+ nestLevel--;
+ sc.Forward();
+ if (nestLevel == 0) {
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sep > 1 && sep == sepCount) { // ]=]-style delim
+ sc.Forward(sep);
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_LUA_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_LUA_NUMBER);
+ if (sc.ch == '0' && toupper(sc.chNext) == 'X') {
+ sc.Forward();
+ }
+ } else if (setWordStart.Contains(sc.ch)) {
+ sc.SetState(SCE_LUA_IDENTIFIER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_LUA_STRING);
+ stringWs = 0;
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_LUA_CHARACTER);
+ stringWs = 0;
+ } else if (sc.ch == '[') {
+ sepCount = LongDelimCheck(sc);
+ if (sepCount == 0) {
+ sc.SetState(SCE_LUA_OPERATOR);
+ } else {
+ nestLevel = 1;
+ sc.SetState(SCE_LUA_LITERALSTRING);
+ sc.Forward(sepCount);
+ }
+ } else if (sc.Match('-', '-')) {
+ sc.SetState(SCE_LUA_COMMENTLINE);
+ if (sc.Match("--[")) {
+ sc.Forward(2);
+ sepCount = LongDelimCheck(sc);
+ if (sepCount > 0) {
+ nestLevel = 1;
+ sc.ChangeState(SCE_LUA_COMMENT);
+ sc.Forward(sepCount);
+ }
+ } else {
+ sc.Forward();
+ }
+ } else if (sc.atLineStart && sc.Match('$')) {
+ sc.SetState(SCE_LUA_PREPROCESSOR); // Obsolete since Lua 4.0, but still in old code
+ } else if (setLuaOperator.Contains(sc.ch)) {
+ sc.SetState(SCE_LUA_OPERATOR);
+ }
+ }
+ }
+
+ if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD4);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD5);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD6);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD7);
+ } else if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_LUA_WORD8);
+ }
+ }
+
+ sc.Complete();
+}
+
+static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ int styleNext = styler.StyleAt(startPos);
+ char s[10];
+
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_LUA_WORD) {
+ if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
+ for (unsigned int j = 0; j < 8; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = styler[i + j];
+ s[j + 1] = '\0';
+ }
+
+ if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) {
+ levelCurrent++;
+ }
+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) {
+ levelCurrent--;
+ }
+ }
+ } else if (style == SCE_LUA_OPERATOR) {
+ if (ch == '{' || ch == '(') {
+ levelCurrent++;
+ } else if (ch == '}' || ch == ')') {
+ levelCurrent--;
+ }
+ } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact) {
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ }
+ if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch)) {
+ visibleChars++;
+ }
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const luaWordListDesc[] = {
+ "Keywords",
+ "Basic functions",
+ "String, (table) & math functions",
+ "(coroutines), I/O & system facilities",
+ "user1",
+ "user2",
+ "user3",
+ "user4",
+ 0
+};
+
+LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexMMIXAL.cxx
+ ** Lexer for MMIX Assembler Language.
+ ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
+ ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
+ **/
+// Copyright 1998-2003 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
+}
+
+inline bool isMMIXALOperator(char ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
+ ch == '*' || ch == '/' ||
+ ch == '%' || ch == '<' || ch == '>' || ch == '&' ||
+ ch == '~' || ch == '$' ||
+ ch == ',' || ch == '(' || ch == ')' ||
+ ch == '[' || ch == ']')
+ return true;
+ return false;
+}
+
+static void ColouriseMMIXALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &opcodes = *keywordlists[0];
+ WordList &special_register = *keywordlists[1];
+ WordList &predef_symbols = *keywordlists[2];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+ // No EOL continuation
+ if (sc.atLineStart) {
+ if (sc.ch == '@' && sc.chNext == 'i') {
+ sc.SetState(SCE_MMIXAL_INCLUDE);
+ } else {
+ sc.SetState(SCE_MMIXAL_LEADWS);
+ }
+ }
+
+ // Check if first non whitespace character in line is alphanumeric
+ if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) { // LEADWS
+ if(!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_MMIXAL_COMMENT);
+ } else {
+ if(sc.atLineStart) {
+ sc.SetState(SCE_MMIXAL_LABEL);
+ } else {
+ sc.SetState(SCE_MMIXAL_OPCODE_PRE);
+ }
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_MMIXAL_OPERATOR) { // OPERATOR
+ sc.SetState(SCE_MMIXAL_OPERANDS);
+ } else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER
+ if (!isdigit(sc.ch)) {
+ if (IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ sc.ChangeState(SCE_MMIXAL_REF);
+ sc.SetState(SCE_MMIXAL_REF);
+ } else {
+ sc.SetState(SCE_MMIXAL_OPERANDS);
+ }
+ }
+ } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
+ if (!IsAWordChar(sc.ch) ) {
+ sc.SetState(SCE_MMIXAL_OPCODE_PRE);
+ }
+ } else if (sc.state == SCE_MMIXAL_REF) { // REF
+ if (!IsAWordChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (*s == ':') { // ignore base prefix for match
+ for (size_t i = 0; i != sizeof(s); ++i) {
+ *(s+i) = *(s+i+1);
+ }
+ }
+ if (special_register.InList(s)) {
+ sc.ChangeState(SCE_MMIXAL_REGISTER);
+ } else if (predef_symbols.InList(s)) {
+ sc.ChangeState(SCE_MMIXAL_SYMBOL);
+ }
+ sc.SetState(SCE_MMIXAL_OPERANDS);
+ }
+ } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
+ if (!isspace(sc.ch)) {
+ sc.SetState(SCE_MMIXAL_OPCODE);
+ }
+ } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
+ if (!IsAWordChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (opcodes.InList(s)) {
+ sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
+ } else {
+ sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
+ }
+ sc.SetState(SCE_MMIXAL_OPCODE_POST);
+ }
+ } else if (sc.state == SCE_MMIXAL_STRING) { // STRING
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
+ } else if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
+ }
+ } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
+ } else if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
+ }
+ } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
+ if (!isdigit(sc.ch)) {
+ sc.SetState(SCE_MMIXAL_OPERANDS);
+ }
+ } else if (sc.state == SCE_MMIXAL_HEX) { // HEX
+ if (!isxdigit(sc.ch)) {
+ sc.SetState(SCE_MMIXAL_OPERANDS);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST
+ sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS
+ if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
+ if (!sc.atLineEnd) {
+ sc.SetState(SCE_MMIXAL_COMMENT);
+ }
+ } else if (isdigit(sc.ch)) {
+ sc.SetState(SCE_MMIXAL_NUMBER);
+ } else if (IsAWordChar(sc.ch) || sc.Match('@')) {
+ sc.SetState(SCE_MMIXAL_REF);
+ } else if (sc.Match('\"')) {
+ sc.SetState(SCE_MMIXAL_STRING);
+ } else if (sc.Match('\'')) {
+ sc.SetState(SCE_MMIXAL_CHAR);
+ } else if (sc.Match('$')) {
+ sc.SetState(SCE_MMIXAL_REGISTER);
+ } else if (sc.Match('#')) {
+ sc.SetState(SCE_MMIXAL_HEX);
+ } else if (isMMIXALOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_MMIXAL_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static const char * const MMIXALWordListDesc[] = {
+ "Operation Codes",
+ "Special Register",
+ "Predefined Symbols",
+ 0
+};
+
+LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexMPT.cxx
+ ** Lexer for MPT specific files. Based on LexOthers.cxx
+ ** LOT = the text log file created by the MPT application while running a test program
+ ** Other MPT specific files to be added later.
+ **/
+// Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>
+// 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 <string>
+
+#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 int GetLotLineState(std::string &line) {
+ if (line.length()) {
+ // Most of the time the first non-blank character in line determines that line's type
+ // Now finds the first non-blank character
+ unsigned i; // Declares counter here to make it persistent after the for loop
+ for (i = 0; i < line.length(); ++i) {
+ if (!(isascii(line[i]) && isspace(line[i])))
+ break;
+ }
+
+ // Checks if it was a blank line
+ if (i == line.length())
+ return SCE_LOT_DEFAULT;
+
+ switch (line[i]) {
+ case '*': // Fail measurement
+ return SCE_LOT_FAIL;
+
+ case '+': // Header
+ case '|': // Header
+ return SCE_LOT_HEADER;
+
+ case ':': // Set test limits
+ return SCE_LOT_SET;
+
+ case '-': // Section break
+ return SCE_LOT_BREAK;
+
+ default: // Any other line
+ // Checks for message at the end of lot file
+ if (line.find("PASSED") != std::string::npos) {
+ return SCE_LOT_PASS;
+ }
+ else if (line.find("FAILED") != std::string::npos) {
+ return SCE_LOT_FAIL;
+ }
+ else if (line.find("ABORTED") != std::string::npos) {
+ return SCE_LOT_ABORT;
+ }
+ else {
+ return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
+ }
+ }
+ }
+ else {
+ return SCE_LOT_DEFAULT;
+ }
+}
+
+static void ColourizeLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ bool atLineStart = true;// Arms the 'at line start' flag
+ char chNext = styler.SafeGetCharAt(startPos);
+ std::string line("");
+ line.reserve(256); // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
+
+ // Styles LOT document
+ unsigned int i; // Declared here because it's used after the for loop
+ for (i = startPos; i < startPos + length; ++i) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ line += ch;
+ atLineStart = false;
+
+ // LOT files are only used on the Win32 platform, thus EOL == CR+LF
+ // Searches for the end of line
+ if (ch == '\r' && chNext == '\n') {
+ line += chNext; // Gets the '\n'
+ ++i; // Advances past the '\n'
+ chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line
+ styler.ColourTo(i, GetLotLineState(line));
+ line = "";
+ atLineStart = true; // Arms flag for next line
+ }
+ }
+
+ // Last line may not have a line ending
+ if (!atLineStart) {
+ styler.ColourTo(i - 1, GetLotLineState(line));
+ }
+}
+
+// Folds an MPT LOT file: the blocks that can be folded are:
+// sections (headed by a set line)
+// passes (contiguous pass results within a section)
+// fails (contiguous fail results within a section)
+static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+
+ char chNext = styler.SafeGetCharAt(startPos);
+ int style = SCE_LOT_DEFAULT;
+ int styleNext = styler.StyleAt(startPos);
+ int lev = SC_FOLDLEVELBASE;
+
+ // Gets style of previous line if not at the beginning of the document
+ if (startPos > 1)
+ style = styler.StyleAt(startPos - 2);
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (ch == '\r' && chNext == '\n') {
+ // TO DO:
+ // Should really get the state of the previous line from the styler
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 2);
+
+ switch (style) {
+/*
+ case SCE_LOT_SET:
+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ break;
+*/
+ case SCE_LOT_FAIL:
+/*
+ if (stylePrev != SCE_LOT_FAIL)
+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ else
+ lev = SC_FOLDLEVELBASE + 1;
+*/
+ lev = SC_FOLDLEVELBASE;
+ break;
+
+ default:
+ if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ else
+ lev = SC_FOLDLEVELBASE + 1;
+
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ break;
+ }
+
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+
+ lineCurrent++;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, lev | flagsNext);
+}
+
+static const char * const emptyWordListDesc[] = {
+ 0
+};
+
+LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexMSSQL.cxx
+ ** Lexer for MSSQL.
+ **/
+// By Filip Yaghob <fyaghob@gmail.com>
+// 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
+
+#define KW_MSSQL_STATEMENTS 0
+#define KW_MSSQL_DATA_TYPES 1
+#define KW_MSSQL_SYSTEM_TABLES 2
+#define KW_MSSQL_GLOBAL_VARIABLES 3
+#define KW_MSSQL_FUNCTIONS 4
+#define KW_MSSQL_STORED_PROCEDURES 5
+#define KW_MSSQL_OPERATORS 6
+
+static bool isMSSQLOperator(char ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
+ ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
+ ch == '<' || ch == '>' || ch == '/' ||
+ ch == '!' || ch == '~' || ch == '(' || ch == ')' ||
+ ch == ',')
+ return true;
+ return false;
+}
+
+static char classifyWordSQL(unsigned int start,
+ unsigned int end,
+ WordList *keywordlists[],
+ Accessor &styler,
+ unsigned int actualState,
+ unsigned int prevState) {
+ char s[256];
+ bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
+
+ WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
+ WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
+ WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
+ WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
+ WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
+ WordList &kwStoredProcedures = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
+ WordList &kwOperators = *keywordlists[KW_MSSQL_OPERATORS];
+
+ for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ s[i + 1] = '\0';
+ }
+ char chAttr = SCE_MSSQL_IDENTIFIER;
+
+ if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {
+
+ if (kwGlobalVariables.InList(&s[2]))
+ chAttr = SCE_MSSQL_GLOBAL_VARIABLE;
+
+ } else if (wordIsNumber) {
+ chAttr = SCE_MSSQL_NUMBER;
+
+ } else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
+ // Look first in datatypes
+ if (kwDataTypes.InList(s))
+ chAttr = SCE_MSSQL_DATATYPE;
+ else if (kwOperators.InList(s))
+ chAttr = SCE_MSSQL_OPERATOR;
+ else if (kwStatements.InList(s))
+ chAttr = SCE_MSSQL_STATEMENT;
+ else if (kwSystemTables.InList(s))
+ chAttr = SCE_MSSQL_SYSTABLE;
+ else if (kwFunctions.InList(s))
+ chAttr = SCE_MSSQL_FUNCTION;
+ else if (kwStoredProcedures.InList(s))
+ chAttr = SCE_MSSQL_STORED_PROCEDURE;
+
+ } else {
+ if (kwOperators.InList(s))
+ chAttr = SCE_MSSQL_OPERATOR;
+ else if (kwStatements.InList(s))
+ chAttr = SCE_MSSQL_STATEMENT;
+ else if (kwSystemTables.InList(s))
+ chAttr = SCE_MSSQL_SYSTABLE;
+ else if (kwFunctions.InList(s))
+ chAttr = SCE_MSSQL_FUNCTION;
+ else if (kwStoredProcedures.InList(s))
+ chAttr = SCE_MSSQL_STORED_PROCEDURE;
+ else if (kwDataTypes.InList(s))
+ chAttr = SCE_MSSQL_DATATYPE;
+ }
+
+ styler.ColourTo(end, chAttr);
+
+ return chAttr;
+}
+
+static void ColouriseMSSQLDoc(unsigned int startPos, int length,
+ int initStyle, WordList *keywordlists[], Accessor &styler) {
+
+
+ styler.StartAt(startPos);
+
+ bool fold = styler.GetPropertyInt("fold") != 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int spaceFlags = 0;
+
+ int state = initStyle;
+ int prevState = initStyle;
+ char chPrev = ' ';
+ char chNext = styler[startPos];
+ styler.StartSegment(startPos);
+ unsigned int lengthDoc = startPos + length;
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
+ int lev = indentCurrent;
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ // Only non whitespace lines can be headers
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
+ if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ if (fold) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ }
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ // When the last char isn't part of the state (have to deal with it too)...
+ if ( (state == SCE_MSSQL_IDENTIFIER) ||
+ (state == SCE_MSSQL_STORED_PROCEDURE) ||
+ (state == SCE_MSSQL_DATATYPE) ||
+ //~ (state == SCE_MSSQL_COLUMN_NAME) ||
+ (state == SCE_MSSQL_FUNCTION) ||
+ //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
+ (state == SCE_MSSQL_VARIABLE)) {
+ if (!iswordchar(ch)) {
+ int stateTmp;
+
+ if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
+ styler.ColourTo(i - 1, state);
+ stateTmp = state;
+ } else
+ stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
+
+ prevState = state;
+
+ if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
+ state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
+ else
+ state = SCE_MSSQL_DEFAULT;
+ }
+ } else if (state == SCE_MSSQL_LINE_COMMENT) {
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, state);
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT;
+ }
+ } else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
+ if ((ch != '@') && !iswordchar(ch)) {
+ classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT;
+ }
+ }
+
+ // If is the default or one of the above succeeded
+ if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
+ if (iswordstart(ch)) {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ state = SCE_MSSQL_IDENTIFIER;
+ } else if (ch == '/' && chNext == '*') {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ state = SCE_MSSQL_COMMENT;
+ } else if (ch == '-' && chNext == '-') {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ state = SCE_MSSQL_LINE_COMMENT;
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ state = SCE_MSSQL_STRING;
+ } else if (ch == '"') {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ state = SCE_MSSQL_COLUMN_NAME;
+ } else if (ch == '[') {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ state = SCE_MSSQL_COLUMN_NAME_2;
+ } else if (isMSSQLOperator(ch)) {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ styler.ColourTo(i, SCE_MSSQL_OPERATOR);
+ //~ style = SCE_MSSQL_DEFAULT;
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT;
+ } else if (ch == '@') {
+ styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
+ prevState = state;
+ if (chNext == '@') {
+ state = SCE_MSSQL_GLOBAL_VARIABLE;
+// i += 2;
+ } else
+ state = SCE_MSSQL_VARIABLE;
+ }
+
+
+ // When the last char is part of the state...
+ } else if (state == SCE_MSSQL_COMMENT) {
+ if (ch == '/' && chPrev == '*') {
+ if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
+ (styler.GetStartSegment() == startPos)))) {
+ styler.ColourTo(i, state);
+ //~ state = SCE_MSSQL_COMMENT;
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT;
+ }
+ }
+ } else if (state == SCE_MSSQL_STRING) {
+ if (ch == '\'') {
+ if ( chNext == '\'' ) {
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ styler.ColourTo(i, state);
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT;
+ //i++;
+ }
+ //ch = chNext;
+ //chNext = styler.SafeGetCharAt(i + 1);
+ }
+ } else if (state == SCE_MSSQL_COLUMN_NAME) {
+ if (ch == '"') {
+ if (chNext == '"') {
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ styler.ColourTo(i, state);
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
+ //i++;
+ }
+ }
+ } else if (state == SCE_MSSQL_COLUMN_NAME_2) {
+ if (ch == ']') {
+ styler.ColourTo(i, state);
+ prevState = state;
+ state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
+ //i++;
+ }
+ }
+
+ chPrev = ch;
+ }
+ styler.ColourTo(lengthDoc - 1, state);
+}
+
+static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
+ char s[10];
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ // Comment folding
+ if (foldComment) {
+ if (!inComment && (style == SCE_MSSQL_COMMENT))
+ levelCurrent++;
+ else if (inComment && (style != SCE_MSSQL_COMMENT))
+ levelCurrent--;
+ inComment = (style == SCE_MSSQL_COMMENT);
+ }
+ if (style == SCE_MSSQL_STATEMENT) {
+ // Folding between begin or case and end
+ if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') {
+ for (unsigned int j = 0; j < 5; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = static_cast<char>(tolower(styler[i + j]));
+ s[j + 1] = '\0';
+ }
+ if ((strcmp(s, "begin") == 0) || (strcmp(s, "case") == 0)) {
+ levelCurrent++;
+ }
+ if (strcmp(s, "end") == 0) {
+ levelCurrent--;
+ }
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const sqlWordListDesc[] = {
+ "Statements",
+ "Data Types",
+ "System tables",
+ "Global variables",
+ "Functions",
+ "System Stored Procedures",
+ "Operators",
+ 0,
+};
+
+LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/**
+ * @file LexMagik.cxx
+ * Lexer for GE(r) Smallworld(tm) MagikSF
+ */
+// Copyright 1998-2005 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
+
+/**
+ * Is it a core character (C isalpha(), exclamation and question mark)
+ *
+ * \param ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlphaCore(int ch) {
+ return (isalpha(ch) || ch == '!' || ch == '?');
+}
+
+/**
+ * Is it a character (IsAlphaCore() and underscore)
+ *
+ * \param ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlpha(int ch) {
+ return (IsAlphaCore(ch) || ch == '_');
+}
+
+/**
+ * Is it a symbolic character (IsAlpha() and colon)
+ *
+ * \param ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlphaSym(int ch) {
+ return (IsAlpha(ch) || ch == ':');
+}
+
+/**
+ * Is it a numerical character (IsAlpha() and 0 - 9)
+ *
+ * \param ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlNum(int ch) {
+ return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
+}
+
+/**
+ * Is it a symbolic numerical character (IsAlNum() and colon)
+ *
+ * \param ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlNumSym(int ch) {
+ return (IsAlNum(ch) || ch == ':');
+}
+
+/**
+ * The lexer function
+ *
+ * \param startPos Where to start scanning
+ * \param length Where to scan to
+ * \param initStyle The style at the initial point, not used in this folder
+ * \param keywordslists The keywordslists, currently, number 5 is used
+ * \param styler The styler
+ */
+static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ styler.StartAt(startPos);
+
+ WordList &keywords = *keywordlists[0];
+ WordList &pragmatics = *keywordlists[1];
+ WordList &containers = *keywordlists[2];
+ WordList &flow = *keywordlists[3];
+ WordList &characters = *keywordlists[4];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+
+ for (; sc.More(); sc.Forward()) {
+
+ repeat:
+
+ if(sc.ch == '#') {
+ if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
+ else sc.SetState(SCE_MAGIK_COMMENT);
+ for(; sc.More() && !(sc.atLineEnd); sc.Forward());
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+
+ if(sc.ch == '"') {
+ sc.SetState(SCE_MAGIK_STRING);
+
+ if(sc.More())
+ {
+ sc.Forward();
+ for(; sc.More() && sc.ch != '"'; sc.Forward());
+ }
+
+ sc.ForwardSetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+
+ // The default state
+ if(sc.state == SCE_MAGIK_DEFAULT) {
+
+ // A certain keyword has been detected
+ if (sc.ch == '_' && (
+ sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
+ char keyword[50];
+ memset(keyword, '\0', 50);
+
+ for(
+ int scanPosition = 0;
+ scanPosition < 50;
+ scanPosition++) {
+ char keywordChar = static_cast<char>(
+ tolower(styler.SafeGetCharAt(
+ scanPosition +
+ static_cast<int>(sc.currentPos+1), ' ')));
+ if(IsAlpha(keywordChar)) {
+ keyword[scanPosition] = keywordChar;
+ } else {
+ break;
+ }
+ }
+
+ // It is a pragma
+ if(pragmatics.InList(keyword)) {
+ sc.SetState(SCE_MAGIK_PRAGMA);
+ }
+
+ // it is a normal keyword like _local, _self, etc.
+ else if(keywords.InList(keyword)) {
+ sc.SetState(SCE_MAGIK_KEYWORD);
+ }
+
+ // It is a container keyword, such as _method, _proc, etc.
+ else if(containers.InList(keyword)) {
+ sc.SetState(SCE_MAGIK_CONTAINER);
+ }
+
+ // It is a flow keyword, such as _for, _if, _try, etc.
+ else if(flow.InList(keyword)) {
+ sc.SetState(SCE_MAGIK_FLOW);
+ }
+
+ // Interpret as unknown keyword
+ else {
+ sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
+ }
+ }
+
+ // Symbolic expression
+ else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
+ sc.SetState(SCE_MAGIK_SYMBOL);
+ bool firstTrip = true;
+ for(sc.Forward(); sc.More(); sc.Forward()) {
+ if(firstTrip && IsAlphaSym(sc.ch));
+ else if(!firstTrip && IsAlNumSym(sc.ch));
+ else if(sc.ch == '|') {
+ for(sc.Forward();
+ sc.More() && sc.ch != '|';
+ sc.Forward());
+ }
+ else break;
+
+ firstTrip = false;
+ }
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+
+ // Identifier (label) expression
+ else if(sc.ch == '@') {
+ sc.SetState(SCE_MAGIK_IDENTIFIER);
+ bool firstTrip = true;
+ for(sc.Forward(); sc.More(); sc.Forward()) {
+ if(firstTrip && IsAlphaCore(sc.ch)) {
+ firstTrip = false;
+ }
+ else if(!firstTrip && IsAlpha(sc.ch));
+ else break;
+ }
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+
+ // Start of a character
+ else if(sc.ch == '%') {
+ sc.SetState(SCE_MAGIK_CHARACTER);
+ sc.Forward();
+ char keyword[50];
+ memset(keyword, '\0', 50);
+
+ for(
+ int scanPosition = 0;
+ scanPosition < 50;
+ scanPosition++) {
+ char keywordChar = static_cast<char>(
+ tolower(styler.SafeGetCharAt(
+ scanPosition +
+ static_cast<int>(sc.currentPos), ' ')));
+ if(IsAlpha(keywordChar)) {
+ keyword[scanPosition] = keywordChar;
+ } else {
+ break;
+ }
+ }
+
+ if(characters.InList(keyword)) {
+ sc.Forward(static_cast<int>(strlen(keyword)));
+ } else {
+ sc.Forward();
+ }
+
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+
+ // Operators
+ else if(
+ sc.ch == '>' ||
+ sc.ch == '<' ||
+ sc.ch == '.' ||
+ sc.ch == ',' ||
+ sc.ch == '+' ||
+ sc.ch == '-' ||
+ sc.ch == '/' ||
+ sc.ch == '*' ||
+ sc.ch == '~' ||
+ sc.ch == '$' ||
+ sc.ch == '=') {
+ sc.SetState(SCE_MAGIK_OPERATOR);
+ }
+
+ // Braces
+ else if(sc.ch == '(' || sc.ch == ')') {
+ sc.SetState(SCE_MAGIK_BRACE_BLOCK);
+ }
+
+ // Brackets
+ else if(sc.ch == '{' || sc.ch == '}') {
+ sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
+ }
+
+ // Square Brackets
+ else if(sc.ch == '[' || sc.ch == ']') {
+ sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
+ }
+
+
+ }
+
+ // It is an operator
+ else if(
+ sc.state == SCE_MAGIK_OPERATOR ||
+ sc.state == SCE_MAGIK_BRACE_BLOCK ||
+ sc.state == SCE_MAGIK_BRACKET_BLOCK ||
+ sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+
+ // It is the pragma state
+ else if(sc.state == SCE_MAGIK_PRAGMA) {
+ if(!IsAlpha(sc.ch)) {
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+ }
+
+ // It is the keyword state
+ else if(
+ sc.state == SCE_MAGIK_KEYWORD ||
+ sc.state == SCE_MAGIK_CONTAINER ||
+ sc.state == SCE_MAGIK_FLOW ||
+ sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
+ if(!IsAlpha(sc.ch)) {
+ sc.SetState(SCE_MAGIK_DEFAULT);
+ goto repeat;
+ }
+ }
+ }
+
+ sc.Complete();
+}
+
+/**
+ * The word list description
+ */
+static const char * const magikWordListDesc[] = {
+ "Accessors (local, global, self, super, thisthread)",
+ "Pragmatic (pragma, private)",
+ "Containers (method, block, proc)",
+ "Flow (if, then, elif, else)",
+ "Characters (space, tab, newline, return)",
+ "Fold Containers (method, proc, block, if, loop)",
+ 0};
+
+/**
+ * This function detects keywords which are able to have a body. Note that it
+ * uses the Fold Containers word description, not the containers description. It
+ * only works when the style at that particular position is set on Containers
+ * or Flow (number 3 or 4).
+ *
+ * \param keywordslist The list of keywords that are scanned, they should only
+ * contain the start keywords, not the end keywords
+ * \param The actual keyword
+ * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
+ * 0 otherwise
+ */
+static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
+ if(
+ strlen(keyword) > 3 &&
+ keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
+ if (keywordslist.InList(keyword + 3)) {
+ return -1;
+ }
+
+ } else {
+ if(keywordslist.InList(keyword)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * The folding function
+ *
+ * \param startPos Where to start scanning
+ * \param length Where to scan to
+ * \param keywordslists The keywordslists, currently, number 5 is used
+ * \param styler The styler
+ */
+static void FoldMagikDoc(unsigned int startPos, int length, int,
+ WordList *keywordslists[], Accessor &styler) {
+
+ bool compact = styler.GetPropertyInt("fold.compact") != 0;
+
+ WordList &foldingElements = *keywordslists[5];
+ int endPos = startPos + length;
+ int line = styler.GetLine(startPos);
+ int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
+ int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
+
+ for(
+ int currentPos = startPos;
+ currentPos < endPos;
+ currentPos++) {
+ char currentState = styler.StyleAt(currentPos);
+ char c = styler.SafeGetCharAt(currentPos, ' ');
+ int prevLine = styler.GetLine(currentPos - 1);
+ line = styler.GetLine(currentPos);
+
+ // Default situation
+ if(prevLine < line) {
+ styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
+ flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
+ }
+
+ if(
+ (
+ currentState == SCE_MAGIK_CONTAINER ||
+ currentState == SCE_MAGIK_FLOW
+ ) &&
+ c == '_') {
+
+ char keyword[50];
+ memset(keyword, '\0', 50);
+
+ for(
+ int scanPosition = 0;
+ scanPosition < 50;
+ scanPosition++) {
+ char keywordChar = static_cast<char>(
+ tolower(styler.SafeGetCharAt(
+ scanPosition +
+ currentPos + 1, ' ')));
+ if(IsAlpha(keywordChar)) {
+ keyword[scanPosition] = keywordChar;
+ } else {
+ break;
+ }
+ }
+
+ if(IsFoldingContainer(foldingElements, keyword) > 0) {
+ styler.SetLevel(
+ line,
+ styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
+ level++;
+ } else if(IsFoldingContainer(foldingElements, keyword) < 0) {
+ styler.SetLevel(line, styler.LevelAt(line));
+ level--;
+ }
+ }
+
+ if(
+ compact && (
+ currentState == SCE_MAGIK_BRACE_BLOCK ||
+ currentState == SCE_MAGIK_BRACKET_BLOCK ||
+ currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
+ if(c == '{' || c == '[' || c == '(') {
+ styler.SetLevel(
+ line,
+ styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
+ level++;
+ } else if(c == '}' || c == ']' || c == ')') {
+ styler.SetLevel(line, styler.LevelAt(line));
+ level--;
+ }
+ }
+ }
+
+}
+
+/**
+ * Injecting the module
+ */
+LexerModule lmMagikSF(
+ SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);
+
--- /dev/null
+/******************************************************************
+ * LexMarkdown.cxx
+ *
+ * A simple Markdown lexer for scintilla.
+ *
+ * Includes highlighting for some extra features from the
+ * Pandoc implementation; strikeout, using '#.' as a default
+ * ordered list item marker, and delimited code blocks.
+ *
+ * Limitations:
+ *
+ * Standard indented code blocks are not highlighted at all,
+ * as it would conflict with other indentation schemes. Use
+ * delimited code blocks for blanket highlighting of an
+ * entire code block. Embedded HTML is not highlighted either.
+ * Blanket HTML highlighting has issues, because some Markdown
+ * implementations allow Markdown markup inside of the HTML. Also,
+ * there is a following blank line issue that can't be ignored,
+ * explained in the next paragraph. Embedded HTML and code
+ * blocks would be better supported with language specific
+ * highlighting.
+ *
+ * The highlighting aims to accurately reflect correct syntax,
+ * but a few restrictions are relaxed. Delimited code blocks are
+ * highlighted, even if the line following the code block is not blank.
+ * Requiring a blank line after a block, breaks the highlighting
+ * in certain cases, because of the way Scintilla ends up calling
+ * the lexer.
+ *
+ * Written by Jon Strait - jstrait@moonloop.net
+ *
+ * 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 "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 IsNewline(const int ch) {
+ return (ch == '\n' || ch == '\r');
+}
+
+// True if can follow ch down to the end with possibly trailing whitespace
+static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
+ unsigned int i = 0;
+ while (sc.GetRelative(++i) == ch)
+ ;
+ // Skip over whitespace
+ while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+ ++i;
+ if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
+ sc.Forward(i);
+ sc.ChangeState(state);
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ return true;
+ }
+ else return false;
+}
+
+// Set the state on text section from current to length characters,
+// then set the rest until the newline to default, except for any characters matching token
+static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
+ sc.SetState(state);
+ sc.Forward(length);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ sc.Forward();
+ bool started = false;
+ while (sc.More() && !IsNewline(sc.ch)) {
+ if (sc.ch == token && !started) {
+ sc.SetState(state);
+ started = true;
+ }
+ else if (sc.ch != token) {
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ started = false;
+ }
+ sc.Forward();
+ }
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+}
+
+// Does the previous line have more than spaces and tabs?
+static bool HasPrevLineContent(StyleContext &sc) {
+ int i = 0;
+ // Go back to the previous newline
+ while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
+ ;
+ while ((--i + (int)sc.currentPos) >= 0) {
+ if (IsNewline(sc.GetRelative(i)))
+ break;
+ if (!IsASpaceOrTab(sc.GetRelative(i)))
+ return true;
+ }
+ return false;
+}
+
+static bool AtTermStart(StyleContext &sc) {
+ return sc.currentPos == 0 || isspacechar(sc.chPrev);
+}
+
+static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
+ int c, count = 1;
+ unsigned int i = 0;
+ while (++i) {
+ c = sc.GetRelative(i);
+ if (c == sc.ch)
+ ++count;
+ // hit a terminating character
+ else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
+ // Are we a valid HRULE
+ if ((IsNewline(c) || sc.currentPos + i == endPos) &&
+ count >= 3 && !HasPrevLineContent(sc)) {
+ sc.SetState(SCE_MARKDOWN_HRULE);
+ sc.Forward(i);
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ return true;
+ }
+ else {
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle,
+ WordList **, Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int precharCount = 0;
+ // Don't advance on a new loop iteration and retry at the same position.
+ // Useful in the corner case of having to start at the beginning file position
+ // in the default state.
+ bool freezeCursor = false;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ while (sc.More()) {
+ // Skip past escaped characters
+ if (sc.ch == '\\') {
+ sc.Forward();
+ continue;
+ }
+
+ // A blockquotes resets the line semantics
+ if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+
+ // Conditional state-based actions
+ if (sc.state == SCE_MARKDOWN_CODE2) {
+ if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_MARKDOWN_CODE) {
+ if (sc.ch == '`' && sc.chPrev != ' ')
+ sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+ }
+ /* De-activated because it gets in the way of other valid indentation
+ * schemes, for example multiple paragraphs inside a list item.
+ // Code block
+ else if (sc.state == SCE_MARKDOWN_CODEBK) {
+ bool d = true;
+ if (IsNewline(sc.ch)) {
+ if (sc.chNext != '\t') {
+ for (int c = 1; c < 5; ++c) {
+ if (sc.GetRelative(c) != ' ')
+ d = false;
+ }
+ }
+ }
+ else if (sc.atLineStart) {
+ if (sc.ch != '\t' ) {
+ for (int i = 0; i < 4; ++i) {
+ if (sc.GetRelative(i) != ' ')
+ d = false;
+ }
+ }
+ }
+ if (!d)
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ }
+ */
+ // Strong
+ else if (sc.state == SCE_MARKDOWN_STRONG1) {
+ if (sc.Match("**") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_MARKDOWN_STRONG2) {
+ if (sc.Match("__") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ // Emphasis
+ else if (sc.state == SCE_MARKDOWN_EM1) {
+ if (sc.ch == '*' && sc.chPrev != ' ')
+ sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+ }
+ else if (sc.state == SCE_MARKDOWN_EM2) {
+ if (sc.ch == '_' && sc.chPrev != ' ')
+ sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+ }
+ else if (sc.state == SCE_MARKDOWN_CODEBK) {
+ if (sc.atLineStart && sc.Match("~~~")) {
+ int i = 1;
+ while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+ i++;
+ sc.Forward(i);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_MARKDOWN_STRIKEOUT) {
+ if (sc.Match("~~") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) {
+ // Header
+ if (sc.Match("######"))
+ SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc);
+ else if (sc.Match("#####"))
+ SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc);
+ else if (sc.Match("####"))
+ SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc);
+ else if (sc.Match("###"))
+ SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc);
+ else if (sc.Match("##"))
+ SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc);
+ else if (sc.Match("#")) {
+ // Catch the special case of an unordered list
+ if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+ precharCount = 0;
+ sc.SetState(SCE_MARKDOWN_PRECHAR);
+ }
+ else
+ SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc);
+ }
+ // Code block
+ else if (sc.Match("~~~")) {
+ if (!HasPrevLineContent(sc))
+ sc.SetState(SCE_MARKDOWN_CODEBK);
+ else
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ else if (sc.ch == '=') {
+ if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc))
+ ;
+ else
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ else if (sc.ch == '-') {
+ if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc))
+ ;
+ else {
+ precharCount = 0;
+ sc.SetState(SCE_MARKDOWN_PRECHAR);
+ }
+ }
+ else if (IsNewline(sc.ch))
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ else {
+ precharCount = 0;
+ sc.SetState(SCE_MARKDOWN_PRECHAR);
+ }
+ }
+
+ // The header lasts until the newline
+ else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
+ sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
+ sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ }
+
+ // New state only within the initial whitespace
+ if (sc.state == SCE_MARKDOWN_PRECHAR) {
+ // Blockquote
+ if (sc.ch == '>' && precharCount < 5)
+ sc.SetState(SCE_MARKDOWN_BLOCKQUOTE);
+ /*
+ // Begin of code block
+ else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
+ sc.SetState(SCE_MARKDOWN_CODEBK);
+ */
+ // HRule - Total of three or more hyphens, asterisks, or underscores
+ // on a line by themselves
+ else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
+ ;
+ // Unordered list
+ else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) {
+ sc.SetState(SCE_MARKDOWN_ULIST_ITEM);
+ sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+ }
+ // Ordered list
+ else if (IsADigit(sc.ch)) {
+ int digitCount = 0;
+ while (IsADigit(sc.GetRelative(++digitCount)))
+ ;
+ if (sc.GetRelative(digitCount) == '.' &&
+ IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
+ sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
+ sc.Forward(digitCount + 1);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ // Alternate Ordered list
+ else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+ sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
+ sc.Forward(2);
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ }
+ else if (sc.ch != ' ' || precharCount > 2)
+ sc.SetState(SCE_MARKDOWN_DEFAULT);
+ else
+ ++precharCount;
+ }
+
+ // New state anywhere in doc
+ if (sc.state == SCE_MARKDOWN_DEFAULT) {
+ if (sc.atLineStart && sc.ch == '#') {
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ freezeCursor = true;
+ }
+ // Links and Images
+ if (sc.Match("![") || sc.ch == '[') {
+ int i = 0, j = 0, k = 0;
+ int len = endPos - sc.currentPos;
+ while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ']') {
+ j = i;
+ if (sc.GetRelative(++i) == '(') {
+ while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ')')
+ k = i;
+ }
+ else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
+ while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ']')
+ k = i;
+ }
+ }
+ // At least a link text
+ if (j) {
+ sc.SetState(SCE_MARKDOWN_LINK);
+ sc.Forward(j);
+ // Also has a URL or reference portion
+ if (k)
+ sc.Forward(k - j);
+ sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+ }
+ }
+ // Code - also a special case for alternate inside spacing
+ if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_CODE2);
+ sc.Forward();
+ }
+ else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_CODE);
+ }
+ // Strong
+ else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_STRONG1);
+ sc.Forward();
+ }
+ else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_STRONG2);
+ sc.Forward();
+ }
+ // Emphasis
+ else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_EM1);
+ }
+ else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_EM2);
+ }
+ // Strikeout
+ else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
+ sc.SetState(SCE_MARKDOWN_STRIKEOUT);
+ sc.Forward();
+ }
+ // Beginning of line
+ else if (IsNewline(sc.ch)) {
+ sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+ }
+ }
+ // Advance if not holding back the cursor for this iteration.
+ if (!freezeCursor)
+ sc.Forward();
+ freezeCursor = false;
+ }
+ sc.Complete();
+}
+
+LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown");
--- /dev/null
+// Scintilla source code edit control
+/** @file LexMatlab.cxx
+ ** Lexer for Matlab.
+ ** Written by José Fonseca
+ **
+ ** Changes by Christoph Dalitz 2003/12/04:
+ ** - added support for Octave
+ ** - Strings can now be included both in single or double quotes
+ **/
+// 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 bool IsMatlabCommentChar(int c) {
+ return (c == '%') ;
+}
+
+static bool IsOctaveCommentChar(int c) {
+ return (c == '%' || c == '#') ;
+}
+
+static bool IsMatlabComment(Accessor &styler, int pos, int len) {
+ return len > 0 && IsMatlabCommentChar(styler[pos]) ;
+}
+
+static bool IsOctaveComment(Accessor &styler, int pos, int len) {
+ return len > 0 && IsOctaveCommentChar(styler[pos]) ;
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static void ColouriseMatlabOctaveDoc(
+ unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler,
+ bool (*IsCommentChar)(int)) {
+
+ WordList &keywords = *keywordlists[0];
+
+ styler.StartAt(startPos);
+
+ bool transpose = false;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_MATLAB_OPERATOR) {
+ if (sc.chPrev == '.') {
+ if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
+ sc.ForwardSetState(SCE_MATLAB_DEFAULT);
+ transpose = false;
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_MATLAB_DEFAULT);
+ transpose = true;
+ } else {
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ }
+ } else {
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ }
+ } else if (sc.state == SCE_MATLAB_KEYWORD) {
+ if (!isalnum(sc.ch) && sc.ch != '_') {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ transpose = false;
+ } else {
+ sc.ChangeState(SCE_MATLAB_IDENTIFIER);
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ transpose = true;
+ }
+ }
+ } else if (sc.state == SCE_MATLAB_NUMBER) {
+ if (!isdigit(sc.ch) && sc.ch != '.'
+ && !(sc.ch == 'e' || sc.ch == 'E')
+ && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ transpose = true;
+ }
+ } else if (sc.state == SCE_MATLAB_STRING) {
+ if (sc.ch == '\'') {
+ if (sc.chNext == '\'') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_MATLAB_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_MATLAB_DEFAULT);
+ }
+ } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ transpose = false;
+ }
+ }
+
+ if (sc.state == SCE_MATLAB_DEFAULT) {
+ if (IsCommentChar(sc.ch)) {
+ sc.SetState(SCE_MATLAB_COMMENT);
+ } else if (sc.ch == '!' && sc.chNext != '=' ) {
+ sc.SetState(SCE_MATLAB_COMMAND);
+ } else if (sc.ch == '\'') {
+ if (transpose) {
+ sc.SetState(SCE_MATLAB_OPERATOR);
+ } else {
+ sc.SetState(SCE_MATLAB_STRING);
+ }
+ } else if (sc.ch == '"') {
+ sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
+ } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+ sc.SetState(SCE_MATLAB_NUMBER);
+ } else if (isalpha(sc.ch)) {
+ sc.SetState(SCE_MATLAB_KEYWORD);
+ } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
+ if (sc.ch == ')' || sc.ch == ']') {
+ transpose = true;
+ } else {
+ transpose = false;
+ }
+ sc.SetState(SCE_MATLAB_OPERATOR);
+ } else {
+ transpose = false;
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
+}
+
+static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
+}
+
+static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler,
+ bool (*IsComment)(Accessor&, int, int)) {
+
+ int endPos = startPos + length;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
+ char chNext = styler[startPos];
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ // Only non whitespace lines can be headers
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
+ // Line after is blank so check the next - maybe should continue further?
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
+}
+
+static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
+}
+
+static const char * const matlabWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+static const char * const octaveWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
+
+LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+
+// File: LexMetapost.cxx - general context conformant metapost coloring scheme
+// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
+// Version: September 28, 2003
+// Modified by instanton: July 10, 2007
+// Folding based on keywordlists[]
+
+// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// This lexer is derived from the one written for the texwork environment (1999++) which in
+// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).
+
+#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
+
+// val SCE_METAPOST_DEFAULT = 0
+// val SCE_METAPOST_SPECIAL = 1
+// val SCE_METAPOST_GROUP = 2
+// val SCE_METAPOST_SYMBOL = 3
+// val SCE_METAPOST_COMMAND = 4
+// val SCE_METAPOST_TEXT = 5
+
+// Definitions in SciTEGlobal.properties:
+//
+// Metapost Highlighting
+//
+// # Default
+// style.metapost.0=fore:#7F7F00
+// # Special
+// style.metapost.1=fore:#007F7F
+// # Group
+// style.metapost.2=fore:#880000
+// # Symbol
+// style.metapost.3=fore:#7F7F00
+// # Command
+// style.metapost.4=fore:#008800
+// # Text
+// style.metapost.5=fore:#000000
+
+// lexer.tex.comment.process=0
+
+// Auxiliary functions:
+
+static inline bool endOfLine(Accessor &styler, unsigned int i) {
+ return
+ (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
+}
+
+static inline bool isMETAPOSTcomment(int ch) {
+ return
+ (ch == '%') ;
+}
+
+static inline bool isMETAPOSTone(int ch) {
+ return
+ (ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') ||
+ (ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') ||
+ (ch == '{') || (ch == '}') || (ch == '\'') || (ch == '\"') ;
+}
+
+static inline bool isMETAPOSTtwo(int ch) {
+ return
+ (ch == ';') || (ch == '$') || (ch == '@') || (ch == '#');
+}
+
+static inline bool isMETAPOSTthree(int ch) {
+ return
+ (ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') ||
+ (ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') ||
+ (ch == '!') || (ch == '?') || (ch == '^') || (ch == '&') ||
+ (ch == '%') ;
+}
+
+static inline bool isMETAPOSTidentifier(int ch) {
+ return
+ ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
+ (ch == '_') ;
+}
+
+static inline bool isMETAPOSTnumber(int ch) {
+ return
+ (ch >= '0') && (ch <= '9') ;
+}
+
+static inline bool isMETAPOSTstring(int ch) {
+ return
+ (ch == '\"') ;
+}
+
+static inline bool isMETAPOSTcolon(int ch) {
+ return
+ (ch == ':') ;
+}
+
+static inline bool isMETAPOSTequal(int ch) {
+ return
+ (ch == '=') ;
+}
+
+static int CheckMETAPOSTInterface(
+ unsigned int startPos,
+ int length,
+ Accessor &styler,
+ int defaultInterface) {
+
+ char lineBuffer[1024] ;
+ unsigned int linePos = 0 ;
+
+ // some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)...
+
+ if (styler.SafeGetCharAt(0) == '%') {
+ for (unsigned int i = 0; i < startPos + length; i++) {
+ lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
+ if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
+ lineBuffer[linePos] = '\0';
+ if (strstr(lineBuffer, "interface=none")) {
+ return 0 ;
+ } else if (strstr(lineBuffer, "interface=metapost") || strstr(lineBuffer, "interface=mp")) {
+ return 1 ;
+ } else if (strstr(lineBuffer, "interface=metafun")) {
+ return 2 ;
+ } else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) {
+ // better would be to limit the search to just one line
+ return 2 ;
+ } else {
+ return defaultInterface ;
+ }
+ }
+ }
+ }
+
+ return defaultInterface ;
+}
+
+static void ColouriseMETAPOSTDoc(
+ unsigned int startPos,
+ int length,
+ int,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ styler.StartAt(startPos) ;
+ styler.StartSegment(startPos) ;
+
+ bool processComment = styler.GetPropertyInt("lexer.metapost.comment.process", 0) == 1 ;
+ int defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ;
+
+ int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
+
+ // 0 no keyword highlighting
+ // 1 metapost keyword hightlighting
+ // 2+ metafun keyword hightlighting
+
+ int extraInterface = 0 ;
+
+ if (currentInterface != 0) {
+ extraInterface = currentInterface ;
+ }
+
+ WordList &keywords = *keywordlists[0] ;
+ WordList &keywords2 = *keywordlists[extraInterface-1] ;
+
+ StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;
+
+ char key[100] ;
+
+ bool inTeX = false ;
+ bool inComment = false ;
+ bool inString = false ;
+ bool inClause = false ;
+
+ bool going = sc.More() ; // needed because of a fuzzy end of file state
+
+ for (; going; sc.Forward()) {
+
+ if (! sc.More()) { going = false ; } // we need to go one behind the end of text
+
+ if (inClause) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inClause = false ;
+ }
+
+ if (inComment) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inTeX = false ;
+ inComment = false ;
+ inClause = false ;
+ inString = false ; // not correct but we want to stimulate one-lines
+ }
+ } else if (inString) {
+ if (isMETAPOSTstring(sc.ch)) {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ sc.ForwardSetState(SCE_METAPOST_TEXT) ;
+ inString = false ;
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inTeX = false ;
+ inComment = false ;
+ inClause = false ;
+ inString = false ; // not correct but we want to stimulate one-lines
+ }
+ } else {
+ if ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) {
+ if (sc.state == SCE_METAPOST_COMMAND) {
+ sc.GetCurrent(key, sizeof(key)) ;
+ if ((strcmp(key,"btex") == 0) || (strcmp(key,"verbatimtex") == 0)) {
+ sc.ChangeState(SCE_METAPOST_GROUP) ;
+ inTeX = true ;
+ } else if (inTeX) {
+ if (strcmp(key,"etex") == 0) {
+ sc.ChangeState(SCE_METAPOST_GROUP) ;
+ inTeX = false ;
+ } else {
+ sc.ChangeState(SCE_METAPOST_TEXT) ;
+ }
+ } else {
+ if (keywords && keywords.InList(key)) {
+ sc.ChangeState(SCE_METAPOST_COMMAND) ;
+ } else if (keywords2 && keywords2.InList(key)) {
+ sc.ChangeState(SCE_METAPOST_EXTRA) ;
+ } else {
+ sc.ChangeState(SCE_METAPOST_TEXT) ;
+ }
+ }
+ }
+ }
+ if (isMETAPOSTcomment(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SYMBOL) ;
+ sc.ForwardSetState(SCE_METAPOST_DEFAULT) ;
+ inComment = ! processComment ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTstring(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ if (! isMETAPOSTstring(sc.chNext)) {
+ sc.ForwardSetState(SCE_METAPOST_TEXT) ;
+ }
+ inString = true ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTcolon(sc.ch)) {
+ if (! inTeX) {
+ if (! isMETAPOSTequal(sc.chNext)) {
+ sc.SetState(SCE_METAPOST_COMMAND) ;
+ inClause = true ;
+ } else {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ }
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTone(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTtwo(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_GROUP) ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTthree(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SYMBOL) ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTidentifier(sc.ch)) {
+ if (sc.state != SCE_METAPOST_COMMAND) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ sc.ChangeState(SCE_METAPOST_COMMAND) ;
+ }
+ } else if (isMETAPOSTnumber(sc.ch)) {
+ // rather redundant since for the moment we don't handle numbers
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inTeX = false ;
+ inComment = false ;
+ inClause = false ;
+ inString = false ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ }
+
+ }
+
+ sc.Complete();
+
+}
+
+// Hooks info the system:
+
+static const char * const metapostWordListDesc[] = {
+ "MetaPost",
+ "MetaFun",
+ 0
+} ;
+
+static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {
+ WordList& keywordsStart=*keywordlists[3];
+ WordList& keywordsStop1=*keywordlists[4];
+
+ if (keywordsStart.InList(s)) {return 1;}
+ else if (keywordsStop1.InList(s)) {return -1;}
+ return 0;
+
+}
+
+static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
+{
+ int length=0;
+ char ch=styler.SafeGetCharAt(pos);
+ *word=0;
+
+ while(isMETAPOSTidentifier(ch) && isalpha(ch) && length<100){
+ word[length]=ch;
+ length++;
+ ch=styler.SafeGetCharAt(pos+length);
+ }
+ word[length]=0;
+ return length;
+}
+
+static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler)
+{
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos+length;
+ int visibleChars=0;
+ int lineCurrent=styler.GetLine(startPos);
+ int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent=levelPrev;
+ char chNext=styler[startPos];
+
+ char buffer[100]="";
+
+ for (unsigned int i=startPos; i < endPos; i++) {
+ char ch=chNext;
+ chNext=styler.SafeGetCharAt(i+1);
+ char chPrev=styler.SafeGetCharAt(i-1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if(i==0 || chPrev == '\r' || chPrev=='\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$')
+ {
+ ParseMetapostWord(i, styler, buffer);
+ levelCurrent += classifyFoldPointMetapost(buffer,keywordlists);
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+
+}
+
+
+LexerModule lmMETAPOST(SCLEX_METAPOST, ColouriseMETAPOSTDoc, "metapost", FoldMetapostDoc, metapostWordListDesc);
--- /dev/null
+// -*- coding: utf-8 -*-
+// Scintilla source code edit control
+/**
+ * @file LexModula.cxx
+ * @author Dariusz "DKnoto" Knociński
+ * @date 2011/02/03
+ * @brief Lexer for Modula-2/3 documents.
+ */
+// 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 "PropSetSimple.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
+
+#ifdef DEBUG_LEX_MODULA
+#define DEBUG_STATE( p, c )\
+ fprintf( stderr, "Unknown state: currentPos = %d, char = '%c'\n", p, c );
+#else
+#define DEBUG_STATE( p, c )
+#endif
+
+static inline bool IsDigitOfBase( unsigned ch, unsigned base ) {
+ if( ch < '0' || ch > 'f' ) return false;
+ if( base <= 10 ) {
+ if( ch >= ( '0' + base ) ) return false;
+ } else {
+ if( ch > '9' ) {
+ unsigned nb = base - 10;
+ if( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) {
+ if( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+static inline unsigned IsOperator( StyleContext & sc, WordList & op ) {
+ int i;
+ char s[3];
+
+ s[0] = sc.ch;
+ s[1] = sc.chNext;
+ s[2] = 0;
+ for( i = 0; i < op.len; i++ ) {
+ if( ( strlen( op.words[i] ) == 2 ) &&
+ ( s[0] == op.words[i][0] && s[1] == op.words[i][1] ) ) {
+ return 2;
+ }
+ }
+ s[1] = 0;
+ for( i = 0; i < op.len; i++ ) {
+ if( ( strlen( op.words[i] ) == 1 ) &&
+ ( s[0] == op.words[i][0] ) ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static inline bool IsEOL( Accessor &styler, unsigned curPos ) {
+ unsigned ch = styler.SafeGetCharAt( curPos );
+ if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) ||
+ ( ch == '\n' ) ) {
+ return true;
+ }
+ return false;
+}
+
+static inline bool checkStatement(
+ Accessor &styler,
+ int &curPos,
+ const char *stt, bool spaceAfter = true ) {
+ int len = static_cast<int>(strlen( stt ));
+ int i;
+ for( i = 0; i < len; i++ ) {
+ if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
+ return false;
+ }
+ }
+ if( spaceAfter ) {
+ if( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
+ return false;
+ }
+ }
+ curPos += ( len - 1 );
+ return true;
+}
+
+static inline bool checkEndSemicolon(
+ Accessor &styler,
+ int &curPos, int endPos )
+{
+ const char *stt = "END";
+ int len = static_cast<int>(strlen( stt ));
+ int i;
+ for( i = 0; i < len; i++ ) {
+ if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
+ return false;
+ }
+ }
+ while( isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
+ i++;
+ if( ( curPos + i ) >= endPos ) return false;
+ }
+ if( styler.SafeGetCharAt( curPos + i ) != ';' ) {
+ return false;
+ }
+ curPos += ( i - 1 );
+ return true;
+}
+
+static inline bool checkKeyIdentOper(
+
+ Accessor &styler,
+ int &curPos, int endPos,
+ const char *stt, const char etk ) {
+ int newPos = curPos;
+ if( ! checkStatement( styler, newPos, stt ) )
+ return false;
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ if( ! isspace( styler.SafeGetCharAt( newPos ) ) )
+ return false;
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ }
+ if( ! isalpha( styler.SafeGetCharAt( newPos ) ) )
+ return false;
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ char ch;
+ ch = styler.SafeGetCharAt( newPos );
+ while( isalpha( ch ) || isdigit( ch ) || ch == '_' ) {
+ newPos++;
+ if( newPos >= endPos ) return false;
+ ch = styler.SafeGetCharAt( newPos );
+ }
+ while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
+ newPos++;
+ if( newPos >= endPos ) return false;
+ }
+ if( styler.SafeGetCharAt( newPos ) != etk )
+ return false;
+ curPos = newPos;
+ return true;
+}
+
+static void FoldModulaDoc( unsigned int startPos,
+ int length,
+ int , WordList *[],
+ Accessor &styler)
+{
+ int curLine = styler.GetLine(startPos);
+ int curLevel = SC_FOLDLEVELBASE;
+ int endPos = startPos + length;
+ if( curLine > 0 )
+ curLevel = styler.LevelAt( curLine - 1 ) >> 16;
+ int curPos = startPos;
+ int style = styler.StyleAt( curPos );
+ int visChars = 0;
+ int nextLevel = curLevel;
+
+ while( curPos < endPos ) {
+ if( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++;
+
+ switch( style ) {
+ case SCE_MODULA_COMMENT:
+ if( checkStatement( styler, curPos, "(*" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "*)" ) )
+ nextLevel--;
+ break;
+
+ case SCE_MODULA_DOXYCOMM:
+ if( checkStatement( styler, curPos, "(**", false ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "*)" ) )
+ nextLevel--;
+ break;
+
+ case SCE_MODULA_KEYWORD:
+ if( checkStatement( styler, curPos, "IF" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "BEGIN" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "TRY" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "LOOP" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "FOR" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "WHILE" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "REPEAT" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "UNTIL" ) )
+ nextLevel--;
+ else
+ if( checkStatement( styler, curPos, "WITH" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "CASE" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "TYPECASE" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "LOCK" ) )
+ nextLevel++;
+ else
+ if( checkKeyIdentOper( styler, curPos, endPos, "PROCEDURE", '(' ) )
+ nextLevel++;
+ else
+ if( checkKeyIdentOper( styler, curPos, endPos, "END", ';' ) ) {
+ int cln = curLine;
+ int clv_old = curLevel;
+ int pos;
+ char ch;
+ int clv_new;
+ while( cln > 0 ) {
+ clv_new = styler.LevelAt( cln - 1 ) >> 16;
+ if( clv_new < clv_old ) {
+ nextLevel--;
+ pos = styler.LineStart( cln );
+ while( ( ch = styler.SafeGetCharAt( pos ) ) != '\n' ) {
+ if( ch == 'P' ) {
+ if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD ) {
+ if( checkKeyIdentOper( styler, pos, endPos,
+ "PROCEDURE", '(' ) ) {
+ break;
+ }
+ }
+ }
+ pos++;
+ }
+ clv_old = clv_new;
+ }
+ cln--;
+ }
+ }
+ else
+ if( checkKeyIdentOper( styler, curPos, endPos, "END", '.' ) )
+ nextLevel--;
+ else
+ if( checkEndSemicolon( styler, curPos, endPos ) )
+ nextLevel--;
+ else {
+ while( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD )
+ curPos++;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) {
+ int efectiveLevel = curLevel | nextLevel << 16;
+ if( visChars == 0 )
+ efectiveLevel |= SC_FOLDLEVELWHITEFLAG;
+ if( curLevel < nextLevel )
+ efectiveLevel |= SC_FOLDLEVELHEADERFLAG;
+ if( efectiveLevel != styler.LevelAt(curLine) ) {
+ styler.SetLevel(curLine, efectiveLevel );
+ }
+ curLine++;
+ curLevel = nextLevel;
+ if( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) {
+ styler.SetLevel( curLine, ( curLevel | curLevel << 16)
+ | SC_FOLDLEVELWHITEFLAG);
+ }
+ visChars = 0;
+ }
+ curPos++;
+ style = styler.StyleAt( curPos );
+ }
+}
+
+static inline bool skipWhiteSpaces( StyleContext & sc ) {
+ while( isspace( sc.ch ) ) {
+ sc.SetState( SCE_MODULA_DEFAULT );
+ if( sc.More() )
+ sc.Forward();
+ else
+ return false;
+ }
+ return true;
+}
+
+static void ColouriseModulaDoc( unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *wl[],
+ Accessor &styler ) {
+ WordList& keyWords = *wl[0];
+ WordList& reservedWords = *wl[1];
+ WordList& operators = *wl[2];
+ WordList& pragmaWords = *wl[3];
+ WordList& escapeCodes = *wl[4];
+ WordList& doxyKeys = *wl[5];
+
+ const int BUFLEN = 128;
+
+ char buf[BUFLEN];
+ int i, kl;
+
+ int charPos = 0;
+
+ StyleContext sc( startPos, length, initStyle, styler );
+
+ while( sc.More() ) {
+ switch( sc.state ) {
+ case SCE_MODULA_DEFAULT:
+ if( ! skipWhiteSpaces( sc ) ) break;
+
+ if( sc.ch == '(' && sc.chNext == '*' ) {
+ if( sc.GetRelative(2) == '*' ) {
+ sc.SetState( SCE_MODULA_DOXYCOMM );
+ sc.Forward();
+ } else {
+ sc.SetState( SCE_MODULA_COMMENT );
+ }
+ sc.Forward();
+ }
+ else
+ if( isalpha( sc.ch ) ) {
+ if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( !isalpha( buf[i] ) && !(buf[i] == '_') )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+
+ if( keyWords.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_KEYWORD );
+ sc.Forward( kl );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ else
+ if( reservedWords.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_RESERVED );
+ sc.Forward( kl );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ /** check procedure identifier */
+ }
+ } else {
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( !isalpha( buf[i] ) &&
+ !isdigit( buf[i] ) &&
+ !(buf[i] == '_') )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+
+ sc.SetState( SCE_MODULA_DEFAULT );
+ sc.Forward( kl );
+ continue;
+ }
+ }
+ else
+ if( isdigit( sc.ch ) ) {
+ sc.SetState( SCE_MODULA_NUMBER );
+ continue;
+ }
+ else
+ if( sc.ch == '\"' ) {
+ sc.SetState( SCE_MODULA_STRING );
+ }
+ else
+ if( sc.ch == '\'' ) {
+ charPos = sc.currentPos;
+ sc.SetState( SCE_MODULA_CHAR );
+ }
+ else
+ if( sc.ch == '<' && sc.chNext == '*' ) {
+ sc.SetState( SCE_MODULA_PRAGMA );
+ sc.Forward();
+ } else {
+ unsigned len = IsOperator( sc, operators );
+ if( len > 0 ) {
+ sc.SetState( SCE_MODULA_OPERATOR );
+ sc.Forward( len );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ DEBUG_STATE( sc.currentPos, sc.ch );
+ }
+ }
+ break;
+
+ case SCE_MODULA_COMMENT:
+ if( sc.ch == '*' && sc.chNext == ')' ) {
+ sc.Forward( 2 );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case SCE_MODULA_DOXYCOMM:
+ switch( sc.ch ) {
+ case '*':
+ if( sc.chNext == ')' ) {
+ sc.Forward( 2 );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case '@':
+ if( islower( sc.chNext ) ) {
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i+1);
+ if( isspace( buf[i] ) ) break;
+ }
+ buf[i] = 0;
+ kl = i;
+
+ if( doxyKeys.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_DOXYKEY );
+ sc.Forward( kl + 1 );
+ sc.SetState( SCE_MODULA_DOXYCOMM );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SCE_MODULA_NUMBER:
+ {
+ buf[0] = sc.ch;
+ for( i = 1; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( ! isdigit( buf[i] ) )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+
+ switch( sc.GetRelative(kl) ) {
+ case '_':
+ {
+ int base = atoi( buf );
+ if( base < 2 || base > 16 ) {
+ sc.SetState( SCE_MODULA_BADSTR );
+ } else {
+ int imax;
+
+ kl++;
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(kl+i);
+ if( ! IsDigitOfBase( buf[i], 16 ) ) {
+ break;
+ }
+ }
+ imax = i;
+ for( i = 0; i < imax; i++ ) {
+ if( ! IsDigitOfBase( buf[i], base ) ) {
+ sc.SetState( SCE_MODULA_BADSTR );
+ break;
+ }
+ }
+ kl += imax;
+ }
+ sc.SetState( SCE_MODULA_BASENUM );
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case '.':
+ if( sc.GetRelative(kl+1) == '.' ) {
+ kl--;
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ bool doNext = false;
+
+ kl++;
+
+ buf[0] = sc.GetRelative(kl);
+ if( isdigit( buf[0] ) ) {
+ for( i = 0;; i++ ) {
+ if( !isdigit(sc.GetRelative(kl+i)) )
+ break;
+ }
+ kl += i;
+ buf[0] = sc.GetRelative(kl);
+
+ switch( buf[0] )
+ {
+ case 'E':
+ case 'e':
+ case 'D':
+ case 'd':
+ case 'X':
+ case 'x':
+ kl++;
+ buf[0] = sc.GetRelative(kl);
+ if( buf[0] == '-' || buf[0] == '+' ) {
+ kl++;
+ }
+ buf[0] = sc.GetRelative(kl);
+ if( isdigit( buf[0] ) ) {
+ for( i = 0;; i++ ) {
+ if( !isdigit(sc.GetRelative(kl+i)) ) {
+ buf[0] = sc.GetRelative(kl+i);
+ break;
+ }
+ }
+ kl += i;
+ doNext = true;
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ break;
+
+ default:
+ doNext = true;
+ break;
+ }
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+
+ if( doNext ) {
+ if( ! isspace( buf[0] ) &&
+ buf[0] != ')' &&
+ buf[0] != '>' &&
+ buf[0] != '<' &&
+ buf[0] != '=' &&
+ buf[0] != '#' &&
+ buf[0] != '+' &&
+ buf[0] != '-' &&
+ buf[0] != '*' &&
+ buf[0] != '/' &&
+ buf[0] != ',' &&
+ buf[0] != ';'
+ ) {
+ sc.SetState( SCE_MODULA_BADSTR );
+ } else {
+ kl--;
+ }
+ }
+ }
+ sc.SetState( SCE_MODULA_FLOAT );
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ break;
+
+ default:
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ break;
+ }
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case SCE_MODULA_STRING:
+ if( sc.ch == '\"' ) {
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ if( sc.ch == '\\' ) {
+ i = 1;
+ if( IsDigitOfBase( sc.chNext, 8 ) ) {
+ for( i = 1; i < BUFLEN - 1; i++ ) {
+ if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
+ break;
+ }
+ if( i == 3 ) {
+ sc.SetState( SCE_MODULA_STRSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ } else {
+ buf[0] = sc.chNext;
+ buf[1] = 0;
+
+ if( escapeCodes.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_STRSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ }
+ sc.Forward(i+1);
+ sc.SetState( SCE_MODULA_STRING );
+ continue;
+ }
+ }
+ break;
+
+ case SCE_MODULA_CHAR:
+ if( sc.ch == '\'' ) {
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ else
+ if( ( sc.currentPos - charPos ) == 1 ) {
+ if( sc.ch == '\\' ) {
+ i = 1;
+ if( IsDigitOfBase( sc.chNext, 8 ) ) {
+ for( i = 1; i < BUFLEN - 1; i++ ) {
+ if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
+ break;
+ }
+ if( i == 3 ) {
+ sc.SetState( SCE_MODULA_CHARSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ } else {
+ buf[0] = sc.chNext;
+ buf[1] = 0;
+
+ if( escapeCodes.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_CHARSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ }
+ sc.Forward(i+1);
+ sc.SetState( SCE_MODULA_CHAR );
+ continue;
+ }
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ sc.Forward();
+ sc.SetState( SCE_MODULA_CHAR );
+ continue;
+ }
+ break;
+
+ case SCE_MODULA_PRAGMA:
+ if( sc.ch == '*' && sc.chNext == '>' ) {
+ sc.Forward();
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ else
+ if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
+ buf[0] = sc.ch;
+ buf[1] = sc.chNext;
+ for( i = 2; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( !isupper( buf[i] ) )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+ if( pragmaWords.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_PRGKEY );
+ sc.Forward( kl );
+ sc.SetState( SCE_MODULA_PRAGMA );
+ continue;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ sc.Forward();
+ }
+ sc.Complete();
+}
+
+static const char *const modulaWordListDesc[] =
+{
+ "Keywords",
+ "ReservedKeywords",
+ "Operators",
+ "PragmaKeyswords",
+ "EscapeCodes",
+ "DoxygeneKeywords",
+ 0
+};
+
+LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, "modula", FoldModulaDoc,
+ modulaWordListDesc);
--- /dev/null
+/**
+ * Scintilla source code edit control
+ * @file LexMySQL.cxx
+ * Lexer for MySQL
+ *
+ * Improved by Mike Lischke <mike.lischke@sun.com>
+ * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com>
+ * Original work by Neil Hodgson <neilh@scintilla.org>
+ * Copyright 1998-2005 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 IsAWordChar(int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalpha(ch) || ch == '_');
+}
+
+static inline bool IsADoxygenChar(int ch) {
+ return (islower(ch) || ch == '$' || ch == '@' ||
+ ch == '\\' || ch == '&' || ch == '<' ||
+ ch == '>' || ch == '#' || ch == '{' ||
+ ch == '}' || ch == '[' || ch == ']');
+}
+
+static inline bool IsANumberChar(int ch) {
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases.
+ return (ch < 0x80) &&
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
+}
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Check if the current content context represent a keyword and set the context state if so.
+ */
+static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[])
+{
+ int length = sc.LengthCurrent() + 1; // +1 for the next char
+ char* s = new char[length];
+ sc.GetCurrentLowered(s, length);
+ if (keywordlists[0]->InList(s))
+ sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
+ else
+ if (keywordlists[1]->InList(s))
+ sc.ChangeState(SCE_MYSQL_KEYWORD);
+ else
+ if (keywordlists[2]->InList(s))
+ sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
+ else
+ if (keywordlists[3]->InList(s))
+ sc.ChangeState(SCE_MYSQL_FUNCTION);
+ else
+ if (keywordlists[5]->InList(s))
+ sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
+ else
+ if (keywordlists[6]->InList(s))
+ sc.ChangeState(SCE_MYSQL_USER1);
+ else
+ if (keywordlists[7]->InList(s))
+ sc.ChangeState(SCE_MYSQL_USER2);
+ else
+ if (keywordlists[8]->InList(s))
+ sc.ChangeState(SCE_MYSQL_USER3);
+ delete [] s;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler)
+{
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+ // Determine if the current state should terminate.
+ switch (sc.state)
+ {
+ case SCE_MYSQL_OPERATOR:
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ break;
+ case SCE_MYSQL_NUMBER:
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char.
+ if (!IsANumberChar(sc.ch))
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ break;
+ case SCE_MYSQL_IDENTIFIER:
+ // Switch from identifier to keyword state and open a new state for the new char.
+ if (!IsAWordChar(sc.ch))
+ {
+ CheckForKeyword(sc, keywordlists);
+
+ // Additional check for function keywords needed.
+ // A function name must be followed by an opening parenthesis.
+ if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
+ sc.ChangeState(SCE_MYSQL_DEFAULT);
+
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ }
+ break;
+ case SCE_MYSQL_VARIABLE:
+ if (!IsAWordChar(sc.ch))
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ break;
+ case SCE_MYSQL_SYSTEMVARIABLE:
+ if (!IsAWordChar(sc.ch))
+ {
+ int length = sc.LengthCurrent() + 1;
+ char* s = new char[length];
+ sc.GetCurrentLowered(s, length);
+
+ // Check for known system variables here.
+ if (keywordlists[4]->InList(&s[2]))
+ sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
+ delete [] s;
+
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ }
+ break;
+ case SCE_MYSQL_QUOTEDIDENTIFIER:
+ if (sc.ch == '`')
+ {
+ if (sc.chNext == '`')
+ sc.Forward(); // Ignore it
+ else
+ sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ }
+ break;
+ case SCE_MYSQL_COMMENT:
+ case SCE_MYSQL_HIDDENCOMMAND:
+ if (sc.Match('*', '/'))
+ {
+ sc.Forward();
+ sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ }
+ break;
+ case SCE_MYSQL_COMMENTLINE:
+ if (sc.atLineStart)
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ break;
+ case SCE_MYSQL_SQSTRING:
+ if (sc.ch == '\\')
+ sc.Forward(); // Escape sequence
+ else
+ if (sc.ch == '\'')
+ {
+ // End of single quoted string reached?
+ if (sc.chNext == '\'')
+ sc.Forward();
+ else
+ sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ }
+ break;
+ case SCE_MYSQL_DQSTRING:
+ if (sc.ch == '\\')
+ sc.Forward(); // Escape sequence
+ else
+ if (sc.ch == '\"')
+ {
+ // End of single quoted string reached?
+ if (sc.chNext == '\"')
+ sc.Forward();
+ else
+ sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_MYSQL_DEFAULT)
+ {
+ switch (sc.ch)
+ {
+ case '@':
+ if (sc.chNext == '@')
+ {
+ sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
+ sc.Forward(2); // Skip past @@.
+ }
+ else
+ if (IsAWordStart(sc.ch))
+ {
+ sc.SetState(SCE_MYSQL_VARIABLE);
+ sc.Forward(); // Skip past @.
+ }
+ else
+ sc.SetState(SCE_MYSQL_OPERATOR);
+ break;
+ case '`':
+ sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
+ break;
+ case '#':
+ sc.SetState(SCE_MYSQL_COMMENTLINE);
+ break;
+ case '\'':
+ sc.SetState(SCE_MYSQL_SQSTRING);
+ break;
+ case '\"':
+ sc.SetState(SCE_MYSQL_DQSTRING);
+ break;
+ default:
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+ sc.SetState(SCE_MYSQL_NUMBER);
+ else
+ if (IsAWordStart(sc.ch))
+ sc.SetState(SCE_MYSQL_IDENTIFIER);
+ else
+ if (sc.Match('/', '*'))
+ {
+ sc.SetState(SCE_MYSQL_COMMENT);
+
+ // Skip comment introducer and check for hidden command.
+ sc.Forward(2);
+ if (sc.ch == '!')
+ {
+ sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
+ sc.Forward();
+ }
+ }
+ else
+ if (sc.Match("--"))
+ {
+ // Special MySQL single line comment.
+ sc.SetState(SCE_MYSQL_COMMENTLINE);
+ sc.Forward(2);
+
+ // Check the third character too. It must be a space or EOL.
+ if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
+ sc.ChangeState(SCE_MYSQL_OPERATOR);
+ }
+ else
+ if (isoperator(static_cast<char>(sc.ch)))
+ sc.SetState(SCE_MYSQL_OPERATOR);
+ }
+ }
+ }
+
+ // Do a final check for keywords if we currently have an identifier, to highlight them
+ // also at the end of a line.
+ if (sc.state == SCE_MYSQL_IDENTIFIER)
+ {
+ CheckForKeyword(sc, keywordlists);
+
+ // Additional check for function keywords needed.
+ // A function name must be followed by an opening parenthesis.
+ if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
+ sc.ChangeState(SCE_MYSQL_DEFAULT);
+ }
+
+ sc.Complete();
+}
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Helper function to determine if we have a foldable comment currently.
+ */
+static bool IsStreamCommentStyle(int style)
+{
+ return style == SCE_MYSQL_COMMENT;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Code copied from StyleContext and modified to work here. Should go into Accessor as a
+ * companion to Match()...
+ */
+bool MatchIgnoreCase(Accessor &styler, int currentPos, const char *s)
+{
+ for (int n = 0; *s; n++)
+ {
+ if (*s != tolower(styler.SafeGetCharAt(currentPos + n)))
+ return false;
+ s++;
+ }
+ return true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment.
+static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)
+{
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
+
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
+ int levelNext = levelCurrent;
+
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+
+ bool endPending = false;
+ bool whenPending = false;
+ bool elseIfPending = false;
+
+ char nextChar = styler.SafeGetCharAt(startPos);
+ for (unsigned int i = startPos; length > 0; i++, length--)
+ {
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+
+ char currentChar = nextChar;
+ nextChar = styler.SafeGetCharAt(i + 1);
+ bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
+
+ switch (style)
+ {
+ case SCE_MYSQL_COMMENT:
+ if (foldComment)
+ {
+ // Multiline comment style /* .. */.
+ if (IsStreamCommentStyle(style))
+ {
+ // Increase level if we just start a foldable comment.
+ if (!IsStreamCommentStyle(stylePrev))
+ levelNext++;
+ else
+ // If we are in the middle of a foldable comment check if it ends now.
+ // Don't end at the line end, though.
+ if (!IsStreamCommentStyle(styleNext) && !atEOL)
+ levelNext--;
+ }
+ }
+ break;
+ case SCE_MYSQL_COMMENTLINE:
+ if (foldComment)
+ {
+ // Not really a standard, but we add support for single line comments
+ // with special curly braces syntax as foldable comments too.
+ // MySQL needs -- comments to be followed by space or control char
+ if (styler.Match(i, "--"))
+ {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ char chNext3 = styler.SafeGetCharAt(i + 3);
+ if (chNext2 == '{' || chNext3 == '{')
+ levelNext++;
+ else
+ if (chNext2 == '}' || chNext3 == '}')
+ levelNext--;
+ }
+ }
+ break;
+ case SCE_MYSQL_HIDDENCOMMAND:
+ if (endPending)
+ {
+ // A conditional command is not a white space so it should end the current block
+ // before opening a new one.
+ endPending = false;
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+ if (style != stylePrev)
+ levelNext++;
+ else
+ if (style != styleNext)
+ {
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+ break;
+ case SCE_MYSQL_OPERATOR:
+ if (endPending)
+ {
+ endPending = false;
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+ if (currentChar == '(')
+ levelNext++;
+ else
+ if (currentChar == ')')
+ {
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+ break;
+ case SCE_MYSQL_MAJORKEYWORD:
+ case SCE_MYSQL_KEYWORD:
+ case SCE_MYSQL_FUNCTION:
+ case SCE_MYSQL_PROCEDUREKEYWORD:
+ // Reserved and other keywords.
+ if (style != stylePrev)
+ {
+ // END decreases the folding level, regardless which keyword follows.
+ bool endFound = MatchIgnoreCase(styler, i, "end");
+ if (endPending)
+ {
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+ else
+ if (!endFound)
+ {
+ if (MatchIgnoreCase(styler, i, "begin"))
+ levelNext++;
+ else
+ {
+ if (!foldOnlyBegin)
+ {
+ bool whileFound = MatchIgnoreCase(styler, i, "while");
+ bool loopFound = MatchIgnoreCase(styler, i, "loop");
+ bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
+ bool caseFound = MatchIgnoreCase(styler, i, "case");
+
+ if (whileFound || loopFound || repeatFound || caseFound)
+ levelNext++;
+ else
+ {
+ // IF alone does not increase the fold level as it is also used in non-block'ed
+ // code like DROP PROCEDURE blah IF EXISTS.
+ // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch).
+ if (MatchIgnoreCase(styler, i, "then"))
+ {
+ if (!elseIfPending && !whenPending)
+ levelNext++;
+ else
+ {
+ elseIfPending = false;
+ whenPending = false;
+ }
+ }
+ else
+ {
+ // Neither of if/then/while/loop/repeat/case, so check for
+ // sub parts of IF and CASE.
+ if (MatchIgnoreCase(styler, i, "elseif"))
+ elseIfPending = true;
+ if (MatchIgnoreCase(styler, i, "when"))
+ whenPending = true;
+ }
+ }
+ }
+ }
+ }
+
+ // Keep the current end state for the next round.
+ endPending = endFound;
+ }
+ break;
+
+ default:
+ if (!isspace(currentChar) && endPending)
+ {
+ // END followed by a non-whitespace character (not covered by other cases like identifiers)
+ // also should end a folding block. Typical case: END followed by self defined delimiter.
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+ break;
+ }
+
+ if (atEOL)
+ {
+ // Apply the new folding level to this line.
+ // Leave pending states as they are otherwise a line break will de-sync
+ // code folding and valid syntax.
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+
+ lineCurrent++;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(currentChar))
+ visibleChars++;
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static const char * const mysqlWordListDesc[] = {
+ "Major Keywords",
+ "Keywords",
+ "Database Objects",
+ "Functions",
+ "System Variables",
+ "Procedure keywords",
+ "User Keywords 1",
+ "User Keywords 2",
+ "User Keywords 3",
+ 0
+};
+
+LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+// Nimrod lexer
+// (c) 2009 Andreas Rumpf
+/** @file LexNimrod.cxx
+ ** Lexer for Nimrod.
+ **/
+// Copyright 1998-2002 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 IsAWordChar(int ch) {
+ return (ch >= 0x80) || isalnum(ch) || ch == '_';
+}
+
+static int tillEndOfTripleQuote(Accessor &styler, int pos, int max) {
+ /* search for """ */
+ for (;;) {
+ if (styler.SafeGetCharAt(pos, '\0') == '\0') return pos;
+ if (pos >= max) return pos;
+ if (styler.Match(pos, "\"\"\"")) {
+ return pos + 2;
+ }
+ pos++;
+ }
+}
+
+#define CR 13 /* use both because Scite allows changing the line ending */
+#define LF 10
+
+static bool inline isNewLine(int ch) {
+ return ch == CR || ch == LF;
+}
+
+static int scanString(Accessor &styler, int pos, int max, bool rawMode) {
+ for (;;) {
+ if (pos >= max) return pos;
+ char ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == CR || ch == LF || ch == '\0') return pos;
+ if (ch == '"') return pos;
+ if (ch == '\\' && !rawMode) {
+ pos += 2;
+ } else {
+ pos++;
+ }
+ }
+}
+
+static int scanChar(Accessor &styler, int pos, int max) {
+ for (;;) {
+ if (pos >= max) return pos;
+ char ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == CR || ch == LF || ch == '\0') return pos;
+ if (ch == '\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\0')) )
+ return pos;
+ if (ch == '\\') {
+ pos += 2;
+ } else {
+ pos++;
+ }
+ }
+}
+
+static int scanIdent(Accessor &styler, int pos, WordList &keywords) {
+ char buf[100]; /* copy to lowercase and ignore underscores */
+ int i = 0;
+
+ for (;;) {
+ char ch = styler.SafeGetCharAt(pos, '\0');
+ if (!IsAWordChar(ch)) break;
+ if (ch != '_' && i < ((int)sizeof(buf))-1) {
+ buf[i] = static_cast<char>(tolower(ch));
+ i++;
+ }
+ pos++;
+ }
+ buf[i] = '\0';
+ /* look for keyword */
+ if (keywords.InList(buf)) {
+ styler.ColourTo(pos-1, SCE_P_WORD);
+ } else {
+ styler.ColourTo(pos-1, SCE_P_IDENTIFIER);
+ }
+ return pos;
+}
+
+static int scanNumber(Accessor &styler, int pos) {
+ char ch, ch2;
+ ch = styler.SafeGetCharAt(pos, '\0');
+ ch2 = styler.SafeGetCharAt(pos+1, '\0');
+ if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) {
+ /* binary number: */
+ pos += 2;
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
+ else break;
+ }
+ } else if (ch == '0' &&
+ (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
+ /* octal number: */
+ pos += 2;
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos;
+ else break;
+ }
+ } else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) {
+ /* hexadecimal number: */
+ pos += 2;
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '_' || (ch >= '0' && ch <= '9')
+ || (ch >= 'a' && ch <= 'f')
+ || (ch >= 'A' && ch <= 'F')) ++pos;
+ else break;
+ }
+ } else {
+ // skip decimal part:
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+ else break;
+ }
+ ch2 = styler.SafeGetCharAt(pos+1, '\0');
+ if (ch == '.' && ch2 >= '0' && ch2 <= '9') {
+ ++pos; // skip '.'
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+ else break;
+ }
+ }
+ if (ch == 'e' || ch == 'E') {
+ ++pos;
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '-' || ch == '+') ++pos;
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+ else break;
+ }
+ }
+ }
+ if (ch == '\'') {
+ /* a type suffix: */
+ pos++;
+ for (;;) {
+ ch = styler.SafeGetCharAt(pos);
+ if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')
+ || (ch >= 'a' && ch <= 'z') || ch == '_') ++pos;
+ else break;
+ }
+ }
+ styler.ColourTo(pos-1, SCE_P_NUMBER);
+ return pos;
+}
+
+/* rewritten from scratch, because I couldn't get rid of the bugs...
+ (A character based approach sucks!)
+*/
+static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ int pos = startPos;
+ int max = startPos + length;
+ char ch;
+ WordList &keywords = *keywordlists[0];
+
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+
+ switch (initStyle) {
+ /* check where we are: */
+ case SCE_P_TRIPLEDOUBLE:
+ pos = tillEndOfTripleQuote(styler, pos, max);
+ styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
+ pos++;
+ break;
+ default: /* nothing to do: */
+ break;
+ }
+ while (pos < max) {
+ ch = styler.SafeGetCharAt(pos, '\0');
+ switch (ch) {
+ case '\0': return;
+ case '#': {
+ bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
+ while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
+ if (doccomment)
+ styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
+ else
+ styler.ColourTo(pos, SCE_P_COMMENTLINE);
+ } break;
+ case 'r': case 'R': {
+ if (styler.SafeGetCharAt(pos+1) == '"') {
+ pos = scanString(styler, pos+2, max, true);
+ styler.ColourTo(pos, SCE_P_STRING);
+ pos++;
+ } else {
+ pos = scanIdent(styler, pos, keywords);
+ }
+ } break;
+ case '"':
+ if (styler.Match(pos+1, "\"\"")) {
+ pos = tillEndOfTripleQuote(styler, pos+3, max);
+ styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
+ } else {
+ pos = scanString(styler, pos+1, max, false);
+ styler.ColourTo(pos, SCE_P_STRING);
+ }
+ pos++;
+ break;
+ case '\'':
+ pos = scanChar(styler, pos+1, max);
+ styler.ColourTo(pos, SCE_P_CHARACTER);
+ pos++;
+ break;
+ default: // identifers, numbers, operators, whitespace
+ if (ch >= '0' && ch <= '9') {
+ pos = scanNumber(styler, pos);
+ } else if (IsAWordChar(ch)) {
+ pos = scanIdent(styler, pos, keywords);
+ } else if (ch == '`') {
+ pos++;
+ while (pos < max) {
+ ch = styler.SafeGetCharAt(pos, LF);
+ if (ch == '`') {
+ ++pos;
+ break;
+ }
+ if (ch == CR || ch == LF) break;
+ ++pos;
+ }
+ styler.ColourTo(pos, SCE_P_IDENTIFIER);
+ } else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", ch)) {
+ styler.ColourTo(pos, SCE_P_OPERATOR);
+ pos++;
+ } else {
+ styler.ColourTo(pos, SCE_P_DEFAULT);
+ pos++;
+ }
+ break;
+ }
+ }
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ if (ch == '#')
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+static bool IsQuoteLine(int line, Accessor &styler) {
+ int style = styler.StyleAt(styler.LineStart(line)) & 31;
+ return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+}
+
+
+static void FoldNimrodDoc(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.nimrod") != 0;
+ const bool foldQuotes = styler.GetPropertyInt("fold.quotes.nimrod") != 0;
+
+ // Backtrack to previous non-blank line so we can determine indent level
+ // for any white space lines (needed esp. within triple quoted strings)
+ // 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)) &&
+ (!IsQuoteLine(lineCurrent, styler)))
+ break;
+ }
+ int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+
+ // Set up initial loop state
+ startPos = styler.LineStart(lineCurrent);
+ int prev_state = SCE_P_DEFAULT & 31;
+ if (lineCurrent >= 1)
+ prev_state = styler.StyleAt(startPos - 1) & 31;
+ int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||
+ (prev_state == SCE_P_TRIPLEDOUBLE));
+ int prevComment = 0;
+ if (lineCurrent >= 1)
+ prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
+
+ // Process all characters to end of requested range or end of any triple quote
+ // or comment that hangs over the end of the range. Cap processing in all cases
+ // to end of document (in case of unclosed quote or comment at end).
+ while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||
+ prevQuote || prevComment)) {
+
+ // Gather info
+ int lev = indentCurrent;
+ int lineNext = lineCurrent + 1;
+ int indentNext = indentCurrent;
+ int quote = false;
+ if (lineNext <= docLines) {
+ // Information about next line is only available if not at end of document
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
+ quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+ }
+ const int quote_start = (quote && !prevQuote);
+ const int quote_continue = (quote && prevQuote);
+ const int comment = foldComment && IsCommentLine(lineCurrent, styler);
+ const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
+ IsCommentLine(lineNext, styler) &&
+ (lev > SC_FOLDLEVELBASE));
+ const int comment_continue = (comment && prevComment);
+ if ((!quote || !prevQuote) && !comment)
+ indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+ if (quote)
+ indentNext = indentCurrentLevel;
+ if (indentNext & SC_FOLDLEVELWHITEFLAG)
+ indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+ if (quote_start) {
+ // Place fold point at start of triple quoted string
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (quote_continue || prevQuote) {
+ // Add level to rest of lines in the string
+ lev = lev + 1;
+ } else if (comment_start) {
+ // Place fold point at start of a block of comments
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (comment_continue) {
+ // Add level to rest of lines in the block
+ lev = lev + 1;
+ }
+
+ // Skip past any blank lines for next indent level info; we skip also
+ // comments (all comments, not just those starting in column 0)
+ // which effectively folds them into surrounding code rather
+ // than screwing up folding.
+
+ while (!quote &&
+ (lineNext < docLines) &&
+ ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
+ (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
+
+ lineNext++;
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ }
+
+ const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+ const int levelBeforeComments =
+ Maximum(indentCurrentLevel,levelAfterComments);
+
+ // Now set all the indent levels on the lines we skipped
+ // Do this from end to start. Once we encounter one line
+ // which is indented more than the line after the end of
+ // the comment-block, use the level of the block before
+
+ int skipLine = lineNext;
+ int skipLevel = levelAfterComments;
+
+ while (--skipLine > lineCurrent) {
+ int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+ skipLevel = levelBeforeComments;
+
+ int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+ styler.SetLevel(skipLine, skipLevel | whiteFlag);
+ }
+
+ // Set fold header on non-quote/non-comment line
+ if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <
+ (indentNext & SC_FOLDLEVELNUMBERMASK))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+
+ // Keep track of triple quote and block comment state of previous line
+ prevQuote = quote;
+ prevComment = comment_start || comment_continue;
+
+ // Set fold level for this line and move to next line
+ styler.SetLevel(lineCurrent, lev);
+ indentCurrent = indentNext;
+ lineCurrent = lineNext;
+ }
+
+ // NOTE: Cannot set level of last line here because indentCurrent doesn't have
+ // header flag set; the loop above is crafted to take care of this case!
+ //styler.SetLevel(lineCurrent, indentCurrent);
+}
+
+static const char * const nimrodWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, "nimrod", FoldNimrodDoc,
+ nimrodWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexNsis.cxx
+ ** Lexer for NSIS
+ **/
+// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
+// Last Updated: 03/13/2005
+// 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
+
+/*
+// located in SciLexer.h
+#define SCLEX_NSIS 43
+
+#define SCE_NSIS_DEFAULT 0
+#define SCE_NSIS_COMMENT 1
+#define SCE_NSIS_STRINGDQ 2
+#define SCE_NSIS_STRINGLQ 3
+#define SCE_NSIS_STRINGRQ 4
+#define SCE_NSIS_FUNCTION 5
+#define SCE_NSIS_VARIABLE 6
+#define SCE_NSIS_LABEL 7
+#define SCE_NSIS_USERDEFINED 8
+#define SCE_NSIS_SECTIONDEF 9
+#define SCE_NSIS_SUBSECTIONDEF 10
+#define SCE_NSIS_IFDEFINEDEF 11
+#define SCE_NSIS_MACRODEF 12
+#define SCE_NSIS_STRINGVAR 13
+#define SCE_NSIS_NUMBER 14
+// ADDED for Scintilla v1.63
+#define SCE_NSIS_SECTIONGROUP 15
+#define SCE_NSIS_PAGEEX 16
+#define SCE_NSIS_FUNCTIONDEF 17
+#define SCE_NSIS_COMMENTBOX 18
+*/
+
+static bool isNsisNumber(char ch)
+{
+ return (ch >= '0' && ch <= '9');
+}
+
+static bool isNsisChar(char ch)
+{
+ return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+static bool isNsisLetter(char ch)
+{
+ return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
+{
+ int nNextLine = -1;
+ for( unsigned int i = start; i < end; i++ )
+ {
+ char cNext = styler.SafeGetCharAt( i );
+ if( cNext == '\n' )
+ {
+ nNextLine = i+1;
+ break;
+ }
+ }
+
+ if( nNextLine == -1 ) // We never found the next line...
+ return false;
+
+ for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
+ {
+ char cNext = styler.SafeGetCharAt( firstChar );
+ if( cNext == ' ' )
+ continue;
+ if( cNext == '\t' )
+ continue;
+ if( cNext == '!' )
+ {
+ if( styler.Match(firstChar, "!else") )
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
+static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )
+{
+ if( bIgnoreCase )
+ return CompareCaseInsensitive( s1, s2);
+
+ return strcmp( s1, s2 );
+}
+
+static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
+{
+ int style = styler.StyleAt(end);
+
+ // If the word is too long, it is not what we are looking for
+ if( end - start > 20 )
+ return foldlevel;
+
+ if( foldUtilityCmd )
+ {
+ // Check the style at this point, if it is not valid, then return zero
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
+ style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
+ return foldlevel;
+ }
+ else
+ {
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
+ return foldlevel;
+ }
+
+ int newFoldlevel = foldlevel;
+ bool bIgnoreCase = false;
+ if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
+ bIgnoreCase = true;
+
+ char s[20]; // The key word we are looking for has atmost 13 characters
+ s[0] = '\0';
+ for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
+ {
+ s[i] = static_cast<char>( styler[ start + i ] );
+ s[i + 1] = '\0';
+ }
+
+ if( s[0] == '!' )
+ {
+ if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
+ newFoldlevel++;
+ else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
+ newFoldlevel--;
+ else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
+ newFoldlevel++;
+ }
+ else
+ {
+ if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
+ newFoldlevel++;
+ else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
+ newFoldlevel--;
+ }
+
+ return newFoldlevel;
+}
+
+static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
+{
+ bool bIgnoreCase = false;
+ if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
+ bIgnoreCase = true;
+
+ bool bUserVars = false;
+ if( styler.GetPropertyInt("nsis.uservars") == 1 )
+ bUserVars = true;
+
+ char s[100];
+
+ WordList &Functions = *keywordLists[0];
+ WordList &Variables = *keywordLists[1];
+ WordList &Lables = *keywordLists[2];
+ WordList &UserDefined = *keywordLists[3];
+
+ for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)
+ {
+ if( bIgnoreCase )
+ s[i] = static_cast<char>( tolower(styler[ start + i ] ) );
+ else
+ s[i] = static_cast<char>( styler[ start + i ] );
+ s[i + 1] = '\0';
+ }
+
+ // Check for special words...
+ if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
+ return SCE_NSIS_MACRODEF;
+
+ if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
+ return SCE_NSIS_IFDEFINEDEF;
+
+ if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // Covers !if and else
+ return SCE_NSIS_IFDEFINEDEF;
+
+ if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 ) // Covers !ifmacrodef and !ifnmacrodef
+ return SCE_NSIS_IFDEFINEDEF;
+
+ if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
+ return SCE_NSIS_SECTIONGROUP;
+
+ if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
+ return SCE_NSIS_SECTIONDEF;
+
+ if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
+ return SCE_NSIS_SUBSECTIONDEF;
+
+ if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
+ return SCE_NSIS_PAGEEX;
+
+ if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
+ return SCE_NSIS_FUNCTIONDEF;
+
+ if ( Functions.InList(s) )
+ return SCE_NSIS_FUNCTION;
+
+ if ( Variables.InList(s) )
+ return SCE_NSIS_VARIABLE;
+
+ if ( Lables.InList(s) )
+ return SCE_NSIS_LABEL;
+
+ if( UserDefined.InList(s) )
+ return SCE_NSIS_USERDEFINED;
+
+ if( strlen(s) > 3 )
+ {
+ if( s[1] == '{' && s[strlen(s)-1] == '}' )
+ return SCE_NSIS_VARIABLE;
+ }
+
+ // See if the variable is a user defined variable
+ if( s[0] == '$' && bUserVars )
+ {
+ bool bHasSimpleNsisChars = true;
+ for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
+ {
+ if( !isNsisChar( s[j] ) )
+ {
+ bHasSimpleNsisChars = false;
+ break;
+ }
+ }
+
+ if( bHasSimpleNsisChars )
+ return SCE_NSIS_VARIABLE;
+ }
+
+ // To check for numbers
+ if( isNsisNumber( s[0] ) )
+ {
+ bool bHasSimpleNsisNumber = true;
+ for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
+ {
+ if( !isNsisNumber( s[j] ) )
+ {
+ bHasSimpleNsisNumber = false;
+ break;
+ }
+ }
+
+ if( bHasSimpleNsisNumber )
+ return SCE_NSIS_NUMBER;
+ }
+
+ return SCE_NSIS_DEFAULT;
+}
+
+static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
+{
+ int state = SCE_NSIS_DEFAULT;
+ if( startPos > 0 )
+ state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
+
+ styler.StartAt( startPos );
+ styler.GetLine( startPos );
+
+ unsigned int nLengthDoc = startPos + length;
+ styler.StartSegment( startPos );
+
+ char cCurrChar;
+ bool bVarInString = false;
+ bool bClassicVarInString = false;
+
+ unsigned int i;
+ for( i = startPos; i < nLengthDoc; i++ )
+ {
+ cCurrChar = styler.SafeGetCharAt( i );
+ char cNextChar = styler.SafeGetCharAt(i+1);
+
+ switch(state)
+ {
+ case SCE_NSIS_DEFAULT:
+ if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line
+ {
+ styler.ColourTo(i-1, state );
+ state = SCE_NSIS_COMMENT;
+ break;
+ }
+ if( cCurrChar == '"' )
+ {
+ styler.ColourTo(i-1, state );
+ state = SCE_NSIS_STRINGDQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ break;
+ }
+ if( cCurrChar == '\'' )
+ {
+ styler.ColourTo(i-1, state );
+ state = SCE_NSIS_STRINGRQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ break;
+ }
+ if( cCurrChar == '`' )
+ {
+ styler.ColourTo(i-1, state );
+ state = SCE_NSIS_STRINGLQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ break;
+ }
+
+ // NSIS KeyWord,Function, Variable, UserDefined:
+ if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )
+ {
+ styler.ColourTo(i-1,state);
+ state = SCE_NSIS_FUNCTION;
+
+ // If it is a number, we must check and set style here first...
+ if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
+ styler.ColourTo( i, SCE_NSIS_NUMBER);
+
+ break;
+ }
+
+ if( cCurrChar == '/' && cNextChar == '*' )
+ {
+ styler.ColourTo(i-1,state);
+ state = SCE_NSIS_COMMENTBOX;
+ break;
+ }
+
+ break;
+ case SCE_NSIS_COMMENT:
+ if( cNextChar == '\n' || cNextChar == '\r' )
+ {
+ // Special case:
+ if( cCurrChar == '\\' )
+ {
+ styler.ColourTo(i-2,state);
+ styler.ColourTo(i,SCE_NSIS_DEFAULT);
+ }
+ else
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ }
+ break;
+ case SCE_NSIS_STRINGDQ:
+ case SCE_NSIS_STRINGLQ:
+ case SCE_NSIS_STRINGRQ:
+
+ if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
+ break; // Ignore the next character, even if it is a quote of some sort
+
+ if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ break;
+ }
+
+ if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ break;
+ }
+
+ if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ break;
+ }
+
+ if( cNextChar == '\r' || cNextChar == '\n' )
+ {
+ int nCurLine = styler.GetLine(i+1);
+ int nBack = i;
+ // We need to check if the previous line has a \ in it...
+ bool bNextLine = false;
+
+ while( nBack > 0 )
+ {
+ if( styler.GetLine(nBack) != nCurLine )
+ break;
+
+ char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
+
+ if( cTemp == '\\' )
+ {
+ bNextLine = true;
+ break;
+ }
+ if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
+ break;
+
+ nBack--;
+ }
+
+ if( bNextLine )
+ {
+ styler.ColourTo(i+1,state);
+ }
+ if( bNextLine == false )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ }
+ break;
+
+ case SCE_NSIS_FUNCTION:
+
+ // NSIS KeyWord:
+ if( cCurrChar == '$' )
+ state = SCE_NSIS_DEFAULT;
+ else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
+ state = SCE_NSIS_DEFAULT;
+ else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
+ {
+ state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
+ styler.ColourTo( i, state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )
+ {
+ if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )
+ styler.ColourTo( i-1, SCE_NSIS_NUMBER );
+
+ state = SCE_NSIS_DEFAULT;
+
+ if( cCurrChar == '"' )
+ {
+ state = SCE_NSIS_STRINGDQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ }
+ else if( cCurrChar == '`' )
+ {
+ state = SCE_NSIS_STRINGLQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ }
+ else if( cCurrChar == '\'' )
+ {
+ state = SCE_NSIS_STRINGRQ;
+ bVarInString = false;
+ bClassicVarInString = false;
+ }
+ else if( cCurrChar == '#' || cCurrChar == ';' )
+ {
+ state = SCE_NSIS_COMMENT;
+ }
+ }
+ break;
+ case SCE_NSIS_COMMENTBOX:
+
+ if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ break;
+ }
+
+ if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
+ {
+ styler.ColourTo(i,state);
+ }
+ else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )
+ {
+ bool bIngoreNextDollarSign = false;
+ bool bUserVars = false;
+ if( styler.GetPropertyInt("nsis.uservars") == 1 )
+ bUserVars = true;
+
+ if( bVarInString && cCurrChar == '$' )
+ {
+ bVarInString = false;
+ bIngoreNextDollarSign = true;
+ }
+ else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
+ {
+ styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
+ bVarInString = false;
+ bIngoreNextDollarSign = false;
+ }
+
+ // Covers "$INSTDIR and user vars like $MYVAR"
+ else if( bVarInString && !isNsisChar(cNextChar) )
+ {
+ int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
+ if( nWordState == SCE_NSIS_VARIABLE )
+ styler.ColourTo( i, SCE_NSIS_STRINGVAR);
+ else if( bUserVars )
+ styler.ColourTo( i, SCE_NSIS_STRINGVAR);
+ bVarInString = false;
+ }
+ // Covers "${TEST}..."
+ else if( bClassicVarInString && cNextChar == '}' )
+ {
+ styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
+ bClassicVarInString = false;
+ }
+
+ // Start of var in string
+ if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )
+ {
+ styler.ColourTo( i-1, state);
+ bClassicVarInString = true;
+ bVarInString = false;
+ }
+ else if( !bIngoreNextDollarSign && cCurrChar == '$' )
+ {
+ styler.ColourTo( i-1, state);
+ bVarInString = true;
+ bClassicVarInString = false;
+ }
+ }
+ }
+
+ // Colourise remaining document
+ styler.ColourTo(nLengthDoc-1,state);
+}
+
+static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ // No folding enabled, no reason to continue...
+ if( styler.GetPropertyInt("fold") == 0 )
+ return;
+
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
+ bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
+ bool blockComment = false;
+
+ int lineCurrent = styler.GetLine(startPos);
+ unsigned int safeStartPos = styler.LineStart( lineCurrent );
+
+ bool bArg1 = true;
+ int nWordStart = -1;
+
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+ int style = styler.StyleAt(safeStartPos);
+ if( style == SCE_NSIS_COMMENTBOX )
+ {
+ if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
+ levelNext++;
+ blockComment = true;
+ }
+
+ for (unsigned int i = safeStartPos; i < startPos + length; i++)
+ {
+ char chCurr = styler.SafeGetCharAt(i);
+ style = styler.StyleAt(i);
+ if( blockComment && style != SCE_NSIS_COMMENTBOX )
+ {
+ levelNext--;
+ blockComment = false;
+ }
+ else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
+ {
+ levelNext++;
+ blockComment = true;
+ }
+
+ if( bArg1 && !blockComment)
+ {
+ if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
+ {
+ nWordStart = i;
+ }
+ else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
+ {
+ int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
+
+ if( newLevel == levelNext )
+ {
+ if( foldAtElse && foldUtilityCmd )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+ }
+ else
+ levelNext = newLevel;
+ bArg1 = false;
+ }
+ }
+
+ if( chCurr == '\n' )
+ {
+ if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+
+ // If we are on a new line...
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (levelUse < levelNext )
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+
+ lineCurrent++;
+ levelCurrent = levelNext;
+ bArg1 = true; // New line, lets look at first argument again
+ nWordStart = -1;
+ }
+ }
+
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+}
+
+static const char * const nsisWordLists[] = {
+ "Functions",
+ "Variables",
+ "Lables",
+ "UserDefined",
+ 0, };
+
+
+LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexOScript.cxx
+ ** Lexer for OScript sources; ocx files and/or OSpace dumps.
+ ** OScript is a programming language used to develop applications for the
+ ** Livelink server platform.
+ **/
+// Written by Ferdinand Prantl <prantlf@gmail.com>, inspired by the code from
+// LexVB.cxx and LexPascal.cxx. 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
+
+// -----------------------------------------
+// Functions classifying a single character.
+
+// This function is generic and should be probably moved to CharSet.h where
+// IsAlphaNumeric the others reside.
+inline bool IsAlpha(int ch) {
+ return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
+}
+
+static inline bool IsIdentifierChar(int ch) {
+ // Identifiers cannot contain non-ASCII letters; a word with non-English
+ // language-specific characters cannot be an identifier.
+ return IsAlphaNumeric(ch) || ch == '_';
+}
+
+static inline bool IsIdentifierStart(int ch) {
+ // Identifiers cannot contain non-ASCII letters; a word with non-English
+ // language-specific characters cannot be an identifier.
+ return IsAlpha(ch) || ch == '_';
+}
+
+static inline bool IsNumberChar(int ch, int chNext) {
+ // Numeric constructs are not checked for lexical correctness. They are
+ // expected to look like +1.23-E9 but actually any bunch of the following
+ // characters will be styled as number.
+ // KNOWN PROBLEM: if you put + or - operators immediately after a number
+ // and the next operand starts with the letter E, the operator will not be
+ // recognized and it will be styled together with the preceding number.
+ // This should not occur; at least not often. The coding style recommends
+ // putting spaces around operators.
+ return IsADigit(ch) || toupper(ch) == 'E' || ch == '.' ||
+ ((ch == '-' || ch == '+') && toupper(chNext) == 'E');
+}
+
+// This function checks for the start or a natural number without any symbols
+// or operators as a prefix; the IsPrefixedNumberStart should be called
+// immediately after this one to cover all possible numeric constructs.
+static inline bool IsNaturalNumberStart(int ch) {
+ return IsADigit(ch) != 0;
+}
+
+static inline bool IsPrefixedNumberStart(int ch, int chNext) {
+ // KNOWN PROBLEM: if you put + or - operators immediately before a number
+ // the operator will not be recognized and it will be styled together with
+ // the succeeding number. This should not occur; at least not often. The
+ // coding style recommends putting spaces around operators.
+ return (ch == '.' || ch == '-' || ch == '+') && IsADigit(chNext);
+}
+
+static inline bool IsOperator(int ch) {
+ return strchr("%^&*()-+={}[]:;<>,/?!.~|\\", ch) != NULL;
+}
+
+// ---------------------------------------------------------------
+// Functions classifying a token currently processed in the lexer.
+
+// Checks if the current line starts with the preprocessor directive used
+// usually to introduce documentation comments: #ifdef DOC. This method is
+// supposed to be called if the line has been recognized as a preprocessor
+// directive already.
+static bool IsDocCommentStart(StyleContext &sc) {
+ // Check the line back to its start only if the end looks promising.
+ if (sc.LengthCurrent() == 10 && !IsAlphaNumeric(sc.ch)) {
+ char s[11];
+ sc.GetCurrentLowered(s, sizeof(s));
+ return strcmp(s, "#ifdef doc") == 0;
+ }
+ return false;
+}
+
+// Checks if the current line starts with the preprocessor directive that
+// is complementary to the #ifdef DOC start: #endif. This method is supposed
+// to be called if the current state point to the documentation comment.
+// QUESTIONAL ASSUMPTION: The complete #endif directive is not checked; just
+// the starting #e. However, there is no other preprocessor directive with
+// the same starting letter and thus this optimization should always work.
+static bool IsDocCommentEnd(StyleContext &sc) {
+ return sc.ch == '#' && sc.chNext == 'e';
+}
+
+class IdentifierClassifier {
+ WordList &keywords; // Passed from keywords property.
+ WordList &constants; // Passed from keywords2 property.
+ WordList &operators; // Passed from keywords3 property.
+ WordList &types; // Passed from keywords4 property.
+ WordList &functions; // Passed from keywords5 property.
+ WordList &objects; // Passed from keywords6 property.
+
+ IdentifierClassifier(IdentifierClassifier const&);
+ IdentifierClassifier& operator=(IdentifierClassifier const&);
+
+public:
+ IdentifierClassifier(WordList *keywordlists[]) :
+ keywords(*keywordlists[0]), constants(*keywordlists[1]),
+ operators(*keywordlists[2]), types(*keywordlists[3]),
+ functions(*keywordlists[4]), objects(*keywordlists[5])
+ {}
+
+ void ClassifyIdentifier(StyleContext &sc) {
+ // Opening parenthesis following an identifier makes it a possible
+ // function call.
+ // KNOWN PROBLEM: If some whitespace is inserted between the
+ // identifier and the parenthesis they will not be able to be
+ // recognized as a function call. This should not occur; at
+ // least not often. Such coding style would be weird.
+ if (sc.Match('(')) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ // Before an opening brace can be control statements and
+ // operators too; function call is the last option.
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_KEYWORD);
+ } else if (operators.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_OPERATOR);
+ } else if (functions.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_FUNCTION);
+ } else {
+ sc.ChangeState(SCE_OSCRIPT_METHOD);
+ }
+ sc.SetState(SCE_OSCRIPT_OPERATOR);
+ } else {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ // A dot following an identifier means an access to an object
+ // member. The related object identifier can be special.
+ // KNOWN PROBLEM: If there is whitespace between the identifier
+ // and the following dot, the identifier will not be recognized
+ // as an object in an object member access. If it is one of the
+ // listed static objects it will not be styled.
+ if (sc.Match('.') && objects.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_OBJECT);
+ sc.SetState(SCE_OSCRIPT_OPERATOR);
+ } else {
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_KEYWORD);
+ } else if (constants.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_CONSTANT);
+ } else if (operators.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_OPERATOR);
+ } else if (types.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_TYPE);
+ } else if (functions.InList(s)) {
+ sc.ChangeState(SCE_OSCRIPT_FUNCTION);
+ }
+ sc.SetState(SCE_OSCRIPT_DEFAULT);
+ }
+ }
+ }
+};
+
+// ------------------------------------------------
+// Function colourising an excerpt of OScript code.
+
+static void ColouriseOScriptDoc(unsigned int startPos, int length,
+ int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ // I wonder how whole-line styles ended by EOLN can escape the resetting
+ // code in the loop below and overflow to the next line. Let us make sure
+ // that a new line does not start with them carried from the previous one.
+ // NOTE: An overflowing string is intentionally not checked; it reminds
+ // the developer that the string must be ended on the same line.
+ if (initStyle == SCE_OSCRIPT_LINE_COMMENT ||
+ initStyle == SCE_OSCRIPT_PREPROCESSOR) {
+ initStyle = SCE_OSCRIPT_DEFAULT;
+ }
+
+ styler.StartAt(startPos);
+ StyleContext sc(startPos, length, initStyle, styler);
+ IdentifierClassifier identifierClassifier(keywordlists);
+
+ // It starts with true at the beginning of a line and changes to false as
+ // soon as the first non-whitespace character has been processed.
+ bool isFirstToken = true;
+ // It starts with true at the beginning of a line and changes to false as
+ // soon as the first identifier on the line is passed by.
+ bool isFirstIdentifier = true;
+ // It becomes false when #ifdef DOC (the preprocessor directive often
+ // used to start a documentation comment) is encountered and remain false
+ // until the end of the documentation block is not detected. This is done
+ // by checking for the complementary #endif preprocessor directive.
+ bool endDocComment = false;
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart) {
+ isFirstToken = true;
+ isFirstIdentifier = true;
+ // Detect the current state is neither whitespace nor identifier. It
+ // means that no next identifier can be the first token on the line.
+ } else if (isFirstIdentifier && sc.state != SCE_OSCRIPT_DEFAULT &&
+ sc.state != SCE_OSCRIPT_IDENTIFIER) {
+ isFirstIdentifier = false;
+ }
+
+ // Check if the current state should be changed.
+ if (sc.state == SCE_OSCRIPT_OPERATOR) {
+ // Multiple-symbol operators are marked by single characters.
+ sc.SetState(SCE_OSCRIPT_DEFAULT);
+ } else if (sc.state == SCE_OSCRIPT_IDENTIFIER) {
+ if (!IsIdentifierChar(sc.ch)) {
+ // Colon after an identifier makes it a label if it is the
+ // first token on the line.
+ // KNOWN PROBLEM: If some whitespace is inserted between the
+ // identifier and the colon they will not be recognized as a
+ // label. This should not occur; at least not often. It would
+ // make the code structure less legible and examples in the
+ // Livelink documentation do not show it.
+ if (sc.Match(':') && isFirstIdentifier) {
+ sc.ChangeState(SCE_OSCRIPT_LABEL);
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ } else {
+ identifierClassifier.ClassifyIdentifier(sc);
+ }
+ // Avoid a sequence of two words be mistaken for a label. A
+ // switch case would be an example.
+ isFirstIdentifier = false;
+ }
+ } else if (sc.state == SCE_OSCRIPT_GLOBAL) {
+ if (!IsIdentifierChar(sc.ch)) {
+ sc.SetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_PROPERTY) {
+ if (!IsIdentifierChar(sc.ch)) {
+ // Any member access introduced by the dot operator is
+ // initially marked as a property access. If an opening
+ // parenthesis is detected later it is changed to method call.
+ // KNOWN PROBLEM: The same as at the function call recognition
+ // for SCE_OSCRIPT_IDENTIFIER above.
+ if (sc.Match('(')) {
+ sc.ChangeState(SCE_OSCRIPT_METHOD);
+ }
+ sc.SetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_NUMBER) {
+ if (!IsNumberChar(sc.ch, sc.chNext)) {
+ sc.SetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_SINGLEQUOTE_STRING) {
+ if (sc.ch == '\'') {
+ // Two consequential apostrophes convert to a single one.
+ if (sc.chNext == '\'') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_DOUBLEQUOTE_STRING) {
+ if (sc.ch == '\"') {
+ // Two consequential quotation marks convert to a single one.
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_BLOCK_COMMENT) {
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_LINE_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_PREPROCESSOR) {
+ if (IsDocCommentStart(sc)) {
+ sc.ChangeState(SCE_OSCRIPT_DOC_COMMENT);
+ endDocComment = false;
+ } else if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ } else if (sc.state == SCE_OSCRIPT_DOC_COMMENT) {
+ // KNOWN PROBLEM: The first line detected that would close a
+ // conditional preprocessor block (#endif) the documentation
+ // comment block will end. (Nested #if-#endif blocks are not
+ // supported. Hopefully it will not occur often that a line
+ // within the text block would stat with #endif.
+ if (isFirstToken && IsDocCommentEnd(sc)) {
+ endDocComment = true;
+ } else if (sc.atLineEnd && endDocComment) {
+ sc.ForwardSetState(SCE_OSCRIPT_DEFAULT);
+ }
+ }
+
+ // Check what state starts with the current character.
+ if (sc.state == SCE_OSCRIPT_DEFAULT) {
+ if (sc.Match('\'')) {
+ sc.SetState(SCE_OSCRIPT_SINGLEQUOTE_STRING);
+ } else if (sc.Match('\"')) {
+ sc.SetState(SCE_OSCRIPT_DOUBLEQUOTE_STRING);
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_OSCRIPT_LINE_COMMENT);
+ sc.Forward();
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_OSCRIPT_BLOCK_COMMENT);
+ sc.Forward();
+ } else if (isFirstToken && sc.Match('#')) {
+ sc.SetState(SCE_OSCRIPT_PREPROCESSOR);
+ } else if (sc.Match('$')) {
+ // Both process-global ($xxx) and thread-global ($$xxx)
+ // variables are handled as one global.
+ sc.SetState(SCE_OSCRIPT_GLOBAL);
+ } else if (IsNaturalNumberStart(sc.ch)) {
+ sc.SetState(SCE_OSCRIPT_NUMBER);
+ } else if (IsPrefixedNumberStart(sc.ch, sc.chNext)) {
+ sc.SetState(SCE_OSCRIPT_NUMBER);
+ sc.Forward();
+ } else if (sc.Match('.') && IsIdentifierStart(sc.chNext)) {
+ // Every object member access is marked as a property access
+ // initially. The decision between property and method is made
+ // after parsing the identifier and looking what comes then.
+ // KNOWN PROBLEM: If there is whitespace between the following
+ // identifier and the dot, the dot will not be recognized
+ // as a member accessing operator. In turn, the identifier
+ // will not be recognizable as a property or a method too.
+ sc.SetState(SCE_OSCRIPT_OPERATOR);
+ sc.Forward();
+ sc.SetState(SCE_OSCRIPT_PROPERTY);
+ } else if (IsIdentifierStart(sc.ch)) {
+ sc.SetState(SCE_OSCRIPT_IDENTIFIER);
+ } else if (IsOperator(sc.ch)) {
+ sc.SetState(SCE_OSCRIPT_OPERATOR);
+ }
+ }
+
+ if (isFirstToken && !IsASpaceOrTab(sc.ch)) {
+ isFirstToken = false;
+ }
+ }
+
+ sc.Complete();
+}
+
+// ------------------------------------------
+// Functions supporting OScript code folding.
+
+static inline bool IsBlockComment(int style) {
+ return style == SCE_OSCRIPT_BLOCK_COMMENT;
+}
+
+static bool IsLineComment(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eolPos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eolPos; i++) {
+ char ch = styler[i];
+ char chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ if (ch == '/' && chNext == '/' && style == SCE_OSCRIPT_LINE_COMMENT) {
+ return true;
+ } else if (!IsASpaceOrTab(ch)) {
+ return false;
+ }
+ }
+ return false;
+}
+
+static inline bool IsPreprocessor(int style) {
+ return style == SCE_OSCRIPT_PREPROCESSOR ||
+ style == SCE_OSCRIPT_DOC_COMMENT;
+}
+
+static void GetRangeLowered(unsigned int start, unsigned int end,
+ Accessor &styler, char *s, unsigned int len) {
+ unsigned int i = 0;
+ while (i < end - start + 1 && i < len - 1) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static void GetForwardWordLowered(unsigned int start, Accessor &styler,
+ char *s, unsigned int len) {
+ unsigned int i = 0;
+ while (i < len - 1 && IsAlpha(styler.SafeGetCharAt(start + i))) {
+ s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static void UpdatePreprocessorFoldLevel(int &levelCurrent,
+ unsigned int startPos, Accessor &styler) {
+ char s[7]; // Size of the longest possible keyword + null.
+ GetForwardWordLowered(startPos, styler, s, sizeof(s));
+
+ if (strcmp(s, "ifdef") == 0 ||
+ strcmp(s, "ifndef") == 0) {
+ levelCurrent++;
+ } else if (strcmp(s, "endif") == 0) {
+ levelCurrent--;
+ if (levelCurrent < SC_FOLDLEVELBASE) {
+ levelCurrent = SC_FOLDLEVELBASE;
+ }
+ }
+}
+
+static void UpdateKeywordFoldLevel(int &levelCurrent, unsigned int lastStart,
+ unsigned int currentPos, Accessor &styler) {
+ char s[9];
+ GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
+
+ if (strcmp(s, "if") == 0 || strcmp(s, "for") == 0 ||
+ strcmp(s, "switch") == 0 || strcmp(s, "function") == 0 ||
+ strcmp(s, "while") == 0 || strcmp(s, "repeat") == 0) {
+ levelCurrent++;
+ } else if (strcmp(s, "end") == 0 || strcmp(s, "until") == 0) {
+ levelCurrent--;
+ if (levelCurrent < SC_FOLDLEVELBASE) {
+ levelCurrent = SC_FOLDLEVELBASE;
+ }
+ }
+}
+
+// ------------------------------
+// Function folding OScript code.
+
+static void FoldOScriptDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ int lastStart = 0;
+
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (foldComment && IsBlockComment(style)) {
+ if (!IsBlockComment(stylePrev)) {
+ levelCurrent++;
+ } else if (!IsBlockComment(styleNext) && !atLineEnd) {
+ // Comments do not end at end of line and the next character
+ // may not be styled.
+ levelCurrent--;
+ }
+ }
+ if (foldComment && atLineEnd && IsLineComment(lineCurrent, styler)) {
+ if (!IsLineComment(lineCurrent - 1, styler) &&
+ IsLineComment(lineCurrent + 1, styler))
+ levelCurrent++;
+ else if (IsLineComment(lineCurrent - 1, styler) &&
+ !IsLineComment(lineCurrent+1, styler))
+ levelCurrent--;
+ }
+ if (foldPreprocessor) {
+ if (ch == '#' && IsPreprocessor(style)) {
+ UpdatePreprocessorFoldLevel(levelCurrent, i + 1, styler);
+ }
+ }
+
+ if (stylePrev != SCE_OSCRIPT_KEYWORD && style == SCE_OSCRIPT_KEYWORD) {
+ lastStart = i;
+ }
+ if (stylePrev == SCE_OSCRIPT_KEYWORD) {
+ if(IsIdentifierChar(ch) && !IsIdentifierChar(chNext)) {
+ UpdateKeywordFoldLevel(levelCurrent, lastStart, i, styler);
+ }
+ }
+
+ if (!IsASpace(ch))
+ visibleChars++;
+
+ if (atLineEnd) {
+ int level = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ level |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ level |= SC_FOLDLEVELHEADERFLAG;
+ if (level != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, level);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ }
+
+ // If we did not reach EOLN in the previous loop, store the line level and
+ // whitespace information. The rest will be filled in later.
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ styler.SetLevel(lineCurrent, lev);
+}
+
+// --------------------------------------------
+// Declaration of the OScript lexer descriptor.
+
+static const char * const oscriptWordListDesc[] = {
+ "Keywords and reserved words",
+ "Literal constants",
+ "Literal operators",
+ "Built-in value and reference types",
+ "Built-in global functions",
+ "Built-in static objects",
+ 0
+};
+
+LexerModule lmOScript(SCLEX_OSCRIPT, ColouriseOScriptDoc, "oscript", FoldOScriptDoc, oscriptWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexOpal.cxx
+ ** Lexer for OPAL (functional language similar to Haskell)
+ ** Written by Sebastian Pipping <webmaster@hartwork.org>
+ **/
+
+#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
+
+inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len )
+{
+ unsigned int i = 0;
+ while( ( i < end - start + 1 ) && ( i < len - 1 ) )
+ {
+ s[i] = static_cast<char>( styler[ start + i ] );
+ i++;
+ }
+ s[ i ] = '\0';
+}
+
+inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
+{
+ char ch;
+
+ // Wait for string to close
+ bool even_backslash_count = true; // Without gaps in between
+ cur++; // Skip initial quote
+ for( ; ; )
+ {
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_STRING );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( ( ch == '\015' ) || ( ch == '\012' ) ) // Deny multi-line strings
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_STRING );
+ styler.StartSegment( cur );
+ return true;
+ }
+ else
+ {
+ if( even_backslash_count )
+ {
+ if( ch == '"' )
+ {
+ styler.ColourTo( cur, SCE_OPAL_STRING );
+ cur++;
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+ else if( ch == '\\' )
+ {
+ even_backslash_count = false;
+ }
+ }
+ else
+ {
+ even_backslash_count = true;
+ }
+ }
+
+ cur++;
+ }
+}
+
+inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
+{
+ char ch;
+
+ if( could_fail )
+ {
+ cur++;
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( ch != '*' )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+
+ // Wait for comment close
+ cur++;
+ bool star_found = false;
+ for( ; ; )
+ {
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( star_found )
+ {
+ if( ch == '/' )
+ {
+ styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
+ cur++;
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+ else if( ch != '*' )
+ {
+ star_found = false;
+ }
+ }
+ else if( ch == '*' )
+ {
+ star_found = true;
+ }
+ cur++;
+ }
+}
+
+inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
+{
+ char ch;
+
+ if( could_fail )
+ {
+ cur++;
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( ch != '-' )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ styler.StartSegment( cur );
+ return true;
+ }
+
+ cur++;
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( ( ch != ' ' ) && ( ch != '\t' ) )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+
+ // Wait for end of line
+ bool fifteen_found = false;
+
+ for( ; ; )
+ {
+ cur++;
+
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( fifteen_found )
+ {
+/*
+ if( ch == '\012' )
+ {
+ // One newline on Windows (015, 012)
+ }
+ else
+ {
+ // One newline on MAC (015) and another char
+ }
+*/
+ cur--;
+ styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
+ styler.StartSegment( cur );
+ return true;
+ }
+ else
+ {
+ if( ch == '\015' )
+ {
+ fifteen_found = true;
+ }
+ else if( ch == '\012' )
+ {
+ // One newline on Linux (012)
+ styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+ }
+}
+
+inline bool HandlePar( unsigned int & cur, Accessor & styler )
+{
+ styler.ColourTo( cur, SCE_OPAL_PAR );
+
+ cur++;
+
+ styler.StartSegment( cur );
+ return true;
+}
+
+inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
+{
+ char ch;
+
+ cur++;
+ for( ; ; )
+ {
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
+ return false;
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ switch( ch )
+ {
+ case ' ':
+ case '\t':
+ case '\015':
+ case '\012':
+ cur++;
+ break;
+
+ default:
+ styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+}
+
+inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
+{
+ char ch;
+
+ for( ; ; )
+ {
+ cur++;
+ if( cur >= one_too_much )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
+ return false; // STOP
+ }
+
+ ch = styler.SafeGetCharAt( cur );
+ if( !( isascii( ch ) && isdigit( ch ) ) )
+ {
+ styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+}
+
+inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] )
+{
+ char ch;
+ const unsigned int beg = cur;
+
+ cur++;
+ for( ; ; )
+ {
+ ch = styler.SafeGetCharAt( cur );
+ if( ( ch != '_' ) && ( ch != '-' ) &&
+ !( isascii( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;
+
+ cur++;
+ if( cur >= one_too_much )
+ {
+ break;
+ }
+ }
+
+ const int ide_len = cur - beg + 1;
+ char * ide = new char[ ide_len ];
+ getRange( beg, cur, styler, ide, ide_len );
+
+ WordList & keywords = *keywordlists[ 0 ];
+ WordList & classwords = *keywordlists[ 1 ];
+
+ if( keywords.InList( ide ) ) // Keyword
+ {
+ delete [] ide;
+
+ styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+ else if( classwords.InList( ide ) ) // Sort
+ {
+ delete [] ide;
+
+ styler.ColourTo( cur - 1, SCE_OPAL_SORT );
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+ else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
+ {
+ delete [] ide;
+
+ styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+ else // Unknown keyword
+ {
+ delete [] ide;
+
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+ }
+
+}
+
+inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
+{
+ cur++;
+ styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
+ if( cur >= one_too_much )
+ {
+ return false; // STOP
+ }
+ else
+ {
+ styler.StartSegment( cur );
+ return true;
+ }
+}
+
+static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor & styler )
+{
+ styler.StartAt( startPos );
+ styler.StartSegment( startPos );
+
+ unsigned int & cur = startPos;
+ const unsigned int one_too_much = startPos + length;
+
+ int state = initStyle;
+
+ for( ; ; )
+ {
+ switch( state )
+ {
+ case SCE_OPAL_KEYWORD:
+ case SCE_OPAL_SORT:
+ if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
+ state = SCE_OPAL_DEFAULT;
+ break;
+
+ case SCE_OPAL_INTEGER:
+ if( !HandleInteger( cur, one_too_much, styler ) ) return;
+ state = SCE_OPAL_DEFAULT;
+ break;
+
+ case SCE_OPAL_COMMENT_BLOCK:
+ if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
+ state = SCE_OPAL_DEFAULT;
+ break;
+
+ case SCE_OPAL_COMMENT_LINE:
+ if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
+ state = SCE_OPAL_DEFAULT;
+ break;
+
+ case SCE_OPAL_STRING:
+ if( !HandleString( cur, one_too_much, styler ) ) return;
+ state = SCE_OPAL_DEFAULT;
+ break;
+
+ default: // SCE_OPAL_DEFAULT:
+ {
+ char ch = styler.SafeGetCharAt( cur );
+
+ switch( ch )
+ {
+ // String
+ case '"':
+ if( !HandleString( cur, one_too_much, styler ) ) return;
+ break;
+
+ // Comment block
+ case '/':
+ if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
+ break;
+
+ // Comment line
+ case '-':
+ if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
+ break;
+
+ // Par
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ if( !HandlePar( cur, styler ) ) return;
+ break;
+
+ // Whitespace
+ case ' ':
+ case '\t':
+ case '\015':
+ case '\012':
+ if( !HandleSpace( cur, one_too_much, styler ) ) return;
+ break;
+
+ default:
+ {
+ // Integer
+ if( isascii( ch ) && isdigit( ch ) )
+ {
+ if( !HandleInteger( cur, one_too_much, styler ) ) return;
+ }
+
+ // Keyword
+ else if( isascii( ch ) && ( islower( ch ) || isupper( ch ) ) )
+ {
+ if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
+
+ }
+
+ // Skip
+ else
+ {
+ if( !HandleSkip( cur, one_too_much, styler ) ) return;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+static const char * const opalWordListDesc[] = {
+ "Keywords",
+ "Sorts",
+ 0
+};
+
+LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexOthers.cxx
+ ** Lexers for batch files, diff results, properties files, make files and error lists.
+ ** Also lexer for LaTeX documents.
+ **/
+// 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 bool strstart(const char *haystack, const char *needle) {
+ return strncmp(haystack, needle, strlen(needle)) == 0;
+}
+
+static bool Is0To9(char ch) {
+ return (ch >= '0') && (ch <= '9');
+}
+
+static bool Is1To9(char ch) {
+ return (ch >= '1') && (ch <= '9');
+}
+
+static bool IsAlphabetic(int ch) {
+ return isascii(ch) && isalpha(ch);
+}
+
+static inline bool AtEOL(Accessor &styler, unsigned int i) {
+ return (styler[i] == '\n') ||
+ ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
+}
+
+// Tests for BATCH Operators
+static bool IsBOperator(char ch) {
+ return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
+ (ch == '|') || (ch == '?') || (ch == '*');
+}
+
+// Tests for BATCH Separators
+static bool IsBSeparator(char ch) {
+ return (ch == '\\') || (ch == '.') || (ch == ';') ||
+ (ch == '\"') || (ch == '\'') || (ch == '/');
+}
+
+static void ColouriseBatchLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int startLine,
+ unsigned int endPos,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ unsigned int offset = 0; // Line Buffer Offset
+ unsigned int cmdLoc; // External Command / Program Location
+ char wordBuffer[81]; // Word Buffer - large to catch long paths
+ unsigned int wbl; // Word Buffer Length
+ unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
+ WordList &keywords = *keywordlists[0]; // Internal Commands
+ WordList &keywords2 = *keywordlists[1]; // External Commands (optional)
+
+ // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
+ // Toggling Regular Keyword Checking off improves readability
+ // Other Regular Keywords and External Commands / Programs might also benefit from toggling
+ // Need a more robust algorithm to properly toggle Regular Keyword Checking
+ bool continueProcessing = true; // Used to toggle Regular Keyword Checking
+ // Special Keywords are those that allow certain characters without whitespace after the command
+ // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
+ // Special Keyword Buffer used to determine if the first n characters is a Keyword
+ char sKeywordBuffer[10]; // Special Keyword Buffer
+ bool sKeywordFound; // Exit Special Keyword for-loop if found
+
+ // Skip initial spaces
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ // Set External Command / Program Location
+ cmdLoc = offset;
+
+ // Check for Fake Label (Comment) or Real Label - return if found
+ if (lineBuffer[offset] == ':') {
+ if (lineBuffer[offset + 1] == ':') {
+ // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
+ styler.ColourTo(endPos, SCE_BAT_COMMENT);
+ } else {
+ // Colorize Real Label
+ styler.ColourTo(endPos, SCE_BAT_LABEL);
+ }
+ return;
+ // Check for Drive Change (Drive Change is internal command) - return if found
+ } else if ((IsAlphabetic(lineBuffer[offset])) &&
+ (lineBuffer[offset + 1] == ':') &&
+ ((isspacechar(lineBuffer[offset + 2])) ||
+ (((lineBuffer[offset + 2] == '\\')) &&
+ (isspacechar(lineBuffer[offset + 3]))))) {
+ // Colorize Regular Keyword
+ styler.ColourTo(endPos, SCE_BAT_WORD);
+ return;
+ }
+
+ // Check for Hide Command (@ECHO OFF/ON)
+ if (lineBuffer[offset] == '@') {
+ styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
+ offset++;
+ }
+ // Skip next spaces
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+
+ // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
+ while (offset < lengthLine) {
+ if (offset > startLine) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Copy word from Line Buffer into Word Buffer
+ wbl = 0;
+ for (; offset < lengthLine && wbl < 80 &&
+ !isspacechar(lineBuffer[offset]); wbl++, offset++) {
+ wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
+ }
+ wordBuffer[wbl] = '\0';
+ wbo = 0;
+
+ // Check for Comment - return if found
+ if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
+ styler.ColourTo(endPos, SCE_BAT_COMMENT);
+ return;
+ }
+ // Check for Separator
+ if (IsBSeparator(wordBuffer[0])) {
+ // Check for External Command / Program
+ if ((cmdLoc == offset - wbl) &&
+ ((wordBuffer[0] == ':') ||
+ (wordBuffer[0] == '\\') ||
+ (wordBuffer[0] == '.'))) {
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize External Command / Program
+ if (!keywords2) {
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ } else if (keywords2.InList(wordBuffer)) {
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ } else {
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ } else {
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Check for Regular Keyword in list
+ } else if ((keywords.InList(wordBuffer)) &&
+ (continueProcessing)) {
+ // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
+ if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "set") == 0)) {
+ continueProcessing = false;
+ }
+ // Identify External Command / Program Location for ERRORLEVEL, and EXIST
+ if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip comparison
+ while ((cmdLoc < lengthLine) &&
+ (!isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
+ } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "do") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ }
+ // Colorize Regular keyword
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
+ // No need to Reset Offset
+ // Check for Special Keyword in list, External Command / Program, or Default Text
+ } else if ((wordBuffer[0] != '%') &&
+ (wordBuffer[0] != '!') &&
+ (!IsBOperator(wordBuffer[0])) &&
+ (continueProcessing)) {
+ // Check for Special Keyword
+ // Affected Commands are in Length range 2-6
+ // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
+ sKeywordFound = false;
+ for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
+ wbo = 0;
+ // Copy Keyword Length from Word Buffer into Special Keyword Buffer
+ for (; wbo < keywordLength; wbo++) {
+ sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
+ }
+ sKeywordBuffer[wbo] = '\0';
+ // Check for Special Keyword in list
+ if ((keywords.InList(sKeywordBuffer)) &&
+ ((IsBOperator(wordBuffer[wbo])) ||
+ (IsBSeparator(wordBuffer[wbo])))) {
+ sKeywordFound = true;
+ // ECHO requires no further Regular Keyword Checking
+ if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
+ continueProcessing = false;
+ }
+ // Colorize Special Keyword as Regular Keyword
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ }
+ // Check for External Command / Program or Default Text
+ if (!sKeywordFound) {
+ wbo = 0;
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (wordBuffer[wbo] != '!') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Reset External Command / Program Location
+ cmdLoc = offset - (wbl - wbo);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ // CHOICE requires no further Regular Keyword Checking
+ if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
+ continueProcessing = false;
+ }
+ // Check for START (and its switches) - What follows is External Command \ Program
+ if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Reset External Command / Program Location if command switch detected
+ if (lineBuffer[cmdLoc] == '/') {
+ // Skip command switch
+ while ((cmdLoc < lengthLine) &&
+ (!isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ }
+ }
+ // Colorize External Command / Program
+ if (!keywords2) {
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ } else if (keywords2.InList(wordBuffer)) {
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ } else {
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // No need to Reset Offset
+ // Check for Default Text
+ } else {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (wordBuffer[wbo] != '!') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ }
+ // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
+ } else if (wordBuffer[0] == '%') {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+ wbo++;
+ // Search to end of word for second % (can be a long path)
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Check for Argument (%n) or (%*)
+ if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
+ (wordBuffer[wbo] != '%')) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - 2);
+ }
+ // Colorize Argument
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ // Check for Expanded Argument (%~...) / Variable (%%~...)
+ } else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
+ ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - wbo);
+ }
+ // Colorize Expanded Argument / Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ // Check for Environment Variable (%x...%)
+ } else if ((wordBuffer[1] != '%') &&
+ (wordBuffer[wbo] == '%')) {
+ wbo++;
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - wbo);
+ }
+ // Colorize Environment Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ // Check for Local Variable (%%a)
+ } else if (
+ (wbl > 2) &&
+ (wordBuffer[1] == '%') &&
+ (wordBuffer[2] != '%') &&
+ (!IsBOperator(wordBuffer[2])) &&
+ (!IsBSeparator(wordBuffer[2]))) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - 3);
+ }
+ // Colorize Local Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 3);
+ }
+ // Check for Environment Variable (!x...!)
+ } else if (wordBuffer[0] == '!') {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+ wbo++;
+ // Search to end of word for second ! (can be a long path)
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '!') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ if (wordBuffer[wbo] == '!') {
+ wbo++;
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - wbo);
+ }
+ // Colorize Environment Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ // Check for Operator
+ } else if (IsBOperator(wordBuffer[0])) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+ // Check for Comparison Operator
+ if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
+ // Identify External Command / Program Location for IF
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Colorize Comparison Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ // Check for Pipe Operator
+ } else if (wordBuffer[0] == '|') {
+ // Reset External Command / Program Location
+ cmdLoc = offset - wbl + 1;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Colorize Pipe Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Check for Other Operator
+ } else {
+ // Check for > Operator
+ if (wordBuffer[0] == '>') {
+ // Turn Keyword and External Command / Program checking back on
+ continueProcessing = true;
+ }
+ // Colorize Other Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ }
+ // Check for Default Text
+ } else {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (wordBuffer[wbo] != '!') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ // Skip next spaces - nothing happens if Offset was Reset
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+ }
+ // Colorize Default Text for remainder of line - currently not lexed
+ styler.ColourTo(endPos, SCE_BAT_DEFAULT);
+}
+
+static void ColouriseBatchDoc(
+ unsigned int startPos,
+ int length,
+ int /*initStyle*/,
+ 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';
+ ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
+ linePos = 0;
+ startLine = i + 1;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ lineBuffer[linePos] = '\0';
+ ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
+ keywordlists, styler);
+ }
+}
+
+#define DIFF_BUFFER_START_SIZE 16
+// Note that ColouriseDiffLine analyzes only the first DIFF_BUFFER_START_SIZE
+// characters of each line to classify the line.
+
+static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
+ // It is needed to remember the current state to recognize starting
+ // comment lines before the first "diff " or "--- ". If a real
+ // difference starts then each line starting with ' ' is a whitespace
+ // otherwise it is considered a comment (Only in..., Binary file...)
+ if (0 == strncmp(lineBuffer, "diff ", 5)) {
+ styler.ColourTo(endLine, SCE_DIFF_COMMAND);
+ } else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff
+ styler.ColourTo(endLine, SCE_DIFF_COMMAND);
+ } else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') {
+ // In a context diff, --- appears in both the header and the position markers
+ if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ else
+ styler.ColourTo(endLine, SCE_DIFF_HEADER);
+ } else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
+ // I don't know of any diff where "+++ " is a position marker, but for
+ // consistency, do the same as with "--- " and "*** ".
+ if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ else
+ styler.ColourTo(endLine, SCE_DIFF_HEADER);
+ } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff
+ styler.ColourTo(endLine, SCE_DIFF_HEADER);
+ } else if (0 == strncmp(lineBuffer, "***", 3)) {
+ // In a context diff, *** appears in both the header and the position markers.
+ // Also ******** is a chunk header, but here it's treated as part of the
+ // position marker since there is no separate style for a chunk header.
+ if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ else if (lineBuffer[3] == '*')
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ else
+ styler.ColourTo(endLine, SCE_DIFF_HEADER);
+ } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib
+ styler.ColourTo(endLine, SCE_DIFF_HEADER);
+ } else if (lineBuffer[0] == '@') {
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ } else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {
+ styler.ColourTo(endLine, SCE_DIFF_POSITION);
+ } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
+ styler.ColourTo(endLine, SCE_DIFF_DELETED);
+ } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
+ styler.ColourTo(endLine, SCE_DIFF_ADDED);
+ } else if (lineBuffer[0] == '!') {
+ styler.ColourTo(endLine, SCE_DIFF_CHANGED);
+ } else if (lineBuffer[0] != ' ') {
+ styler.ColourTo(endLine, SCE_DIFF_COMMENT);
+ } else {
+ styler.ColourTo(endLine, SCE_DIFF_DEFAULT);
+ }
+}
+
+static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ char lineBuffer[DIFF_BUFFER_START_SIZE];
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ unsigned int linePos = 0;
+ for (unsigned int i = startPos; i < startPos + length; i++) {
+ if (AtEOL(styler, i)) {
+ if (linePos < DIFF_BUFFER_START_SIZE) {
+ lineBuffer[linePos] = 0;
+ }
+ ColouriseDiffLine(lineBuffer, i, styler);
+ linePos = 0;
+ } else if (linePos < DIFF_BUFFER_START_SIZE - 1) {
+ lineBuffer[linePos++] = styler[i];
+ } else if (linePos == DIFF_BUFFER_START_SIZE - 1) {
+ lineBuffer[linePos++] = 0;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ if (linePos < DIFF_BUFFER_START_SIZE) {
+ lineBuffer[linePos] = 0;
+ }
+ ColouriseDiffLine(lineBuffer, startPos + length - 1, styler);
+ }
+}
+
+static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ int curLine = styler.GetLine(startPos);
+ int curLineStart = styler.LineStart(curLine);
+ int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;
+ int nextLevel;
+
+ do {
+ int lineType = styler.StyleAt(curLineStart);
+ if (lineType == SCE_DIFF_COMMAND)
+ nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ else if (lineType == SCE_DIFF_HEADER)
+ nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
+ else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')
+ nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
+ else if (prevLevel & SC_FOLDLEVELHEADERFLAG)
+ nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
+ else
+ nextLevel = prevLevel;
+
+ if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
+ styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
+
+ styler.SetLevel(curLine, nextLevel);
+ prevLevel = nextLevel;
+
+ curLineStart = styler.LineStart(++curLine);
+ } while (static_cast<int>(startPos) + length > curLineStart);
+}
+
+static void ColourisePoLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int startLine,
+ unsigned int endPos,
+ Accessor &styler) {
+
+ unsigned int i = 0;
+ static unsigned int state = SCE_PO_DEFAULT;
+ unsigned int state_start = SCE_PO_DEFAULT;
+
+ while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
+ i++;
+ if (i < lengthLine) {
+ if (lineBuffer[i] == '#') {
+ // check if the comment contains any flags ("#, ") and
+ // then whether the flags contain "fuzzy"
+ if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
+ styler.ColourTo(endPos, SCE_PO_FUZZY);
+ else
+ styler.ColourTo(endPos, SCE_PO_COMMENT);
+ } else {
+ if (lineBuffer[0] == '"') {
+ // line continuation, use previous style
+ styler.ColourTo(endPos, state);
+ return;
+ // this implicitly also matches "msgid_plural"
+ } else if (strstart(lineBuffer, "msgid")) {
+ state_start = SCE_PO_MSGID;
+ state = SCE_PO_MSGID_TEXT;
+ } else if (strstart(lineBuffer, "msgstr")) {
+ state_start = SCE_PO_MSGSTR;
+ state = SCE_PO_MSGSTR_TEXT;
+ } else if (strstart(lineBuffer, "msgctxt")) {
+ state_start = SCE_PO_MSGCTXT;
+ state = SCE_PO_MSGCTXT_TEXT;
+ }
+ if (state_start != SCE_PO_DEFAULT) {
+ // find the next space
+ while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
+ i++;
+ styler.ColourTo(startLine + i - 1, state_start);
+ styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
+ styler.ColourTo(endPos, state);
+ }
+ }
+ } else {
+ styler.ColourTo(endPos, SCE_PO_DEFAULT);
+ }
+}
+
+static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], 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';
+ ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
+ linePos = 0;
+ startLine = i + 1;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
+ }
+}
+
+static inline bool isassignchar(unsigned char ch) {
+ return (ch == '=') || (ch == ':');
+}
+
+static void ColourisePropsLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int startLine,
+ unsigned int endPos,
+ Accessor &styler,
+ bool allowInitialSpaces) {
+
+ unsigned int 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(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ char lineBuffer[1024];
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ unsigned int linePos = 0;
+ unsigned int 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 (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';
+ 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(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ bool headerPoint = false;
+ int lev;
+
+ for (unsigned int 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 void ColouriseMakeLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int startLine,
+ unsigned int endPos,
+ Accessor &styler) {
+
+ unsigned int i = 0;
+ int lastNonSpace = -1;
+ unsigned int state = SCE_MAKE_DEFAULT;
+ bool bSpecial = false;
+
+ // check for a tab character in column 0 indicating a command
+ bool bCommand = false;
+ if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
+ bCommand = true;
+
+ // Skip initial spaces
+ while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
+ i++;
+ }
+ if (lineBuffer[i] == '#') { // Comment
+ styler.ColourTo(endPos, SCE_MAKE_COMMENT);
+ return;
+ }
+ if (lineBuffer[i] == '!') { // Special directive
+ styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
+ return;
+ }
+ int varCount = 0;
+ while (i < lengthLine) {
+ if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
+ styler.ColourTo(startLine + i - 1, state);
+ state = SCE_MAKE_IDENTIFIER;
+ varCount++;
+ } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
+ if (--varCount == 0) {
+ styler.ColourTo(startLine + i, state);
+ state = SCE_MAKE_DEFAULT;
+ }
+ }
+
+ // skip identifier and target styling if this is a command line
+ if (!bSpecial && !bCommand) {
+ if (lineBuffer[i] == ':') {
+ if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
+ // it's a ':=', so style as an identifier
+ if (lastNonSpace >= 0)
+ styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
+ styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
+ styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
+ } else {
+ // We should check that no colouring was made since the beginning of the line,
+ // to avoid colouring stuff like /OUT:file
+ if (lastNonSpace >= 0)
+ styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
+ styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
+ styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
+ }
+ bSpecial = true; // Only react to the first ':' of the line
+ state = SCE_MAKE_DEFAULT;
+ } else if (lineBuffer[i] == '=') {
+ if (lastNonSpace >= 0)
+ styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
+ styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
+ styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
+ bSpecial = true; // Only react to the first '=' of the line
+ state = SCE_MAKE_DEFAULT;
+ }
+ }
+ if (!isspacechar(lineBuffer[i])) {
+ lastNonSpace = i;
+ }
+ i++;
+ }
+ if (state == SCE_MAKE_IDENTIFIER) {
+ styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended
+ } else {
+ styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
+ }
+}
+
+static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], 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';
+ ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler);
+ linePos = 0;
+ startLine = i + 1;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
+ }
+}
+
+static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) {
+ if (lineBuffer[0] == '>') {
+ // Command or return status
+ return SCE_ERR_CMD;
+ } else if (lineBuffer[0] == '<') {
+ // Diff removal.
+ return SCE_ERR_DIFF_DELETION;
+ } else if (lineBuffer[0] == '!') {
+ return SCE_ERR_DIFF_CHANGED;
+ } else if (lineBuffer[0] == '+') {
+ if (strstart(lineBuffer, "+++ ")) {
+ return SCE_ERR_DIFF_MESSAGE;
+ } else {
+ return SCE_ERR_DIFF_ADDITION;
+ }
+ } else if (lineBuffer[0] == '-') {
+ if (strstart(lineBuffer, "--- ")) {
+ return SCE_ERR_DIFF_MESSAGE;
+ } else {
+ return SCE_ERR_DIFF_DELETION;
+ }
+ } else if (strstart(lineBuffer, "cf90-")) {
+ // Absoft Pro Fortran 90/95 v8.2 error and/or warning message
+ return SCE_ERR_ABSF;
+ } else if (strstart(lineBuffer, "fortcom:")) {
+ // Intel Fortran Compiler v8.0 error/warning message
+ return SCE_ERR_IFORT;
+ } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
+ return SCE_ERR_PYTHON;
+ } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
+ return SCE_ERR_PHP;
+ } else if ((strstart(lineBuffer, "Error ") ||
+ strstart(lineBuffer, "Warning ")) &&
+ strstr(lineBuffer, " at (") &&
+ strstr(lineBuffer, ") : ") &&
+ (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
+ // Intel Fortran Compiler error/warning message
+ return SCE_ERR_IFC;
+ } else if (strstart(lineBuffer, "Error ")) {
+ // Borland error message
+ return SCE_ERR_BORLAND;
+ } else if (strstart(lineBuffer, "Warning ")) {
+ // Borland warning message
+ return SCE_ERR_BORLAND;
+ } else if (strstr(lineBuffer, "at line ") &&
+ (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) &&
+ strstr(lineBuffer, "file ") &&
+ (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
+ // Lua 4 error message
+ return SCE_ERR_LUA;
+ } else if (strstr(lineBuffer, " at ") &&
+ (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) &&
+ strstr(lineBuffer, " line ") &&
+ (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
+ (strstr(lineBuffer, " at ") < (strstr(lineBuffer, " line ")))) {
+ // perl error message
+ return SCE_ERR_PERL;
+ } else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
+ strstr(lineBuffer, ":line ")) {
+ // A .NET traceback
+ return SCE_ERR_NET;
+ } else if (strstart(lineBuffer, "Line ") &&
+ strstr(lineBuffer, ", file ")) {
+ // Essential Lahey Fortran error message
+ return SCE_ERR_ELF;
+ } else if (strstart(lineBuffer, "line ") &&
+ strstr(lineBuffer, " column ")) {
+ // HTML tidy style: line 42 column 1
+ return SCE_ERR_TIDY;
+ } else if (strstart(lineBuffer, "\tat ") &&
+ strstr(lineBuffer, "(") &&
+ strstr(lineBuffer, ".java:")) {
+ // Java stack back trace
+ return SCE_ERR_JAVA_STACK;
+ } else {
+ // Look for one of the following formats:
+ // GCC: <filename>:<line>:<message>
+ // Microsoft: <filename>(<line>) :<message>
+ // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal
+ // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal
+ // Microsoft: <filename>(<line>,<column>)<message>
+ // CTags: \t<message>
+ // Lua 5 traceback: \t<filename>:<line>:<message>
+ // Lua 5.1: <exe>: <filename>:<line>:<message>
+ bool initialTab = (lineBuffer[0] == '\t');
+ bool initialColonPart = false;
+ enum { stInitial,
+ stGccStart, stGccDigit, stGccColumn, stGcc,
+ stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
+ stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
+ stUnrecognized
+ } state = stInitial;
+ for (unsigned int i = 0; i < lengthLine; i++) {
+ char ch = lineBuffer[i];
+ char chNext = ' ';
+ if ((i + 1) < lengthLine)
+ chNext = lineBuffer[i + 1];
+ if (state == stInitial) {
+ if (ch == ':') {
+ // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
+ if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) {
+ // This check is not completely accurate as may be on
+ // GTK+ with a file name that includes ':'.
+ state = stGccStart;
+ } else if (chNext == ' ') { // indicates a Lua 5.1 error message
+ initialColonPart = true;
+ }
+ } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
+ // May be Microsoft
+ // Check against '0' often removes phone numbers
+ state = stMsStart;
+ } else if ((ch == '\t') && (!initialTab)) {
+ // May be CTags
+ state = stCtagsStart;
+ }
+ } else if (state == stGccStart) { // <filename>:
+ state = Is1To9(ch) ? stGccDigit : stUnrecognized;
+ } else if (state == stGccDigit) { // <filename>:<line>
+ if (ch == ':') {
+ state = stGccColumn; // :9.*: is GCC
+ startValue = i + 1;
+ } else if (!Is0To9(ch)) {
+ state = stUnrecognized;
+ }
+ } else if (state == stGccColumn) { // <filename>:<line>:<column>
+ if (!Is0To9(ch)) {
+ state = stGcc;
+ if (ch == ':')
+ startValue = i + 1;
+ break;
+ }
+ } else if (state == stMsStart) { // <filename>(
+ state = Is0To9(ch) ? stMsDigit : stUnrecognized;
+ } else if (state == stMsDigit) { // <filename>(<line>
+ if (ch == ',') {
+ state = stMsDigitComma;
+ } else if (ch == ')') {
+ state = stMsBracket;
+ } else if ((ch != ' ') && !Is0To9(ch)) {
+ state = stUnrecognized;
+ }
+ } else if (state == stMsBracket) { // <filename>(<line>)
+ if ((ch == ' ') && (chNext == ':')) {
+ state = stMsVc;
+ } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {
+ // Possibly Delphi.. don't test against chNext as it's one of the strings below.
+ char word[512];
+ unsigned int j, chPos;
+ unsigned numstep;
+ chPos = 0;
+ if (ch == ' ')
+ numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
+ else
+ numstep = 2; // otherwise add 2.
+ for (j = i + numstep; j < lengthLine && IsAlphabetic(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
+ word[chPos++] = lineBuffer[j];
+ word[chPos] = 0;
+ if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
+ !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") ||
+ !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) {
+ state = stMsVc;
+ } else
+ state = stUnrecognized;
+ } else {
+ state = stUnrecognized;
+ }
+ } else if (state == stMsDigitComma) { // <filename>(<line>,
+ if (ch == ')') {
+ state = stMsDotNet;
+ break;
+ } else if ((ch != ' ') && !Is0To9(ch)) {
+ state = stUnrecognized;
+ }
+ } else if (state == stCtagsStart) {
+ if ((lineBuffer[i - 1] == '\t') &&
+ ((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) {
+ state = stCtags;
+ break;
+ } else if ((ch == '/') && (lineBuffer[i + 1] == '^')) {
+ state = stCtagsStartString;
+ }
+ } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) {
+ state = stCtagsStringDollar;
+ break;
+ }
+ }
+ if (state == stGcc) {
+ return initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC;
+ } else if ((state == stMsVc) || (state == stMsDotNet)) {
+ return SCE_ERR_MS;
+ } else if ((state == stCtagsStringDollar) || (state == stCtags)) {
+ return SCE_ERR_CTAG;
+ } else {
+ return SCE_ERR_DEFAULT;
+ }
+ }
+}
+
+static void ColouriseErrorListLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int endPos,
+ Accessor &styler,
+ bool valueSeparate) {
+ int startValue = -1;
+ int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue);
+ if (valueSeparate && (startValue >= 0)) {
+ styler.ColourTo(endPos - (lengthLine - startValue), style);
+ styler.ColourTo(endPos, SCE_ERR_VALUE);
+ } else {
+ styler.ColourTo(endPos, style);
+ }
+}
+
+static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ char lineBuffer[10000];
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ unsigned int linePos = 0;
+
+ // property lexer.errorlist.value.separate
+ // For lines in the output pane that are matches from Find in Files or GCC-style
+ // diagnostics, style the path and line number separately from the rest of the
+ // line with style 21 used for the rest of the line.
+ // This allows matched text to be more easily distinguished from its location.
+ bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 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';
+ ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate);
+ linePos = 0;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate);
+ }
+}
+
+static bool latexIsSpecial(int ch) {
+ return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
+ (ch == '{') || (ch == '}') || (ch == ' ');
+}
+
+static bool latexIsBlank(int ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+static bool latexIsBlankAndNL(int ch) {
+ return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
+}
+
+static bool latexIsLetter(int ch) {
+ return isascii(ch) && isalpha(ch);
+}
+
+static bool latexIsTagValid(int &i, int l, Accessor &styler) {
+ while (i < l) {
+ if (styler.SafeGetCharAt(i) == '{') {
+ while (i < l) {
+ i++;
+ if (styler.SafeGetCharAt(i) == '}') {
+ return true;
+ } else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
+ styler.SafeGetCharAt(i)!='*') {
+ return false;
+ }
+ }
+ } else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
+ return false;
+ }
+ i++;
+ }
+ return false;
+}
+
+static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) {
+ char ch;
+ while (i < l) {
+ ch = styler.SafeGetCharAt(i);
+ if (!latexIsBlankAndNL(ch) && ch != '*') {
+ if (ch == needle)
+ return true;
+ else
+ return false;
+ }
+ i++;
+ }
+ return false;
+}
+
+static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
+ unsigned int i = 0;
+ unsigned int l = static_cast<unsigned int>(strlen(needle));
+ int ini = start-l+1;
+ char s[32];
+
+ while (i < l && i < 32) {
+ s[i] = styler.SafeGetCharAt(ini + i);
+ i++;
+ }
+ s[i] = '\0';
+
+ return (strcmp(s, needle) == 0);
+}
+
+static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+
+ styler.StartAt(startPos);
+
+ int state = initStyle;
+ char chNext = styler.SafeGetCharAt(startPos);
+ styler.StartSegment(startPos);
+ int lengthDoc = startPos + length;
+ char chVerbatimDelim = '\0';
+
+ for (int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch)) {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ continue;
+ }
+
+ switch (state) {
+ case SCE_L_DEFAULT :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsSpecial(chNext)) {
+ state = SCE_L_SPECIAL;
+ } else {
+ if (latexIsLetter(chNext)) {
+ state = SCE_L_COMMAND;
+ } else {
+ if (chNext == '(' || chNext == '[') {
+ styler.ColourTo(i-1, state);
+ styler.ColourTo(i+1, SCE_L_SHORTCMD);
+ state = SCE_L_MATH;
+ if (chNext == '[')
+ state = SCE_L_MATH2;
+ i++;
+ chNext = styler.SafeGetCharAt(i+1);
+ } else {
+ state = SCE_L_SHORTCMD;
+ }
+ }
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_MATH;
+ if (chNext == '$') {
+ state = SCE_L_MATH2;
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ case SCE_L_ERROR:
+ styler.ColourTo(i-1, state);
+ state = SCE_L_DEFAULT;
+ break;
+ case SCE_L_SPECIAL:
+ case SCE_L_SHORTCMD:
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ break;
+ case SCE_L_COMMAND :
+ if (!latexIsLetter(chNext)) {
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) {
+ state = SCE_L_CMDOPT;
+ } else if (latexLastWordIs(i, styler, "\\begin")) {
+ state = SCE_L_TAG;
+ } else if (latexLastWordIs(i, styler, "\\end")) {
+ state = SCE_L_TAG2;
+ } else if (latexLastWordIs(i, styler, "\\verb") &&
+ chNext != '*' && chNext != ' ') {
+ chVerbatimDelim = chNext;
+ state = SCE_L_VERBATIM;
+ }
+ }
+ break;
+ case SCE_L_CMDOPT :
+ if (ch == ']') {
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ }
+ break;
+ case SCE_L_TAG :
+ if (latexIsTagValid(i, lengthDoc, styler)) {
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ if (latexLastWordIs(i, styler, "{verbatim}")) {
+ state = SCE_L_VERBATIM;
+ } else if (latexLastWordIs(i, styler, "{comment}")) {
+ state = SCE_L_COMMENT2;
+ } else if (latexLastWordIs(i, styler, "{math}")) {
+ state = SCE_L_MATH;
+ } else if (latexLastWordIs(i, styler, "{displaymath}")) {
+ state = SCE_L_MATH2;
+ } else if (latexLastWordIs(i, styler, "{equation}")) {
+ state = SCE_L_MATH2;
+ }
+ } else {
+ state = SCE_L_ERROR;
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ }
+ chNext = styler.SafeGetCharAt(i+1);
+ break;
+ case SCE_L_TAG2 :
+ if (latexIsTagValid(i, lengthDoc, styler)) {
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ } else {
+ state = SCE_L_ERROR;
+ }
+ chNext = styler.SafeGetCharAt(i+1);
+ break;
+ case SCE_L_MATH :
+ if (ch == '$') {
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ } else if (ch == '\\' && chNext == ')') {
+ styler.ColourTo(i-1, state);
+ styler.ColourTo(i+1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i+1);
+ state = SCE_L_DEFAULT;
+ } else if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{math}")) {
+ styler.ColourTo(i-1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ }
+
+ break;
+ case SCE_L_MATH2 :
+ if (ch == '$') {
+ if (chNext == '$') {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ styler.ColourTo(i, state);
+ state = SCE_L_DEFAULT;
+ } else {
+ styler.ColourTo(i, SCE_L_ERROR);
+ state = SCE_L_DEFAULT;
+ }
+ } else if (ch == '\\' && chNext == ']') {
+ styler.ColourTo(i-1, state);
+ styler.ColourTo(i+1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i+1);
+ state = SCE_L_DEFAULT;
+ } else if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{displaymath}")) {
+ styler.ColourTo(i-1, state);
+ state = SCE_L_COMMAND;
+ } else if (latexLastWordIs(match, styler, "{equation}")) {
+ styler.ColourTo(i-1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ }
+ break;
+ case SCE_L_COMMENT :
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_DEFAULT;
+ }
+ break;
+ case SCE_L_COMMENT2 :
+ if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{comment}")) {
+ styler.ColourTo(i-1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ }
+ break;
+ case SCE_L_VERBATIM :
+ if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{verbatim}")) {
+ styler.ColourTo(i-1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ } else if (chNext == chVerbatimDelim) {
+ styler.ColourTo(i+1, state);
+ state = SCE_L_DEFAULT;
+ chVerbatimDelim = '\0';
+ } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
+ styler.ColourTo(i, SCE_L_ERROR);
+ state = SCE_L_DEFAULT;
+ chVerbatimDelim = '\0';
+ }
+ break;
+ }
+ }
+ styler.ColourTo(lengthDoc-1, state);
+}
+
+static const char *const batchWordListDesc[] = {
+ "Internal Commands",
+ "External Commands",
+ 0
+};
+
+static const char *const emptyWordListDesc[] = {
+ 0
+};
+
+static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[],
+ Accessor &styler) {
+ // Null language means all style bytes are 0 so just mark the end - no need to fill in.
+ if (length > 0) {
+ styler.StartAt(startPos + length - 1);
+ styler.StartSegment(startPos + length - 1);
+ styler.ColourTo(startPos + length - 1, 0);
+ }
+}
+
+LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
+LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
+LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
+LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
+LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
+LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
+LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
+LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
--- /dev/null
+// Scintilla source code edit control
+// @file LexPB.cxx
+// Lexer for PowerBasic by Roland Walter, roland@rowalt.de (for PowerBasic see www.powerbasic.com)
+//
+// Changes:
+// 17.10.2003: Toggling of subs/functions now until next sub/function - this gives better results
+// 29.10.2003: 1. Bug: Toggling didn't work for subs/functions added in editor
+// 2. Own colors for PB constants and Inline Assembler SCE_B_CONSTANT and SCE_B_ASM
+// 3. Several smaller syntax coloring improvements and speed optimizations
+// 12.07.2004: 1. Toggling for macros added
+// 2. Further folding speed optimitations (for people dealing with very large listings)
+//
+// Necessary changes for the PB lexer in Scintilla project:
+// - In SciLexer.h and Scintilla.iface:
+//
+// #define SCLEX_POWERBASIC 51 //ID for PowerBasic lexer
+// (...)
+// #define SCE_B_DEFAULT 0 //in both VB and PB lexer
+// #define SCE_B_COMMENT 1 //in both VB and PB lexer
+// #define SCE_B_NUMBER 2 //in both VB and PB lexer
+// #define SCE_B_KEYWORD 3 //in both VB and PB lexer
+// #define SCE_B_STRING 4 //in both VB and PB lexer
+// #define SCE_B_PREPROCESSOR 5 //VB lexer only, not in PB lexer
+// #define SCE_B_OPERATOR 6 //in both VB and PB lexer
+// #define SCE_B_IDENTIFIER 7 //in both VB and PB lexer
+// #define SCE_B_DATE 8 //VB lexer only, not in PB lexer
+// #define SCE_B_CONSTANT 13 //PB lexer only, not in VB lexer
+// #define SCE_B_ASM 14 //PB lexer only, not in VB lexer
+
+// - Statement added to KeyWords.cxx: 'LINK_LEXER(lmPB);'
+// - Statement added to scintilla_vc6.mak: '$(DIR_O)\LexPB.obj: ...\src\LexPB.cxx $(LEX_HEADERS)'
+//
+// Copyright for Scintilla: 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 IsTypeCharacter(const int ch)
+{
+ return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$' || ch == '?';
+}
+
+static inline bool IsAWordChar(const int ch)
+{
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch)
+{
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+bool MatchUpperCase(Accessor &styler, int pos, const char *s) //Same as styler.Match() but uppercase comparison (a-z,A-Z and space only)
+{
+ char ch;
+ for (int i=0; *s; i++)
+ {
+ ch=styler.SafeGetCharAt(pos+i);
+ if (ch > 0x60) ch -= '\x20';
+ if (*s != ch) return false;
+ s++;
+ }
+ return true;
+}
+
+static void ColourisePBDoc(unsigned int startPos, int length, int initStyle,WordList *keywordlists[],Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ switch (sc.state)
+ {
+ case SCE_B_OPERATOR:
+ {
+ sc.SetState(SCE_B_DEFAULT);
+ break;
+ }
+ case SCE_B_KEYWORD:
+ {
+ if (!IsAWordChar(sc.ch))
+ {
+ if (!IsTypeCharacter(sc.ch))
+ {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s))
+ {
+ if (strcmp(s, "rem") == 0)
+ {
+ sc.ChangeState(SCE_B_COMMENT);
+ if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
+ }
+ else if (strcmp(s, "asm") == 0)
+ {
+ sc.ChangeState(SCE_B_ASM);
+ if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
+ }
+ else
+ {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+ else
+ {
+ sc.ChangeState(SCE_B_IDENTIFIER);
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+ }
+ break;
+ }
+ case SCE_B_NUMBER:
+ {
+ if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);}
+ break;
+ }
+ case SCE_B_STRING:
+ {
+ if (sc.ch == '\"'){sc.ForwardSetState(SCE_B_DEFAULT);}
+ break;
+ }
+ case SCE_B_CONSTANT:
+ {
+ if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);}
+ break;
+ }
+ case SCE_B_COMMENT:
+ {
+ if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
+ break;
+ }
+ case SCE_B_ASM:
+ {
+ if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
+ break;
+ }
+ } //switch (sc.state)
+
+ // Determine if a new state should be entered:
+ if (sc.state == SCE_B_DEFAULT)
+ {
+ if (sc.ch == '\'') {sc.SetState(SCE_B_COMMENT);}
+ else if (sc.ch == '\"') {sc.SetState(SCE_B_STRING);}
+ else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {sc.SetState(SCE_B_NUMBER);}
+ else if (sc.ch == '&' && tolower(sc.chNext) == 'b') {sc.SetState(SCE_B_NUMBER);}
+ else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {sc.SetState(SCE_B_NUMBER);}
+ else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_B_NUMBER);}
+ else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_B_KEYWORD);}
+ else if (sc.ch == '%') {sc.SetState(SCE_B_CONSTANT);}
+ else if (sc.ch == '$') {sc.SetState(SCE_B_CONSTANT);}
+ else if (sc.ch == '#') {sc.SetState(SCE_B_KEYWORD);}
+ else if (sc.ch == '!') {sc.SetState(SCE_B_ASM);}
+ else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {sc.SetState(SCE_B_OPERATOR);}
+ }
+ } //for (; sc.More(); sc.Forward())
+ sc.Complete();
+}
+
+//The folding routine for PowerBasic toggles SUBs and FUNCTIONs only. This was exactly what I wanted,
+//nothing more. I had worked with this kind of toggling for several years when I used the great good old
+//GFA Basic which is dead now. After testing the feature of toggling FOR-NEXT loops, WHILE-WEND loops
+//and so on too I found this is more disturbing then helping (for me). So if You think in another way
+//you can (or must) write Your own toggling routine ;-)
+static void FoldPBDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ // No folding enabled, no reason to continue...
+ if( styler.GetPropertyInt("fold") == 0 )
+ return;
+
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+
+ bool fNewLine=true;
+ bool fMightBeMultiLineMacro=false;
+ bool fBeginOfCommentFound=false;
+ for (unsigned int i = startPos; i < endPos; i++)
+ {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (fNewLine) //Begin of a new line (The Sub/Function/Macro keywords may occur at begin of line only)
+ {
+ fNewLine=false;
+ fBeginOfCommentFound=false;
+ switch (ch)
+ {
+ case ' ': //Most lines start with space - so check this first, the code is the same as for 'default:'
+ case '\t': //Handle tab too
+ {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ styler.SetLevel(lineCurrent, lev);
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ switch (chNext)
+ {
+ case 'U':
+ case 'u':
+ {
+ if( MatchUpperCase(styler,i,"FUNCTION") )
+ {
+ styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
+ levelNext=SC_FOLDLEVELBASE+1;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ switch (chNext)
+ {
+ case 'U':
+ case 'u':
+ {
+ if( MatchUpperCase(styler,i,"SUB") )
+ {
+ styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
+ levelNext=SC_FOLDLEVELBASE+1;
+ }
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if( MatchUpperCase(styler,i,"STATIC FUNCTION") )
+ {
+ styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
+ levelNext=SC_FOLDLEVELBASE+1;
+ }
+ else if( MatchUpperCase(styler,i,"STATIC SUB") )
+ {
+ styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
+ levelNext=SC_FOLDLEVELBASE+1;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ switch (chNext)
+ {
+ case 'A':
+ case 'a':
+ {
+ if( MatchUpperCase(styler,i,"CALLBACK FUNCTION") )
+ {
+ styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
+ levelNext=SC_FOLDLEVELBASE+1;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ switch (chNext)
+ {
+ case 'A':
+ case 'a':
+ {
+ if( MatchUpperCase(styler,i,"MACRO") )
+ {
+ fMightBeMultiLineMacro=true; //Set folder level at end of line, we have to check for single line macro
+ }
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ styler.SetLevel(lineCurrent, lev);
+ break;
+ }
+ } //switch (ch)
+ } //if( fNewLine )
+
+ switch (ch)
+ {
+ case '=': //To test single line macros
+ {
+ if (fBeginOfCommentFound==false)
+ fMightBeMultiLineMacro=false; //The found macro is a single line macro only;
+ break;
+ }
+ case '\'': //A comment starts
+ {
+ fBeginOfCommentFound=true;
+ break;
+ }
+ case '\n':
+ {
+ if (fMightBeMultiLineMacro) //The current line is the begin of a multi line macro
+ {
+ fMightBeMultiLineMacro=false;
+ styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
+ levelNext=SC_FOLDLEVELBASE+1;
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ fNewLine=true;
+ break;
+ }
+ case '\r':
+ {
+ if (chNext != '\n')
+ {
+ lineCurrent++;
+ levelCurrent = levelNext;
+ fNewLine=true;
+ }
+ break;
+ }
+ } //switch (ch)
+ } //for (unsigned int i = startPos; i < endPos; i++)
+}
+
+static const char * const pbWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmPB(SCLEX_POWERBASIC, ColourisePBDoc, "powerbasic", FoldPBDoc, pbWordListDesc);
--- /dev/null
+// Copyright (c) 1990-2007, Scientific Toolworks, Inc.
+// Author: Jason Haslam
+// 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 void GetRange(unsigned int start,
+ unsigned int end,
+ Accessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static void ColourisePlmDoc(unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ unsigned int endPos = startPos + length;
+ int state = initStyle;
+
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = styler.SafeGetCharAt(i);
+ char chNext = styler.SafeGetCharAt(i + 1);
+
+ if (state == SCE_PLM_DEFAULT) {
+ if (ch == '/' && chNext == '*') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_COMMENT;
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_STRING;
+ } else if (isdigit(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_NUMBER;
+ } else if (isalpha(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_IDENTIFIER;
+ } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
+ ch == '=' || ch == '<' || ch == '>' || ch == ':') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_OPERATOR;
+ } else if (ch == '$') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_CONTROL;
+ }
+ } else if (state == SCE_PLM_COMMENT) {
+ if (ch == '*' && chNext == '/') {
+ i++;
+ styler.ColourTo(i, state);
+ state = SCE_PLM_DEFAULT;
+ }
+ } else if (state == SCE_PLM_STRING) {
+ if (ch == '\'') {
+ if (chNext == '\'') {
+ i++;
+ } else {
+ styler.ColourTo(i, state);
+ state = SCE_PLM_DEFAULT;
+ }
+ }
+ } else if (state == SCE_PLM_NUMBER) {
+ if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
+ i--;
+ styler.ColourTo(i, state);
+ state = SCE_PLM_DEFAULT;
+ }
+ } else if (state == SCE_PLM_IDENTIFIER) {
+ if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
+ // Get the entire identifier.
+ char word[1024];
+ int segmentStart = styler.GetStartSegment();
+ GetRange(segmentStart, i - 1, styler, word, sizeof(word));
+
+ i--;
+ if (keywordlists[0]->InList(word))
+ styler.ColourTo(i, SCE_PLM_KEYWORD);
+ else
+ styler.ColourTo(i, state);
+ state = SCE_PLM_DEFAULT;
+ }
+ } else if (state == SCE_PLM_OPERATOR) {
+ if (ch != '=' && ch != '>') {
+ i--;
+ styler.ColourTo(i, state);
+ state = SCE_PLM_DEFAULT;
+ }
+ } else if (state == SCE_PLM_CONTROL) {
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_PLM_DEFAULT;
+ }
+ }
+ }
+ styler.ColourTo(endPos - 1, state);
+}
+
+static void FoldPlmDoc(unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *[],
+ Accessor &styler)
+{
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ int startKeyword = 0;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD)
+ startKeyword = i;
+
+ if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) {
+ char word[1024];
+ GetRange(startKeyword, i, styler, word, sizeof(word));
+
+ if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0)
+ levelCurrent++;
+ else if (strcmp(word, "end") == 0)
+ levelCurrent--;
+ }
+
+ if (foldComment) {
+ if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT)
+ levelCurrent++;
+ else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT)
+ levelCurrent--;
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char *const plmWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, "PL/M", FoldPlmDoc, plmWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPOV.cxx
+ ** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language).
+ ** Written by Philippe Lhoste but this is mostly a derivative of LexCPP...
+ **/
+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// Some points that distinguish from a simple C lexer:
+// Identifiers start only by a character.
+// No line continuation character.
+// Strings are limited to 256 characters.
+// Directives are similar to preprocessor commands,
+// but we match directive keywords and colorize incorrect ones.
+// Block comments can be nested (code stolen from my code in LexLua).
+
+#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 IsAWordChar(int ch) {
+ return ch < 0x80 && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return ch < 0x80 && isalpha(ch);
+}
+
+static inline bool IsANumberChar(int ch) {
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases.
+ return (ch < 0x80) &&
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
+}
+
+static void ColourisePovDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords1 = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+
+ int currentLine = styler.GetLine(startPos);
+ // Initialize the block comment /* */ nesting level, if we are inside such a comment.
+ int blockCommentLevel = 0;
+ if (initStyle == SCE_POV_COMMENT) {
+ blockCommentLevel = styler.GetLineState(currentLine - 1);
+ }
+
+ // Do not leak onto next line
+ if (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) {
+ initStyle = SCE_POV_DEFAULT;
+ }
+
+ short stringLen = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ currentLine = styler.GetLine(sc.currentPos);
+ if (sc.state == SCE_POV_COMMENT) {
+ // Inside a block comment, we set the line state
+ styler.SetLineState(currentLine, blockCommentLevel);
+ } else {
+ // Reset the line state
+ styler.SetLineState(currentLine, 0);
+ }
+ }
+
+ if (sc.atLineStart && (sc.state == SCE_POV_STRING)) {
+ // Prevent SCE_POV_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_POV_STRING);
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_POV_OPERATOR) {
+ sc.SetState(SCE_POV_DEFAULT);
+ } else if (sc.state == SCE_POV_NUMBER) {
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_POV_DEFAULT);
+ }
+ } else if (sc.state == SCE_POV_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD4);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD5);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD6);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD7);
+ } else if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_POV_WORD8);
+ }
+ sc.SetState(SCE_POV_DEFAULT);
+ }
+ } else if (sc.state == SCE_POV_DIRECTIVE) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ char *p;
+ sc.GetCurrent(s, sizeof(s));
+ p = s;
+ // Skip # and whitespace between # and directive word
+ do {
+ p++;
+ } while ((*p == ' ' || *p == '\t') && *p != '\0');
+ if (!keywords1.InList(p)) {
+ sc.ChangeState(SCE_POV_BADDIRECTIVE);
+ }
+ sc.SetState(SCE_POV_DEFAULT);
+ }
+ } else if (sc.state == SCE_POV_COMMENT) {
+ if (sc.Match('/', '*')) {
+ blockCommentLevel++;
+ sc.Forward();
+ } else if (sc.Match('*', '/') && blockCommentLevel > 0) {
+ blockCommentLevel--;
+ sc.Forward();
+ if (blockCommentLevel == 0) {
+ sc.ForwardSetState(SCE_POV_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_POV_COMMENTLINE) {
+ if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_POV_DEFAULT);
+ }
+ } else if (sc.state == SCE_POV_STRING) {
+ if (sc.ch == '\\') {
+ stringLen++;
+ if (strchr("abfnrtuv0'\"", sc.chNext)) {
+ // Compound characters are counted as one.
+ // Note: for Unicode chars \u, we shouldn't count the next 4 digits...
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_POV_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_POV_STRINGEOL);
+ sc.ForwardSetState(SCE_POV_DEFAULT);
+ } else {
+ stringLen++;
+ }
+ if (stringLen > 256) {
+ // Strings are limited to 256 chars
+ sc.SetState(SCE_POV_STRINGEOL);
+ }
+ } else if (sc.state == SCE_POV_STRINGEOL) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_POV_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_POV_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_POV_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_POV_IDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ blockCommentLevel = 1;
+ sc.SetState(SCE_POV_COMMENT);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_POV_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_POV_STRING);
+ stringLen = 0;
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_POV_DIRECTIVE);
+ // Skip whitespace between # and directive word
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_POV_DEFAULT);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_POV_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldPovDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *[],
+ Accessor &styler) {
+
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldDirective = styler.GetPropertyInt("fold.directive") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && (style == SCE_POV_COMMENT)) {
+ if (stylePrev != SCE_POV_COMMENT) {
+ levelCurrent++;
+ } else if ((styleNext != SCE_POV_COMMENT) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+ if (foldComment && (style == SCE_POV_COMMENTLINE)) {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelCurrent++;
+ } else if (chNext2 == '}') {
+ levelCurrent--;
+ }
+ }
+ }
+ if (foldDirective && (style == SCE_POV_DIRECTIVE)) {
+ if (ch == '#') {
+ unsigned int j=i+1;
+ while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ }
+ }
+ if (style == SCE_POV_OPERATOR) {
+ if (ch == '{') {
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const povWordLists[] = {
+ "Language directives",
+ "Objects & CSG & Appearance",
+ "Types & Modifiers & Items",
+ "Predefined Identifiers",
+ "Predefined Functions",
+ "User defined 1",
+ "User defined 2",
+ "User defined 3",
+ 0,
+};
+
+LexerModule lmPOV(SCLEX_POV, ColourisePovDoc, "pov", FoldPovDoc, povWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPS.cxx
+ ** Lexer for PostScript
+ **
+ ** Written by Nigel Hathaway <nigel@bprj.co.uk>.
+ ** 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 IsASelfDelimitingChar(const int ch) {
+ return (ch == '[' || ch == ']' || ch == '{' || ch == '}' ||
+ ch == '/' || ch == '<' || ch == '>' ||
+ ch == '(' || ch == ')' || ch == '%');
+}
+
+static inline bool IsAWhitespaceChar(const int ch) {
+ return (ch == ' ' || ch == '\t' || ch == '\r' ||
+ ch == '\n' || ch == '\f' || ch == '\0');
+}
+
+static bool IsABaseNDigit(const int ch, const int base) {
+ int maxdig = '9';
+ int letterext = -1;
+
+ if (base <= 10)
+ maxdig = '0' + base - 1;
+ else
+ letterext = base - 11;
+
+ return ((ch >= '0' && ch <= maxdig) ||
+ (ch >= 'A' && ch <= ('A' + letterext)) ||
+ (ch >= 'a' && ch <= ('a' + letterext)));
+}
+
+static inline bool IsABase85Char(const int ch) {
+ return ((ch >= '!' && ch <= 'u') || ch == 'z');
+}
+
+static void ColourisePSDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords1 = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ bool tokenizing = styler.GetPropertyInt("ps.tokenize") != 0;
+ int pslevel = styler.GetPropertyInt("ps.level", 3);
+ int lineCurrent = styler.GetLine(startPos);
+ int nestTextCurrent = 0;
+ if (lineCurrent > 0 && initStyle == SCE_PS_TEXT)
+ nestTextCurrent = styler.GetLineState(lineCurrent - 1);
+ int numRadix = 0;
+ bool numHasPoint = false;
+ bool numHasExponent = false;
+ bool numHasSign = false;
+
+ // Clear out existing tokenization
+ if (tokenizing && length > 0) {
+ styler.StartAt(startPos, static_cast<char>(INDIC2_MASK));
+ styler.ColourTo(startPos + length-1, 0);
+ styler.Flush();
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ }
+
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineStart)
+ lineCurrent = styler.GetLine(sc.currentPos);
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_PS_COMMENT || sc.state == SCE_PS_DSC_VALUE) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ } else if (sc.state == SCE_PS_DSC_COMMENT) {
+ if (sc.ch == ':') {
+ sc.Forward();
+ if (!sc.atLineEnd)
+ sc.SetState(SCE_PS_DSC_VALUE);
+ else
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (IsAWhitespaceChar(sc.ch) && sc.ch != '\r') {
+ sc.ChangeState(SCE_PS_COMMENT);
+ }
+ } else if (sc.state == SCE_PS_NUMBER) {
+ if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {
+ if ((sc.chPrev == '+' || sc.chPrev == '-' ||
+ sc.chPrev == 'E' || sc.chPrev == 'e') && numRadix == 0)
+ sc.ChangeState(SCE_PS_NAME);
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '#') {
+ if (numHasPoint || numHasExponent || numHasSign || numRadix != 0) {
+ sc.ChangeState(SCE_PS_NAME);
+ } else {
+ char szradix[5];
+ sc.GetCurrent(szradix, 4);
+ numRadix = atoi(szradix);
+ if (numRadix < 2 || numRadix > 36)
+ sc.ChangeState(SCE_PS_NAME);
+ }
+ } else if ((sc.ch == 'E' || sc.ch == 'e') && numRadix == 0) {
+ if (numHasExponent) {
+ sc.ChangeState(SCE_PS_NAME);
+ } else {
+ numHasExponent = true;
+ if (sc.chNext == '+' || sc.chNext == '-')
+ sc.Forward();
+ }
+ } else if (sc.ch == '.') {
+ if (numHasPoint || numHasExponent || numRadix != 0) {
+ sc.ChangeState(SCE_PS_NAME);
+ } else {
+ numHasPoint = true;
+ }
+ } else if (numRadix == 0) {
+ if (!IsABaseNDigit(sc.ch, 10))
+ sc.ChangeState(SCE_PS_NAME);
+ } else {
+ if (!IsABaseNDigit(sc.ch, numRadix))
+ sc.ChangeState(SCE_PS_NAME);
+ }
+ } else if (sc.state == SCE_PS_NAME || sc.state == SCE_PS_KEYWORD) {
+ if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if ((pslevel >= 1 && keywords1.InList(s)) ||
+ (pslevel >= 2 && keywords2.InList(s)) ||
+ (pslevel >= 3 && keywords3.InList(s)) ||
+ keywords4.InList(s) || keywords5.InList(s)) {
+ sc.ChangeState(SCE_PS_KEYWORD);
+ }
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ } else if (sc.state == SCE_PS_LITERAL || sc.state == SCE_PS_IMMEVAL) {
+ if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch))
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.state == SCE_PS_PAREN_ARRAY || sc.state == SCE_PS_PAREN_DICT ||
+ sc.state == SCE_PS_PAREN_PROC) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.state == SCE_PS_TEXT) {
+ if (sc.ch == '(') {
+ nestTextCurrent++;
+ } else if (sc.ch == ')') {
+ if (--nestTextCurrent == 0)
+ sc.ForwardSetState(SCE_PS_DEFAULT);
+ } else if (sc.ch == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.state == SCE_PS_HEXSTRING) {
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_PS_DEFAULT);
+ } else if (!IsABaseNDigit(sc.ch, 16) && !IsAWhitespaceChar(sc.ch)) {
+ sc.SetState(SCE_PS_HEXSTRING);
+ styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
+ }
+ } else if (sc.state == SCE_PS_BASE85STRING) {
+ if (sc.Match('~', '>')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_PS_DEFAULT);
+ } else if (!IsABase85Char(sc.ch) && !IsAWhitespaceChar(sc.ch)) {
+ sc.SetState(SCE_PS_BASE85STRING);
+ styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_C_DEFAULT) {
+ unsigned int tokenpos = sc.currentPos;
+
+ if (sc.ch == '[' || sc.ch == ']') {
+ sc.SetState(SCE_PS_PAREN_ARRAY);
+ } else if (sc.ch == '{' || sc.ch == '}') {
+ sc.SetState(SCE_PS_PAREN_PROC);
+ } else if (sc.ch == '/') {
+ if (sc.chNext == '/') {
+ sc.SetState(SCE_PS_IMMEVAL);
+ sc.Forward();
+ } else {
+ sc.SetState(SCE_PS_LITERAL);
+ }
+ } else if (sc.ch == '<') {
+ if (sc.chNext == '<') {
+ sc.SetState(SCE_PS_PAREN_DICT);
+ sc.Forward();
+ } else if (sc.chNext == '~') {
+ sc.SetState(SCE_PS_BASE85STRING);
+ sc.Forward();
+ } else {
+ sc.SetState(SCE_PS_HEXSTRING);
+ }
+ } else if (sc.ch == '>' && sc.chNext == '>') {
+ sc.SetState(SCE_PS_PAREN_DICT);
+ sc.Forward();
+ } else if (sc.ch == '>' || sc.ch == ')') {
+ sc.SetState(SCE_C_DEFAULT);
+ styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
+ } else if (sc.ch == '(') {
+ sc.SetState(SCE_PS_TEXT);
+ nestTextCurrent = 1;
+ } else if (sc.ch == '%') {
+ if (sc.chNext == '%' && sc.atLineStart) {
+ sc.SetState(SCE_PS_DSC_COMMENT);
+ sc.Forward();
+ if (sc.chNext == '+') {
+ sc.Forward();
+ sc.ForwardSetState(SCE_PS_DSC_VALUE);
+ }
+ } else {
+ sc.SetState(SCE_PS_COMMENT);
+ }
+ } else if ((sc.ch == '+' || sc.ch == '-' || sc.ch == '.') &&
+ IsABaseNDigit(sc.chNext, 10)) {
+ sc.SetState(SCE_PS_NUMBER);
+ numRadix = 0;
+ numHasPoint = (sc.ch == '.');
+ numHasExponent = false;
+ numHasSign = (sc.ch == '+' || sc.ch == '-');
+ } else if ((sc.ch == '+' || sc.ch == '-') && sc.chNext == '.' &&
+ IsABaseNDigit(sc.GetRelative(2), 10)) {
+ sc.SetState(SCE_PS_NUMBER);
+ numRadix = 0;
+ numHasPoint = false;
+ numHasExponent = false;
+ numHasSign = true;
+ } else if (IsABaseNDigit(sc.ch, 10)) {
+ sc.SetState(SCE_PS_NUMBER);
+ numRadix = 0;
+ numHasPoint = false;
+ numHasExponent = false;
+ numHasSign = false;
+ } else if (!IsAWhitespaceChar(sc.ch)) {
+ sc.SetState(SCE_PS_NAME);
+ }
+
+ // Mark the start of tokens
+ if (tokenizing && sc.state != SCE_C_DEFAULT && sc.state != SCE_PS_COMMENT &&
+ sc.state != SCE_PS_DSC_COMMENT && sc.state != SCE_PS_DSC_VALUE) {
+ styler.Flush();
+ styler.StartAt(tokenpos, static_cast<char>(INDIC2_MASK));
+ styler.ColourTo(tokenpos, INDIC2_MASK);
+ styler.Flush();
+ styler.StartAt(tokenpos);
+ styler.StartSegment(tokenpos);
+ }
+ }
+
+ if (sc.atLineEnd)
+ styler.SetLineState(lineCurrent, nestTextCurrent);
+ }
+
+ sc.Complete();
+}
+
+static void FoldPSDoc(unsigned int startPos, int length, int, WordList *[],
+ Accessor &styler) {
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); //mac??
+ if ((style & 31) == SCE_PS_PAREN_PROC) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+}
+
+static const char * const psWordListDesc[] = {
+ "PS Level 1 operators",
+ "PS Level 2 operators",
+ "PS Level 3 operators",
+ "RIP-specific operators",
+ "User-defined operators",
+ 0
+};
+
+LexerModule lmPS(SCLEX_PS, ColourisePSDoc, "ps", FoldPSDoc, psWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPascal.cxx
+ ** Lexer for Pascal.
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Completely rewritten by Marko Njezic <sf@maxempire.com> October 2008
+ **/
+
+/*
+
+A few words about features of the new completely rewritten LexPascal...
+
+Generally speaking LexPascal tries to support all available Delphi features (up
+to Delphi 2009 at this time), including .NET specific features.
+
+~ HIGHLIGHTING:
+
+If you enable "lexer.pascal.smart.highlighting" property, some keywords will
+only be highlighted in appropriate context. As implemented those are keywords
+related to property and DLL exports declarations (similar to how Delphi IDE
+works).
+
+For example, keywords "read" and "write" will only be highlighted if they are in
+property declaration:
+
+property MyProperty: boolean read FMyProperty write FMyProperty;
+
+~ FOLDING:
+
+Folding is supported in the following cases:
+
+- Folding of stream-like comments
+- Folding of groups of consecutive line comments
+- Folding of preprocessor blocks (the following preprocessor blocks are
+supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION
+blocks), including nesting of preprocessor blocks up to 255 levels
+- Folding of code blocks on appropriate keywords (the following code blocks are
+supported: "begin, asm, record, try, case / end" blocks, class & object
+declarations and interface declarations)
+
+Remarks:
+
+- Folding of code blocks tries to handle all special cases in which folding
+should not occur. As implemented those are:
+
+1. Structure "record case / end" (there's only one "end" statement and "case" is
+ignored as fold point)
+2. Forward class declarations ("type TMyClass = class;") and object method
+declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are
+ignored as fold points
+3. Simplified complete class declarations ("type TMyClass = class(TObject);")
+are ignored as fold points
+4. Every other situation when class keyword doesn't actually start class
+declaration ("class procedure", "class function", "class of", "class var",
+"class property" and "class operator")
+5. Forward (disp)interface declarations ("type IMyInterface = interface;") are
+ignored as fold points
+
+- Folding of code blocks inside preprocessor blocks is disabled (any comments
+inside them will be folded fine) because there is no guarantee that complete
+code block will be contained inside folded preprocessor block in which case
+folded code block could end prematurely at the end of preprocessor block if
+there is no closing statement inside. This was done in order to properly process
+document that may contain something like this:
+
+type
+{$IFDEF UNICODE}
+ TMyClass = class(UnicodeAncestor)
+{$ELSE}
+ TMyClass = class(AnsiAncestor)
+{$ENDIF}
+ private
+ ...
+ public
+ ...
+ published
+ ...
+end;
+
+If class declarations were folded, then the second class declaration would end
+at "$ENDIF" statement, first class statement would end at "end;" statement and
+preprocessor "$IFDEF" block would go all the way to the end of document.
+However, having in mind all this, if you want to enable folding of code blocks
+inside preprocessor blocks, you can disable folding of preprocessor blocks by
+changing "fold.preprocessor" property, in which case everything inside them
+would be folded.
+
+~ KEYWORDS:
+
+The list of keywords that can be used in pascal.properties file (up to Delphi
+2009):
+
+- Keywords: absolute abstract and array as asm assembler automated begin case
+cdecl class const constructor deprecated destructor dispid dispinterface div do
+downto dynamic else end except export exports external far file final
+finalization finally for forward function goto if implementation in inherited
+initialization inline interface is label library message mod near nil not object
+of on or out overload override packed pascal platform private procedure program
+property protected public published raise record register reintroduce repeat
+resourcestring safecall sealed set shl shr static stdcall strict string then
+threadvar to try type unit unsafe until uses var varargs virtual while with xor
+
+- Keywords related to the "smart highlithing" feature: add default implements
+index name nodefault read readonly remove stored write writeonly
+
+- Keywords related to Delphi packages (in addition to all above): package
+contains requires
+
+*/
+
+#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 void GetRangeLowered(unsigned int start,
+ unsigned int end,
+ Accessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static void GetForwardRangeLowered(unsigned int start,
+ CharacterSet &charSet,
+ Accessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
+ s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
+ i++;
+ }
+ s[i] = '\0';
+
+}
+
+enum {
+ stateInAsm = 0x1000,
+ stateInProperty = 0x2000,
+ stateInExport = 0x4000,
+ stateFoldInPreprocessor = 0x0100,
+ stateFoldInRecord = 0x0200,
+ stateFoldInPreprocessorLevelMask = 0x00FF,
+ stateFoldMaskAll = 0x0FFF
+};
+
+static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) {
+ WordList& keywords = *keywordlists[0];
+
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ if (curLineState & stateInAsm) {
+ if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') {
+ curLineState &= ~stateInAsm;
+ sc.ChangeState(SCE_PAS_WORD);
+ } else {
+ sc.ChangeState(SCE_PAS_ASM);
+ }
+ } else {
+ bool ignoreKeyword = false;
+ if (strcmp(s, "asm") == 0) {
+ curLineState |= stateInAsm;
+ } else if (bSmartHighlighting) {
+ if (strcmp(s, "property") == 0) {
+ curLineState |= stateInProperty;
+ } else if (strcmp(s, "exports") == 0) {
+ curLineState |= stateInExport;
+ } else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) {
+ ignoreKeyword = true;
+ } else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) {
+ ignoreKeyword = true;
+ } else if (!(curLineState & stateInProperty) &&
+ (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 ||
+ strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 ||
+ strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 ||
+ strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 ||
+ strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) {
+ ignoreKeyword = true;
+ }
+ }
+ if (!ignoreKeyword) {
+ sc.ChangeState(SCE_PAS_WORD);
+ }
+ }
+ } else if (curLineState & stateInAsm) {
+ sc.ChangeState(SCE_PAS_ASM);
+ }
+ sc.SetState(SCE_PAS_DEFAULT);
+}
+
+static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0;
+
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+ CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
+ CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
+ CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}");
+
+ int curLine = styler.GetLine(startPos);
+ int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curLineState);
+ }
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_PAS_NUMBER:
+ if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
+ sc.SetState(SCE_PAS_DEFAULT);
+ } else if (sc.ch == '-' || sc.ch == '+') {
+ if (sc.chPrev != 'E' && sc.chPrev != 'e') {
+ sc.SetState(SCE_PAS_DEFAULT);
+ }
+ }
+ break;
+ case SCE_PAS_IDENTIFIER:
+ if (!setWord.Contains(sc.ch)) {
+ ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
+ }
+ break;
+ case SCE_PAS_HEXNUMBER:
+ if (!setHexNumber.Contains(sc.ch)) {
+ sc.SetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_COMMENT:
+ case SCE_PAS_PREPROCESSOR:
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_COMMENT2:
+ case SCE_PAS_PREPROCESSOR2:
+ if (sc.Match('*', ')')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_PAS_STRINGEOL);
+ } else if (sc.ch == '\'' && sc.chNext == '\'') {
+ sc.Forward();
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_CHARACTER:
+ if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
+ sc.SetState(SCE_PAS_DEFAULT);
+ }
+ break;
+ case SCE_PAS_OPERATOR:
+ if (bSmartHighlighting && sc.chPrev == ';') {
+ curLineState &= ~(stateInProperty | stateInExport);
+ }
+ sc.SetState(SCE_PAS_DEFAULT);
+ break;
+ case SCE_PAS_ASM:
+ sc.SetState(SCE_PAS_DEFAULT);
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_PAS_DEFAULT) {
+ if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) {
+ sc.SetState(SCE_PAS_NUMBER);
+ } else if (setWordStart.Contains(sc.ch)) {
+ sc.SetState(SCE_PAS_IDENTIFIER);
+ } else if (sc.ch == '$' && !(curLineState & stateInAsm)) {
+ sc.SetState(SCE_PAS_HEXNUMBER);
+ } else if (sc.Match('{', '$')) {
+ sc.SetState(SCE_PAS_PREPROCESSOR);
+ } else if (sc.ch == '{') {
+ sc.SetState(SCE_PAS_COMMENT);
+ } else if (sc.Match("(*$")) {
+ sc.SetState(SCE_PAS_PREPROCESSOR2);
+ } else if (sc.Match('(', '*')) {
+ sc.SetState(SCE_PAS_COMMENT2);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_PAS_COMMENTLINE);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_PAS_STRING);
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_PAS_CHARACTER);
+ } else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) {
+ sc.SetState(SCE_PAS_OPERATOR);
+ } else if (curLineState & stateInAsm) {
+ sc.SetState(SCE_PAS_ASM);
+ }
+ }
+ }
+
+ if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) {
+ ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
+ }
+
+ sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2;
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eolPos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eolPos; i++) {
+ char ch = styler[i];
+ char chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ if (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) {
+ return true;
+ } else if (!IsASpaceOrTab(ch)) {
+ return false;
+ }
+ }
+ return false;
+}
+
+static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
+ return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
+}
+
+static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
+ lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
+ lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
+}
+
+static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
+ unsigned int startPos, Accessor &styler) {
+ CharacterSet setWord(CharacterSet::setAlpha);
+
+ char s[11]; // Size of the longest possible keyword + one additional character + null
+ GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
+
+ unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
+
+ if (strcmp(s, "if") == 0 ||
+ strcmp(s, "ifdef") == 0 ||
+ strcmp(s, "ifndef") == 0 ||
+ strcmp(s, "ifopt") == 0 ||
+ strcmp(s, "region") == 0) {
+ nestLevel++;
+ SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+ lineFoldStateCurrent |= stateFoldInPreprocessor;
+ levelCurrent++;
+ } else if (strcmp(s, "endif") == 0 ||
+ strcmp(s, "ifend") == 0 ||
+ strcmp(s, "endregion") == 0) {
+ nestLevel--;
+ SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+ if (nestLevel == 0) {
+ lineFoldStateCurrent &= ~stateFoldInPreprocessor;
+ }
+ levelCurrent--;
+ if (levelCurrent < SC_FOLDLEVELBASE) {
+ levelCurrent = SC_FOLDLEVELBASE;
+ }
+ }
+}
+
+static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos,
+ Accessor &styler, bool includeChars = false) {
+ CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+ unsigned int j = currentPos + 1;
+ char ch = styler.SafeGetCharAt(j);
+ while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
+ IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
+ j++;
+ ch = styler.SafeGetCharAt(j);
+ }
+ return j;
+}
+
+static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
+ int startPos, unsigned int endPos,
+ unsigned int lastStart, unsigned int currentPos, Accessor &styler) {
+ char s[100];
+ GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
+
+ if (strcmp(s, "record") == 0) {
+ lineFoldStateCurrent |= stateFoldInRecord;
+ levelCurrent++;
+ } else if (strcmp(s, "begin") == 0 ||
+ strcmp(s, "asm") == 0 ||
+ strcmp(s, "try") == 0 ||
+ (strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {
+ levelCurrent++;
+ } else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) {
+ // "class" & "object" keywords require special handling...
+ bool ignoreKeyword = false;
+ unsigned int j = SkipWhiteSpace(currentPos, endPos, styler);
+ if (j < endPos) {
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_");
+ CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+
+ if (styler.SafeGetCharAt(j) == ';') {
+ // Handle forward class declarations ("type TMyClass = class;")
+ // and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;")
+ ignoreKeyword = true;
+ } else if (strcmp(s, "class") == 0) {
+ // "class" keyword has a few more special cases...
+ if (styler.SafeGetCharAt(j) == '(') {
+ // Handle simplified complete class declarations ("type TMyClass = class(TObject);")
+ j = SkipWhiteSpace(j, endPos, styler, true);
+ if (j < endPos && styler.SafeGetCharAt(j) == ')') {
+ j = SkipWhiteSpace(j, endPos, styler);
+ if (j < endPos && styler.SafeGetCharAt(j) == ';') {
+ ignoreKeyword = true;
+ }
+ }
+ } else if (setWordStart.Contains(styler.SafeGetCharAt(j))) {
+ char s2[11]; // Size of the longest possible keyword + one additional character + null
+ GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));
+
+ if (strcmp(s2, "procedure") == 0 ||
+ strcmp(s2, "function") == 0 ||
+ strcmp(s2, "of") == 0 ||
+ strcmp(s2, "var") == 0 ||
+ strcmp(s2, "property") == 0 ||
+ strcmp(s2, "operator") == 0) {
+ ignoreKeyword = true;
+ }
+ }
+ }
+ }
+ if (!ignoreKeyword) {
+ levelCurrent++;
+ }
+ } else if (strcmp(s, "interface") == 0) {
+ // "interface" keyword requires special handling...
+ bool ignoreKeyword = true;
+ int j = lastStart - 1;
+ char ch = styler.SafeGetCharAt(j);
+ while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
+ IsStreamCommentStyle(styler.StyleAt(j)))) {
+ j--;
+ ch = styler.SafeGetCharAt(j);
+ }
+ if (j >= startPos && styler.SafeGetCharAt(j) == '=') {
+ ignoreKeyword = false;
+ }
+ if (!ignoreKeyword) {
+ unsigned int k = SkipWhiteSpace(currentPos, endPos, styler);
+ if (k < endPos && styler.SafeGetCharAt(k) == ';') {
+ // Handle forward interface declarations ("type IMyInterface = interface;")
+ ignoreKeyword = true;
+ }
+ }
+ if (!ignoreKeyword) {
+ levelCurrent++;
+ }
+ } else if (strcmp(s, "dispinterface") == 0) {
+ // "dispinterface" keyword requires special handling...
+ bool ignoreKeyword = false;
+ unsigned int j = SkipWhiteSpace(currentPos, endPos, styler);
+ if (j < endPos && styler.SafeGetCharAt(j) == ';') {
+ // Handle forward dispinterface declarations ("type IMyInterface = dispinterface;")
+ ignoreKeyword = true;
+ }
+ if (!ignoreKeyword) {
+ levelCurrent++;
+ }
+ } else if (strcmp(s, "end") == 0) {
+ lineFoldStateCurrent &= ~stateFoldInRecord;
+ levelCurrent--;
+ if (levelCurrent < SC_FOLDLEVELBASE) {
+ levelCurrent = SC_FOLDLEVELBASE;
+ }
+ }
+}
+
+static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+
+ int lastStart = 0;
+ CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelCurrent++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+ {
+ if (!IsCommentLine(lineCurrent - 1, styler)
+ && IsCommentLine(lineCurrent + 1, styler))
+ levelCurrent++;
+ else if (IsCommentLine(lineCurrent - 1, styler)
+ && !IsCommentLine(lineCurrent+1, styler))
+ levelCurrent--;
+ }
+ if (foldPreprocessor) {
+ if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
+ ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
+ } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*'
+ && styler.SafeGetCharAt(i + 2) == '$') {
+ ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
+ }
+ }
+
+ if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD)
+ {
+ // Store last word start point.
+ lastStart = i;
+ }
+ if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) {
+ if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
+ ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler);
+ }
+ }
+
+ if (!IsASpace(ch))
+ visibleChars++;
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
+ styler.SetLineState(lineCurrent, newLineState);
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ }
+
+ // If we didn't reach the EOL in previous loop, store line level and whitespace information.
+ // The rest will be filled in later...
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ styler.SetLevel(lineCurrent, lev);
+}
+
+static const char * const pascalWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPerl.cxx
+ ** Lexer for Perl.
+ ** Converted to lexer object by "Udo Lechner" <dlchnr(at)gmx(dot)net>
+ **/
+// Copyright 1998-2008 by Neil Hodgson <neilh@scintilla.org>
+// Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my>
+// 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 <string>
+#include <map>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+// Info for HERE document handling from perldata.pod (reformatted):
+// ----------------------------------------------------------------
+// A line-oriented form of quoting is based on the shell ``here-doc'' syntax.
+// Following a << you specify a string to terminate the quoted material, and
+// all lines following the current line down to the terminating string are
+// the value of the item.
+// * The terminating string may be either an identifier (a word), or some
+// quoted text.
+// * If quoted, the type of quotes you use determines the treatment of the
+// text, just as in regular quoting.
+// * An unquoted identifier works like double quotes.
+// * There must be no space between the << and the identifier.
+// (If you put a space it will be treated as a null identifier,
+// which is valid, and matches the first empty line.)
+// (This is deprecated, -w warns of this syntax)
+// * The terminating string must appear by itself (unquoted and
+// with no surrounding whitespace) on the terminating line.
+
+#define HERE_DELIM_MAX 256 // maximum length of HERE doc delimiter
+
+#define PERLNUM_BINARY 1 // order is significant: 1-4 cannot have a dot
+#define PERLNUM_HEX 2
+#define PERLNUM_OCTAL 3
+#define PERLNUM_FLOAT_EXP 4 // exponent part only
+#define PERLNUM_DECIMAL 5 // 1-5 are numbers; 6-7 are strings
+#define PERLNUM_VECTOR 6
+#define PERLNUM_V_VECTOR 7
+#define PERLNUM_BAD 8
+
+#define BACK_NONE 0 // lookback state for bareword disambiguation:
+#define BACK_OPERATOR 1 // whitespace/comments are insignificant
+#define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation
+
+// all interpolated styles are different from their parent styles by a constant difference
+// we also assume SCE_PL_STRING_VAR is the interpolated style with the smallest value
+#define INTERPOLATE_SHIFT (SCE_PL_STRING_VAR - SCE_PL_STRING)
+
+static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) {
+ // old-style keyword matcher; needed because GetCurrent() needs
+ // current segment to be committed, but we may abandon early...
+ char s[100];
+ unsigned int i, len = end - start;
+ if (len > 30) { len = 30; }
+ for (i = 0; i < len; i++, start++) s[i] = styler[start];
+ s[i] = '\0';
+ return keywords.InList(s);
+}
+
+static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned int fw,
+ int backFlag, unsigned int backPos, unsigned int endPos) {
+ // identifiers are recognized by Perl as barewords under some
+ // conditions, the following attempts to do the disambiguation
+ // by looking backward and forward; result in 2 LSB
+ int result = 0;
+ bool moreback = false; // true if passed newline/comments
+ bool brace = false; // true if opening brace found
+ // if BACK_NONE, neither operator nor keyword, so skip test
+ if (backFlag == BACK_NONE)
+ return result;
+ // first look backwards past whitespace/comments to set EOL flag
+ // (some disambiguation patterns must be on a single line)
+ if (backPos <= static_cast<unsigned int>(styler.LineStart(styler.GetLine(bk))))
+ moreback = true;
+ // look backwards at last significant lexed item for disambiguation
+ bk = backPos - 1;
+ int ch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
+ if (ch == '{' && !moreback) {
+ // {bareword: possible variable spec
+ brace = true;
+ } else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&')
+ // &bareword: subroutine call
+ || styler.Match(bk - 1, "->")
+ // ->bareword: part of variable spec
+ || styler.Match(bk - 2, "sub")) {
+ // sub bareword: subroutine declaration
+ // (implied BACK_KEYWORD, no keywords end in 'sub'!)
+ result |= 1;
+ }
+ // next, scan forward after word past tab/spaces only;
+ // if ch isn't one of '[{(,' we can skip the test
+ if ((ch == '{' || ch == '(' || ch == '['|| ch == ',')
+ && fw < endPos) {
+ while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)),
+ IsASpaceOrTab(ch) && fw < endPos) {
+ fw++;
+ }
+ if ((ch == '}' && brace)
+ // {bareword}: variable spec
+ || styler.Match(fw, "=>")) {
+ // [{(, bareword=>: hash literal
+ result |= 2;
+ }
+ }
+ return result;
+}
+
+static void skipWhitespaceComment(LexAccessor &styler, unsigned int &p) {
+ // when backtracking, we need to skip whitespace and comments
+ int style;
+ while ((p > 0) && (style = styler.StyleAt(p),
+ style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
+ p--;
+}
+
+static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk) {
+ // backtrack to find open '{' corresponding to a '}', balanced
+ // return significant style to be tested for '/' disambiguation
+ int braceCount = 1;
+ if (bk == 0)
+ return SCE_PL_DEFAULT;
+ while (--bk > 0) {
+ if (styler.StyleAt(bk) == SCE_PL_OPERATOR) {
+ int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
+ if (bkch == ';') { // early out
+ break;
+ } else if (bkch == '}') {
+ braceCount++;
+ } else if (bkch == '{') {
+ if (--braceCount == 0) break;
+ }
+ }
+ }
+ if (bk > 0 && braceCount == 0) {
+ // balanced { found, bk > 0, skip more whitespace/comments
+ bk--;
+ skipWhitespaceComment(styler, bk);
+ return styler.StyleAt(bk);
+ }
+ return SCE_PL_DEFAULT;
+}
+
+static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk) {
+ // backtrack to classify sub-styles of identifier under test
+ // return sub-style to be tested for '/' disambiguation
+ if (styler.SafeGetCharAt(bk) == '>') // inputsymbol, like <foo>
+ return 1;
+ // backtrack to check for possible "->" or "::" before identifier
+ while (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) {
+ bk--;
+ }
+ while (bk > 0) {
+ int bkstyle = styler.StyleAt(bk);
+ if (bkstyle == SCE_PL_DEFAULT
+ || bkstyle == SCE_PL_COMMENTLINE) {
+ // skip whitespace, comments
+ } else if (bkstyle == SCE_PL_OPERATOR) {
+ // test for "->" and "::"
+ if (styler.Match(bk - 1, "->") || styler.Match(bk - 1, "::"))
+ return 2;
+ } else
+ return 3; // bare identifier
+ bk--;
+ }
+ return 0;
+}
+
+static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int endPos) {
+ // looks forward for matching > on same line; a bit ugly
+ unsigned int fw = pos;
+ while (++fw < endPos) {
+ int fwch = static_cast<unsigned char>(styler.SafeGetCharAt(fw));
+ if (fwch == '\r' || fwch == '\n') {
+ return 0;
+ } else if (fwch == '>') {
+ if (styler.Match(fw - 2, "<=>")) // '<=>' case
+ return 0;
+ return fw - pos;
+ }
+ }
+ return 0;
+}
+
+static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endPos) {
+ // forward scan the current line to classify line for POD style
+ int state = -1;
+ while (pos <= endPos) {
+ int ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ if (ch == '\n' || ch == '\r' || pos >= endPos) {
+ if (ch == '\r' && styler.SafeGetCharAt(pos + 1) == '\n') pos++;
+ break;
+ }
+ if (IsASpaceOrTab(ch)) { // whitespace, take note
+ if (state == -1)
+ state = SCE_PL_DEFAULT;
+ } else if (state == SCE_PL_DEFAULT) { // verbatim POD line
+ state = SCE_PL_POD_VERB;
+ } else if (state != SCE_PL_POD_VERB) { // regular POD line
+ state = SCE_PL_POD;
+ }
+ pos++;
+ }
+ if (state == -1)
+ state = SCE_PL_DEFAULT;
+ return state;
+}
+
+static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) {
+ // backtrack to identify if we're starting a subroutine prototype
+ // we also need to ignore whitespace/comments:
+ // 'sub' [whitespace|comment] <identifier> [whitespace|comment]
+ styler.Flush();
+ skipWhitespaceComment(styler, bk);
+ if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier
+ return false;
+ while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) {
+ bk--;
+ }
+ skipWhitespaceComment(styler, bk);
+ if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword
+ || !styler.Match(bk - 2, "sub")) // assume suffix is unique!
+ return false;
+ return true;
+}
+
+static int actualNumStyle(int numberStyle) {
+ if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) {
+ return SCE_PL_STRING;
+ } else if (numberStyle == PERLNUM_BAD) {
+ return SCE_PL_ERROR;
+ }
+ return SCE_PL_NUMBER;
+}
+
+static int opposite(int ch) {
+ if (ch == '(') return ')';
+ if (ch == '[') return ']';
+ if (ch == '{') return '}';
+ if (ch == '<') return '>';
+ return ch;
+}
+
+static bool IsCommentLine(int line, LexAccessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ int style = styler.StyleAt(i);
+ if (ch == '#' && style == SCE_PL_COMMENTLINE)
+ return true;
+ else if (!IsASpaceOrTab(ch))
+ return false;
+ }
+ return false;
+}
+
+static bool IsPackageLine(int line, LexAccessor &styler) {
+ int pos = styler.LineStart(line);
+ int style = styler.StyleAt(pos);
+ if (style == SCE_PL_WORD && styler.Match(pos, "package")) {
+ return true;
+ }
+ return false;
+}
+
+static int PodHeadingLevel(int pos, LexAccessor &styler) {
+ int lvl = static_cast<unsigned char>(styler.SafeGetCharAt(pos + 5));
+ if (lvl >= '1' && lvl <= '4') {
+ return lvl - '0';
+ }
+ return 0;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerPerl
+struct OptionsPerl {
+ bool fold;
+ bool foldComment;
+ bool foldCompact;
+ // Custom folding of POD and packages
+ bool foldPOD; // fold.perl.pod
+ // Enable folding Pod blocks when using the Perl lexer.
+ bool foldPackage; // fold.perl.package
+ // Enable folding packages when using the Perl lexer.
+
+ bool foldCommentExplicit;
+
+ bool foldAtElse;
+
+ OptionsPerl() {
+ fold = false;
+ foldComment = false;
+ foldCompact = true;
+ foldPOD = true;
+ foldPackage = true;
+ foldCommentExplicit = true;
+ foldAtElse = false;
+ }
+};
+
+static const char *const perlWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+struct OptionSetPerl : public OptionSet<OptionsPerl> {
+ OptionSetPerl() {
+ DefineProperty("fold", &OptionsPerl::fold);
+
+ DefineProperty("fold.comment", &OptionsPerl::foldComment);
+
+ DefineProperty("fold.compact", &OptionsPerl::foldCompact);
+
+ DefineProperty("fold.perl.pod", &OptionsPerl::foldPOD,
+ "Set to 0 to disable folding Pod blocks when using the Perl lexer.");
+
+ DefineProperty("fold.perl.package", &OptionsPerl::foldPackage,
+ "Set to 0 to disable folding packages when using the Perl lexer.");
+
+ DefineProperty("fold.perl.comment.explicit", &OptionsPerl::foldCommentExplicit,
+ "Set to 0 to disable explicit folding.");
+
+ DefineProperty("fold.perl.at.else", &OptionsPerl::foldAtElse,
+ "This option enables Perl folding on a \"} else {\" line of an if statement.");
+
+ DefineWordListSets(perlWordListDesc);
+ }
+};
+
+class LexerPerl : public ILexer {
+ CharacterSet setWordStart;
+ CharacterSet setWord;
+ CharacterSet setSpecialVar;
+ CharacterSet setControlVar;
+ WordList keywords;
+ OptionsPerl options;
+ OptionSetPerl osPerl;
+public:
+ LexerPerl() :
+ setWordStart(CharacterSet::setAlpha, "_", 0x80, true),
+ setWord(CharacterSet::setAlphaNum, "_", 0x80, true),
+ setSpecialVar(CharacterSet::setNone, "\"$;<>&`'+,./\\%:=~!?@[]"),
+ setControlVar(CharacterSet::setNone, "ACDEFHILMNOPRSTVWX") {
+ }
+ virtual ~LexerPerl() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char *SCI_METHOD PropertyNames() {
+ return osPerl.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osPerl.PropertyType(name);
+ }
+ const char *SCI_METHOD DescribeProperty(const char *name) {
+ return osPerl.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char *SCI_METHOD DescribeWordListSets() {
+ return osPerl.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+ void *SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryPerl() {
+ return new LexerPerl();
+ }
+ void InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern=false);
+};
+
+int SCI_METHOD LexerPerl::PropertySet(const char *key, const char *val) {
+ if (osPerl.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerPerl::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void LexerPerl::InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern) {
+ // interpolate a segment (with no active backslashes or delimiters within)
+ // switch in or out of an interpolation style or continue current style
+ // commit variable patterns if found, trim segment, repeat until done
+ while (maxSeg > 0) {
+ bool isVar = false;
+ int sLen = 0;
+ if ((maxSeg > 1) && (sc.ch == '$' || sc.ch == '@')) {
+ // $#[$]*word [$@][$]*word (where word or {word} is always present)
+ bool braces = false;
+ sLen = 1;
+ if (sc.ch == '$' && sc.chNext == '#') { // starts with $#
+ sLen++;
+ }
+ while ((maxSeg > sLen) && (sc.GetRelative(sLen) == '$')) // >0 $ dereference within
+ sLen++;
+ if ((maxSeg > sLen) && (sc.GetRelative(sLen) == '{')) { // { start for {word}
+ sLen++;
+ braces = true;
+ }
+ if (maxSeg > sLen) {
+ int c = sc.GetRelative(sLen);
+ if (setWordStart.Contains(c)) { // word (various)
+ sLen++;
+ isVar = true;
+ while ((maxSeg > sLen) && setWord.Contains(sc.GetRelative(sLen)))
+ sLen++;
+ } else if (braces && IsADigit(c) && (sLen == 2)) { // digit for ${digit}
+ sLen++;
+ isVar = true;
+ }
+ }
+ if (braces) {
+ if ((maxSeg > sLen) && (sc.GetRelative(sLen) == '}')) { // } end for {word}
+ sLen++;
+ } else
+ isVar = false;
+ }
+ }
+ if (!isVar && (maxSeg > 1)) { // $- or @-specific variable patterns
+ sLen = 1;
+ int c = sc.chNext;
+ if (sc.ch == '$') {
+ if (IsADigit(c)) { // $[0-9] and slurp trailing digits
+ sLen++;
+ isVar = true;
+ while ((maxSeg > sLen) && IsADigit(sc.GetRelative(sLen)))
+ sLen++;
+ } else if (setSpecialVar.Contains(c)) { // $ special variables
+ sLen++;
+ isVar = true;
+ } else if (!isPattern && ((c == '(') || (c == ')') || (c == '|'))) { // $ additional
+ sLen++;
+ isVar = true;
+ } else if (c == '^') { // $^A control-char style
+ sLen++;
+ if ((maxSeg > sLen) && setControlVar.Contains(sc.GetRelative(sLen))) {
+ sLen++;
+ isVar = true;
+ }
+ }
+ } else if (sc.ch == '@') {
+ if (!isPattern && ((c == '+') || (c == '-'))) { // @ specials non-pattern
+ sLen++;
+ isVar = true;
+ }
+ }
+ }
+ if (isVar) { // commit as interpolated variable or normal character
+ if (sc.state < SCE_PL_STRING_VAR)
+ sc.SetState(sc.state + INTERPOLATE_SHIFT);
+ sc.Forward(sLen);
+ maxSeg -= sLen;
+ } else {
+ if (sc.state >= SCE_PL_STRING_VAR)
+ sc.SetState(sc.state - INTERPOLATE_SHIFT);
+ sc.Forward();
+ maxSeg--;
+ }
+ }
+ if (sc.state >= SCE_PL_STRING_VAR)
+ sc.SetState(sc.state - INTERPOLATE_SHIFT);
+}
+
+void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
+ // keywords that forces /PATTERN/ at all times; should track vim's behaviour
+ WordList reWords;
+ reWords.Set("elsif if split while");
+
+ // charset classes
+ CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMAC");
+ // lexing of "%*</" operators is non-trivial; these are missing in the set below
+ CharacterSet setPerlOperator(CharacterSet::setNone, "^&\\()-+=|{}[]:;>,?!.~");
+ CharacterSet setQDelim(CharacterSet::setNone, "qrwx");
+ CharacterSet setModifiers(CharacterSet::setAlpha);
+ CharacterSet setPreferRE(CharacterSet::setNone, "*/<%");
+ // setArray and setHash also accepts chars for special vars like $_,
+ // which are then truncated when the next char does not match setVar
+ CharacterSet setVar(CharacterSet::setAlphaNum, "#$_'", 0x80, true);
+ CharacterSet setArray(CharacterSet::setAlpha, "#$_+-", 0x80, true);
+ CharacterSet setHash(CharacterSet::setAlpha, "#$_!^+-", 0x80, true);
+ CharacterSet &setPOD = setModifiers;
+ CharacterSet setNonHereDoc(CharacterSet::setDigits, "=$@");
+ CharacterSet setHereDocDelim(CharacterSet::setAlphaNum, "_");
+ CharacterSet setSubPrototype(CharacterSet::setNone, "\\[$@%&*+];");
+ // for format identifiers
+ CharacterSet setFormatStart(CharacterSet::setAlpha, "_=");
+ CharacterSet &setFormat = setHereDocDelim;
+
+ // Lexer for perl often has to backtrack to start of current style to determine
+ // which characters are being used as quotes, how deeply nested is the
+ // start position and what the termination string is for HERE documents.
+
+ class HereDocCls { // Class to manage HERE doc sequence
+ public:
+ int State;
+ // 0: '<<' encountered
+ // 1: collect the delimiter
+ // 2: here doc text (lines after the delimiter)
+ int Quote; // the char after '<<'
+ bool Quoted; // true if Quote in ('\'','"','`')
+ int DelimiterLength; // strlen(Delimiter)
+ char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
+ HereDocCls() {
+ State = 0;
+ Quote = 0;
+ Quoted = false;
+ DelimiterLength = 0;
+ Delimiter = new char[HERE_DELIM_MAX];
+ Delimiter[0] = '\0';
+ }
+ void Append(int ch) {
+ Delimiter[DelimiterLength++] = static_cast<char>(ch);
+ Delimiter[DelimiterLength] = '\0';
+ }
+ ~HereDocCls() {
+ delete []Delimiter;
+ }
+ };
+ HereDocCls HereDoc; // TODO: FIFO for stacked here-docs
+
+ class QuoteCls { // Class to manage quote pairs
+ public:
+ int Rep;
+ int Count;
+ int Up, Down;
+ QuoteCls() {
+ this->New(1);
+ }
+ void New(int r = 1) {
+ Rep = r;
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ }
+ void Open(int u) {
+ Count++;
+ Up = u;
+ Down = opposite(Up);
+ }
+ };
+ QuoteCls Quote;
+
+ // additional state for number lexing
+ int numState = PERLNUM_DECIMAL;
+ int dotCount = 0;
+
+ unsigned int endPos = startPos + length;
+
+ // Backtrack to beginning of style if required...
+ // If in a long distance lexical state, backtrack to find quote characters.
+ // Includes strings (may be multi-line), numbers (additional state), format
+ // bodies, as well as POD sections.
+ if (initStyle == SCE_PL_HERE_Q
+ || initStyle == SCE_PL_HERE_QQ
+ || initStyle == SCE_PL_HERE_QX
+ || initStyle == SCE_PL_FORMAT
+ || initStyle == SCE_PL_HERE_QQ_VAR
+ || initStyle == SCE_PL_HERE_QX_VAR
+ ) {
+ // backtrack through multiple styles to reach the delimiter start
+ int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;
+ while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {
+ startPos--;
+ }
+ startPos = styler.LineStart(styler.GetLine(startPos));
+ initStyle = styler.StyleAt(startPos - 1);
+ }
+ if (initStyle == SCE_PL_STRING
+ || initStyle == SCE_PL_STRING_QQ
+ || initStyle == SCE_PL_BACKTICKS
+ || initStyle == SCE_PL_STRING_QX
+ || initStyle == SCE_PL_REGEX
+ || initStyle == SCE_PL_STRING_QR
+ || initStyle == SCE_PL_REGSUBST
+ || initStyle == SCE_PL_STRING_VAR
+ || initStyle == SCE_PL_STRING_QQ_VAR
+ || initStyle == SCE_PL_BACKTICKS_VAR
+ || initStyle == SCE_PL_STRING_QX_VAR
+ || initStyle == SCE_PL_REGEX_VAR
+ || initStyle == SCE_PL_STRING_QR_VAR
+ || initStyle == SCE_PL_REGSUBST_VAR
+ ) {
+ // for interpolation, must backtrack through a mix of two different styles
+ int otherStyle = (initStyle >= SCE_PL_STRING_VAR) ?
+ initStyle - INTERPOLATE_SHIFT : initStyle + INTERPOLATE_SHIFT;
+ while (startPos > 1) {
+ int st = styler.StyleAt(startPos - 1);
+ if ((st != initStyle) && (st != otherStyle))
+ break;
+ startPos--;
+ }
+ initStyle = SCE_PL_DEFAULT;
+ } else if (initStyle == SCE_PL_STRING_Q
+ || initStyle == SCE_PL_STRING_QW
+ || initStyle == SCE_PL_XLAT
+ || initStyle == SCE_PL_CHARACTER
+ || initStyle == SCE_PL_NUMBER
+ || initStyle == SCE_PL_IDENTIFIER
+ || initStyle == SCE_PL_ERROR
+ || initStyle == SCE_PL_SUB_PROTOTYPE
+ ) {
+ while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
+ startPos--;
+ }
+ initStyle = SCE_PL_DEFAULT;
+ } else if (initStyle == SCE_PL_POD
+ || initStyle == SCE_PL_POD_VERB
+ ) {
+ // POD backtracking finds preceeding blank lines and goes back past them
+ int ln = styler.GetLine(startPos);
+ if (ln > 0) {
+ initStyle = styler.StyleAt(styler.LineStart(--ln));
+ if (initStyle == SCE_PL_POD || initStyle == SCE_PL_POD_VERB) {
+ while (ln > 0 && styler.GetLineState(ln) == SCE_PL_DEFAULT)
+ ln--;
+ }
+ startPos = styler.LineStart(++ln);
+ initStyle = styler.StyleAt(startPos - 1);
+ } else {
+ startPos = 0;
+ initStyle = SCE_PL_DEFAULT;
+ }
+ }
+
+ // backFlag, backPos are additional state to aid identifier corner cases.
+ // Look backwards past whitespace and comments in order to detect either
+ // operator or keyword. Later updated as we go along.
+ int backFlag = BACK_NONE;
+ unsigned int backPos = startPos;
+ if (backPos > 0) {
+ backPos--;
+ skipWhitespaceComment(styler, backPos);
+ if (styler.StyleAt(backPos) == SCE_PL_OPERATOR)
+ backFlag = BACK_OPERATOR;
+ else if (styler.StyleAt(backPos) == SCE_PL_WORD)
+ backFlag = BACK_KEYWORD;
+ backPos++;
+ }
+
+ StyleContext sc(startPos, endPos - startPos, initStyle, styler, static_cast<char>(STYLE_MAX));
+
+ for (; sc.More(); sc.Forward()) {
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_PL_OPERATOR:
+ sc.SetState(SCE_PL_DEFAULT);
+ backFlag = BACK_OPERATOR;
+ backPos = sc.currentPos;
+ break;
+ case SCE_PL_IDENTIFIER: // identifier, bareword, inputsymbol
+ if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
+ || sc.Match('.', '.')
+ || sc.chPrev == '>') { // end of inputsymbol
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_WORD: // keyword, plus special cases
+ if (!setWord.Contains(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
+ sc.ChangeState(SCE_PL_DATASECTION);
+ } else {
+ if ((strcmp(s, "format") == 0)) {
+ sc.SetState(SCE_PL_FORMAT_IDENT);
+ HereDoc.State = 0;
+ } else {
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ backFlag = BACK_KEYWORD;
+ backPos = sc.currentPos;
+ }
+ }
+ break;
+ case SCE_PL_SCALAR:
+ case SCE_PL_ARRAY:
+ case SCE_PL_HASH:
+ case SCE_PL_SYMBOLTABLE:
+ if (sc.Match(':', ':')) { // skip ::
+ sc.Forward();
+ } else if (!setVar.Contains(sc.ch)) {
+ if (sc.LengthCurrent() == 1) {
+ // Special variable: $(, $_ etc.
+ sc.Forward();
+ }
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_NUMBER:
+ // if no early break, number style is terminated at "(go through)"
+ if (sc.ch == '.') {
+ if (sc.chNext == '.') {
+ // double dot is always an operator (go through)
+ } else if (numState <= PERLNUM_FLOAT_EXP) {
+ // non-decimal number or float exponent, consume next dot
+ sc.SetState(SCE_PL_OPERATOR);
+ break;
+ } else { // decimal or vectors allows dots
+ dotCount++;
+ if (numState == PERLNUM_DECIMAL) {
+ if (dotCount <= 1) // number with one dot in it
+ break;
+ if (IsADigit(sc.chNext)) { // really a vector
+ numState = PERLNUM_VECTOR;
+ break;
+ }
+ // number then dot (go through)
+ } else if (IsADigit(sc.chNext)) // vectors
+ break;
+ // vector then dot (go through)
+ }
+ } else if (sc.ch == '_') {
+ // permissive underscoring for number and vector literals
+ break;
+ } else if (numState == PERLNUM_DECIMAL) {
+ if (sc.ch == 'E' || sc.ch == 'e') { // exponent, sign
+ numState = PERLNUM_FLOAT_EXP;
+ if (sc.chNext == '+' || sc.chNext == '-') {
+ sc.Forward();
+ }
+ break;
+ } else if (IsADigit(sc.ch))
+ break;
+ // number then word (go through)
+ } else if (numState == PERLNUM_HEX) {
+ if (IsADigit(sc.ch, 16))
+ break;
+ } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
+ if (IsADigit(sc.ch)) // vector
+ break;
+ if (setWord.Contains(sc.ch) && dotCount == 0) { // change to word
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ break;
+ }
+ // vector then word (go through)
+ } else if (IsADigit(sc.ch)) {
+ if (numState == PERLNUM_FLOAT_EXP) {
+ break;
+ } else if (numState == PERLNUM_OCTAL) {
+ if (sc.ch <= '7') break;
+ } else if (numState == PERLNUM_BINARY) {
+ if (sc.ch <= '1') break;
+ }
+ // mark invalid octal, binary numbers (go through)
+ numState = PERLNUM_BAD;
+ break;
+ }
+ // complete current number or vector
+ sc.ChangeState(actualNumStyle(numState));
+ sc.SetState(SCE_PL_DEFAULT);
+ break;
+ case SCE_PL_COMMENTLINE:
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_HERE_DELIM:
+ if (HereDoc.State == 0) { // '<<' encountered
+ int delim_ch = sc.chNext;
+ int ws_skip = 0;
+ HereDoc.State = 1; // pre-init HERE doc class
+ HereDoc.Quote = sc.chNext;
+ HereDoc.Quoted = false;
+ HereDoc.DelimiterLength = 0;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ if (IsASpaceOrTab(delim_ch)) {
+ // skip whitespace; legal only for quoted delimiters
+ unsigned int i = sc.currentPos + 1;
+ while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
+ i++;
+ delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ }
+ ws_skip = i - sc.currentPos - 1;
+ }
+ if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
+ // a quoted here-doc delimiter; skip any whitespace
+ sc.Forward(ws_skip + 1);
+ HereDoc.Quote = delim_ch;
+ HereDoc.Quoted = true;
+ } else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
+ || ws_skip > 0) {
+ // left shift << or <<= operator cases
+ // restore position if operator
+ sc.ChangeState(SCE_PL_OPERATOR);
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ backFlag = BACK_OPERATOR;
+ backPos = sc.currentPos;
+ HereDoc.State = 0;
+ } else {
+ // specially handle initial '\' for identifier
+ if (ws_skip == 0 && HereDoc.Quote == '\\')
+ sc.Forward();
+ // an unquoted here-doc delimiter, no special handling
+ // (cannot be prefixed by spaces/tabs), or
+ // symbols terminates; deprecated zero-length delimiter
+ }
+ } else if (HereDoc.State == 1) { // collect the delimiter
+ backFlag = BACK_NONE;
+ if (HereDoc.Quoted) { // a quoted here-doc delimiter
+ if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ } else if (!sc.atLineEnd) {
+ if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
+ sc.Forward();
+ }
+ if (sc.ch != '\r') { // skip CR if CRLF
+ HereDoc.Append(sc.ch);
+ }
+ }
+ } else { // an unquoted here-doc delimiter
+ if (setHereDocDelim.Contains(sc.ch)) {
+ HereDoc.Append(sc.ch);
+ } else {
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ }
+ if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
+ sc.SetState(SCE_PL_ERROR);
+ HereDoc.State = 0;
+ }
+ }
+ break;
+ case SCE_PL_HERE_Q:
+ case SCE_PL_HERE_QQ:
+ case SCE_PL_HERE_QX:
+ // also implies HereDoc.State == 2
+ sc.Complete();
+ if (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) {
+ int c = sc.GetRelative(HereDoc.DelimiterLength);
+ if (c == '\r' || c == '\n') { // peek first, do not consume match
+ sc.Forward(HereDoc.DelimiterLength);
+ sc.SetState(SCE_PL_DEFAULT);
+ backFlag = BACK_NONE;
+ HereDoc.State = 0;
+ if (!sc.atLineEnd)
+ sc.Forward();
+ break;
+ }
+ }
+ if (sc.state == SCE_PL_HERE_Q) { // \EOF and 'EOF' non-interpolated
+ while (!sc.atLineEnd)
+ sc.Forward();
+ break;
+ }
+ while (!sc.atLineEnd) { // "EOF" and `EOF` interpolated
+ int s = 0, endType = 0;
+ int maxSeg = endPos - sc.currentPos;
+ while (s < maxSeg) { // scan to break string into segments
+ int c = sc.GetRelative(s);
+ if (c == '\\') {
+ endType = 1; break;
+ } else if (c == '\r' || c == '\n') {
+ endType = 2; break;
+ }
+ s++;
+ }
+ if (s > 0) // process non-empty segments
+ InterpolateSegment(sc, s);
+ if (endType == 1) {
+ sc.Forward();
+ // \ at end-of-line does not appear to have any effect, skip
+ if (sc.ch != '\r' && sc.ch != '\n')
+ sc.Forward();
+ } else if (endType == 2) {
+ if (!sc.atLineEnd)
+ sc.Forward();
+ }
+ }
+ break;
+ case SCE_PL_POD:
+ case SCE_PL_POD_VERB: {
+ unsigned int fw = sc.currentPos;
+ int ln = styler.GetLine(fw);
+ if (sc.atLineStart && sc.Match("=cut")) { // end of POD
+ sc.SetState(SCE_PL_POD);
+ sc.Forward(4);
+ sc.SetState(SCE_PL_DEFAULT);
+ styler.SetLineState(ln, SCE_PL_POD);
+ break;
+ }
+ int pod = podLineScan(styler, fw, endPos); // classify POD line
+ styler.SetLineState(ln, pod);
+ if (pod == SCE_PL_DEFAULT) {
+ if (sc.state == SCE_PL_POD_VERB) {
+ unsigned int fw2 = fw;
+ while (fw2 <= endPos && pod == SCE_PL_DEFAULT) {
+ fw = fw2++; // penultimate line (last blank line)
+ pod = podLineScan(styler, fw2, endPos);
+ styler.SetLineState(styler.GetLine(fw2), pod);
+ }
+ if (pod == SCE_PL_POD) { // truncate verbatim POD early
+ sc.SetState(SCE_PL_POD);
+ } else
+ fw = fw2;
+ }
+ } else {
+ if (pod == SCE_PL_POD_VERB // still part of current paragraph
+ && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
+ pod = SCE_PL_POD;
+ styler.SetLineState(ln, pod);
+ } else if (pod == SCE_PL_POD
+ && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
+ pod = SCE_PL_POD_VERB;
+ styler.SetLineState(ln, pod);
+ }
+ sc.SetState(pod);
+ }
+ sc.Forward(fw - sc.currentPos); // commit style
+ }
+ break;
+ case SCE_PL_REGEX:
+ case SCE_PL_STRING_QR:
+ if (Quote.Rep <= 0) {
+ if (!setModifiers.Contains(sc.ch))
+ sc.SetState(SCE_PL_DEFAULT);
+ } else if (!Quote.Up && !IsASpace(sc.ch)) {
+ Quote.Open(sc.ch);
+ } else {
+ int s = 0, endType = 0;
+ int maxSeg = endPos - sc.currentPos;
+ while (s < maxSeg) { // scan to break string into segments
+ int c = sc.GetRelative(s);
+ if (IsASpace(c)) {
+ break;
+ } else if (c == '\\' && Quote.Up != '\\') {
+ endType = 1; break;
+ } else if (c == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ Quote.Rep--;
+ break;
+ }
+ } else if (c == Quote.Up)
+ Quote.Count++;
+ s++;
+ }
+ if (s > 0) { // process non-empty segments
+ if (Quote.Up != '\'') {
+ InterpolateSegment(sc, s, true);
+ } else // non-interpolated path
+ sc.Forward(s);
+ }
+ if (endType == 1)
+ sc.Forward();
+ }
+ break;
+ case SCE_PL_REGSUBST:
+ case SCE_PL_XLAT:
+ if (Quote.Rep <= 0) {
+ if (!setModifiers.Contains(sc.ch))
+ sc.SetState(SCE_PL_DEFAULT);
+ } else if (!Quote.Up && !IsASpace(sc.ch)) {
+ Quote.Open(sc.ch);
+ } else {
+ int s = 0, endType = 0;
+ int maxSeg = endPos - sc.currentPos;
+ bool isPattern = (Quote.Rep == 2);
+ while (s < maxSeg) { // scan to break string into segments
+ int c = sc.GetRelative(s);
+ if (c == '\\' && Quote.Up != '\\') {
+ endType = 2; break;
+ } else if (Quote.Count == 0 && Quote.Rep == 1) {
+ // We matched something like s(...) or tr{...}, Perl 5.10
+ // appears to allow almost any character for use as the
+ // next delimiters. Whitespace and comments are accepted in
+ // between, but we'll limit to whitespace here.
+ // For '#', if no whitespace in between, it's a delimiter.
+ if (IsASpace(c)) {
+ // Keep going
+ } else if (c == '#' && IsASpaceOrTab(sc.GetRelative(s - 1))) {
+ endType = 3;
+ } else
+ Quote.Open(c);
+ break;
+ } else if (c == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ Quote.Rep--;
+ endType = 1;
+ }
+ if (Quote.Up == Quote.Down)
+ Quote.Count++;
+ if (endType == 1)
+ break;
+ } else if (c == Quote.Up) {
+ Quote.Count++;
+ } else if (IsASpace(c))
+ break;
+ s++;
+ }
+ if (s > 0) { // process non-empty segments
+ if (sc.state == SCE_PL_REGSUBST && Quote.Up != '\'') {
+ InterpolateSegment(sc, s, isPattern);
+ } else // non-interpolated path
+ sc.Forward(s);
+ }
+ if (endType == 2) {
+ sc.Forward();
+ } else if (endType == 3)
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_STRING_Q:
+ case SCE_PL_STRING_QQ:
+ case SCE_PL_STRING_QX:
+ case SCE_PL_STRING_QW:
+ case SCE_PL_STRING:
+ case SCE_PL_CHARACTER:
+ case SCE_PL_BACKTICKS:
+ if (!Quote.Down && !IsASpace(sc.ch)) {
+ Quote.Open(sc.ch);
+ } else {
+ int s = 0, endType = 0;
+ int maxSeg = endPos - sc.currentPos;
+ while (s < maxSeg) { // scan to break string into segments
+ int c = sc.GetRelative(s);
+ if (IsASpace(c)) {
+ break;
+ } else if (c == '\\' && Quote.Up != '\\') {
+ endType = 2; break;
+ } else if (c == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ endType = 3; break;
+ }
+ } else if (c == Quote.Up)
+ Quote.Count++;
+ s++;
+ }
+ if (s > 0) { // process non-empty segments
+ switch (sc.state) {
+ case SCE_PL_STRING:
+ case SCE_PL_STRING_QQ:
+ case SCE_PL_BACKTICKS:
+ InterpolateSegment(sc, s);
+ break;
+ case SCE_PL_STRING_QX:
+ if (Quote.Up != '\'') {
+ InterpolateSegment(sc, s);
+ break;
+ }
+ // (continued for ' delim)
+ default: // non-interpolated path
+ sc.Forward(s);
+ }
+ }
+ if (endType == 2) {
+ sc.Forward();
+ } else if (endType == 3)
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_SUB_PROTOTYPE: {
+ int i = 0;
+ // forward scan; must all be valid proto characters
+ while (setSubPrototype.Contains(sc.GetRelative(i)))
+ i++;
+ if (sc.GetRelative(i) == ')') { // valid sub prototype
+ sc.Forward(i);
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ } else {
+ // abandon prototype, restart from '('
+ sc.ChangeState(SCE_PL_OPERATOR);
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_PL_FORMAT: {
+ sc.Complete();
+ if (sc.Match('.')) {
+ sc.Forward();
+ if (sc.atLineEnd || ((sc.ch == '\r' && sc.chNext == '\n')))
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ while (!sc.atLineEnd)
+ sc.Forward();
+ }
+ break;
+ case SCE_PL_ERROR:
+ break;
+ }
+ // Needed for specific continuation styles (one follows the other)
+ switch (sc.state) {
+ // continued from SCE_PL_WORD
+ case SCE_PL_FORMAT_IDENT:
+ // occupies HereDoc state 3 to avoid clashing with HERE docs
+ if (IsASpaceOrTab(sc.ch)) { // skip whitespace
+ sc.ChangeState(SCE_PL_DEFAULT);
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+ sc.Forward();
+ sc.SetState(SCE_PL_FORMAT_IDENT);
+ }
+ if (setFormatStart.Contains(sc.ch)) { // identifier or '='
+ if (sc.ch != '=') {
+ do {
+ sc.Forward();
+ } while (setFormat.Contains(sc.ch));
+ }
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+ sc.Forward();
+ if (sc.ch == '=') {
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ HereDoc.State = 3;
+ } else {
+ // invalid indentifier; inexact fallback, but hey
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ } else {
+ sc.ChangeState(SCE_PL_DEFAULT); // invalid indentifier
+ }
+ backFlag = BACK_NONE;
+ break;
+ }
+
+ // Must check end of HereDoc states here before default state is handled
+ if (HereDoc.State == 1 && sc.atLineEnd) {
+ // Begin of here-doc (the line after the here-doc delimiter):
+ // Lexically, the here-doc starts from the next line after the >>, but the
+ // first line of here-doc seem to follow the style of the last EOL sequence
+ int st_new = SCE_PL_HERE_QQ;
+ HereDoc.State = 2;
+ if (HereDoc.Quoted) {
+ if (sc.state == SCE_PL_HERE_DELIM) {
+ // Missing quote at end of string! We are stricter than perl.
+ // Colour here-doc anyway while marking this bit as an error.
+ sc.ChangeState(SCE_PL_ERROR);
+ }
+ switch (HereDoc.Quote) {
+ case '\'':
+ st_new = SCE_PL_HERE_Q ;
+ break;
+ case '"' :
+ st_new = SCE_PL_HERE_QQ;
+ break;
+ case '`' :
+ st_new = SCE_PL_HERE_QX;
+ break;
+ }
+ } else {
+ if (HereDoc.Quote == '\\')
+ st_new = SCE_PL_HERE_Q;
+ }
+ sc.SetState(st_new);
+ }
+ if (HereDoc.State == 3 && sc.atLineEnd) {
+ // Start of format body.
+ HereDoc.State = 0;
+ sc.SetState(SCE_PL_FORMAT);
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_PL_DEFAULT) {
+ if (IsADigit(sc.ch) ||
+ (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
+ sc.SetState(SCE_PL_NUMBER);
+ backFlag = BACK_NONE;
+ numState = PERLNUM_DECIMAL;
+ dotCount = 0;
+ if (sc.ch == '0') { // hex,bin,octal
+ if (sc.chNext == 'x' || sc.chNext == 'X') {
+ numState = PERLNUM_HEX;
+ } else if (sc.chNext == 'b' || sc.chNext == 'B') {
+ numState = PERLNUM_BINARY;
+ } else if (IsADigit(sc.chNext)) {
+ numState = PERLNUM_OCTAL;
+ }
+ if (numState != PERLNUM_DECIMAL) {
+ sc.Forward();
+ }
+ } else if (sc.ch == 'v') { // vector
+ numState = PERLNUM_V_VECTOR;
+ }
+ } else if (setWord.Contains(sc.ch)) {
+ // if immediately prefixed by '::', always a bareword
+ sc.SetState(SCE_PL_WORD);
+ if (sc.chPrev == ':' && sc.GetRelative(-2) == ':') {
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ }
+ unsigned int bk = sc.currentPos;
+ unsigned int fw = sc.currentPos + 1;
+ // first check for possible quote-like delimiter
+ if (sc.ch == 's' && !setWord.Contains(sc.chNext)) {
+ sc.ChangeState(SCE_PL_REGSUBST);
+ Quote.New(2);
+ } else if (sc.ch == 'm' && !setWord.Contains(sc.chNext)) {
+ sc.ChangeState(SCE_PL_REGEX);
+ Quote.New();
+ } else if (sc.ch == 'q' && !setWord.Contains(sc.chNext)) {
+ sc.ChangeState(SCE_PL_STRING_Q);
+ Quote.New();
+ } else if (sc.ch == 'y' && !setWord.Contains(sc.chNext)) {
+ sc.ChangeState(SCE_PL_XLAT);
+ Quote.New(2);
+ } else if (sc.Match('t', 'r') && !setWord.Contains(sc.GetRelative(2))) {
+ sc.ChangeState(SCE_PL_XLAT);
+ Quote.New(2);
+ sc.Forward();
+ fw++;
+ } else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext)
+ && !setWord.Contains(sc.GetRelative(2))) {
+ if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
+ else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);
+ else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);
+ else sc.ChangeState(SCE_PL_STRING_QW); // sc.chNext == 'w'
+ Quote.New();
+ sc.Forward();
+ fw++;
+ } else if (sc.ch == 'x' && (sc.chNext == '=' || // repetition
+ !setWord.Contains(sc.chNext) ||
+ (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
+ sc.ChangeState(SCE_PL_OPERATOR);
+ }
+ // if potentially a keyword, scan forward and grab word, then check
+ // if it's really one; if yes, disambiguation test is performed
+ // otherwise it is always a bareword and we skip a lot of scanning
+ if (sc.state == SCE_PL_WORD) {
+ while (setWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(fw))))
+ fw++;
+ if (!isPerlKeyword(styler.GetStartSegment(), fw, keywords, styler)) {
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ }
+ }
+ // if already SCE_PL_IDENTIFIER, then no ambiguity, skip this
+ // for quote-like delimiters/keywords, attempt to disambiguate
+ // to select for bareword, change state -> SCE_PL_IDENTIFIER
+ if (sc.state != SCE_PL_IDENTIFIER && bk > 0) {
+ if (disambiguateBareword(styler, bk, fw, backFlag, backPos, endPos))
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ }
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_PL_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_PL_STRING);
+ Quote.New();
+ Quote.Open(sc.ch);
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '\'') {
+ if (sc.chPrev == '&' && setWordStart.Contains(sc.chNext)) {
+ // Archaic call
+ sc.SetState(SCE_PL_IDENTIFIER);
+ } else {
+ sc.SetState(SCE_PL_CHARACTER);
+ Quote.New();
+ Quote.Open(sc.ch);
+ }
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '`') {
+ sc.SetState(SCE_PL_BACKTICKS);
+ Quote.New();
+ Quote.Open(sc.ch);
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_PL_SCALAR);
+ if (sc.chNext == '{') {
+ sc.ForwardSetState(SCE_PL_OPERATOR);
+ } else if (IsASpace(sc.chNext)) {
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ } else {
+ sc.Forward();
+ if (sc.Match('`', '`') || sc.Match(':', ':')) {
+ sc.Forward();
+ }
+ }
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '@') {
+ sc.SetState(SCE_PL_ARRAY);
+ if (setArray.Contains(sc.chNext)) {
+ // no special treatment
+ } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
+ sc.Forward(2);
+ } else if (sc.chNext == '{' || sc.chNext == '[') {
+ sc.ForwardSetState(SCE_PL_OPERATOR);
+ } else {
+ sc.ChangeState(SCE_PL_OPERATOR);
+ }
+ backFlag = BACK_NONE;
+ } else if (setPreferRE.Contains(sc.ch)) {
+ // Explicit backward peeking to set a consistent preferRE for
+ // any slash found, so no longer need to track preferRE state.
+ // Find first previous significant lexed element and interpret.
+ // A few symbols shares this code for disambiguation.
+ bool preferRE = false;
+ bool isHereDoc = sc.Match('<', '<');
+ bool hereDocSpace = false; // for: SCALAR [whitespace] '<<'
+ unsigned int bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0;
+ sc.Complete();
+ styler.Flush();
+ if (styler.StyleAt(bk) == SCE_PL_DEFAULT)
+ hereDocSpace = true;
+ skipWhitespaceComment(styler, bk);
+ if (bk == 0) {
+ // avoid backward scanning breakage
+ preferRE = true;
+ } else {
+ int bkstyle = styler.StyleAt(bk);
+ int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
+ switch (bkstyle) {
+ case SCE_PL_OPERATOR:
+ preferRE = true;
+ if (bkch == ')' || bkch == ']') {
+ preferRE = false;
+ } else if (bkch == '}') {
+ // backtrack by counting balanced brace pairs
+ // needed to test for variables like ${}, @{} etc.
+ bkstyle = styleBeforeBracePair(styler, bk);
+ if (bkstyle == SCE_PL_SCALAR
+ || bkstyle == SCE_PL_ARRAY
+ || bkstyle == SCE_PL_HASH
+ || bkstyle == SCE_PL_SYMBOLTABLE
+ || bkstyle == SCE_PL_OPERATOR) {
+ preferRE = false;
+ }
+ } else if (bkch == '+' || bkch == '-') {
+ if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1))
+ && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
+ // exceptions for operators: unary suffixes ++, --
+ preferRE = false;
+ }
+ break;
+ case SCE_PL_IDENTIFIER:
+ preferRE = true;
+ bkstyle = styleCheckIdentifier(styler, bk);
+ if ((bkstyle == 1) || (bkstyle == 2)) {
+ // inputsymbol or var with "->" or "::" before identifier
+ preferRE = false;
+ } else if (bkstyle == 3) {
+ // bare identifier, test cases follows:
+ if (sc.ch == '/') {
+ // if '/', /PATTERN/ unless digit/space immediately after '/'
+ // if '//', always expect defined-or operator to follow identifier
+ if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')
+ preferRE = false;
+ } else if (sc.ch == '*' || sc.ch == '%') {
+ if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))
+ preferRE = false;
+ } else if (sc.ch == '<') {
+ if (IsASpace(sc.chNext) || sc.chNext == '=')
+ preferRE = false;
+ }
+ }
+ break;
+ case SCE_PL_SCALAR: // for $var<< case:
+ if (isHereDoc && hereDocSpace) // if SCALAR whitespace '<<', *always* a HERE doc
+ preferRE = true;
+ break;
+ case SCE_PL_WORD:
+ preferRE = true;
+ // for HERE docs, always true
+ if (sc.ch == '/') {
+ // adopt heuristics similar to vim-style rules:
+ // keywords always forced as /PATTERN/: split, if, elsif, while
+ // everything else /PATTERN/ unless digit/space immediately after '/'
+ // for '//', defined-or favoured unless special keywords
+ unsigned int bkend = bk + 1;
+ while (bk > 0 && styler.StyleAt(bk - 1) == SCE_PL_WORD) {
+ bk--;
+ }
+ if (isPerlKeyword(bk, bkend, reWords, styler))
+ break;
+ if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')
+ preferRE = false;
+ } else if (sc.ch == '*' || sc.ch == '%') {
+ if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))
+ preferRE = false;
+ } else if (sc.ch == '<') {
+ if (IsASpace(sc.chNext) || sc.chNext == '=')
+ preferRE = false;
+ }
+ break;
+
+ // other styles uses the default, preferRE=false
+ case SCE_PL_POD:
+ case SCE_PL_HERE_Q:
+ case SCE_PL_HERE_QQ:
+ case SCE_PL_HERE_QX:
+ preferRE = true;
+ break;
+ }
+ }
+ backFlag = BACK_NONE;
+ if (isHereDoc) { // handle '<<', HERE doc
+ if (preferRE) {
+ sc.SetState(SCE_PL_HERE_DELIM);
+ HereDoc.State = 0;
+ } else { // << operator
+ sc.SetState(SCE_PL_OPERATOR);
+ sc.Forward();
+ }
+ } else if (sc.ch == '*') { // handle '*', typeglob
+ if (preferRE) {
+ sc.SetState(SCE_PL_SYMBOLTABLE);
+ if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
+ sc.Forward(2);
+ } else if (sc.chNext == '{') {
+ sc.ForwardSetState(SCE_PL_OPERATOR);
+ } else {
+ sc.Forward();
+ }
+ } else {
+ sc.SetState(SCE_PL_OPERATOR);
+ if (sc.chNext == '*') // exponentiation
+ sc.Forward();
+ }
+ } else if (sc.ch == '%') { // handle '%', hash
+ if (preferRE) {
+ sc.SetState(SCE_PL_HASH);
+ if (setHash.Contains(sc.chNext)) {
+ sc.Forward();
+ } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
+ sc.Forward(2);
+ } else if (sc.chNext == '{') {
+ sc.ForwardSetState(SCE_PL_OPERATOR);
+ } else {
+ sc.ChangeState(SCE_PL_OPERATOR);
+ }
+ } else {
+ sc.SetState(SCE_PL_OPERATOR);
+ }
+ } else if (sc.ch == '<') { // handle '<', inputsymbol
+ if (preferRE) {
+ // forward scan
+ int i = inputsymbolScan(styler, sc.currentPos, endPos);
+ if (i > 0) {
+ sc.SetState(SCE_PL_IDENTIFIER);
+ sc.Forward(i);
+ } else {
+ sc.SetState(SCE_PL_OPERATOR);
+ }
+ } else {
+ sc.SetState(SCE_PL_OPERATOR);
+ }
+ } else { // handle '/', regexp
+ if (preferRE) {
+ sc.SetState(SCE_PL_REGEX);
+ Quote.New();
+ Quote.Open(sc.ch);
+ } else { // / and // operators
+ sc.SetState(SCE_PL_OPERATOR);
+ if (sc.chNext == '/') {
+ sc.Forward();
+ }
+ }
+ }
+ } else if (sc.ch == '=' // POD
+ && setPOD.Contains(sc.chNext)
+ && sc.atLineStart) {
+ sc.SetState(SCE_PL_POD);
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) { // extended '-' cases
+ unsigned int bk = sc.currentPos;
+ unsigned int fw = 2;
+ if (setSingleCharOp.Contains(sc.chNext) && // file test operators
+ !setWord.Contains(sc.GetRelative(2))) {
+ sc.SetState(SCE_PL_WORD);
+ } else {
+ // nominally a minus and bareword; find extent of bareword
+ while (setWord.Contains(sc.GetRelative(fw)))
+ fw++;
+ sc.SetState(SCE_PL_OPERATOR);
+ }
+ // force to bareword for hash key => or {variable literal} cases
+ if (disambiguateBareword(styler, bk, bk + fw, backFlag, backPos, endPos) & 2) {
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ }
+ backFlag = BACK_NONE;
+ } else if (sc.ch == '(' && sc.currentPos > 0) { // '(' or subroutine prototype
+ sc.Complete();
+ if (styleCheckSubPrototype(styler, sc.currentPos - 1)) {
+ sc.SetState(SCE_PL_SUB_PROTOTYPE);
+ backFlag = BACK_NONE;
+ } else {
+ sc.SetState(SCE_PL_OPERATOR);
+ }
+ } else if (setPerlOperator.Contains(sc.ch)) { // operators
+ sc.SetState(SCE_PL_OPERATOR);
+ if (sc.Match('.', '.')) { // .. and ...
+ sc.Forward();
+ if (sc.chNext == '.') sc.Forward();
+ }
+ } else if (sc.ch == 4 || sc.ch == 26) { // ^D and ^Z ends valid perl source
+ sc.SetState(SCE_PL_DATASECTION);
+ } else {
+ // keep colouring defaults
+ sc.Complete();
+ }
+ }
+ }
+ sc.Complete();
+ if (sc.state == SCE_PL_HERE_Q
+ || sc.state == SCE_PL_HERE_QQ
+ || sc.state == SCE_PL_HERE_QX
+ || sc.state == SCE_PL_FORMAT) {
+ styler.ChangeLexerState(sc.currentPos, styler.Length());
+ }
+ sc.Complete();
+}
+
+#define PERL_HEADFOLD_SHIFT 4
+#define PERL_HEADFOLD_MASK 0xF0
+
+void SCI_METHOD LexerPerl::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+
+ // Backtrack to previous line in case need to fix its fold status
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+
+ int levelPrev = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
+ int styleNext = styler.StyleAt(startPos);
+ // Used at end of line to determine if the line was a package definition
+ bool isPackageLine = false;
+ int podHeading = 0;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;
+ // Comment folding
+ if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
+ if (!IsCommentLine(lineCurrent - 1, styler)
+ && IsCommentLine(lineCurrent + 1, styler))
+ levelCurrent++;
+ else if (IsCommentLine(lineCurrent - 1, styler)
+ && !IsCommentLine(lineCurrent + 1, styler))
+ levelCurrent--;
+ }
+ // {} [] block folding
+ if (style == SCE_PL_OPERATOR) {
+ if (ch == '{') {
+ if (options.foldAtElse && levelCurrent < levelPrev)
+ --levelPrev;
+ levelCurrent++;
+ } else if (ch == '}') {
+ levelCurrent--;
+ }
+ if (ch == '[') {
+ if (options.foldAtElse && levelCurrent < levelPrev)
+ --levelPrev;
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
+ }
+ // POD folding
+ if (options.foldPOD && atLineStart) {
+ if (style == SCE_PL_POD) {
+ if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
+ levelCurrent++;
+ else if (styler.Match(i, "=cut"))
+ levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;
+ else if (styler.Match(i, "=head"))
+ podHeading = PodHeadingLevel(i, styler);
+ } else if (style == SCE_PL_DATASECTION) {
+ if (ch == '=' && isascii(chNext) && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
+ levelCurrent++;
+ else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
+ levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;
+ else if (styler.Match(i, "=head"))
+ podHeading = PodHeadingLevel(i, styler);
+ // if package used or unclosed brace, level > SC_FOLDLEVELBASE!
+ // reset needed as level test is vs. SC_FOLDLEVELBASE
+ else if (stylePrevCh != SCE_PL_DATASECTION)
+ levelCurrent = SC_FOLDLEVELBASE;
+ }
+ }
+ // package folding
+ if (options.foldPackage && atLineStart) {
+ if (IsPackageLine(lineCurrent, styler)
+ && !IsPackageLine(lineCurrent + 1, styler))
+ isPackageLine = true;
+ }
+
+ //heredoc folding
+ switch (style) {
+ case SCE_PL_HERE_QQ :
+ case SCE_PL_HERE_Q :
+ case SCE_PL_HERE_QX :
+ switch (stylePrevCh) {
+ case SCE_PL_HERE_QQ :
+ case SCE_PL_HERE_Q :
+ case SCE_PL_HERE_QX :
+ //do nothing;
+ break;
+ default :
+ levelCurrent++;
+ break;
+ }
+ break;
+ default:
+ switch (stylePrevCh) {
+ case SCE_PL_HERE_QQ :
+ case SCE_PL_HERE_Q :
+ case SCE_PL_HERE_QX :
+ levelCurrent--;
+ break;
+ default :
+ //do nothing;
+ break;
+ }
+ break;
+ }
+
+ //explicit folding
+ if (options.foldCommentExplicit && style == SCE_PL_COMMENTLINE && ch == '#') {
+ if (chNext == '{') {
+ levelCurrent++;
+ } else if (levelCurrent > SC_FOLDLEVELBASE && chNext == '}') {
+ levelCurrent--;
+ }
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ // POD headings occupy bits 7-4, leaving some breathing room for
+ // non-standard practice -- POD sections stuck in blocks, etc.
+ if (podHeading > 0) {
+ levelCurrent = (lev & ~PERL_HEADFOLD_MASK) | (podHeading << PERL_HEADFOLD_SHIFT);
+ lev = levelCurrent - 1;
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ podHeading = 0;
+ }
+ // Check if line was a package declaration
+ // because packages need "special" treatment
+ if (isPackageLine) {
+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ levelCurrent = SC_FOLDLEVELBASE + 1;
+ isPackageLine = false;
+ }
+ lev |= levelCurrent << 16;
+ if (visibleChars == 0 && options.foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ chPrev = ch;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+LexerModule lmPerl(SCLEX_PERL, LexerPerl::LexerFactoryPerl, "perl", perlWordListDesc, 8);
--- /dev/null
+// Scintilla source code edit control
+// @file LexPowerPro.cxx
+// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com
+// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net)
+//
+// Lexer code heavily borrowed from:
+// LexAU3.cxx by Jos van der Zande
+// LexCPP.cxx by Neil Hodgson
+// LexVB.cxx by Neil Hodgson
+//
+// Changes:
+// 2008-10-25 - Initial release
+// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that
+// local isFunction = "" and local functions = "" don't get falsely highlighted
+// 2008-12-14 - Added bounds checking for szFirstWord and szDo
+// - Replaced SetOfCharacters with CharacterSet
+// - Made sure that CharacterSet::Contains is passed only positive values
+// - Made sure that the return value of Accessor::SafeGetCharAt is positive before
+// passing to functions that require positive values like isspacechar()
+// - Removed unused visibleChars processing from ColourisePowerProDoc()
+// - Fixed bug with folding logic where line continuations didn't end where
+// they were supposed to
+// - Moved all helper functions to the top of the file
+// 2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented
+// - Modified HasFunction function to be a bit more robust
+// - Renamed HasFunction function to IsFunction
+// - Cleanup
+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <string.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 IsStreamCommentStyle(int style) {
+ return style == SCE_POWERPRO_COMMENTBLOCK;
+}
+
+static inline bool IsLineEndChar(unsigned char ch) {
+ return ch == 0x0a //LF
+ || ch == 0x0c //FF
+ || ch == 0x0d; //CR
+}
+
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
+{
+ int startPos = styler.LineStart(szLine);
+ int endPos = styler.LineStart(szLine + 1) - 2;
+ while (startPos < endPos)
+ {
+ char stylech = styler.StyleAt(startPos);
+ if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
+ char ch = styler.SafeGetCharAt(endPos);
+ char chPrev = styler.SafeGetCharAt(endPos - 1);
+ char chPrevPrev = styler.SafeGetCharAt(endPos - 2);
+ if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) )
+ return (chPrevPrev == ';' && chPrev == ';' && ch == '+');
+ }
+ endPos--; // skip to next char
+ }
+ return false;
+}
+
+// Routine to find first none space on the current line and return its Style
+// needed for comment lines not starting on pos 1
+static int GetStyleFirstWord(int szLine, Accessor &styler)
+{
+ int startPos = styler.LineStart(szLine);
+ int endPos = styler.LineStart(szLine + 1) - 1;
+ char ch = styler.SafeGetCharAt(startPos);
+
+ while (ch > 0 && isspacechar(ch) && startPos < endPos)
+ {
+ startPos++; // skip to next char
+ ch = styler.SafeGetCharAt(startPos);
+ }
+ return styler.StyleAt(startPos);
+}
+
+//returns true if there is a function to highlight
+//used to highlight <name> in 'function <name>'
+//note:
+// sample line (without quotes): "\tfunction asdf()
+// currentPos will be the position of 'a'
+static bool IsFunction(Accessor &styler, unsigned int currentPos) {
+
+ const char function[10] = "function "; //10 includes \0
+ unsigned int numberOfCharacters = sizeof(function) - 1;
+ unsigned int position = currentPos - numberOfCharacters;
+
+ //compare each character with the letters in the function array
+ //return false if ALL don't match
+ for (unsigned int i = 0; i < numberOfCharacters; i++) {
+ char c = styler.SafeGetCharAt(position++);
+ if (c != function[i])
+ return false;
+ }
+
+ //make sure that there are only spaces (or tabs) between the beginning
+ //of the line and the function declaration
+ position = currentPos - numberOfCharacters - 1; //-1 to move to char before 'function'
+ for (unsigned int j = 0; j < 16; j++) { //check up to 16 preceeding characters
+ char c = styler.SafeGetCharAt(position--, '\0'); //if can't read char, return NUL (past beginning of document)
+ if (c <= 0) //reached beginning of document
+ return true;
+ if (c > 0 && IsLineEndChar(c))
+ return true;
+ else if (c > 0 && !IsASpaceOrTab(c))
+ return false;
+ }
+
+ //fall-through
+ return false;
+}
+
+static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler, bool caseSensitive) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ //define the character sets
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ char s_save[100]; //for last line highlighting
+
+ //are there only spaces between the first letter of the line and the beginning of the line
+ bool onlySpaces = true;
+
+ for (; sc.More(); sc.Forward()) {
+
+ // save the total current word for eof processing
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+
+ if ((sc.ch > 0) && setWord.Contains(sc.ch))
+ {
+ strcpy(s_save,s);
+ int tp = static_cast<int>(strlen(s_save));
+ if (tp < 99) {
+ s_save[tp] = static_cast<char>(tolower(sc.ch));
+ s_save[tp+1] = '\0';
+ }
+ }
+
+ if (sc.atLineStart) {
+ if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
+ // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which
+ // ends with a line continuation by locking in the state upto this position.
+ sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
+ }
+ }
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_POWERPRO_OPERATOR:
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ break;
+
+ case SCE_POWERPRO_NUMBER:
+
+ if (!IsADigit(sc.ch))
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+
+ break;
+
+ case SCE_POWERPRO_IDENTIFIER:
+ //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized
+ if ((sc.ch > 0) && !setWord.Contains(sc.ch)){ // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately
+ char s[1000];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_POWERPRO_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_POWERPRO_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_POWERPRO_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_POWERPRO_WORD4);
+ }
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_LINECONTINUE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ } else if (sc.Match('/', '*') || sc.Match('/', '/')) {
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_COMMENTBLOCK:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_DOUBLEQUOTEDSTRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_POWERPRO_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_SINGLEQUOTEDSTRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_POWERPRO_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+
+ case SCE_POWERPRO_VERBATIM:
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+ }
+ }
+ break;
+
+ case SCE_POWERPRO_ALTQUOTE:
+ if (sc.ch == '#') {
+ if (sc.chNext == '#') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+ }
+ }
+ break;
+
+ case SCE_POWERPRO_FUNCTION:
+ if (isspacechar(sc.ch) || sc.ch == '(') {
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_POWERPRO_DEFAULT) {
+ if (sc.Match('?', '\"')) {
+ sc.SetState(SCE_POWERPRO_VERBATIM);
+ sc.Forward();
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_POWERPRO_NUMBER);
+ }else if (sc.Match('?','#')) {
+ if (sc.ch == '?' && sc.chNext == '#') {
+ sc.SetState(SCE_POWERPRO_ALTQUOTE);
+ sc.Forward();
+ }
+ } else if (IsFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
+ sc.SetState(SCE_POWERPRO_FUNCTION);
+ } else if (onlySpaces && sc.ch == '@') { //alternate function definition [label]
+ sc.SetState(SCE_POWERPRO_FUNCTION);
+ } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
+ sc.SetState(SCE_POWERPRO_IDENTIFIER);
+ } else if (sc.Match(";;+")) {
+ sc.SetState(SCE_POWERPRO_LINECONTINUE);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_POWERPRO_COMMENTBLOCK);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(SCE_POWERPRO_COMMENTLINE);
+ } else if (onlySpaces && sc.ch == ';') { //legacy comment that can only have blank space in front of it
+ sc.SetState(SCE_POWERPRO_COMMENTLINE);
+ } else if (sc.Match(";;")) {
+ sc.SetState(SCE_POWERPRO_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_POWERPRO_OPERATOR);
+ }
+ }
+
+ //maintain a record of whether or not all the preceding characters on
+ //a line are space characters
+ if (onlySpaces && !IsASpaceOrTab(sc.ch))
+ onlySpaces = false;
+
+ //reset when starting a new line
+ if (sc.atLineEnd)
+ onlySpaces = true;
+ }
+
+ //*************************************
+ // Colourize the last word correctly
+ //*************************************
+ if (sc.state == SCE_POWERPRO_IDENTIFIER)
+ {
+ if (keywords.InList(s_save)) {
+ sc.ChangeState(SCE_POWERPRO_WORD);
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ else if (keywords2.InList(s_save)) {
+ sc.ChangeState(SCE_POWERPRO_WORD2);
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ else if (keywords3.InList(s_save)) {
+ sc.ChangeState(SCE_POWERPRO_WORD3);
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ else if (keywords4.InList(s_save)) {
+ sc.ChangeState(SCE_POWERPRO_WORD4);
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ else {
+ sc.SetState(SCE_POWERPRO_DEFAULT);
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ //define the character sets
+ CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
+ CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+ //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
+ bool isFoldingAll = true;
+
+ int endPos = startPos + length;
+ int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
+
+ // get settings from the config files for folding comments and preprocessor lines
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
+ bool foldCompact = true;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ isFoldingAll = false;
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ // vars for style of previous/current/next lines
+ int style = GetStyleFirstWord(lineCurrent,styler);
+ int stylePrev = 0;
+
+ // find the first previous line without continuation character at the end
+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler))
+ || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+
+ if (lineCurrent > 0) {
+ stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
+ }
+
+ // vars for getting first word to check for keywords
+ bool isFirstWordStarted = false;
+ bool isFirstWordEnded = false;
+
+ const unsigned int FIRST_WORD_MAX_LEN = 10;
+ char szFirstWord[FIRST_WORD_MAX_LEN] = "";
+ unsigned int firstWordLen = 0;
+
+ char szDo[3]="";
+ int szDolen = 0;
+ bool isDoLastWord = false;
+
+ // var for indentlevel
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+
+ int visibleChars = 0;
+ int functionCount = 0;
+
+ char chNext = styler.SafeGetCharAt(startPos);
+ char chPrev = '\0';
+ char chPrevPrev = '\0';
+ char chPrevPrevPrev = '\0';
+
+ for (int i = startPos; i < endPos; i++) {
+
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch > 0) && setWord.Contains(ch))
+ visibleChars++;
+
+ // get the syle for the current character neede to check in comment
+ int stylech = styler.StyleAt(i);
+
+ // start the capture of the first word
+ if (!isFirstWordStarted && (ch > 0)) {
+ if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') {
+ isFirstWordStarted = true;
+ if (firstWordLen < FIRST_WORD_MAX_LEN - 1) {
+ szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
+ szFirstWord[firstWordLen] = '\0';
+ }
+ }
+ } // continue capture of the first word on the line
+ else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) {
+ if (!setWord.Contains(ch)) {
+ isFirstWordEnded = true;
+ }
+ else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) {
+ szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
+ szFirstWord[firstWordLen] = '\0';
+ }
+ }
+
+ if (stylech != SCE_POWERPRO_COMMENTLINE) {
+
+ //reset isDoLastWord if we find a character(ignoring spaces) after 'do'
+ if (isDoLastWord && (ch > 0) && setWord.Contains(ch))
+ isDoLastWord = false;
+
+ // --find out if the word "do" is the last on a "if" line--
+ // collect each letter and put it into a buffer 2 chars long
+ // if we end up with "do" in the buffer when we reach the end of
+ // the line, "do" was the last word on the line
+ if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "if") == 0) {
+ if (szDolen == 2) {
+ szDo[0] = szDo[1];
+ szDo[1] = static_cast<char>(tolower(ch));
+ szDo[2] = '\0';
+
+ if (strcmp(szDo, "do") == 0)
+ isDoLastWord = true;
+
+ } else if (szDolen < 2) {
+ szDo[szDolen++] = static_cast<char>(tolower(ch));
+ szDo[szDolen] = '\0';
+ }
+ }
+ }
+
+ // End of Line found so process the information
+ if ((ch == '\r' && chNext != '\n') // \r\n
+ || ch == '\n' // \n
+ || i == endPos) { // end of selection
+
+ // **************************
+ // Folding logic for Keywords
+ // **************************
+
+ // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
+ // and we are not inside a commentblock.
+ if (firstWordLen > 0
+ && chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';'
+ && (!IsStreamCommentStyle(style) || foldInComment) ) {
+
+ // only fold "if" last keyword is "then" (else its a one line if)
+ if (strcmp(szFirstWord, "if") == 0 && isDoLastWord)
+ levelNext++;
+
+ // create new fold for these words
+ if (strcmp(szFirstWord, "for") == 0)
+ levelNext++;
+
+ //handle folding for functions/labels
+ //Note: Functions and labels don't have an explicit end like [end function]
+ // 1. functions/labels end at the start of another function
+ // 2. functions/labels end at the end of the file
+ if ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) {
+ if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
+
+ if (functionCount > 0) {
+ levelCurrent--;
+ } else {
+ levelNext++;
+ }
+ functionCount++;
+
+ } else { //if just folding a small piece (by clicking on the minus sign next to the word)
+ levelCurrent--;
+ }
+ }
+
+ // end the fold for these words before the current line
+ if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "endfor") == 0) {
+ levelNext--;
+ levelCurrent--;
+ }
+
+ // end the fold for these words before the current line and Start new fold
+ if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 )
+ levelCurrent--;
+
+ }
+ // Preprocessor and Comment folding
+ int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
+
+ // *********************************
+ // Folding logic for Comment blocks
+ // *********************************
+ if (foldComment && IsStreamCommentStyle(style)) {
+
+ // Start of a comment block
+ if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) {
+ levelNext++;
+ } // fold till the last line for normal comment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && styleNext != SCE_POWERPRO_COMMENTLINE
+ && stylePrev == SCE_POWERPRO_COMMENTLINE
+ && style == SCE_POWERPRO_COMMENTLINE) {
+ levelNext--;
+ } // fold till the one but last line for Blockcomment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && styleNext != SCE_POWERPRO_COMMENTBLOCK
+ && style == SCE_POWERPRO_COMMENTBLOCK) {
+ levelNext--;
+ levelCurrent--;
+ }
+ }
+
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
+
+ // reset values for the next line
+ lineCurrent++;
+ stylePrev = style;
+ style = styleNext;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+
+ // if the last characters are ;;+ then don't reset since the line continues on the next line.
+ if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') {
+ firstWordLen = 0;
+ szDolen = 0;
+ isFirstWordStarted = false;
+ isFirstWordEnded = false;
+ isDoLastWord = false;
+
+ //blank out first word
+ for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++)
+ szFirstWord[i] = '\0';
+ }
+ }
+
+ // save the last processed characters
+ if ((ch > 0) && !isspacechar(ch)) {
+ chPrevPrevPrev = chPrevPrev;
+ chPrevPrev = chPrev;
+ chPrev = ch;
+ }
+ }
+
+ //close folds on the last line - without this a 'phantom'
+ //fold can appear when an open fold is on the last line
+ //this can occur because functions and labels don't have an explicit end
+ if (lineCurrent >= lastLine) {
+ int lev = 0;
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ styler.SetLevel(lineCurrent, lev);
+ }
+
+}
+
+static const char * const powerProWordLists[] = {
+ "Keyword list 1",
+ "Keyword list 2",
+ "Keyword list 3",
+ "Keyword list 4",
+ 0,
+ };
+
+static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);
+
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPowerShell.cxx
+ ** Lexer for PowerShell scripts.
+ **/
+// Copyright 2008 by Tim Gerundt <tim@gerundt.de>
+// 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
+
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+ return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
+}
+
+static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_POWERSHELL_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {
+ if (sc.ch == '>' && sc.chPrev == '#') {
+ sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_STRING) {
+ // This is a doubles quotes string
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_CHARACTER) {
+ // This is a single quote string
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_NUMBER) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_VARIABLE) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_OPERATOR) {
+ if (!isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_POWERSHELL_DEFAULT);
+ }
+ } else if (sc.state == SCE_POWERSHELL_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_CMDLET);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_ALIAS);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_FUNCTION);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_USER1);
+ }
+ sc.SetState(SCE_POWERSHELL_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_POWERSHELL_DEFAULT) {
+ if (sc.ch == '#') {
+ sc.SetState(SCE_POWERSHELL_COMMENT);
+ } else if (sc.ch == '<' && sc.chNext == '#') {
+ sc.SetState(SCE_POWERSHELL_COMMENTSTREAM);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_POWERSHELL_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_POWERSHELL_CHARACTER);
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_POWERSHELL_VARIABLE);
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_POWERSHELL_NUMBER);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_POWERSHELL_OPERATOR);
+ } else if (IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_POWERSHELL_IDENTIFIER);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldPowerShellDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_POWERSHELL_OPERATOR) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ } else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) {
+ if (stylePrev != SCE_POWERSHELL_COMMENTSTREAM) {
+ levelNext++;
+ } else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM) {
+ levelNext--;
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ }
+}
+
+static const char * const powershellWordLists[] = {
+ "Commands",
+ "Cmdlets",
+ "Aliases",
+ "Functions",
+ "User1",
+ 0
+};
+
+LexerModule lmPowerShell(SCLEX_POWERSHELL, ColourisePowerShellDoc, "powershell", FoldPowerShellDoc, powershellWordLists);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexProgress.cxx
+ ** Lexer for Progress 4GL.
+ ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>
+ **/
+// Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+/** TODO:
+WebSpeed support in html lexer
+Support "end triggers" expression of the triggers phrase
+Support more than 6 comments levels
+**/
+#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 IsAWordChar(int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalpha(ch) || ch == '_');
+}
+
+enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0
+
+static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords1 = *keywordlists[0]; // regular keywords
+ WordList &keywords2 = *keywordlists[1]; // block opening keywords, only when SentenceStart
+ WordList &keywords3 = *keywordlists[2]; // block opening keywords
+ //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented
+
+
+ int visibleChars = 0;
+ int mask;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart) {
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ }
+
+ // Handle line continuation generically.
+ if ((sc.state & 0xf) < SCE_4GL_COMMENT1) {
+ if (sc.ch == '~') {
+ if (sc.chNext > ' ') {
+ // skip special char after ~
+ sc.Forward();
+ continue;
+ }
+ else {
+ // Skip whitespace between ~ and EOL
+ while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) {
+ sc.Forward();
+ }
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ sc.Forward();
+ continue;
+ }
+ }
+ }
+ }
+ // Determine if a new state should be terminated.
+ mask = sc.state & 0x10;
+ switch (sc.state & 0xf) {
+ case SCE_4GL_OPERATOR:
+ sc.SetState(SCE_4GL_DEFAULT | mask);
+ break;
+ case SCE_4GL_NUMBER:
+ if (!(IsADigit(sc.ch))) {
+ sc.SetState(SCE_4GL_DEFAULT | mask);
+ }
+ break;
+ case SCE_4GL_IDENTIFIER:
+ if (!IsAWordChar(sc.ch) && sc.ch != '-') {
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if ((((sc.state & 0x10) == 0) && keywords2.InList(s)) || keywords3.InList(s)) {
+ sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);
+ }
+ else if (keywords1.InList(s)) {
+ if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') ||
+ (s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) {
+ sc.ChangeState(SCE_4GL_END | ResetSentenceStart);
+ }
+ else if ((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') ||
+ (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) {
+ sc.ChangeState(SCE_4GL_WORD & SetSentenceStart);
+ }
+ else {
+ sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart);
+ }
+ }
+ sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10));
+ }
+ break;
+ case SCE_4GL_PREPROCESSOR:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);
+ }
+ /* code removed to allow comments inside preprocessor
+ else if (sc.ch == '*' && sc.chNext == '/') {
+ sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState); } */
+ break;
+ case SCE_4GL_STRING:
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+ }
+ break;
+ case SCE_4GL_CHARACTER:
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+ }
+ break;
+ default:
+ if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) {
+ if (sc.ch == '*' && sc.chNext == '/') {
+ sc.Forward();
+ if ((sc.state & 0xf) == SCE_4GL_COMMENT1) {
+ sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+ }
+ else
+ sc.SetState((sc.state & 0x1f) - 1);
+ } else if (sc.ch == '/' && sc.chNext == '*') {
+ sc.Forward();
+ sc.SetState((sc.state & 0x1f) + 1);
+ }
+ }
+ }
+
+ // Determine if a new state should be entered.
+ mask = sc.state & 0x10;
+ if ((sc.state & 0xf) == SCE_4GL_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart);
+ } else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {
+ sc.SetState(SCE_4GL_IDENTIFIER | mask);
+ } else if (sc.ch == '/' && sc.chNext == '*') {
+ sc.SetState(SCE_4GL_COMMENT1 | mask);
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_4GL_STRING | ResetSentenceStart);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart);
+ } else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) {
+ sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart);
+ // Skip whitespace between & and preprocessor word
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ // Handle syntactical line termination
+ } else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {
+ sc.SetState(sc.state & SetSentenceStart);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ /* This code allows highlight of handles. Alas, it would cause the phrase "last-event:function"
+ to be recognized as a BlockBegin */
+
+ if (sc.ch == ':')
+ sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
+ /* else */
+ sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);
+ }
+ }
+
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return (style & 0xf) >= SCE_4GL_COMMENT1 ;
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle,
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = static_cast<char>(tolower(styler[startPos]));
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) {
+ levelNext++;
+ }
+ else if ((style & 0xf) == SCE_4GL_END && (ch == 'e' || ch == 'f')) {
+ levelNext--;
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+}
+
+static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ FoldNoBox4glDoc(startPos, length, initStyle, styler);
+}
+
+static const char * const FglWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Unused",
+ "Global classes and typedefs",
+ 0,
+ };
+
+LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexPython.cxx
+ ** Lexer for Python.
+ **/
+// Copyright 1998-2002 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
+
+/* kwCDef, kwCTypeName only used for Cython */
+enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
+
+static const int indicatorWhitespace = 1;
+
+static bool IsPyComment(Accessor &styler, int pos, int len) {
+ return len > 0 && styler[pos] == '#';
+}
+
+enum literalsAllowed { litNone=0, litU=1, litB=2};
+
+static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
+ return
+ ((allowed & litB) && (ch == 'b' || ch == 'B')) ||
+ ((allowed & litU) && (ch == 'u' || ch == 'U'));
+}
+
+static bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
+ if (ch == '\'' || ch == '"')
+ return true;
+ if (IsPyStringTypeChar(ch, allowed)) {
+ if (chNext == '"' || chNext == '\'')
+ return true;
+ if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
+ return true;
+ }
+ if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\''))
+ return true;
+
+ return false;
+}
+
+/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
+static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex, literalsAllowed allowed) {
+ char ch = styler.SafeGetCharAt(i);
+ char chNext = styler.SafeGetCharAt(i + 1);
+
+ // Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
+ if (ch == 'r' || ch == 'R') {
+ i++;
+ ch = styler.SafeGetCharAt(i);
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (IsPyStringTypeChar(ch, allowed)) {
+ if (chNext == 'r' || chNext == 'R')
+ i += 2;
+ else
+ i += 1;
+ ch = styler.SafeGetCharAt(i);
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+
+ if (ch != '"' && ch != '\'') {
+ *nextIndex = i + 1;
+ return SCE_P_DEFAULT;
+ }
+
+ if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {
+ *nextIndex = i + 3;
+
+ if (ch == '"')
+ return SCE_P_TRIPLEDOUBLE;
+ else
+ return SCE_P_TRIPLE;
+ } else {
+ *nextIndex = i + 1;
+
+ if (ch == '"')
+ return SCE_P_STRING;
+ else
+ return SCE_P_CHARACTER;
+ }
+}
+
+static inline bool IsAWordChar(int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ int endPos = startPos + length;
+
+ // Backtrack to previous line in case need to fix its tab whinging
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ // Look for backslash-continued lines
+ while (lineCurrent > 0) {
+ int eolPos = styler.LineStart(lineCurrent) - 1;
+ int eolStyle = styler.StyleAt(eolPos);
+ if (eolStyle == SCE_P_STRING
+ || eolStyle == SCE_P_CHARACTER
+ || eolStyle == SCE_P_STRINGEOL) {
+ lineCurrent -= 1;
+ } else {
+ break;
+ }
+ }
+ startPos = styler.LineStart(lineCurrent);
+ }
+ initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1);
+ }
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+
+ // property tab.timmy.whinge.level
+ // For Python code, checks whether indenting is consistent.
+ // The default, 0 turns off indentation checking,
+ // 1 checks whether each line is potentially inconsistent with the previous line,
+ // 2 checks whether any space characters occur before a tab character in the indentation,
+ // 3 checks whether any spaces are in the indentation, and
+ // 4 checks for any tab characters in the indentation.
+ // 1 is a good level to use.
+ const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
+
+ // property lexer.python.literals.binary
+ // Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.
+ bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0;
+
+ // property lexer.python.strings.u
+ // Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.
+ literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone;
+
+ // property lexer.python.strings.b
+ // Set to 0 to not recognise Python 3 bytes literals b"x".
+ if (styler.GetPropertyInt("lexer.python.strings.b", 1))
+ allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
+
+ // property lexer.python.strings.over.newline
+ // Set to 1 to allow strings to span newline characters.
+ bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
+
+ // property lexer.python.keywords2.no.sub.identifiers
+ // When enabled, it will not style keywords2 items that are used as a sub-identifier.
+ // Example: when set, will not highlight "foo.open" when "open" is a keywords2 item.
+ const bool keywords2NoSubIdentifiers = styler.GetPropertyInt("lexer.python.keywords2.no.sub.identifiers") != 0;
+
+ initStyle = initStyle & 31;
+ if (initStyle == SCE_P_STRINGEOL) {
+ initStyle = SCE_P_DEFAULT;
+ }
+
+ kwType kwLast = kwOther;
+ int spaceFlags = 0;
+ styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
+ bool base_n_number = false;
+
+ StyleContext sc(startPos, endPos - startPos, initStyle, styler);
+
+ bool indentGood = true;
+ int startIndicator = sc.currentPos;
+ bool inContinuedString = false;
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart) {
+ styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
+ indentGood = true;
+ if (whingeLevel == 1) {
+ indentGood = (spaceFlags & wsInconsistent) == 0;
+ } else if (whingeLevel == 2) {
+ indentGood = (spaceFlags & wsSpaceTab) == 0;
+ } else if (whingeLevel == 3) {
+ indentGood = (spaceFlags & wsSpace) == 0;
+ } else if (whingeLevel == 4) {
+ indentGood = (spaceFlags & wsTab) == 0;
+ }
+ if (!indentGood) {
+ styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
+ startIndicator = sc.currentPos;
+ }
+ }
+
+ if (sc.atLineEnd) {
+ if ((sc.state == SCE_P_DEFAULT) ||
+ (sc.state == SCE_P_TRIPLE) ||
+ (sc.state == SCE_P_TRIPLEDOUBLE)) {
+ // Perform colourisation of white space and triple quoted strings at end of each line to allow
+ // tab marking to work inside white space and triple quoted strings
+ sc.SetState(sc.state);
+ }
+ lineCurrent++;
+ if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
+ if (inContinuedString || stringsOverNewline) {
+ inContinuedString = false;
+ } else {
+ sc.ChangeState(SCE_P_STRINGEOL);
+ sc.ForwardSetState(SCE_P_DEFAULT);
+ }
+ }
+ if (!sc.More())
+ break;
+ }
+
+ bool needEOLCheck = false;
+
+ // Check for a state end
+ if (sc.state == SCE_P_OPERATOR) {
+ kwLast = kwOther;
+ sc.SetState(SCE_P_DEFAULT);
+ } else if (sc.state == SCE_P_NUMBER) {
+ if (!IsAWordChar(sc.ch) &&
+ !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ sc.SetState(SCE_P_DEFAULT);
+ }
+ } else if (sc.state == SCE_P_IDENTIFIER) {
+ if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ int style = SCE_P_IDENTIFIER;
+ if ((kwLast == kwImport) && (strcmp(s, "as") == 0)) {
+ style = SCE_P_WORD;
+ } else if (keywords.InList(s)) {
+ style = SCE_P_WORD;
+ } else if (kwLast == kwClass) {
+ style = SCE_P_CLASSNAME;
+ } else if (kwLast == kwDef) {
+ style = SCE_P_DEFNAME;
+ } else if (kwLast == kwCDef || kwLast == kwCPDef) {
+ int pos = sc.currentPos;
+ unsigned char ch = styler.SafeGetCharAt(pos, '\0');
+ while (ch != '\0') {
+ if (ch == '(') {
+ style = SCE_P_DEFNAME;
+ break;
+ } else if (ch == ':') {
+ style = SCE_P_CLASSNAME;
+ break;
+ } else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
+ pos++;
+ ch = styler.SafeGetCharAt(pos, '\0');
+ } else {
+ break;
+ }
+ }
+ } else if (keywords2.InList(s)) {
+ if (keywords2NoSubIdentifiers) {
+ // We don't want to highlight keywords2
+ // that are used as a sub-identifier,
+ // i.e. not open in "foo.open".
+ int pos = styler.GetStartSegment() - 1;
+ if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
+ style = SCE_P_WORD2;
+ } else {
+ style = SCE_P_WORD2;
+ }
+ }
+ sc.ChangeState(style);
+ sc.SetState(SCE_P_DEFAULT);
+ if (style == SCE_P_WORD) {
+ if (0 == strcmp(s, "class"))
+ kwLast = kwClass;
+ else if (0 == strcmp(s, "def"))
+ kwLast = kwDef;
+ else if (0 == strcmp(s, "import"))
+ kwLast = kwImport;
+ else if (0 == strcmp(s, "cdef"))
+ kwLast = kwCDef;
+ else if (0 == strcmp(s, "cpdef"))
+ kwLast = kwCPDef;
+ else if (0 == strcmp(s, "cimport"))
+ kwLast = kwImport;
+ else if (kwLast != kwCDef && kwLast != kwCPDef)
+ kwLast = kwOther;
+ } else if (kwLast != kwCDef && kwLast != kwCPDef) {
+ kwLast = kwOther;
+ }
+ }
+ } else if ((sc.state == SCE_P_COMMENTLINE) || (sc.state == SCE_P_COMMENTBLOCK)) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_P_DEFAULT);
+ }
+ } else if (sc.state == SCE_P_DECORATOR) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_P_DEFAULT);
+ }
+ } else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
+ if (sc.ch == '\\') {
+ if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
+ sc.Forward();
+ }
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ inContinuedString = true;
+ } else {
+ // Don't roll over the newline.
+ sc.Forward();
+ }
+ } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
+ sc.ForwardSetState(SCE_P_DEFAULT);
+ needEOLCheck = true;
+ } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
+ sc.ForwardSetState(SCE_P_DEFAULT);
+ needEOLCheck = true;
+ }
+ } else if (sc.state == SCE_P_TRIPLE) {
+ if (sc.ch == '\\') {
+ sc.Forward();
+ } else if (sc.Match("\'\'\'")) {
+ sc.Forward();
+ sc.Forward();
+ sc.ForwardSetState(SCE_P_DEFAULT);
+ needEOLCheck = true;
+ }
+ } else if (sc.state == SCE_P_TRIPLEDOUBLE) {
+ if (sc.ch == '\\') {
+ sc.Forward();
+ } else if (sc.Match("\"\"\"")) {
+ sc.Forward();
+ sc.Forward();
+ sc.ForwardSetState(SCE_P_DEFAULT);
+ needEOLCheck = true;
+ }
+ }
+
+ if (!indentGood && !IsASpaceOrTab(sc.ch)) {
+ styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
+ startIndicator = sc.currentPos;
+ indentGood = true;
+ }
+
+ // One cdef or cpdef line, clear kwLast only at end of line
+ if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
+ kwLast = kwOther;
+ }
+
+ // State exit code may have moved on to end of line
+ if (needEOLCheck && sc.atLineEnd) {
+ lineCurrent++;
+ styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
+ if (!sc.More())
+ break;
+ }
+
+ // Check for a new state starting character
+ if (sc.state == SCE_P_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
+ base_n_number = true;
+ sc.SetState(SCE_P_NUMBER);
+ } else if (sc.ch == '0' &&
+ (sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
+ if (base2or8Literals) {
+ base_n_number = true;
+ sc.SetState(SCE_P_NUMBER);
+ } else {
+ sc.SetState(SCE_P_NUMBER);
+ sc.ForwardSetState(SCE_P_IDENTIFIER);
+ }
+ } else {
+ base_n_number = false;
+ sc.SetState(SCE_P_NUMBER);
+ }
+ } else if ((isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') {
+ sc.SetState(SCE_P_OPERATOR);
+ } else if (sc.ch == '#') {
+ sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
+ } else if (sc.ch == '@') {
+ sc.SetState(SCE_P_DECORATOR);
+ } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) {
+ unsigned int nextIndex = 0;
+ sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals));
+ while (nextIndex > (sc.currentPos + 1) && sc.More()) {
+ sc.Forward();
+ }
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_P_IDENTIFIER);
+ }
+ }
+ }
+ styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
+ sc.Complete();
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ if (ch == '#')
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+static bool IsQuoteLine(int line, Accessor &styler) {
+ int style = styler.StyleAt(styler.LineStart(line)) & 31;
+ return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+}
+
+
+static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
+ WordList *[], Accessor &styler) {
+ const int maxPos = startPos + length;
+ const int maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line
+ const int docLines = styler.GetLine(styler.Length()); // Available last line
+
+ // property fold.quotes.python
+ // This option enables folding multi-line quoted strings when using the Python lexer.
+ const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0;
+
+ const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
+
+ // Backtrack to previous non-blank line so we can determine indent level
+ // for any white space lines (needed esp. within triple quoted strings)
+ // 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)) &&
+ (!IsQuoteLine(lineCurrent, styler)))
+ break;
+ }
+ int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+
+ // Set up initial loop state
+ startPos = styler.LineStart(lineCurrent);
+ int prev_state = SCE_P_DEFAULT & 31;
+ if (lineCurrent >= 1)
+ prev_state = styler.StyleAt(startPos - 1) & 31;
+ int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));
+
+ // Process all characters to end of requested range or end of any triple quote
+ //that hangs over the end of the range. Cap processing in all cases
+ // to end of document (in case of unclosed quote at end).
+ while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {
+
+ // Gather info
+ int lev = indentCurrent;
+ int lineNext = lineCurrent + 1;
+ int indentNext = indentCurrent;
+ int quote = false;
+ if (lineNext <= docLines) {
+ // Information about next line is only available if not at end of document
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ int lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
+ int style = styler.StyleAt(lookAtPos) & 31;
+ quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+ }
+ const int quote_start = (quote && !prevQuote);
+ const int quote_continue = (quote && prevQuote);
+ if (!quote || !prevQuote)
+ indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+ if (quote)
+ indentNext = indentCurrentLevel;
+ if (indentNext & SC_FOLDLEVELWHITEFLAG)
+ indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+ if (quote_start) {
+ // Place fold point at start of triple quoted string
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (quote_continue || prevQuote) {
+ // Add level to rest of lines in the string
+ lev = lev + 1;
+ }
+
+ // Skip past any blank lines for next indent level info; we skip also
+ // comments (all comments, not just those starting in column 0)
+ // which effectively folds them into surrounding code rather
+ // than screwing up folding.
+
+ while (!quote &&
+ (lineNext < docLines) &&
+ ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
+ (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
+
+ lineNext++;
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ }
+
+ const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+ const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);
+
+ // Now set all the indent levels on the lines we skipped
+ // Do this from end to start. Once we encounter one line
+ // which is indented more than the line after the end of
+ // the comment-block, use the level of the block before
+
+ int skipLine = lineNext;
+ int skipLevel = levelAfterComments;
+
+ while (--skipLine > lineCurrent) {
+ int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+ if (foldCompact) {
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+ skipLevel = levelBeforeComments;
+
+ int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+ styler.SetLevel(skipLine, skipLevel | whiteFlag);
+ } else {
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
+ !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
+ !IsCommentLine(skipLine, styler))
+ skipLevel = levelBeforeComments;
+
+ styler.SetLevel(skipLine, skipLevel);
+ }
+ }
+
+ // Set fold header on non-quote line
+ if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+
+ // Keep track of triple quote state of previous line
+ prevQuote = quote;
+
+ // Set fold level for this line and move to next line
+ styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
+ indentCurrent = indentNext;
+ lineCurrent = lineNext;
+ }
+
+ // NOTE: Cannot set level of last line here because indentCurrent doesn't have
+ // header flag set; the loop above is crafted to take care of this case!
+ //styler.SetLevel(lineCurrent, indentCurrent);
+}
+
+static const char *const pythonWordListDesc[] = {
+ "Keywords",
+ "Highlighted identifiers",
+ 0
+};
+
+LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
+ pythonWordListDesc);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file Lexr.cxx
+ ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
+ **
+ **/
+// Copyright 1998-2002 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAnOperator(const int ch) {
+ if (isascii(ch) && isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||
+ ch == '?' || ch == ':' || ch == '*' || ch == '/' ||
+ ch == '^' || ch == '<' || ch == '>' || ch == '=' ||
+ ch == '&' || ch == '|' || ch == '$' || ch == '(' ||
+ ch == ')' || ch == '}' || ch == '{' || ch == '[' ||
+ ch == ']')
+ return true;
+ return false;
+}
+
+static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+
+
+ // Do not leak onto next line
+ if (initStyle == SCE_R_INFIXEOL)
+ initStyle = SCE_R_DEFAULT;
+
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart && (sc.state == SCE_R_STRING)) {
+ // Prevent SCE_R_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_R_STRING);
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_R_OPERATOR) {
+ sc.SetState(SCE_R_DEFAULT);
+ } else if (sc.state == SCE_R_NUMBER) {
+ if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_R_DEFAULT);
+ }
+ } else if (sc.state == SCE_R_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_R_KWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_R_BASEKWORD);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_R_OTHERKWORD);
+ }
+ sc.SetState(SCE_R_DEFAULT);
+ }
+ } else if (sc.state == SCE_R_COMMENT) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_R_DEFAULT);
+ }
+ } else if (sc.state == SCE_R_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_R_DEFAULT);
+ }
+ } else if (sc.state == SCE_R_INFIX) {
+ if (sc.ch == '%') {
+ sc.ForwardSetState(SCE_R_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_R_INFIXEOL);
+ sc.ForwardSetState(SCE_R_DEFAULT);
+ }
+ }else if (sc.state == SCE_R_STRING2) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_R_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_R_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_R_NUMBER);
+ } else if (IsAWordStart(sc.ch) ) {
+ sc.SetState(SCE_R_IDENTIFIER);
+ } else if (sc.Match('#')) {
+ sc.SetState(SCE_R_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_R_STRING);
+ } else if (sc.ch == '%') {
+ sc.SetState(SCE_R_INFIX);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_R_STRING2);
+ } else if (IsAnOperator(sc.ch)) {
+ sc.SetState(SCE_R_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldRDoc(unsigned int startPos, int length, int, WordList *[],
+ Accessor &styler) {
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_R_OPERATOR) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+}
+
+
+static const char * const RWordLists[] = {
+ "Language Keywords",
+ "Base / Default package function",
+ "Other Package Functions",
+ "Unused",
+ "Unused",
+ 0,
+ };
+
+
+
+LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexRebol.cxx
+ ** Lexer for REBOL.
+ ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste
+ **
+ ** History:
+ ** 2005-04-07 First release.
+ ** 2005-04-10 Closing parens and brackets go now in default style
+ ** String and comment nesting should be more safe
+ **/
+// Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm>
+// 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 IsAWordChar(const int ch) {
+ return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
+}
+
+static inline bool IsAWordStart(const int ch, const int ch2) {
+ return ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) ||
+ (isalpha(ch) || ch == '?' || ch == '!' || ch == '\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
+}
+
+static inline bool IsAnOperator(const int ch, const int ch2, const int ch3) {
+ // One char operators
+ if (IsASpaceOrTab(ch2)) {
+ return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?';
+ }
+
+ // Two char operators
+ if (IsASpaceOrTab(ch3)) {
+ return (ch == '*' && ch2 == '*') ||
+ (ch == '/' && ch2 == '/') ||
+ (ch == '<' && (ch2 == '=' || ch2 == '>')) ||
+ (ch == '>' && ch2 == '=') ||
+ (ch == '=' && (ch2 == '=' || ch2 == '?')) ||
+ (ch == '?' && ch2 == '?');
+ }
+
+ return false;
+}
+
+static inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) {
+ return (ch == '#' && ch2 == '{') ||
+ (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) ||
+ (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' );
+}
+
+
+static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+
+ int currentLine = styler.GetLine(startPos);
+ // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string.
+ int stringLevel = 0;
+ if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) {
+ stringLevel = styler.GetLineState(currentLine - 1);
+ }
+
+ bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK;
+ int dotCount = 0;
+
+ // Do not leak onto next line
+ if (initStyle == SCE_REBOL_COMMENTLINE) {
+ initStyle = SCE_REBOL_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ if (startPos == 0) {
+ sc.SetState(SCE_REBOL_PREFACE);
+ }
+ for (; sc.More(); sc.Forward()) {
+
+ //--- What to do at line end ?
+ if (sc.atLineEnd) {
+ // Can be either inside a {} string or simply at eol
+ if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK &&
+ sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE)
+ sc.SetState(SCE_REBOL_DEFAULT);
+
+ // Update the line state, so it can be seen by next line
+ currentLine = styler.GetLine(sc.currentPos);
+ switch (sc.state) {
+ case SCE_REBOL_BRACEDSTRING:
+ case SCE_REBOL_COMMENTBLOCK:
+ // Inside a braced string, we set the line state
+ styler.SetLineState(currentLine, stringLevel);
+ break;
+ default:
+ // Reset the line state
+ styler.SetLineState(currentLine, 0);
+ break;
+ }
+
+ // continue with next char
+ continue;
+ }
+
+ //--- What to do on white-space ?
+ if (IsASpaceOrTab(sc.ch))
+ {
+ // Return to default if any of these states
+ if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER ||
+ sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR ||
+ sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE ||
+ sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME ||
+ sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE ||
+ sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Specialize state ?
+ // URL, Email look like identifier
+ if (sc.state == SCE_REBOL_IDENTIFIER)
+ {
+ if (sc.ch == ':' && !IsASpace(sc.chNext)) {
+ sc.ChangeState(SCE_REBOL_URL);
+ } else if (sc.ch == '@') {
+ sc.ChangeState(SCE_REBOL_EMAIL);
+ } else if (sc.ch == '$') {
+ sc.ChangeState(SCE_REBOL_MONEY);
+ }
+ }
+ // Words look like identifiers
+ if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) {
+ // Keywords ?
+ if (!IsAWordChar(sc.ch) || sc.Match('/')) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ blockComment = strcmp(s, "comment") == 0;
+ if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD8);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD7);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD6);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD5);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD4);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD3);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD2);
+ } else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD);
+ }
+ // Keep same style if there are refinements
+ if (!sc.Match('/')) {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+ // special numbers
+ } else if (sc.state == SCE_REBOL_NUMBER) {
+ switch (sc.ch) {
+ case 'x': sc.ChangeState(SCE_REBOL_PAIR);
+ break;
+ case ':': sc.ChangeState(SCE_REBOL_TIME);
+ break;
+ case '-':
+ case '/': sc.ChangeState(SCE_REBOL_DATE);
+ break;
+ case '.': if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE);
+ break;
+ }
+ }
+
+ //--- Determine if the current state should terminate
+ if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) {
+ if (sc.ch == '^' && sc.chNext == '\"') {
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) {
+ if (sc.ch == '}') {
+ if (--stringLevel == 0) {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.ch == '{') {
+ stringLevel++;
+ }
+ } else if (sc.state == SCE_REBOL_BINARY) {
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_TAG) {
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_PREFACE) {
+ if (sc.MatchIgnoreCase("rebol"))
+ {
+ int i;
+ for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++);
+ if (sc.GetRelative(i) == '[')
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Parens and bracket changes to default style when the current is a number
+ if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE ||
+ sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL ||
+ sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) {
+ if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Determine if a new state should be entered.
+ if (sc.state == SCE_REBOL_DEFAULT) {
+ if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) {
+ sc.SetState(SCE_REBOL_OPERATOR);
+ } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) {
+ sc.SetState(SCE_REBOL_BINARY);
+ } else if (IsAWordStart(sc.ch, sc.chNext)) {
+ sc.SetState(SCE_REBOL_IDENTIFIER);
+ } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') {
+ dotCount = 0;
+ sc.SetState(SCE_REBOL_NUMBER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_REBOL_QUOTEDSTRING);
+ } else if (sc.ch == '{') {
+ sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING);
+ ++stringLevel;
+ } else if (sc.ch == ';') {
+ sc.SetState(SCE_REBOL_COMMENTLINE);
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_REBOL_MONEY);
+ } else if (sc.ch == '%') {
+ sc.SetState(SCE_REBOL_FILE);
+ } else if (sc.ch == '<') {
+ sc.SetState(SCE_REBOL_TAG);
+ } else if (sc.ch == '#' && sc.chNext == '"') {
+ sc.SetState(SCE_REBOL_CHARACTER);
+ sc.Forward();
+ } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) {
+ sc.SetState(SCE_REBOL_ISSUE);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+
+static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_REBOL_DEFAULT) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const rebolWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, "rebol", FoldRebolDoc, rebolWordListDesc);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexRuby.cxx
+ ** Lexer for Ruby.
+ **/
+// Copyright 2001- by Clemens Wyss <wys@helbling.ch>
+// 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
+
+//XXX Identical to Perl, put in common area
+static inline bool isEOLChar(char ch) {
+ return (ch == '\r') || (ch == '\n');
+}
+
+#define isSafeASCII(ch) ((unsigned int)(ch) <= 127)
+// This one's redundant, but makes for more readable code
+#define isHighBitChar(ch) ((unsigned int)(ch) > 127)
+
+static inline bool isSafeAlpha(char ch) {
+ return (isSafeASCII(ch) && isalpha(ch)) || ch == '_';
+}
+
+static inline bool isSafeAlnum(char ch) {
+ return (isSafeASCII(ch) && isalnum(ch)) || ch == '_';
+}
+
+static inline bool isSafeAlnumOrHigh(char ch) {
+ return isHighBitChar(ch) || isalnum(ch) || ch == '_';
+}
+
+static inline bool isSafeDigit(char ch) {
+ return isSafeASCII(ch) && isdigit(ch);
+}
+
+static inline bool isSafeWordcharOrHigh(char ch) {
+ // Error: scintilla's KeyWords.h includes '.' as a word-char
+ // we want to separate things that can take methods from the
+ // methods.
+ return isHighBitChar(ch) || isalnum(ch) || ch == '_';
+}
+
+static bool inline iswhitespace(char ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+#define MAX_KEYWORD_LENGTH 200
+
+#define STYLE_MASK 63
+#define actual_style(style) (style & STYLE_MASK)
+
+static bool followsDot(unsigned int pos, Accessor &styler) {
+ styler.Flush();
+ for (; pos >= 1; --pos) {
+ int style = actual_style(styler.StyleAt(pos));
+ char ch;
+ switch (style) {
+ case SCE_RB_DEFAULT:
+ ch = styler[pos];
+ if (ch == ' ' || ch == '\t') {
+ //continue
+ } else {
+ return false;
+ }
+ break;
+
+ case SCE_RB_OPERATOR:
+ return styler[pos] == '.';
+
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+// Forward declarations
+static bool keywordIsAmbiguous(const char *prevWord);
+static bool keywordDoStartsLoop(int pos,
+ Accessor &styler);
+static bool keywordIsModifier(const char *word,
+ int pos,
+ Accessor &styler);
+
+static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
+ char s[MAX_KEYWORD_LENGTH];
+ unsigned int i, j;
+ unsigned int lim = end - start + 1; // num chars to copy
+ if (lim >= MAX_KEYWORD_LENGTH) {
+ lim = MAX_KEYWORD_LENGTH - 1;
+ }
+ for (i = start, j = 0; j < lim; i++, j++) {
+ s[j] = styler[i];
+ }
+ s[j] = '\0';
+ int chAttr;
+ if (0 == strcmp(prevWord, "class"))
+ chAttr = SCE_RB_CLASSNAME;
+ else if (0 == strcmp(prevWord, "module"))
+ chAttr = SCE_RB_MODULE_NAME;
+ else if (0 == strcmp(prevWord, "def"))
+ chAttr = SCE_RB_DEFNAME;
+ else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
+ if (keywordIsAmbiguous(s)
+ && keywordIsModifier(s, start, styler)) {
+
+ // Demoted keywords are colored as keywords,
+ // but do not affect changes in indentation.
+ //
+ // Consider the word 'if':
+ // 1. <<if test ...>> : normal
+ // 2. <<stmt if test>> : demoted
+ // 3. <<lhs = if ...>> : normal: start a new indent level
+ // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
+
+ chAttr = SCE_RB_WORD_DEMOTED;
+ } else {
+ chAttr = SCE_RB_WORD;
+ }
+ } else
+ chAttr = SCE_RB_IDENTIFIER;
+ styler.ColourTo(end, chAttr);
+ if (chAttr == SCE_RB_WORD) {
+ strcpy(prevWord, s);
+ } else {
+ prevWord[0] = 0;
+ }
+ return chAttr;
+}
+
+
+//XXX Identical to Perl, put in common area
+static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
+ if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
+ return false;
+ }
+ while (*val) {
+ if (*val != styler[pos++]) {
+ return false;
+ }
+ val++;
+ }
+ return true;
+}
+
+// Do Ruby better -- find the end of the line, work back,
+// and then check for leading white space
+
+// Precondition: the here-doc target can be indented
+static bool lookingAtHereDocDelim(Accessor &styler,
+ int pos,
+ int lengthDoc,
+ const char *HereDocDelim)
+{
+ if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {
+ return false;
+ }
+ while (--pos > 0) {
+ char ch = styler[pos];
+ if (isEOLChar(ch)) {
+ return true;
+ } else if (ch != ' ' && ch != '\t') {
+ return false;
+ }
+ }
+ return false;
+}
+
+//XXX Identical to Perl, put in common area
+static char opposite(char ch) {
+ if (ch == '(')
+ return ')';
+ if (ch == '[')
+ return ']';
+ if (ch == '{')
+ return '}';
+ if (ch == '<')
+ return '>';
+ return ch;
+}
+
+// Null transitions when we see we've reached the end
+// and need to relex the curr char.
+
+static void redo_char(int &i, char &ch, char &chNext, char &chNext2,
+ int &state) {
+ i--;
+ chNext2 = chNext;
+ chNext = ch;
+ state = SCE_RB_DEFAULT;
+}
+
+static void advance_char(int &i, char &ch, char &chNext, char &chNext2) {
+ i++;
+ ch = chNext;
+ chNext = chNext2;
+}
+
+// precondition: startPos points to one after the EOL char
+static bool currLineContainsHereDelims(int& startPos,
+ Accessor &styler) {
+ if (startPos <= 1)
+ return false;
+
+ int pos;
+ for (pos = startPos - 1; pos > 0; pos--) {
+ char ch = styler.SafeGetCharAt(pos);
+ if (isEOLChar(ch)) {
+ // Leave the pointers where they are -- there are no
+ // here doc delims on the current line, even if
+ // the EOL isn't default style
+
+ return false;
+ } else {
+ styler.Flush();
+ if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {
+ break;
+ }
+ }
+ }
+ if (pos == 0) {
+ return false;
+ }
+ // Update the pointers so we don't have to re-analyze the string
+ startPos = pos;
+ return true;
+}
+
+// This class is used by the enter and exit methods, so it needs
+// to be hoisted out of the function.
+
+class QuoteCls {
+ public:
+ int Count;
+ char Up;
+ char Down;
+ QuoteCls() {
+ this->New();
+ }
+ void New() {
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ }
+ void Open(char u) {
+ Count++;
+ Up = u;
+ Down = opposite(Up);
+ }
+ QuoteCls(const QuoteCls& q) {
+ // copy constructor -- use this for copying in
+ Count = q.Count;
+ Up = q.Up;
+ Down = q.Down;
+ }
+ QuoteCls& operator=(const QuoteCls& q) { // assignment constructor
+ if (this != &q) {
+ Count = q.Count;
+ Up = q.Up;
+ Down = q.Down;
+ }
+ return *this;
+ }
+
+};
+
+
+static void enterInnerExpression(int *p_inner_string_types,
+ int *p_inner_expn_brace_counts,
+ QuoteCls *p_inner_quotes,
+ int& inner_string_count,
+ int& state,
+ int& brace_counts,
+ QuoteCls curr_quote
+ ) {
+ p_inner_string_types[inner_string_count] = state;
+ state = SCE_RB_DEFAULT;
+ p_inner_expn_brace_counts[inner_string_count] = brace_counts;
+ brace_counts = 0;
+ p_inner_quotes[inner_string_count] = curr_quote;
+ ++inner_string_count;
+}
+
+static void exitInnerExpression(int *p_inner_string_types,
+ int *p_inner_expn_brace_counts,
+ QuoteCls *p_inner_quotes,
+ int& inner_string_count,
+ int& state,
+ int& brace_counts,
+ QuoteCls& curr_quote
+ ) {
+ --inner_string_count;
+ state = p_inner_string_types[inner_string_count];
+ brace_counts = p_inner_expn_brace_counts[inner_string_count];
+ curr_quote = p_inner_quotes[inner_string_count];
+}
+
+static bool isEmptyLine(int pos,
+ Accessor &styler) {
+ int spaceFlags = 0;
+ int lineCurrent = styler.GetLine(pos);
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+ return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;
+}
+
+static bool RE_CanFollowKeyword(const char *keyword) {
+ if (!strcmp(keyword, "and")
+ || !strcmp(keyword, "begin")
+ || !strcmp(keyword, "break")
+ || !strcmp(keyword, "case")
+ || !strcmp(keyword, "do")
+ || !strcmp(keyword, "else")
+ || !strcmp(keyword, "elsif")
+ || !strcmp(keyword, "if")
+ || !strcmp(keyword, "next")
+ || !strcmp(keyword, "return")
+ || !strcmp(keyword, "when")
+ || !strcmp(keyword, "unless")
+ || !strcmp(keyword, "until")
+ || !strcmp(keyword, "not")
+ || !strcmp(keyword, "or")) {
+ return true;
+ }
+ return false;
+}
+
+// Look at chars up to but not including endPos
+// Don't look at styles in case we're looking forward
+
+static int skipWhitespace(int startPos,
+ int endPos,
+ Accessor &styler) {
+ for (int i = startPos; i < endPos; i++) {
+ if (!iswhitespace(styler[i])) {
+ return i;
+ }
+ }
+ return endPos;
+}
+
+// This routine looks for false positives like
+// undef foo, <<
+// There aren't too many.
+//
+// iPrev points to the start of <<
+
+static bool sureThisIsHeredoc(int iPrev,
+ Accessor &styler,
+ char *prevWord) {
+
+ // Not so fast, since Ruby's so dynamic. Check the context
+ // to make sure we're OK.
+ int prevStyle;
+ int lineStart = styler.GetLine(iPrev);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+
+ // Find the first word after some whitespace
+ int firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler);
+ if (firstWordPosn >= iPrev) {
+ // Have something like {^ <<}
+ //XXX Look at the first previous non-comment non-white line
+ // to establish the context. Not too likely though.
+ return true;
+ } else {
+ switch (prevStyle = styler.StyleAt(firstWordPosn)) {
+ case SCE_RB_WORD:
+ case SCE_RB_WORD_DEMOTED:
+ case SCE_RB_IDENTIFIER:
+ break;
+ default:
+ return true;
+ }
+ }
+ int firstWordEndPosn = firstWordPosn;
+ char *dst = prevWord;
+ for (;;) {
+ if (firstWordEndPosn >= iPrev ||
+ styler.StyleAt(firstWordEndPosn) != prevStyle) {
+ *dst = 0;
+ break;
+ }
+ *dst++ = styler[firstWordEndPosn];
+ firstWordEndPosn += 1;
+ }
+ //XXX Write a style-aware thing to regex scintilla buffer objects
+ if (!strcmp(prevWord, "undef")
+ || !strcmp(prevWord, "def")
+ || !strcmp(prevWord, "alias")) {
+ // These keywords are what we were looking for
+ return false;
+ }
+ return true;
+}
+
+// Routine that saves us from allocating a buffer for the here-doc target
+// targetEndPos points one past the end of the current target
+static bool haveTargetMatch(int currPos,
+ int lengthDoc,
+ int targetStartPos,
+ int targetEndPos,
+ Accessor &styler) {
+ if (lengthDoc - currPos < targetEndPos - targetStartPos) {
+ return false;
+ }
+ int i, j;
+ for (i = targetStartPos, j = currPos;
+ i < targetEndPos && j < lengthDoc;
+ i++, j++) {
+ if (styler[i] != styler[j]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// We need a check because the form
+// [identifier] <<[target]
+// is ambiguous. The Ruby lexer/parser resolves it by
+// looking to see if [identifier] names a variable or a
+// function. If it's the first, it's the start of a here-doc.
+// If it's a var, it's an operator. This lexer doesn't
+// maintain a symbol table, so it looks ahead to see what's
+// going on, in cases where we have
+// ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target]
+//
+// If there's no occurrence of [target] on a line, assume we don't.
+
+// return true == yes, we have no heredocs
+
+static bool sureThisIsNotHeredoc(int lt2StartPos,
+ Accessor &styler) {
+ int prevStyle;
+ // Use full document, not just part we're styling
+ int lengthDoc = styler.Length();
+ int lineStart = styler.GetLine(lt2StartPos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ const bool definitely_not_a_here_doc = true;
+ const bool looks_like_a_here_doc = false;
+
+ // Find the first word after some whitespace
+ int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);
+ if (firstWordPosn >= lt2StartPos) {
+ return definitely_not_a_here_doc;
+ }
+ prevStyle = styler.StyleAt(firstWordPosn);
+ // If we have '<<' following a keyword, it's not a heredoc
+ if (prevStyle != SCE_RB_IDENTIFIER) {
+ return definitely_not_a_here_doc;
+ }
+ int newStyle = prevStyle;
+ // Some compilers incorrectly warn about uninit newStyle
+ for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
+ // Inner loop looks at the name
+ for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
+ newStyle = styler.StyleAt(firstWordPosn);
+ if (newStyle != prevStyle) {
+ break;
+ }
+ }
+ // Do we have '::' or '.'?
+ if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) {
+ char ch = styler[firstWordPosn];
+ if (ch == '.') {
+ // yes
+ } else if (ch == ':') {
+ if (styler.StyleAt(++firstWordPosn) != SCE_RB_OPERATOR) {
+ return definitely_not_a_here_doc;
+ } else if (styler[firstWordPosn] != ':') {
+ return definitely_not_a_here_doc;
+ }
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ // Skip next batch of white-space
+ firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);
+ if (firstWordPosn != lt2StartPos) {
+ // Have [[^ws[identifier]ws[*something_else*]ws<<
+ return definitely_not_a_here_doc;
+ }
+ // OK, now 'j' will point to the current spot moving ahead
+ int j = firstWordPosn + 1;
+ if (styler.StyleAt(j) != SCE_RB_OPERATOR || styler[j] != '<') {
+ // This shouldn't happen
+ return definitely_not_a_here_doc;
+ }
+ int nextLineStartPosn = styler.LineStart(lineStart + 1);
+ if (nextLineStartPosn >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ }
+ j = skipWhitespace(j + 1, nextLineStartPosn, styler);
+ if (j >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ }
+ bool allow_indent;
+ int target_start, target_end;
+ // From this point on no more styling, since we're looking ahead
+ if (styler[j] == '-') {
+ allow_indent = true;
+ j++;
+ } else {
+ allow_indent = false;
+ }
+
+ // Allow for quoted targets.
+ char target_quote = 0;
+ switch (styler[j]) {
+ case '\'':
+ case '"':
+ case '`':
+ target_quote = styler[j];
+ j += 1;
+ }
+
+ if (isSafeAlnum(styler[j])) {
+ // Init target_end because some compilers think it won't
+ // be initialized by the time it's used
+ target_start = target_end = j;
+ j++;
+ } else {
+ return definitely_not_a_here_doc;
+ }
+ for (; j < lengthDoc; j++) {
+ if (!isSafeAlnum(styler[j])) {
+ if (target_quote && styler[j] != target_quote) {
+ // unquoted end
+ return definitely_not_a_here_doc;
+ }
+
+ // And for now make sure that it's a newline
+ // don't handle arbitrary expressions yet
+
+ target_end = j;
+ if (target_quote) {
+ // Now we can move to the character after the string delimiter.
+ j += 1;
+ }
+ j = skipWhitespace(j, lengthDoc, styler);
+ if (j >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ } else {
+ char ch = styler[j];
+ if (ch == '#' || isEOLChar(ch)) {
+ // This is OK, so break and continue;
+ break;
+ } else {
+ return definitely_not_a_here_doc;
+ }
+ }
+ }
+ }
+
+ // Just look at the start of each line
+ int last_line = styler.GetLine(lengthDoc - 1);
+ // But don't go too far
+ if (last_line > lineStart + 50) {
+ last_line = lineStart + 50;
+ }
+ for (int line_num = lineStart + 1; line_num <= last_line; line_num++) {
+ if (allow_indent) {
+ j = skipWhitespace(styler.LineStart(line_num), lengthDoc, styler);
+ } else {
+ j = styler.LineStart(line_num);
+ }
+ // target_end is one past the end
+ if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) {
+ // We got it
+ return looks_like_a_here_doc;
+ }
+ }
+ return definitely_not_a_here_doc;
+}
+
+//todo: if we aren't looking at a stdio character,
+// move to the start of the first line that is not in a
+// multi-line construct
+
+static void synchronizeDocStart(unsigned int& startPos,
+ int &length,
+ int &initStyle,
+ Accessor &styler,
+ bool skipWhiteSpace=false) {
+
+ styler.Flush();
+ int style = actual_style(styler.StyleAt(startPos));
+ switch (style) {
+ case SCE_RB_STDIN:
+ case SCE_RB_STDOUT:
+ case SCE_RB_STDERR:
+ // Don't do anything else with these.
+ return;
+ }
+
+ int pos = startPos;
+ // Quick way to characterize each line
+ int lineStart;
+ for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {
+ // Now look at the style before the previous line's EOL
+ pos = styler.LineStart(lineStart) - 1;
+ if (pos <= 10) {
+ lineStart = 0;
+ break;
+ }
+ char ch = styler.SafeGetCharAt(pos);
+ char chPrev = styler.SafeGetCharAt(pos - 1);
+ if (ch == '\n' && chPrev == '\r') {
+ pos--;
+ }
+ if (styler.SafeGetCharAt(pos - 1) == '\\') {
+ // Continuation line -- keep going
+ } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {
+ // Part of multi-line construct -- keep going
+ } else if (currLineContainsHereDelims(pos, styler)) {
+ // Keep going, with pos and length now pointing
+ // at the end of the here-doc delimiter
+ } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {
+ // Keep going
+ } else {
+ break;
+ }
+ }
+ pos = styler.LineStart(lineStart);
+ length += (startPos - pos);
+ startPos = pos;
+ initStyle = SCE_RB_DEFAULT;
+}
+
+static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ // Lexer for Ruby often has to backtrack to start of current style to determine
+ // which characters are being used as quotes, how deeply nested is the
+ // start position and what the termination string is for here documents
+
+ WordList &keywords = *keywordlists[0];
+
+ class HereDocCls {
+ public:
+ int State;
+ // States
+ // 0: '<<' encountered
+ // 1: collect the delimiter
+ // 1b: text between the end of the delimiter and the EOL
+ // 2: here doc text (lines after the delimiter)
+ char Quote; // the char after '<<'
+ bool Quoted; // true if Quote in ('\'','"','`')
+ int DelimiterLength; // strlen(Delimiter)
+ char Delimiter[256]; // the Delimiter, limit of 256: from Perl
+ bool CanBeIndented;
+ HereDocCls() {
+ State = 0;
+ DelimiterLength = 0;
+ Delimiter[0] = '\0';
+ CanBeIndented = false;
+ }
+ };
+ HereDocCls HereDoc;
+
+ QuoteCls Quote;
+
+ int numDots = 0; // For numbers --
+ // Don't start lexing in the middle of a num
+
+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
+ false);
+
+ bool preferRE = true;
+ int state = initStyle;
+ int lengthDoc = startPos + length;
+
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ prevWord[0] = '\0';
+ if (length == 0)
+ return;
+
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
+ char chNext = styler.SafeGetCharAt(startPos);
+ bool is_real_number = true; // Differentiate between constants and ?-sequences.
+ // Ruby uses a different mask because bad indentation is marked by oring with 32
+ styler.StartAt(startPos, 127);
+ styler.StartSegment(startPos);
+
+ static int q_states[] = {SCE_RB_STRING_Q,
+ SCE_RB_STRING_QQ,
+ SCE_RB_STRING_QR,
+ SCE_RB_STRING_QW,
+ SCE_RB_STRING_QW,
+ SCE_RB_STRING_QX};
+ static const char* q_chars = "qQrwWx";
+
+ // In most cases a value of 2 should be ample for the code in the
+ // Ruby library, and the code the user is likely to enter.
+ // For example,
+ // fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}"
+ // if options[:verbose]
+ // from fileutils.rb nests to a level of 2
+ // If the user actually hits a 6th occurrence of '#{' in a double-quoted
+ // string (including regex'es, %Q, %<sym>, %w, and other strings
+ // that interpolate), it will stay as a string. The problem with this
+ // is that quotes might flip, a 7th '#{' will look like a comment,
+ // and code-folding might be wrong.
+
+ // If anyone runs into this problem, I recommend raising this
+ // value slightly higher to replacing the fixed array with a linked
+ // list. Keep in mind this code will be called everytime the lexer
+ // is invoked.
+
+#define INNER_STRINGS_MAX_COUNT 5
+ // These vars track our instances of "...#{,,,%Q<..#{,,,}...>,,,}..."
+ int inner_string_types[INNER_STRINGS_MAX_COUNT];
+ // Track # braces when we push a new #{ thing
+ int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT];
+ QuoteCls inner_quotes[INNER_STRINGS_MAX_COUNT];
+ int inner_string_count = 0;
+ int brace_counts = 0; // Number of #{ ... } things within an expression
+
+ int i;
+ for (i = 0; i < INNER_STRINGS_MAX_COUNT; i++) {
+ inner_string_types[i] = 0;
+ inner_expn_brace_counts[i] = 0;
+ }
+ for (i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = chNext2;
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ // skip on DOS/Windows
+ //No, don't, because some things will get tagged on,
+ // so we won't recognize keywords, for example
+#if 0
+ if (ch == '\r' && chNext == '\n') {
+ continue;
+ }
+#endif
+
+ if (HereDoc.State == 1 && isEOLChar(ch)) {
+ // Begin of here-doc (the line after the here-doc delimiter):
+ HereDoc.State = 2;
+ styler.ColourTo(i-1, state);
+ // Don't check for a missing quote, just jump into
+ // the here-doc state
+ state = SCE_RB_HERE_Q;
+ }
+
+ // Regular transitions
+ if (state == SCE_RB_DEFAULT) {
+ if (isSafeDigit(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_NUMBER;
+ is_real_number = true;
+ numDots = 0;
+ } else if (isHighBitChar(ch) || iswordstart(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_WORD;
+ } else if (ch == '#') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_COMMENTLINE;
+ } else if (ch == '=') {
+ // =begin indicates the start of a comment (doc) block
+ if ((i == 0 || isEOLChar(chPrev))
+ && chNext == 'b'
+ && styler.SafeGetCharAt(i + 2) == 'e'
+ && styler.SafeGetCharAt(i + 3) == 'g'
+ && styler.SafeGetCharAt(i + 4) == 'i'
+ && styler.SafeGetCharAt(i + 5) == 'n'
+ && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_POD;
+ } else {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ preferRE = true;
+ }
+ } else if (ch == '"') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_STRING;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_CHARACTER;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '`') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_BACKTICKS;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '@') {
+ // Instance or class var
+ styler.ColourTo(i - 1, state);
+ if (chNext == '@') {
+ state = SCE_RB_CLASS_VAR;
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ state = SCE_RB_INSTANCE_VAR;
+ }
+ } else if (ch == '$') {
+ // Check for a builtin global
+ styler.ColourTo(i - 1, state);
+ // Recognize it bit by bit
+ state = SCE_RB_GLOBAL;
+ } else if (ch == '/' && preferRE) {
+ // Ambigous operator
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_REGEX;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '<' && chNext == '<' && chNext2 != '=') {
+
+ // Recognise the '<<' symbol - either a here document or a binary op
+ styler.ColourTo(i - 1, state);
+ i++;
+ chNext = chNext2;
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+
+ if (! (strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) {
+ // It's definitely not a here-doc,
+ // based on Ruby's lexer/parser in the
+ // heredoc_identifier routine.
+ // Nothing else to do.
+ } else if (preferRE) {
+ if (sureThisIsHeredoc(i - 1, styler, prevWord)) {
+ state = SCE_RB_HERE_DELIM;
+ HereDoc.State = 0;
+ }
+ // else leave it in default state
+ } else {
+ if (sureThisIsNotHeredoc(i - 1, styler)) {
+ // leave state as default
+ // We don't have all the heuristics Perl has for indications
+ // of a here-doc, because '<<' is overloadable and used
+ // for so many other classes.
+ } else {
+ state = SCE_RB_HERE_DELIM;
+ HereDoc.State = 0;
+ }
+ }
+ preferRE = (state != SCE_RB_HERE_DELIM);
+ } else if (ch == ':') {
+ styler.ColourTo(i - 1, state);
+ if (chNext == ':') {
+ // Mark "::" as an operator, not symbol start
+ styler.ColourTo(i + 1, SCE_RB_OPERATOR);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else if (isSafeWordcharOrHigh(chNext)) {
+ state = SCE_RB_SYMBOL;
+ } else if (strchr("[*!~+-*/%=<>&^|", chNext)) {
+ // Do the operator analysis in-line, looking ahead
+ // Based on the table in pickaxe 2nd ed., page 339
+ bool doColoring = true;
+ switch (chNext) {
+ case '[':
+ if (chNext2 == ']' ) {
+ char ch_tmp = styler.SafeGetCharAt(i + 3);
+ if (ch_tmp == '=') {
+ i += 3;
+ ch = ch_tmp;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ i += 2;
+ ch = chNext2;
+ chNext = ch_tmp;
+ }
+ } else {
+ doColoring = false;
+ }
+ break;
+
+ case '*':
+ if (chNext2 == '*') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ case '!':
+ if (chNext2 == '=' || chNext2 == '~') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ case '<':
+ if (chNext2 == '<') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext2 == '=') {
+ char ch_tmp = styler.SafeGetCharAt(i + 3);
+ if (ch_tmp == '>') { // <=> operator
+ i += 3;
+ ch = ch_tmp;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ i += 2;
+ ch = chNext2;
+ chNext = ch_tmp;
+ }
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ default:
+ // Simple one-character operators
+ advance_char(i, ch, chNext, chNext2);
+ break;
+ }
+ if (doColoring) {
+ styler.ColourTo(i, SCE_RB_SYMBOL);
+ state = SCE_RB_DEFAULT;
+ }
+ } else if (!preferRE) {
+ // Don't color symbol strings (yet)
+ // Just color the ":" and color rest as string
+ styler.ColourTo(i, SCE_RB_SYMBOL);
+ state = SCE_RB_DEFAULT;
+ } else {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ state = SCE_RB_DEFAULT;
+ preferRE = true;
+ }
+ } else if (ch == '%') {
+ styler.ColourTo(i - 1, state);
+ bool have_string = false;
+ if (strchr(q_chars, chNext) && !isSafeWordcharOrHigh(chNext2)) {
+ Quote.New();
+ const char *hit = strchr(q_chars, chNext);
+ if (hit != NULL) {
+ state = q_states[hit - q_chars];
+ Quote.Open(chNext2);
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ have_string = true;
+ }
+ } else if (preferRE && !isSafeWordcharOrHigh(chNext)) {
+ // Ruby doesn't allow high bit chars here,
+ // but the editor host might
+ Quote.New();
+ state = SCE_RB_STRING_QQ;
+ Quote.Open(chNext);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ have_string = true;
+ } else if (!isSafeWordcharOrHigh(chNext) && !iswhitespace(chNext) && !isEOLChar(chNext)) {
+ // Ruby doesn't allow high bit chars here,
+ // but the editor host might
+ Quote.New();
+ state = SCE_RB_STRING_QQ;
+ Quote.Open(chNext);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ have_string = true;
+ }
+ if (!have_string) {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ // stay in default
+ preferRE = true;
+ }
+ } else if (ch == '?') {
+ styler.ColourTo(i - 1, state);
+ if (iswhitespace(chNext) || chNext == '\n' || chNext == '\r') {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ } else {
+ // It's the start of a character code escape sequence
+ // Color it as a number.
+ state = SCE_RB_NUMBER;
+ is_real_number = false;
+ }
+ } else if (isoperator(ch) || ch == '.') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ // If we're ending an expression or block,
+ // assume it ends an object, and the ambivalent
+ // constructs are binary operators
+ //
+ // So if we don't have one of these chars,
+ // we aren't ending an object exp'n, and ops
+ // like : << / are unary operators.
+
+ if (ch == '{') {
+ ++brace_counts;
+ preferRE = true;
+ } else if (ch == '}' && --brace_counts < 0
+ && inner_string_count > 0) {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ exitInnerExpression(inner_string_types,
+ inner_expn_brace_counts,
+ inner_quotes,
+ inner_string_count,
+ state, brace_counts, Quote);
+ } else {
+ preferRE = (strchr(")}].", ch) == NULL);
+ }
+ // Stay in default state
+ } else if (isEOLChar(ch)) {
+ // Make sure it's a true line-end, with no backslash
+ if ((ch == '\r' || (ch == '\n' && chPrev != '\r'))
+ && chPrev != '\\') {
+ // Assume we've hit the end of the statement.
+ preferRE = true;
+ }
+ }
+ } else if (state == SCE_RB_WORD) {
+ if (ch == '.' || !isSafeWordcharOrHigh(ch)) {
+ // Words include x? in all contexts,
+ // and <letters>= after either 'def' or a dot
+ // Move along until a complete word is on our left
+
+ // Default accessor treats '.' as word-chars,
+ // but we don't for now.
+
+ if (ch == '='
+ && isSafeWordcharOrHigh(chPrev)
+ && (chNext == '('
+ || strchr(" \t\n\r", chNext) != NULL)
+ && (!strcmp(prevWord, "def")
+ || followsDot(styler.GetStartSegment(), styler))) {
+ // <name>= is a name only when being def'd -- Get it the next time
+ // This means that <name>=<name> is always lexed as
+ // <name>, (op, =), <name>
+ } else if ((ch == '?' || ch == '!')
+ && isSafeWordcharOrHigh(chPrev)
+ && !isSafeWordcharOrHigh(chNext)) {
+ // <name>? is a name -- Get it the next time
+ // But <name>?<name> is always lexed as
+ // <name>, (op, ?), <name>
+ // Same with <name>! to indicate a method that
+ // modifies its target
+ } else if (isEOLChar(ch)
+ && isMatch(styler, lengthDoc, i - 7, "__END__")) {
+ styler.ColourTo(i, SCE_RB_DATASECTION);
+ state = SCE_RB_DATASECTION;
+ // No need to handle this state -- we'll just move to the end
+ preferRE = false;
+ } else {
+ int wordStartPos = styler.GetStartSegment();
+ int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord);
+ switch (word_style) {
+ case SCE_RB_WORD:
+ preferRE = RE_CanFollowKeyword(prevWord);
+ break;
+
+ case SCE_RB_WORD_DEMOTED:
+ preferRE = true;
+ break;
+
+ case SCE_RB_IDENTIFIER:
+ if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
+ preferRE = true;
+ } else if (isEOLChar(ch)) {
+ preferRE = true;
+ } else {
+ preferRE = false;
+ }
+ break;
+ default:
+ preferRE = false;
+ }
+ if (ch == '.') {
+ // We might be redefining an operator-method
+ preferRE = false;
+ }
+ // And if it's the first
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ }
+ }
+ } else if (state == SCE_RB_NUMBER) {
+ if (!is_real_number) {
+ if (ch != '\\') {
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else if (strchr("\\ntrfvaebs", chNext)) {
+ // Terminal escape sequence -- handle it next time
+ // Nothing more to do this time through the loop
+ } else if (chNext == 'C' || chNext == 'M') {
+ if (chNext2 != '-') {
+ // \C or \M ends the sequence -- handle it next time
+ } else {
+ // Move from abc?\C-x
+ // ^
+ // to
+ // ^
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ } else if (chNext == 'c') {
+ // Stay here, \c is a combining sequence
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ // ?\x, including ?\\ is final.
+ styler.ColourTo(i + 1, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ advance_char(i, ch, chNext, chNext2);
+ }
+ } else if (isSafeAlnumOrHigh(ch) || ch == '_') {
+ // Keep going
+ } else if (ch == '.' && chNext == '.') {
+ ++numDots;
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ } else if (ch == '.' && ++numDots == 1) {
+ // Keep going
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_COMMENTLINE) {
+ if (isEOLChar(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ // Use whatever setting we had going into the comment
+ }
+ } else if (state == SCE_RB_HERE_DELIM) {
+ // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
+ // Slightly different: if we find an immediate '-',
+ // the target can appear indented.
+
+ if (HereDoc.State == 0) { // '<<' encountered
+ HereDoc.State = 1;
+ HereDoc.DelimiterLength = 0;
+ if (ch == '-') {
+ HereDoc.CanBeIndented = true;
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ HereDoc.CanBeIndented = false;
+ }
+ if (isEOLChar(ch)) {
+ // Bail out of doing a here doc if there's no target
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else {
+ HereDoc.Quote = ch;
+
+ if (ch == '\'' || ch == '"' || ch == '`') {
+ HereDoc.Quoted = true;
+ HereDoc.Delimiter[0] = '\0';
+ } else {
+ HereDoc.Quoted = false;
+ HereDoc.Delimiter[0] = ch;
+ HereDoc.Delimiter[1] = '\0';
+ HereDoc.DelimiterLength = 1;
+ }
+ }
+ } else if (HereDoc.State == 1) { // collect the delimiter
+ if (isEOLChar(ch)) {
+ // End the quote now, and go back for more
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ i--;
+ chNext = ch;
+ preferRE = false;
+ } else if (HereDoc.Quoted) {
+ if (ch == HereDoc.Quote) { // closing quote => end of delimiter
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else {
+ if (ch == '\\' && !isEOLChar(chNext)) {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ }
+ } else { // an unquoted here-doc delimiter
+ if (isSafeAlnumOrHigh(ch) || ch == '_') {
+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state);
+ preferRE = false;
+ }
+ }
+ if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_ERROR;
+ preferRE = false;
+ }
+ }
+ } else if (state == SCE_RB_HERE_Q) {
+ // Not needed: HereDoc.State == 2
+ // Indentable here docs: look backwards
+ // Non-indentable: look forwards, like in Perl
+ //
+ // Why: so we can quickly resolve things like <<-" abc"
+
+ if (!HereDoc.CanBeIndented) {
+ if (isEOLChar(chPrev)
+ && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
+ styler.ColourTo(i - 1, state);
+ i += HereDoc.DelimiterLength - 1;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (isEOLChar(chNext)) {
+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
+ state = SCE_RB_DEFAULT;
+ HereDoc.State = 0;
+ preferRE = false;
+ }
+ // Otherwise we skipped through the here doc faster.
+ }
+ } else if (isEOLChar(chNext)
+ && lookingAtHereDocDelim(styler,
+ i - HereDoc.DelimiterLength + 1,
+ lengthDoc,
+ HereDoc.Delimiter)) {
+ styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state);
+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ HereDoc.State = 0;
+ }
+ } else if (state == SCE_RB_CLASS_VAR
+ || state == SCE_RB_INSTANCE_VAR
+ || state == SCE_RB_SYMBOL) {
+ if (!isSafeWordcharOrHigh(ch)) {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_GLOBAL) {
+ if (!isSafeWordcharOrHigh(ch)) {
+ // handle special globals here as well
+ if (chPrev == '$') {
+ if (ch == '-') {
+ // Include the next char, like $-a
+ advance_char(i, ch, chNext, chNext2);
+ }
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ }
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_POD) {
+ // PODs end with ^=end\s, -- any whitespace can follow =end
+ if (strchr(" \t\n\r", ch) != NULL
+ && i > 5
+ && isEOLChar(styler[i - 5])
+ && isMatch(styler, lengthDoc, i - 4, "=end")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {
+ if (ch == '\\' && Quote.Up != '\\') {
+ // Skip one
+ advance_char(i, ch, chNext, chNext2);
+ } else if (ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ // Include the options
+ while (isSafeAlpha(chNext)) {
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (ch == Quote.Up) {
+ // Only if close quoter != open quoter
+ Quote.Count++;
+
+ } else if (ch == '#' ) {
+ if (chNext == '{'
+ && inner_string_count < INNER_STRINGS_MAX_COUNT) {
+ // process #{ ... }
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i + 1, SCE_RB_OPERATOR);
+ enterInnerExpression(inner_string_types,
+ inner_expn_brace_counts,
+ inner_quotes,
+ inner_string_count,
+ state,
+ brace_counts,
+ Quote);
+ preferRE = true;
+ // Skip one
+ advance_char(i, ch, chNext, chNext2);
+ } else {
+ //todo: distinguish comments from pound chars
+ // for now, handle as comment
+ styler.ColourTo(i - 1, state);
+ bool inEscape = false;
+ while (++i < lengthDoc) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\\') {
+ inEscape = true;
+ } else if (isEOLChar(ch)) {
+ // Comment inside a regex
+ styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);
+ break;
+ } else if (inEscape) {
+ inEscape = false; // don't look at char
+ } else if (ch == Quote.Down) {
+ // Have the regular handler deal with this
+ // to get trailing modifiers.
+ i--;
+ ch = styler[i];
+ break;
+ }
+ }
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ }
+ // Quotes of all kinds...
+ } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
+ state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
+ state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
+ state == SCE_RB_BACKTICKS) {
+ if (!Quote.Down && !isspacechar(ch)) {
+ Quote.Open(ch);
+ } else if (ch == '\\' && Quote.Up != '\\') {
+ //Riddle me this: Is it safe to skip *every* escaped char?
+ advance_char(i, ch, chNext, chNext2);
+ } else if (ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (ch == Quote.Up) {
+ Quote.Count++;
+ } else if (ch == '#' && chNext == '{'
+ && inner_string_count < INNER_STRINGS_MAX_COUNT
+ && state != SCE_RB_CHARACTER
+ && state != SCE_RB_STRING_Q) {
+ // process #{ ... }
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i + 1, SCE_RB_OPERATOR);
+ enterInnerExpression(inner_string_types,
+ inner_expn_brace_counts,
+ inner_quotes,
+ inner_string_count,
+ state,
+ brace_counts,
+ Quote);
+ preferRE = true;
+ // Skip one
+ advance_char(i, ch, chNext, chNext2);
+ }
+ }
+
+ if (state == SCE_RB_ERROR) {
+ break;
+ }
+ chPrev = ch;
+ }
+ if (state == SCE_RB_WORD) {
+ // We've ended on a word, possibly at EOF, and need to
+ // classify it.
+ (void) ClassifyWordRb(styler.GetStartSegment(), lengthDoc - 1, keywords, styler, prevWord);
+ } else {
+ styler.ColourTo(lengthDoc - 1, state);
+ }
+}
+
+// Helper functions for folding, disambiguation keywords
+// Assert that there are no high-bit chars
+
+static void getPrevWord(int pos,
+ char *prevWord,
+ Accessor &styler,
+ int word_state)
+{
+ int i;
+ styler.Flush();
+ for (i = pos - 1; i > 0; i--) {
+ if (actual_style(styler.StyleAt(i)) != word_state) {
+ i++;
+ break;
+ }
+ }
+ if (i < pos - MAX_KEYWORD_LENGTH) // overflow
+ i = pos - MAX_KEYWORD_LENGTH;
+ char *dst = prevWord;
+ for (; i <= pos; i++) {
+ *dst++ = styler[i];
+ }
+ *dst = 0;
+}
+
+static bool keywordIsAmbiguous(const char *prevWord)
+{
+ // Order from most likely used to least likely
+ // Lots of ways to do a loop in Ruby besides 'while/until'
+ if (!strcmp(prevWord, "if")
+ || !strcmp(prevWord, "do")
+ || !strcmp(prevWord, "while")
+ || !strcmp(prevWord, "unless")
+ || !strcmp(prevWord, "until")) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Demote keywords in the following conditions:
+// if, while, unless, until modify a statement
+// do after a while or until, as a noise word (like then after if)
+
+static bool keywordIsModifier(const char *word,
+ int pos,
+ Accessor &styler)
+{
+ if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
+ return keywordDoStartsLoop(pos, styler);
+ }
+ char ch, chPrev, chPrev2;
+ int style = SCE_RB_DEFAULT;
+ int lineStart = styler.GetLine(pos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ // We want to step backwards until we don't care about the current
+ // position. But first move lineStartPosn back behind any
+ // continuations immediately above word.
+ while (lineStartPosn > 0) {
+ ch = styler[lineStartPosn-1];
+ if (ch == '\n' || ch == '\r') {
+ chPrev = styler.SafeGetCharAt(lineStartPosn-2);
+ chPrev2 = styler.SafeGetCharAt(lineStartPosn-3);
+ lineStart = styler.GetLine(lineStartPosn-1);
+ // If we find a continuation line, include it in our analysis.
+ if (chPrev == '\\') {
+ lineStartPosn = styler.LineStart(lineStart);
+ } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') {
+ lineStartPosn = styler.LineStart(lineStart);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ styler.Flush();
+ while (--pos >= lineStartPosn) {
+ style = actual_style(styler.StyleAt(pos));
+ if (style == SCE_RB_DEFAULT) {
+ if (iswhitespace(ch = styler[pos])) {
+ //continue
+ } else if (ch == '\r' || ch == '\n') {
+ // Scintilla's LineStart() and GetLine() routines aren't
+ // platform-independent, so if we have text prepared with
+ // a different system we can't rely on it.
+
+ // Also, lineStartPosn may have been moved to more than one
+ // line above word's line while pushing past continuations.
+ chPrev = styler.SafeGetCharAt(pos - 1);
+ chPrev2 = styler.SafeGetCharAt(pos - 2);
+ if (chPrev == '\\') {
+ pos-=1; // gloss over the "\\"
+ //continue
+ } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') {
+ pos-=2; // gloss over the "\\\r"
+ //continue
+ } else {
+ return false;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ if (pos < lineStartPosn) {
+ return false;
+ }
+ // First things where the action is unambiguous
+ switch (style) {
+ case SCE_RB_DEFAULT:
+ case SCE_RB_COMMENTLINE:
+ case SCE_RB_POD:
+ case SCE_RB_CLASSNAME:
+ case SCE_RB_DEFNAME:
+ case SCE_RB_MODULE_NAME:
+ return false;
+ case SCE_RB_OPERATOR:
+ break;
+ case SCE_RB_WORD:
+ // Watch out for uses of 'else if'
+ //XXX: Make a list of other keywords where 'if' isn't a modifier
+ // and can appear legitimately
+ // Formulate this to avoid warnings from most compilers
+ if (strcmp(word, "if") == 0) {
+ char prevWord[MAX_KEYWORD_LENGTH + 1];
+ getPrevWord(pos, prevWord, styler, SCE_RB_WORD);
+ return strcmp(prevWord, "else") != 0;
+ }
+ return true;
+ default:
+ return true;
+ }
+ // Assume that if the keyword follows an operator,
+ // usually it's a block assignment, like
+ // a << if x then y else z
+
+ ch = styler[pos];
+ switch (ch) {
+ case ')':
+ case ']':
+ case '}':
+ return true;
+ default:
+ return false;
+ }
+}
+
+#define WHILE_BACKWARDS "elihw"
+#define UNTIL_BACKWARDS "litnu"
+
+// Nothing fancy -- look to see if we follow a while/until somewhere
+// on the current line
+
+static bool keywordDoStartsLoop(int pos,
+ Accessor &styler)
+{
+ char ch;
+ int style;
+ int lineStart = styler.GetLine(pos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ while (--pos >= lineStartPosn) {
+ style = actual_style(styler.StyleAt(pos));
+ if (style == SCE_RB_DEFAULT) {
+ if ((ch = styler[pos]) == '\r' || ch == '\n') {
+ // Scintilla's LineStart() and GetLine() routines aren't
+ // platform-independent, so if we have text prepared with
+ // a different system we can't rely on it.
+ return false;
+ }
+ } else if (style == SCE_RB_WORD) {
+ // Check for while or until, but write the word in backwards
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ char *dst = prevWord;
+ int wordLen = 0;
+ int start_word;
+ for (start_word = pos;
+ start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD;
+ start_word--) {
+ if (++wordLen < MAX_KEYWORD_LENGTH) {
+ *dst++ = styler[start_word];
+ }
+ }
+ *dst = 0;
+ // Did we see our keyword?
+ if (!strcmp(prevWord, WHILE_BACKWARDS)
+ || !strcmp(prevWord, UNTIL_BACKWARDS)) {
+ return true;
+ }
+ // We can move pos to the beginning of the keyword, and then
+ // accept another decrement, as we can never have two contiguous
+ // keywords:
+ // word1 word2
+ // ^
+ // <- move to start_word
+ // ^
+ // <- loop decrement
+ // ^ # pointing to end of word1 is fine
+ pos = start_word;
+ }
+ }
+ return false;
+}
+
+/*
+ * Folding Ruby
+ *
+ * The language is quite complex to analyze without a full parse.
+ * For example, this line shouldn't affect fold level:
+ *
+ * print "hello" if feeling_friendly?
+ *
+ * Neither should this:
+ *
+ * print "hello" \
+ * if feeling_friendly?
+ *
+ *
+ * But this should:
+ *
+ * if feeling_friendly? #++
+ * print "hello" \
+ * print "goodbye"
+ * end #--
+ *
+ * So we cheat, by actually looking at the existing indentation
+ * levels for each line, and just echoing it back. Like Python.
+ * Then if we get better at it, we'll take braces into consideration,
+ * which always affect folding levels.
+
+ * How the keywords should work:
+ * No effect:
+ * __FILE__ __LINE__ BEGIN END alias and
+ * defined? false in nil not or self super then
+ * true undef
+
+ * Always increment:
+ * begin class def do for module when {
+ *
+ * Always decrement:
+ * end }
+ *
+ * Increment if these start a statement
+ * if unless until while -- do nothing if they're modifiers
+
+ * These end a block if there's no modifier, but don't bother
+ * break next redo retry return yield
+ *
+ * These temporarily de-indent, but re-indent
+ * case else elsif ensure rescue
+ *
+ * This means that the folder reflects indentation rather
+ * than setting it. The language-service updates indentation
+ * when users type return and finishes entering de-denters.
+ *
+ * Later offer to fold POD, here-docs, strings, and blocks of comments
+ */
+
+static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
+ false);
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)
+ & SC_FOLDLEVELNUMBERMASK
+ & ~SC_FOLDLEVELBASE);
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1);
+ bool buffer_ends_with_eol = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_RB_COMMENTLINE) {
+ if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
+ if (chNext == '{') {
+ levelCurrent++;
+ } else if (chNext == '}' && levelCurrent > 0) {
+ levelCurrent--;
+ }
+ }
+ } else if (style == SCE_RB_OPERATOR) {
+ if (strchr("[{(", ch)) {
+ levelCurrent++;
+ } else if (strchr(")}]", ch)) {
+ // Don't decrement below 0
+ if (levelCurrent > 0)
+ levelCurrent--;
+ }
+ } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {
+ // Look at the keyword on the left and decide what to do
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ prevWord[0] = 0;
+ getPrevWord(i, prevWord, styler, SCE_RB_WORD);
+ if (!strcmp(prevWord, "end")) {
+ // Don't decrement below 0
+ if (levelCurrent > 0)
+ levelCurrent--;
+ } else if ( !strcmp(prevWord, "if")
+ || !strcmp(prevWord, "def")
+ || !strcmp(prevWord, "class")
+ || !strcmp(prevWord, "module")
+ || !strcmp(prevWord, "begin")
+ || !strcmp(prevWord, "case")
+ || !strcmp(prevWord, "do")
+ || !strcmp(prevWord, "while")
+ || !strcmp(prevWord, "unless")
+ || !strcmp(prevWord, "until")
+ || !strcmp(prevWord, "for")
+ ) {
+ levelCurrent++;
+ }
+ } else if (style == SCE_RB_HERE_DELIM) {
+ if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') {
+ levelCurrent++;
+ } else if (styleNext == SCE_RB_DEFAULT) {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ buffer_ends_with_eol = true;
+ } else if (!isspacechar(ch)) {
+ visibleChars++;
+ buffer_ends_with_eol = false;
+ }
+ stylePrev = style;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ if (!buffer_ends_with_eol) {
+ lineCurrent++;
+ int new_lev = levelCurrent;
+ if (visibleChars == 0 && foldCompact)
+ new_lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ new_lev |= SC_FOLDLEVELHEADERFLAG;
+ levelCurrent = new_lev;
+ }
+ styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE);
+}
+
+static const char * const rubyWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSML.cxx
+ ** Lexer for SML.
+ **/
+// Copyright 2009 by James Moffatt and Yuzhou Xin
+// Modified from LexCaml.cxx by Robert Roessler <robertr@rftp.com> Copyright 2005
+// 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"
+
+inline int issml(int c) {return isalnum(c) || c == '_';}
+inline int issmlf(int c) {return isalpha(c) || c == '_';}
+inline int issmld(int c) {return isdigit(c) || c == '_';}
+
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+void ColouriseSMLDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ StyleContext sc(startPos, length, initStyle, styler);
+ int nesting = 0;
+ if (sc.state < SCE_SML_STRING)
+ sc.state = SCE_SML_DEFAULT;
+ if (sc.state >= SCE_SML_COMMENT)
+ nesting = (sc.state & 0x0f) - SCE_SML_COMMENT;
+
+ int chBase = 0, chToken = 0, chLit = 0;
+ WordList& keywords = *keywordlists[0];
+ WordList& keywords2 = *keywordlists[1];
+ WordList& keywords3 = *keywordlists[2];
+ const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
+
+ while (sc.More()) {
+ int state2 = -1;
+ int chColor = sc.currentPos - 1;
+ bool advance = true;
+
+ switch (sc.state & 0x0f) {
+ case SCE_SML_DEFAULT:
+ chToken = sc.currentPos;
+ if (issmlf(sc.ch))
+ state2 = SCE_SML_IDENTIFIER;
+ else if (sc.Match('`') && issmlf(sc.chNext))
+ state2 = SCE_SML_TAGNAME;
+ else if (sc.Match('#')&&isdigit(sc.chNext))
+ state2 = SCE_SML_LINENUM;
+ else if (sc.Match('#','\"')){
+ state2 = SCE_SML_CHAR,chLit = 0;
+ sc.Forward();
+
+ }
+ else if (isdigit(sc.ch)) {
+ state2 = SCE_SML_NUMBER, chBase = 10;
+ if (sc.Match('0') && strchr("xX", sc.chNext))
+ chBase = 16, sc.Forward();}
+ else if (sc.Match('\"')&&sc.chPrev!='#')
+ state2 = SCE_SML_STRING;
+ else if (sc.Match('(', '*')){
+ state2 = SCE_SML_COMMENT,
+ sc.ch = ' ',
+ sc.Forward();}
+ else if (strchr("!~"
+ "=<>@^+-*/"
+ "()[];,:.#", sc.ch))
+ state2 = SCE_SML_OPERATOR;
+ break;
+
+ case SCE_SML_IDENTIFIER:
+ if (!(issml(sc.ch) || sc.Match('\''))) {
+ const int n = sc.currentPos - chToken;
+ if (n < 24) {
+ char t[24];
+ for (int i = -n; i < 0; i++)
+ t[n + i] = static_cast<char>(sc.GetRelative(i));
+ t[n] = '\0';
+ if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
+ sc.ChangeState(SCE_SML_KEYWORD);
+ else if (keywords2.InList(t))
+ sc.ChangeState(SCE_SML_KEYWORD2);
+ else if (keywords3.InList(t))
+ sc.ChangeState(SCE_SML_KEYWORD3);
+ }
+ state2 = SCE_SML_DEFAULT, advance = false;
+ }
+ break;
+
+ case SCE_SML_TAGNAME:
+ if (!(issml(sc.ch) || sc.Match('\'')))
+ state2 = SCE_SML_DEFAULT, advance = false;
+ break;
+
+ case SCE_SML_LINENUM:
+ if (!isdigit(sc.ch))
+ state2 = SCE_SML_DEFAULT, advance = false;
+ break;
+
+ case SCE_SML_OPERATOR: {
+ const char* o = 0;
+ if (issml(sc.ch) || isspace(sc.ch)
+ || (o = strchr(")]};,\'\"`#", sc.ch),o)
+ || !strchr("!$%&*+-./:<=>?@^|~", sc.ch)) {
+ if (o && strchr(")]};,", sc.ch)) {
+ if ((sc.Match(')') && sc.chPrev == '(')
+ || (sc.Match(']') && sc.chPrev == '['))
+ sc.ChangeState(SCE_SML_KEYWORD);
+ chColor++;
+ } else
+ advance = false;
+ state2 = SCE_SML_DEFAULT;
+ }
+ break;
+ }
+
+ case SCE_SML_NUMBER:
+ if (issmld(sc.ch) || IsADigit(sc.ch, chBase))
+ break;
+ if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
+ && (issmld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))
+ break;
+ if (chBase == 10) {
+ if (sc.Match('.') && issmld(sc.chPrev))
+ break;
+ if ((sc.Match('e') || sc.Match('E'))
+ && (issmld(sc.chPrev) || sc.chPrev == '.'))
+ break;
+ if ((sc.Match('+') || sc.Match('-'))
+ && (sc.chPrev == 'e' || sc.chPrev == 'E'))
+ break;
+ }
+ state2 = SCE_SML_DEFAULT, advance = false;
+ break;
+
+ case SCE_SML_CHAR:
+ if (sc.Match('\\')) {
+ chLit = 1;
+ if (sc.chPrev == '\\')
+ sc.ch = ' ';
+ } else if ((sc.Match('\"') && sc.chPrev != '\\') || sc.atLineEnd) {
+ state2 = SCE_SML_DEFAULT;
+ chLit = 1;
+ if (sc.Match('\"'))
+ chColor++;
+ else
+ sc.ChangeState(SCE_SML_IDENTIFIER);
+ } else if (chLit < 1 && sc.currentPos - chToken >= 3)
+ sc.ChangeState(SCE_SML_IDENTIFIER), advance = false;
+ break;
+
+ case SCE_SML_STRING:
+ if (sc.Match('\\') && sc.chPrev == '\\')
+ sc.ch = ' ';
+ else if (sc.Match('\"') && sc.chPrev != '\\')
+ state2 = SCE_SML_DEFAULT, chColor++;
+ break;
+
+ case SCE_SML_COMMENT:
+ case SCE_SML_COMMENT1:
+ case SCE_SML_COMMENT2:
+ case SCE_SML_COMMENT3:
+ if (sc.Match('(', '*'))
+ state2 = sc.state + 1, chToken = sc.currentPos,
+ sc.ch = ' ',
+ sc.Forward(), nesting++;
+ else if (sc.Match(')') && sc.chPrev == '*') {
+ if (nesting)
+ state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
+ else
+ state2 = SCE_SML_DEFAULT;
+ chColor++;
+ } else if (useMagic && sc.currentPos - chToken == 4
+ && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
+ sc.state |= 0x10;
+ break;
+ }
+
+ if (state2 >= 0)
+ styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
+ if (advance)
+ sc.Forward();
+ }
+
+ sc.Complete();
+}
+
+void FoldSMLDoc(
+ unsigned int, int,
+ int,
+ WordList *[],
+ Accessor &)
+{
+}
+
+static const char * const SMLWordListDesc[] = {
+ "Keywords",
+ "Keywords2",
+ "Keywords3",
+ 0
+};
+
+LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc);
+
--- /dev/null
+//-*- coding: utf-8 -*-
+// Scintilla source code edit control
+/** @file LexSQL.cxx
+ ** Lexer for SQL, including PL/SQL and SQL*Plus.
+ ** Improved by Jérôme LAFORGE <jerome.laforge_AT_gmail_DOT_com> from 2010 to 2012.
+ **/
+// Copyright 1998-2012 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 <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#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"
+#include "OptionSet.h"
+#include "SparseState.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) {
+ if (!sqlAllowDottedWord)
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+ else
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalpha(ch) || ch == '_');
+}
+
+static inline bool IsADoxygenChar(int ch) {
+ return (islower(ch) || ch == '$' || ch == '@' ||
+ ch == '\\' || ch == '&' || ch == '<' ||
+ ch == '>' || ch == '#' || ch == '{' ||
+ ch == '}' || ch == '[' || ch == ']');
+}
+
+static inline bool IsANumberChar(int ch) {
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases.
+ return (ch < 0x80) &&
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
+}
+
+
+class SQLStates {
+public :
+ void Set(int lineNumber, unsigned short int sqlStatesLine) {
+ sqlStatement.Set(lineNumber, sqlStatesLine);
+ }
+
+ unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_IGNORE_WHEN;
+ else
+ sqlStatesLine &= ~MASK_IGNORE_WHEN;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoCondition (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_CONDITION;
+ else
+ sqlStatesLine &= ~MASK_INTO_CONDITION;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoExceptionBlock (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_EXCEPTION;
+ else
+ sqlStatesLine &= ~MASK_INTO_EXCEPTION;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoDeclareBlock (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_DECLARE;
+ else
+ sqlStatesLine &= ~MASK_INTO_DECLARE;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoMergeStatement (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_MERGE_STATEMENT;
+ else
+ sqlStatesLine &= ~MASK_MERGE_STATEMENT;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int CaseMergeWithoutWhenFound (unsigned short int sqlStatesLine, bool found) {
+ if (found)
+ sqlStatesLine |= MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
+ else
+ sqlStatesLine &= ~MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoSelectStatement (unsigned short int sqlStatesLine, bool found) {
+ if (found)
+ sqlStatesLine |= MASK_INTO_SELECT_STATEMENT;
+ else
+ sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) {
+ if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
+ sqlStatesLine++;
+ }
+ return sqlStatesLine;
+ }
+
+ unsigned short int EndCaseBlock (unsigned short int sqlStatesLine) {
+ if ((sqlStatesLine & MASK_NESTED_CASES) > 0) {
+ sqlStatesLine--;
+ }
+ return sqlStatesLine;
+ }
+
+ bool IsIgnoreWhen (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_IGNORE_WHEN) != 0;
+ }
+
+ bool IsIntoCondition (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_CONDITION) != 0;
+ }
+
+ bool IsIntoCaseBlock (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_NESTED_CASES) != 0;
+ }
+
+ bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
+ }
+
+ bool IsIntoSelectStatement (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT) != 0;
+ }
+
+ bool IsCaseMergeWithoutWhenFound (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;
+ }
+
+ bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
+ }
+
+ bool IsIntoMergeStatement (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_MERGE_STATEMENT) != 0;
+ }
+
+ unsigned short int ForLine(int lineNumber) {
+ return sqlStatement.ValueAt(lineNumber);
+ }
+
+ SQLStates() {}
+
+private :
+ SparseState <unsigned short int> sqlStatement;
+ enum {
+ MASK_NESTED_CASES = 0x01FF,
+ MASK_INTO_SELECT_STATEMENT = 0x0200,
+ MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x0400,
+ MASK_MERGE_STATEMENT = 0x0800,
+ MASK_INTO_DECLARE = 0x1000,
+ MASK_INTO_EXCEPTION = 0x2000,
+ MASK_INTO_CONDITION = 0x4000,
+ MASK_IGNORE_WHEN = 0x8000
+ };
+};
+
+// Options used for LexerSQL
+struct OptionsSQL {
+ bool fold;
+ bool foldAtElse;
+ bool foldComment;
+ bool foldCompact;
+ bool foldOnlyBegin;
+ bool sqlBackticksIdentifier;
+ bool sqlNumbersignComment;
+ bool sqlBackslashEscapes;
+ bool sqlAllowDottedWord;
+ OptionsSQL() {
+ fold = false;
+ foldAtElse = false;
+ foldComment = false;
+ foldCompact = false;
+ foldOnlyBegin = false;
+ sqlBackticksIdentifier = false;
+ sqlNumbersignComment = false;
+ sqlBackslashEscapes = false;
+ sqlAllowDottedWord = false;
+ }
+};
+
+static const char * const sqlWordListDesc[] = {
+ "Keywords",
+ "Database Objects",
+ "PLDoc",
+ "SQL*Plus",
+ "User Keywords 1",
+ "User Keywords 2",
+ "User Keywords 3",
+ "User Keywords 4",
+ 0
+};
+
+struct OptionSetSQL : public OptionSet<OptionsSQL> {
+ OptionSetSQL() {
+ DefineProperty("fold", &OptionsSQL::fold);
+
+ DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
+ "This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
+
+ DefineProperty("fold.comment", &OptionsSQL::foldComment);
+
+ DefineProperty("fold.compact", &OptionsSQL::foldCompact);
+
+ DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin);
+
+ DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier);
+
+ DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment,
+ "If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.");
+
+ DefineProperty("sql.backslash.escapes", &OptionsSQL::sqlBackslashEscapes,
+ "Enables backslash as an escape character in SQL.");
+
+ DefineProperty("lexer.sql.allow.dotted.word", &OptionsSQL::sqlAllowDottedWord,
+ "Set to 1 to colourise recognized words with dots "
+ "(recommended for Oracle PL/SQL objects).");
+
+ DefineWordListSets(sqlWordListDesc);
+ }
+};
+
+class LexerSQL : public ILexer {
+public :
+ LexerSQL() {}
+
+ virtual ~LexerSQL() {}
+
+ int SCI_METHOD Version () const {
+ return lvOriginal;
+ }
+
+ void SCI_METHOD Release() {
+ delete this;
+ }
+
+ const char * SCI_METHOD PropertyNames() {
+ return osSQL.PropertyNames();
+ }
+
+ int SCI_METHOD PropertyType(const char *name) {
+ return osSQL.PropertyType(name);
+ }
+
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osSQL.DescribeProperty(name);
+ }
+
+ int SCI_METHOD PropertySet(const char *key, const char *val) {
+ if (osSQL.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+ }
+
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osSQL.DescribeWordListSets();
+ }
+
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex (unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactorySQL() {
+ return new LexerSQL();
+ }
+private:
+ bool IsStreamCommentStyle(int style) {
+ return style == SCE_SQL_COMMENT ||
+ style == SCE_SQL_COMMENTDOC ||
+ style == SCE_SQL_COMMENTDOCKEYWORD ||
+ style == SCE_SQL_COMMENTDOCKEYWORDERROR;
+ }
+
+ bool IsCommentStyle (int style) {
+ switch (style) {
+ case SCE_SQL_COMMENT :
+ case SCE_SQL_COMMENTDOC :
+ case SCE_SQL_COMMENTLINE :
+ case SCE_SQL_COMMENTLINEDOC :
+ case SCE_SQL_COMMENTDOCKEYWORD :
+ case SCE_SQL_COMMENTDOCKEYWORDERROR :
+ return true;
+ default :
+ return false;
+ }
+ }
+
+ bool IsCommentLine (int line, LexAccessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i + 1 < eol_pos; i++) {
+ int style = styler.StyleAt(i);
+ // MySQL needs -- comments to be followed by space or control char
+ if (style == SCE_SQL_COMMENTLINE && styler.Match(i, "--"))
+ return true;
+ else if (!IsASpaceOrTab(styler[i]))
+ return false;
+ }
+ return false;
+ }
+
+ OptionsSQL options;
+ OptionSetSQL osSQL;
+ SQLStates sqlStates;
+
+ WordList keywords1;
+ WordList keywords2;
+ WordList kw_pldoc;
+ WordList kw_sqlplus;
+ WordList kw_user1;
+ WordList kw_user2;
+ WordList kw_user3;
+ WordList kw_user4;
+};
+
+int SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords1;
+ break;
+ case 1:
+ wordListN = &keywords2;
+ break;
+ case 2:
+ wordListN = &kw_pldoc;
+ break;
+ case 3:
+ wordListN = &kw_sqlplus;
+ break;
+ case 4:
+ wordListN = &kw_user1;
+ break;
+ case 5:
+ wordListN = &kw_user2;
+ break;
+ case 6:
+ wordListN = &kw_user3;
+ break;
+ case 7:
+ wordListN = &kw_user4;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerSQL::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+ StyleContext sc(startPos, length, initStyle, styler);
+ int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
+ int offset = 0;
+ for (; sc.More(); sc.Forward(), offset++) {
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_SQL_OPERATOR:
+ sc.SetState(SCE_SQL_DEFAULT);
+ break;
+ case SCE_SQL_NUMBER:
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_IDENTIFIER:
+ if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {
+ int nextState = SCE_SQL_DEFAULT;
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords1.InList(s)) {
+ sc.ChangeState(SCE_SQL_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_SQL_WORD2);
+ } else if (kw_sqlplus.InListAbbreviated(s, '~')) {
+ sc.ChangeState(SCE_SQL_SQLPLUS);
+ if (strncmp(s, "rem", 3) == 0) {
+ nextState = SCE_SQL_SQLPLUS_COMMENT;
+ } else if (strncmp(s, "pro", 3) == 0) {
+ nextState = SCE_SQL_SQLPLUS_PROMPT;
+ }
+ } else if (kw_user1.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER1);
+ } else if (kw_user2.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER2);
+ } else if (kw_user3.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER3);
+ } else if (kw_user4.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER4);
+ }
+ sc.SetState(nextState);
+ }
+ break;
+ case SCE_SQL_QUOTEDIDENTIFIER:
+ if (sc.ch == 0x60) {
+ if (sc.chNext == 0x60) {
+ sc.Forward(); // Ignore it
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SQL_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = SCE_SQL_COMMENTDOC;
+ sc.SetState(SCE_SQL_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_SQL_COMMENTLINE:
+ case SCE_SQL_COMMENTLINEDOC:
+ case SCE_SQL_SQLPLUS_COMMENT:
+ case SCE_SQL_SQLPLUS_PROMPT:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ } else if (!IsADoxygenChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {
+ sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_SQL_CHARACTER:
+ if (options.sqlBackslashEscapes && sc.ch == '\\') {
+ sc.Forward();
+ } else if (sc.ch == '\'') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SQL_STRING:
+ if (sc.ch == '\\') {
+ // Escape sequence
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_SQL_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_SQL_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_SQL_IDENTIFIER);
+ } else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {
+ sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
+ sc.SetState(SCE_SQL_COMMENTDOC);
+ } else {
+ sc.SetState(SCE_SQL_COMMENT);
+ }
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('-', '-')) {
+ // MySQL requires a space or control char after --
+ // http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
+ // Perhaps we should enforce that with proper property:
+ //~ } else if (sc.Match("-- ")) {
+ sc.SetState(SCE_SQL_COMMENTLINE);
+ } else if (sc.ch == '#' && options.sqlNumbersignComment) {
+ sc.SetState(SCE_SQL_COMMENTLINEDOC);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_SQL_CHARACTER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_SQL_STRING);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_SQL_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ if (!options.fold)
+ return;
+ LexAccessor styler(pAccess);
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+
+ if (lineCurrent > 0) {
+ // Backtrack to previous line in case need to fix its fold status for folding block of single-line comments (i.e. '--').
+ lineCurrent -= 1;
+ startPos = styler.LineStart(lineCurrent);
+
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
+ }
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ bool endFound = false;
+ bool isUnfoldingIgnored = false;
+ // this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF
+ // eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;"
+ bool statementFound = false;
+ unsigned short int sqlStatesCurrentLine = 0;
+ if (!options.foldOnlyBegin) {
+ sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);
+ }
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
+ if (endFound) {
+ //Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
+ sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
+ }
+ // set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found
+ endFound = false;
+ isUnfoldingIgnored = false;
+ }
+ if ((!IsCommentStyle(style) && ch == ';')) {
+ if (sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)) {
+ // This is the end of "MERGE" statement.
+ if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ levelNext--;
+ sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false);
+ levelNext--;
+ }
+ if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine))
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine, false);
+ }
+ if (options.foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (options.foldComment && (style == SCE_SQL_COMMENTLINE)) {
+ // MySQL needs -- comments to be followed by space or control char
+ if ((ch == '-') && (chNext == '-')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ char chNext3 = styler.SafeGetCharAt(i + 3);
+ if (chNext2 == '{' || chNext3 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}' || chNext3 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ // Fold block of single-line comments (i.e. '--').
+ if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
+ if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler))
+ levelNext++;
+ else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent + 1, styler))
+ levelNext--;
+ }
+ if (style == SCE_SQL_OPERATOR) {
+ if (ch == '(') {
+ if (levelCurrent > levelNext)
+ levelCurrent--;
+ levelNext++;
+ } else if (ch == ')') {
+ levelNext--;
+ } else if ((!options.foldOnlyBegin) && ch == ';') {
+ sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);
+ }
+ }
+ // If new keyword (cannot trigger on elseif or nullif, does less tests)
+ if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
+ const int MAX_KW_LEN = 9; // Maximum length of folding keywords
+ char s[MAX_KW_LEN + 2];
+ unsigned int j = 0;
+ for (; j < MAX_KW_LEN + 1; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = static_cast<char>(tolower(styler[i + j]));
+ }
+ if (j == MAX_KW_LEN + 1) {
+ // Keyword too long, don't test it
+ s[0] = '\0';
+ } else {
+ s[j] = '\0';
+ }
+
+ if (!options.foldOnlyBegin &&
+ strcmp(s, "select") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine, true);
+ } else if (strcmp(s, "if") == 0) {
+ if (endFound) {
+ endFound = false;
+ if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+ // this end isn't for begin block, but for if block ("end if;")
+ // so ignore previous "end" by increment levelNext.
+ levelNext++;
+ }
+ } else {
+ if (!options.foldOnlyBegin)
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+ if (levelCurrent > levelNext) {
+ // doesn't include this line into the folding block
+ // because doesn't hide IF (eg "END; IF")
+ levelCurrent = levelNext;
+ }
+ }
+ } else if (!options.foldOnlyBegin &&
+ strcmp(s, "then") == 0 &&
+ sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);
+ if (!options.foldOnlyBegin) {
+ if (levelCurrent > levelNext) {
+ levelCurrent = levelNext;
+ }
+ if (!statementFound)
+ levelNext++;
+
+ statementFound = true;
+ } else if (levelCurrent > levelNext) {
+ // doesn't include this line into the folding block
+ // because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+ levelCurrent = levelNext;
+ }
+ } else if (strcmp(s, "loop") == 0 ||
+ strcmp(s, "case") == 0) {
+ if (endFound) {
+ endFound = false;
+ if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+ // this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;")
+ // so ignore previous "end" by increment levelNext.
+ levelNext++;
+ }
+ if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
+ sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
+ if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ levelNext--; //again for the "end case;" and block when
+ }
+ } else if (!options.foldOnlyBegin) {
+ if (strcmp(s, "case") == 0)
+ sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
+
+ if (levelCurrent > levelNext)
+ levelCurrent = levelNext;
+
+ if (!statementFound)
+ levelNext++;
+
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
+ statementFound = true;
+ } else if (levelCurrent > levelNext) {
+ // doesn't include this line into the folding block
+ // because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+ levelCurrent = levelNext;
+ }
+ } else if ((!options.foldOnlyBegin) && (
+ // folding for ELSE and ELSIF block only if foldAtElse is set
+ // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+ options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+ levelCurrent--;
+ levelNext--;
+ } else if ((!options.foldOnlyBegin) && (
+ // folding for ELSE and ELSIF block only if foldAtElse is set
+ // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+ options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
+ // prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
+ statementFound = true;
+ if (sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) && sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);
+ levelNext++;
+ } else {
+ // we are in same case "} ELSE {" in C language
+ levelCurrent--;
+ }
+ } else if (strcmp(s, "begin") == 0) {
+ levelNext++;
+ sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
+ } else if ((strcmp(s, "end") == 0) ||
+ // SQL Anywhere permits IF ... ELSE ... ENDIF
+ // will only be active if "endif" appears in the
+ // keyword list.
+ (strcmp(s, "endif") == 0)) {
+ endFound = true;
+ levelNext--;
+ if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE) {
+ levelNext = SC_FOLDLEVELBASE;
+ isUnfoldingIgnored = true;
+ }
+ } else if ((!options.foldOnlyBegin) &&
+ strcmp(s, "when") == 0 &&
+ !sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) &&
+ !sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) && (
+ sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) ||
+ sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)
+ )
+ ) {
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+
+ // Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n")
+ // and same way for MERGE statement.
+ if (!statementFound) {
+ if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {
+ levelCurrent--;
+ levelNext--;
+ }
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);
+ }
+ } else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) {
+ sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, "exception") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) &&
+ (strcmp(s, "declare") == 0 ||
+ strcmp(s, "function") == 0 ||
+ strcmp(s, "procedure") == 0 ||
+ strcmp(s, "package") == 0)) {
+ sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) &&
+ strcmp(s, "merge") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, true);
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
+ levelNext++;
+ statementFound = true;
+ }
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && options.foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+ statementFound = false;
+ if (!options.foldOnlyBegin)
+ sqlStates.Set(lineCurrent, sqlStatesCurrentLine);
+ }
+ if (!isspacechar(ch)) {
+ visibleChars++;
+ }
+ }
+}
+
+LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", sqlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexScriptol.cxx
+ ** Lexer for Scriptol.
+ **/
+
+#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 void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
+{
+ char s[100];
+ bool wordIsNumber = isdigit(styler[start]) != 0;
+ for (unsigned int i = 0; i < end - start + 1 && i < 30; i++)
+ {
+ s[i] = styler[start + i];
+ s[i + 1] = '\0';
+ }
+ char chAttr = SCE_SCRIPTOL_IDENTIFIER;
+ if (0 == strcmp(prevWord, "class")) chAttr = SCE_SCRIPTOL_CLASSNAME;
+ else if (wordIsNumber) chAttr = SCE_SCRIPTOL_NUMBER;
+ else if (keywords.InList(s)) chAttr = SCE_SCRIPTOL_KEYWORD;
+ else for (unsigned int i = 0; i < end - start + 1; i++) // test dotted idents
+ {
+ if (styler[start + i] == '.')
+ {
+ styler.ColourTo(start + i - 1, chAttr);
+ styler.ColourTo(start + i, SCE_SCRIPTOL_OPERATOR);
+ }
+ }
+ styler.ColourTo(end, chAttr);
+ strcpy(prevWord, s);
+}
+
+static bool IsSolComment(Accessor &styler, int pos, int len)
+{
+ if(len > 0)
+ {
+ char c = styler[pos];
+ if(c == '`') return true;
+ if(len > 1)
+ {
+ if(c == '/')
+ {
+ c = styler[pos + 1];
+ if(c == '/') return true;
+ if(c == '*') return true;
+ }
+ }
+ }
+ return false;
+}
+
+static bool IsSolStringStart(char ch)
+{
+ if (ch == '\'' || ch == '"') return true;
+ return false;
+}
+
+static bool IsSolWordStart(char ch)
+{
+ return (iswordchar(ch) && !IsSolStringStart(ch));
+}
+
+
+static int GetSolStringState(Accessor &styler, int i, int *nextIndex)
+{
+ char ch = styler.SafeGetCharAt(i);
+ char chNext = styler.SafeGetCharAt(i + 1);
+
+ if (ch != '\"' && ch != '\'')
+ {
+ *nextIndex = i + 1;
+ return SCE_SCRIPTOL_DEFAULT;
+ }
+ // ch is either single or double quotes in string
+ // code below seem non-sense but is here for future extensions
+ if (ch == chNext && ch == styler.SafeGetCharAt(i + 2))
+ {
+ *nextIndex = i + 3;
+ if(ch == '\"') return SCE_SCRIPTOL_TRIPLE;
+ if(ch == '\'') return SCE_SCRIPTOL_TRIPLE;
+ return SCE_SCRIPTOL_STRING;
+ }
+ else
+ {
+ *nextIndex = i + 1;
+ if (ch == '"') return SCE_SCRIPTOL_STRING;
+ else return SCE_SCRIPTOL_STRING;
+ }
+}
+
+
+static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler)
+ {
+
+ int lengthDoc = startPos + length;
+ char stringType = '\"';
+
+ if (startPos > 0)
+ {
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0)
+ {
+ startPos = styler.LineStart(lineCurrent-1);
+ if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT;
+ else initStyle = styler.StyleAt(startPos-1);
+ }
+ }
+
+ styler.StartAt(startPos, 127);
+
+ WordList &keywords = *keywordlists[0];
+
+ int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
+ char prevWord[200];
+ prevWord[0] = '\0';
+ if (length == 0) return;
+
+ int state = initStyle & 31;
+
+ int nextIndex = 0;
+ char chPrev = ' ';
+ char chPrev2 = ' ';
+ char chNext = styler[startPos];
+ styler.StartSegment(startPos);
+ bool atStartLine = true;
+ int spaceFlags = 0;
+ for (int i = startPos; i < lengthDoc; i++)
+ {
+
+ if (atStartLine)
+ {
+ char chBad = static_cast<char>(64);
+ char chGood = static_cast<char>(0);
+ char chFlags = chGood;
+
+ if (whingeLevel == 1)
+ {
+ chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
+ }
+ else if (whingeLevel == 2)
+ {
+ chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
+ }
+ else if (whingeLevel == 3)
+ {
+ chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
+ }
+ else if (whingeLevel == 4)
+ {
+ chFlags = (spaceFlags & wsTab) ? chBad : chGood;
+ }
+ styler.SetFlags(chFlags, static_cast<char>(state));
+ atStartLine = false;
+ }
+
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
+ {
+ if ((state == SCE_SCRIPTOL_DEFAULT) ||
+ (state == SCE_SCRIPTOL_TRIPLE) ||
+ (state == SCE_SCRIPTOL_COMMENTBLOCK))
+ {
+ styler.ColourTo(i, state);
+ }
+ atStartLine = true;
+ }
+
+ if (styler.IsLeadByte(ch))
+ {
+ chNext = styler.SafeGetCharAt(i + 2);
+ chPrev = ' ';
+ chPrev2 = ' ';
+ i += 1;
+ continue;
+ }
+
+ if (state == SCE_SCRIPTOL_STRINGEOL)
+ {
+ if (ch != '\r' && ch != '\n')
+ {
+ styler.ColourTo(i - 1, state);
+ state = SCE_SCRIPTOL_DEFAULT;
+ }
+ }
+
+ if (state == SCE_SCRIPTOL_DEFAULT)
+ {
+ if (IsSolWordStart(ch))
+ {
+ styler.ColourTo(i - 1, state);
+ state = SCE_SCRIPTOL_KEYWORD;
+ }
+ else if (ch == '`')
+ {
+ styler.ColourTo(i - 1, state);
+ state = SCE_SCRIPTOL_COMMENTLINE;
+ }
+ else if (ch == '/')
+ {
+ styler.ColourTo(i - 1, state);
+ if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;
+ if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;
+ }
+
+ else if (IsSolStringStart(ch))
+ {
+ styler.ColourTo(i - 1, state);
+ state = GetSolStringState(styler, i, &nextIndex);
+ if(state == SCE_SCRIPTOL_STRING)
+ {
+ stringType = ch;
+ }
+ if (nextIndex != i + 1)
+ {
+ i = nextIndex - 1;
+ ch = ' ';
+ chPrev = ' ';
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ }
+ else if (isoperator(ch))
+ {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
+ }
+ }
+ else if (state == SCE_SCRIPTOL_KEYWORD)
+ {
+ if (!iswordchar(ch))
+ {
+ ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
+ state = SCE_SCRIPTOL_DEFAULT;
+ if (ch == '`')
+ {
+ state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;
+ }
+ else if (IsSolStringStart(ch))
+ {
+ styler.ColourTo(i - 1, state);
+ state = GetSolStringState(styler, i, &nextIndex);
+ if (nextIndex != i + 1)
+ {
+ i = nextIndex - 1;
+ ch = ' ';
+ chPrev = ' ';
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ }
+ else if (isoperator(ch))
+ {
+ styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
+ }
+ }
+ }
+ else
+ {
+ if (state == SCE_SCRIPTOL_COMMENTLINE ||
+ state == SCE_SCRIPTOL_PERSISTENT ||
+ state == SCE_SCRIPTOL_CSTYLE)
+ {
+ if (ch == '\r' || ch == '\n')
+ {
+ styler.ColourTo(i - 1, state);
+ state = SCE_SCRIPTOL_DEFAULT;
+ }
+ }
+ else if(state == SCE_SCRIPTOL_COMMENTBLOCK)
+ {
+ if(chPrev == '*' && ch == '/')
+ {
+ styler.ColourTo(i, state);
+ state = SCE_SCRIPTOL_DEFAULT;
+ }
+ }
+ else if ((state == SCE_SCRIPTOL_STRING) ||
+ (state == SCE_SCRIPTOL_CHARACTER))
+ {
+ if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
+ {
+ styler.ColourTo(i - 1, state);
+ state = SCE_SCRIPTOL_STRINGEOL;
+ }
+ else if (ch == '\\')
+ {
+ if (chNext == '\"' || chNext == '\'' || chNext == '\\')
+ {
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ }
+ else if ((ch == '\"') || (ch == '\''))
+ {
+ // must match the entered quote type
+ if(ch == stringType)
+ {
+ styler.ColourTo(i, state);
+ state = SCE_SCRIPTOL_DEFAULT;
+ }
+ }
+ }
+ else if (state == SCE_SCRIPTOL_TRIPLE)
+ {
+ if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') ||
+ (ch == '\"' && chPrev == '\"' && chPrev2 == '\"'))
+ {
+ styler.ColourTo(i, state);
+ state = SCE_SCRIPTOL_DEFAULT;
+ }
+ }
+
+ }
+ chPrev2 = chPrev;
+ chPrev = ch;
+ }
+ if (state == SCE_SCRIPTOL_KEYWORD)
+ {
+ ClassifyWordSol(styler.GetStartSegment(),
+ lengthDoc-1, keywords, styler, prevWord);
+ }
+ else
+ {
+ styler.ColourTo(lengthDoc-1, state);
+ }
+}
+
+static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler)
+ {
+ int lengthDoc = startPos + length;
+
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0)
+ {
+ if (lineCurrent > 0)
+ {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ if (startPos == 0)
+ initStyle = SCE_SCRIPTOL_DEFAULT;
+ else
+ initStyle = styler.StyleAt(startPos-1);
+ }
+ }
+ int state = initStyle & 31;
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
+ if (state == SCE_SCRIPTOL_TRIPLE)
+ indentCurrent |= SC_FOLDLEVELWHITEFLAG;
+ char chNext = styler[startPos];
+ for (int i = startPos; i < lengthDoc; i++)
+ {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i) & 31;
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
+ {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);
+ if (style == SCE_SCRIPTOL_TRIPLE)
+ indentNext |= SC_FOLDLEVELWHITEFLAG;
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
+ {
+ // Only non whitespace lines can be headers
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
+ {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ else if (indentNext & SC_FOLDLEVELWHITEFLAG)
+ {
+ // Line after is blank so check the next - maybe should continue further?
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))
+ {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSmalltalk.cxx
+ ** Lexer for Smalltalk language.
+ ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com
+ **/
+// Copyright 1998-2002 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
+
+/*
+| lexTable classificationBlock charClasses |
+charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
+lexTable := ByteArray new: 128.
+classificationBlock := [ :charClass :chars |
+ | flag |
+ flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
+ chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
+
+classificationBlock
+ value: #DecDigit value: '0123456789';
+ value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ value: #Special value: '()[]{};.^:';
+ value: #BinSel value: '~@%&*-+=|\/,<>?!';
+ value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
+
+((String new: 500) streamContents: [ :stream |
+ stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
+ lexTable keysAndValuesDo: [ :index :value |
+ ((index - 1) rem: 16) == 0 ifTrue: [
+ stream crLf; tab]
+ ifFalse: [
+ stream space].
+ stream print: value.
+ index ~= 256 ifTrue: [
+ stream nextPut: $,]].
+ stream crLf; nextPutAll: '};'; crLf.
+
+ charClasses keysAndValuesDo: [ :index :name |
+ stream
+ crLf;
+ nextPutAll: (
+ ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
+ expandMacrosWith: name with: (1 bitShift: (index - 1)))
+ ]]) edit
+*/
+
+// autogenerated {{{{
+
+static int ClassificationTable[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16,
+ 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2,
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0,
+};
+
+static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}
+static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}
+static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}
+static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}
+static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}
+// autogenerated }}}}
+
+static inline bool isAlphaNumeric(int ch) {
+ return isDecDigit(ch) || isLetter(ch);
+}
+
+static inline bool isDigitOfRadix(int ch, int radix)
+{
+ if (isDecDigit(ch))
+ return (ch - '0') < radix;
+ else if (!isUpper(ch))
+ return false;
+ else
+ return (ch - 'A' + 10) < radix;
+}
+
+static inline void skipComment(StyleContext& sc)
+{
+ while (sc.More() && sc.ch != '\"')
+ sc.Forward();
+}
+
+static inline void skipString(StyleContext& sc)
+{
+ while (sc.More()) {
+ if (sc.ch == '\'') {
+ if (sc.chNext != '\'')
+ return;
+ sc.Forward();
+ }
+ sc.Forward();
+ }
+}
+
+static void handleHash(StyleContext& sc)
+{
+ if (isSpecial(sc.chNext)) {
+ sc.SetState(SCE_ST_SPECIAL);
+ return;
+ }
+
+ sc.SetState(SCE_ST_SYMBOL);
+ sc.Forward();
+ if (sc.ch == '\'') {
+ sc.Forward();
+ skipString(sc);
+ }
+ else {
+ if (isLetter(sc.ch)) {
+ while (isAlphaNumeric(sc.chNext) || sc.chNext == ':')
+ sc.Forward();
+ }
+ else if (isBinSel(sc.ch)) {
+ while (isBinSel(sc.chNext))
+ sc.Forward();
+ }
+ }
+}
+
+static inline void handleSpecial(StyleContext& sc)
+{
+ if (sc.ch == ':' && sc.chNext == '=') {
+ sc.SetState(SCE_ST_ASSIGN);
+ sc.Forward();
+ }
+ else {
+ if (sc.ch == '^')
+ sc.SetState(SCE_ST_RETURN);
+ else
+ sc.SetState(SCE_ST_SPECIAL);
+ }
+}
+
+static inline void skipInt(StyleContext& sc, int radix)
+{
+ while (isDigitOfRadix(sc.chNext, radix))
+ sc.Forward();
+}
+
+static void handleNumeric(StyleContext& sc)
+{
+ char num[256];
+ int nl;
+ int radix;
+
+ sc.SetState(SCE_ST_NUMBER);
+ num[0] = static_cast<char>(sc.ch);
+ nl = 1;
+ while (isDecDigit(sc.chNext)) {
+ num[nl++] = static_cast<char>(sc.chNext);
+ sc.Forward();
+ if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check
+ break;
+ }
+ if (sc.chNext == 'r') {
+ num[nl] = 0;
+ if (num[0] == '-')
+ radix = atoi(num + 1);
+ else
+ radix = atoi(num);
+ sc.Forward();
+ if (sc.chNext == '-')
+ sc.Forward();
+ skipInt(sc, radix);
+ }
+ else
+ radix = 10;
+ if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix))
+ return;
+ sc.Forward();
+ skipInt(sc, radix);
+ if (sc.chNext == 's') {
+ // ScaledDecimal
+ sc.Forward();
+ while (isDecDigit(sc.chNext))
+ sc.Forward();
+ return;
+ }
+ else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q')
+ return;
+ sc.Forward();
+ if (sc.chNext == '+' || sc.chNext == '-')
+ sc.Forward();
+ skipInt(sc, radix);
+}
+
+static inline void handleBinSel(StyleContext& sc)
+{
+ sc.SetState(SCE_ST_BINARY);
+ while (isBinSel(sc.chNext))
+ sc.Forward();
+}
+
+static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
+{
+ char ident[256];
+ int il;
+ int state;
+ bool doubleColonPresent;
+
+ sc.SetState(SCE_ST_DEFAULT);
+
+ ident[0] = static_cast<char>(sc.ch);
+ il = 1;
+ while (isAlphaNumeric(sc.chNext)) {
+ ident[il++] = static_cast<char>(sc.chNext);
+ sc.Forward();
+ if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check
+ break;
+ }
+
+ if (sc.chNext == ':') {
+ doubleColonPresent = true;
+ ident[il++] = ':';
+ sc.Forward();
+ }
+ else
+ doubleColonPresent = false;
+ ident[il] = 0;
+
+ if (specialSelectorList->InList(ident))
+ state = SCE_ST_SPEC_SEL;
+ else if (doubleColonPresent)
+ state = SCE_ST_KWSEND;
+ else if (isUpper(ident[0]))
+ state = SCE_ST_GLOBAL;
+ else {
+ if (!strcmp(ident, "self"))
+ state = SCE_ST_SELF;
+ else if (!strcmp(ident, "super"))
+ state = SCE_ST_SUPER;
+ else if (!strcmp(ident, "nil"))
+ state = SCE_ST_NIL;
+ else if (!strcmp(ident, "true") || !strcmp(ident, "false"))
+ state = SCE_ST_BOOL;
+ else
+ state = SCE_ST_DEFAULT;
+ }
+
+ sc.ChangeState(state);
+}
+
+static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *wordLists[], Accessor &styler)
+{
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ if (initStyle == SCE_ST_COMMENT) {
+ skipComment(sc);
+ if (sc.More())
+ sc.Forward();
+ }
+ else if (initStyle == SCE_ST_STRING) {
+ skipString(sc);
+ if (sc.More())
+ sc.Forward();
+ }
+
+ for (; sc.More(); sc.Forward()) {
+ int ch;
+
+ ch = sc.ch;
+ if (ch == '\"') {
+ sc.SetState(SCE_ST_COMMENT);
+ sc.Forward();
+ skipComment(sc);
+ }
+ else if (ch == '\'') {
+ sc.SetState(SCE_ST_STRING);
+ sc.Forward();
+ skipString(sc);
+ }
+ else if (ch == '#')
+ handleHash(sc);
+ else if (ch == '$') {
+ sc.SetState(SCE_ST_CHARACTER);
+ sc.Forward();
+ }
+ else if (isSpecial(ch))
+ handleSpecial(sc);
+ else if (isDecDigit(ch))
+ handleNumeric(sc);
+ else if (isLetter(ch))
+ handleLetter(sc, wordLists[0]);
+ else if (isBinSel(ch)) {
+ if (ch == '-' && isDecDigit(sc.chNext))
+ handleNumeric(sc);
+ else
+ handleBinSel(sc);
+ }
+ else
+ sc.SetState(SCE_ST_DEFAULT);
+ }
+ sc.Complete();
+}
+
+static const char* const smalltalkWordListDesc[] = {
+ "Special selectors",
+ 0
+};
+
+LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSorcus.cxx
+** Lexer for SORCUS installation files
+** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany
+** Based on the ASM Lexer by The Black Horus
+**/
+
+// 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
+
+
+//each character a..z and A..Z + '_' can be part of a keyword
+//additionally numbers that follow 'M' can be contained in a keyword
+static inline bool IsSWordStart(const int ch, const int prev_ch)
+{
+ if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
+ return true;
+
+ return false;
+}
+
+
+//only digits that are not preceded by 'M' count as a number
+static inline bool IsSorcusNumber(const int ch, const int prev_ch)
+{
+ if ((isdigit(ch)) && (prev_ch != 'M'))
+ return true;
+
+ return false;
+}
+
+
+//only = is a valid operator
+static inline bool IsSorcusOperator(const int ch)
+{
+ if (ch == '=')
+ return true;
+
+ return false;
+}
+
+
+static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler)
+{
+
+ WordList &Command = *keywordlists[0];
+ WordList &Parameter = *keywordlists[1];
+ WordList &Constant = *keywordlists[2];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_SORCUS_STRINGEOL)
+ initStyle = SCE_SORCUS_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+
+ // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
+ if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
+ {
+ sc.SetState(SCE_SORCUS_STRING);
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_SORCUS_OPERATOR)
+ {
+ if (!IsSorcusOperator(sc.ch))
+ {
+ sc.SetState(SCE_SORCUS_DEFAULT);
+ }
+ }
+ else if(sc.state == SCE_SORCUS_NUMBER)
+ {
+ if(!IsSorcusNumber(sc.ch, sc.chPrev))
+ {
+ sc.SetState(SCE_SORCUS_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_SORCUS_IDENTIFIER)
+ {
+ if (!IsSWordStart(sc.ch, sc.chPrev))
+ {
+ char s[100];
+
+ sc.GetCurrent(s, sizeof(s));
+
+ if (Command.InList(s))
+ {
+ sc.ChangeState(SCE_SORCUS_COMMAND);
+ }
+ else if (Parameter.InList(s))
+ {
+ sc.ChangeState(SCE_SORCUS_PARAMETER);
+ }
+ else if (Constant.InList(s))
+ {
+ sc.ChangeState(SCE_SORCUS_CONSTANT);
+ }
+
+ sc.SetState(SCE_SORCUS_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_SORCUS_COMMENTLINE )
+ {
+ if (sc.atLineEnd)
+ {
+ sc.SetState(SCE_SORCUS_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_SORCUS_STRING)
+ {
+ if (sc.ch == '\"')
+ {
+ sc.ForwardSetState(SCE_SORCUS_DEFAULT);
+ }
+ else if (sc.atLineEnd)
+ {
+ sc.ChangeState(SCE_SORCUS_STRINGEOL);
+ sc.ForwardSetState(SCE_SORCUS_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_SORCUS_DEFAULT)
+ {
+ if ((sc.ch == ';') || (sc.ch == '\''))
+ {
+ sc.SetState(SCE_SORCUS_COMMENTLINE);
+ }
+ else if (IsSWordStart(sc.ch, sc.chPrev))
+ {
+ sc.SetState(SCE_SORCUS_IDENTIFIER);
+ }
+ else if (sc.ch == '\"')
+ {
+ sc.SetState(SCE_SORCUS_STRING);
+ }
+ else if (IsSorcusOperator(sc.ch))
+ {
+ sc.SetState(SCE_SORCUS_OPERATOR);
+ }
+ else if (IsSorcusNumber(sc.ch, sc.chPrev))
+ {
+ sc.SetState(SCE_SORCUS_NUMBER);
+ }
+ }
+
+ }
+ sc.Complete();
+}
+
+
+static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
+
+LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSpecman.cxx
+ ** Lexer for Specman E language.
+ ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson
+ **/
+// Copyright 1998-2002 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
+}
+
+static inline bool IsANumberChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\'');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '`');
+}
+
+static void ColouriseSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler, bool caseSensitive) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_SN_STRINGEOL)
+ initStyle = SCE_SN_CODE;
+
+ int visibleChars = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart && (sc.state == SCE_SN_STRING)) {
+ // Prevent SCE_SN_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_SN_STRING);
+ }
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_SN_OPERATOR) {
+ sc.SetState(SCE_SN_CODE);
+ } else if (sc.state == SCE_SN_NUMBER) {
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_SN_CODE);
+ }
+ } else if (sc.state == SCE_SN_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[100];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_SN_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_SN_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_SN_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_SN_USER);
+ }
+ sc.SetState(SCE_SN_CODE);
+ }
+ } else if (sc.state == SCE_SN_PREPROCESSOR) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_SN_CODE);
+ }
+ } else if (sc.state == SCE_SN_DEFAULT) {
+ if (sc.Match('<', '\'')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SN_CODE);
+ }
+ } else if (sc.state == SCE_SN_COMMENTLINE || sc.state == SCE_SN_COMMENTLINEBANG) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_SN_CODE);
+ visibleChars = 0;
+ }
+ } else if (sc.state == SCE_SN_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_SN_CODE);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_SN_STRINGEOL);
+ sc.ForwardSetState(SCE_SN_CODE);
+ visibleChars = 0;
+ }
+ } else if (sc.state == SCE_SN_SIGNAL) {
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_SN_STRINGEOL);
+ sc.ForwardSetState(SCE_SN_CODE);
+ visibleChars = 0;
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_SN_CODE);
+ }
+ } else if (sc.state == SCE_SN_REGEXTAG) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_SN_CODE);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_SN_CODE) {
+ if (sc.ch == '$' && IsADigit(sc.chNext)) {
+ sc.SetState(SCE_SN_REGEXTAG);
+ sc.Forward();
+ } else if (IsADigit(sc.ch)) {
+ sc.SetState(SCE_SN_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_SN_IDENTIFIER);
+ } else if (sc.Match('\'', '>')) {
+ sc.SetState(SCE_SN_DEFAULT);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ if (sc.Match("//!")) // Nice to have a different comment style
+ sc.SetState(SCE_SN_COMMENTLINEBANG);
+ else
+ sc.SetState(SCE_SN_COMMENTLINE);
+ } else if (sc.Match('-', '-')) {
+ if (sc.Match("--!")) // Nice to have a different comment style
+ sc.SetState(SCE_SN_COMMENTLINEBANG);
+ else
+ sc.SetState(SCE_SN_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_SN_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_SN_SIGNAL);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_SN_PREPROCESSOR);
+ // Skip whitespace between # and preprocessor word
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_SN_CODE);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@') {
+ sc.SetState(SCE_SN_OPERATOR);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldNoBoxSpecmanDoc(unsigned int startPos, int length, int,
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ //int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && (style == SCE_SN_COMMENTLINE)) {
+ if (((ch == '/') && (chNext == '/')) ||
+ ((ch == '-') && (chNext == '-'))) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ if (style == SCE_SN_OPERATOR) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+}
+
+static void FoldSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ FoldNoBoxSpecmanDoc(startPos, length, initStyle, styler);
+}
+
+static const char * const specmanWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Sequence keywords and identifiers",
+ "User defined keywords and identifiers",
+ "Unused",
+ 0,
+ };
+
+static void ColouriseSpecmanDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ ColouriseSpecmanDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+
+LexerModule lmSpecman(SCLEX_SPECMAN, ColouriseSpecmanDocSensitive, "specman", FoldSpecmanDoc, specmanWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSpice.cxx
+ ** Lexer for Spice
+ **/
+// Copyright 2006 by Fabien Proriol
+// 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 <string>
+
+#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
+
+/*
+ * Interface
+ */
+
+static void ColouriseDocument(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static const char * const spiceWordListDesc[] = {
+ "Keywords", // SPICE command
+ "Keywords2", // SPICE functions
+ "Keywords3", // SPICE params
+ 0
+};
+
+LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
+
+/*
+ * Implementation
+ */
+
+static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
+
+static inline bool IsDelimiterCharacter(int ch);
+static inline bool IsNumberStartCharacter(int ch);
+static inline bool IsNumberCharacter(int ch);
+static inline bool IsSeparatorOrDelimiterCharacter(int ch);
+static inline bool IsWordStartCharacter(int ch);
+static inline bool IsWordCharacter(int ch);
+
+static void ColouriseComment(StyleContext& sc, bool&) {
+ sc.SetState(SCE_SPICE_COMMENTLINE);
+ while (!sc.atLineEnd) {
+ sc.Forward();
+ }
+}
+
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = sc.Match (')');
+ sc.SetState(SCE_SPICE_DELIMITER);
+ sc.ForwardSetState(SCE_SPICE_DEFAULT);
+}
+
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = true;
+ std::string number;
+ sc.SetState(SCE_SPICE_NUMBER);
+ // Get all characters up to a delimiter or a separator, including points, but excluding
+ // double points (ranges).
+ while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward();
+ }
+ // Special case: exponent with sign
+ if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+ (sc.ch == '+' || sc.ch == '-')) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward ();
+ while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ number += static_cast<char>(sc.ch);
+ sc.Forward();
+ }
+ }
+ sc.SetState(SCE_SPICE_DEFAULT);
+}
+
+static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
+ sc.SetState(SCE_SPICE_DEFAULT);
+ sc.ForwardSetState(SCE_SPICE_DEFAULT);
+}
+
+static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
+ apostropheStartsAttribute = true;
+ sc.SetState(SCE_SPICE_IDENTIFIER);
+ std::string word;
+ while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+ word += static_cast<char>(tolower(sc.ch));
+ sc.Forward();
+ }
+ if (keywords.InList(word.c_str())) {
+ sc.ChangeState(SCE_SPICE_KEYWORD);
+ if (word != "all") {
+ apostropheStartsAttribute = false;
+ }
+ }
+ else if (keywords2.InList(word.c_str())) {
+ sc.ChangeState(SCE_SPICE_KEYWORD2);
+ if (word != "all") {
+ apostropheStartsAttribute = false;
+ }
+ }
+ else if (keywords3.InList(word.c_str())) {
+ sc.ChangeState(SCE_SPICE_KEYWORD3);
+ if (word != "all") {
+ apostropheStartsAttribute = false;
+ }
+ }
+ sc.SetState(SCE_SPICE_DEFAULT);
+}
+
+//
+// ColouriseDocument
+//
+static void ColouriseDocument(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler) {
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ StyleContext sc(startPos, length, initStyle, styler);
+ int lineCurrent = styler.GetLine(startPos);
+ bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
+ while (sc.More()) {
+ if (sc.atLineEnd) {
+ // Go to the next line
+ sc.Forward();
+ lineCurrent++;
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, apostropheStartsAttribute);
+ // Don't continue any styles on the next line
+ sc.SetState(SCE_SPICE_DEFAULT);
+ }
+ // Comments
+ if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
+ ColouriseComment(sc, apostropheStartsAttribute);
+ // Whitespace
+ } else if (IsASpace(sc.ch)) {
+ ColouriseWhiteSpace(sc, apostropheStartsAttribute);
+ // Delimiters
+ } else if (IsDelimiterCharacter(sc.ch)) {
+ ColouriseDelimiter(sc, apostropheStartsAttribute);
+ // Numbers
+ } else if (IsADigit(sc.ch) || sc.ch == '#') {
+ ColouriseNumber(sc, apostropheStartsAttribute);
+ // Keywords or identifiers
+ } else {
+ ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
+ }
+ }
+ sc.Complete();
+}
+
+static inline bool IsDelimiterCharacter(int ch) {
+ switch (ch) {
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case '-':
+ case '.':
+ case '/':
+ case ':':
+ case ';':
+ case '<':
+ case '=':
+ case '>':
+ case '|':
+ return true;
+ default:
+ return false;
+ }
+}
+
+static inline bool IsNumberCharacter(int ch) {
+ return IsNumberStartCharacter(ch) ||
+ ch == '_' ||
+ ch == '.' ||
+ ch == '#' ||
+ (ch >= 'a' && ch <= 'f') ||
+ (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool IsNumberStartCharacter(int ch) {
+ return IsADigit(ch);
+}
+
+static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
+ return IsASpace(ch) || IsDelimiterCharacter(ch);
+}
+
+static inline bool IsWordCharacter(int ch) {
+ return IsWordStartCharacter(ch) || IsADigit(ch);
+}
+
+static inline bool IsWordStartCharacter(int ch) {
+ return (isascii(ch) && isalpha(ch)) || ch == '_';
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file LexTAL.cxx
+ ** Lexer for TAL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to TACL
+ **/
+
+#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
+
+inline bool isTACLoperator(char ch)
+ {
+ return ch == '\'' || isoperator(ch);
+ }
+
+inline bool isTACLwordchar(char ch)
+ {
+ return ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch);
+ }
+
+inline bool isTACLwordstart(char ch)
+ {
+ return ch == '#' || ch == '|' || ch == '_' || iswordstart(ch);
+ }
+
+static void getRange(unsigned int start,
+ unsigned int end,
+ Accessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_C_COMMENT ||
+ style == SCE_C_COMMENTDOC ||
+ style == SCE_C_COMMENTDOCKEYWORD ||
+ style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
+ if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
+ styler.ColourTo(end, SCE_C_REGEX);
+ } else
+ styler.ColourTo(end, attr);
+}
+
+// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
+static int classifyWordTACL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
+ int ret = 0;
+
+ WordList& keywords = *keywordlists[0];
+ WordList& builtins = *keywordlists[1];
+ WordList& commands = *keywordlists[2];
+
+ char s[100];
+ getRange(start, end, styler, s, sizeof(s));
+
+ char chAttr = SCE_C_IDENTIFIER;
+ if (isdigit(s[0]) || (s[0] == '.')) {
+ chAttr = SCE_C_NUMBER;
+ }
+ else {
+ if (s[0] == '#' || keywords.InList(s)) {
+ chAttr = SCE_C_WORD;
+
+ if (strcmp(s, "asm") == 0) {
+ ret = 2;
+ }
+ else if (strcmp(s, "end") == 0) {
+ ret = -1;
+ }
+ }
+ else if (s[0] == '|' || builtins.InList(s)) {
+ chAttr = SCE_C_WORD2;
+ }
+ else if (commands.InList(s)) {
+ chAttr = SCE_C_UUID;
+ }
+ else if (strcmp(s, "comment") == 0) {
+ chAttr = SCE_C_COMMENTLINE;
+ ret = 3;
+ }
+ }
+ ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
+ return ret;
+}
+
+static int classifyFoldPointTACL(const char* s) {
+ int lev = 0;
+ if (s[0] == '[')
+ lev=1;
+ else if (s[0] == ']')
+ lev=-1;
+ return lev;
+}
+
+static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ styler.StartAt(startPos);
+
+ int state = initStyle;
+ if (state == SCE_C_CHARACTER) // Does not leak onto next line
+ state = SCE_C_DEFAULT;
+ char chPrev = ' ';
+ char chNext = styler[startPos];
+ unsigned int lengthDoc = startPos + length;
+
+ bool bInClassDefinition;
+
+ int currentLine = styler.GetLine(startPos);
+ if (currentLine > 0) {
+ styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+ bInClassDefinition = (styler.GetLineState(currentLine) == 1);
+ } else {
+ styler.SetLineState(currentLine, 0);
+ bInClassDefinition = false;
+ }
+
+ bool bInAsm = (state == SCE_C_REGEX);
+ if (bInAsm)
+ state = SCE_C_DEFAULT;
+
+ styler.StartSegment(startPos);
+ int visibleChars = 0;
+ unsigned int i;
+ for (i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+ // Avoid triggering two times on Dos/Win
+ // End of line
+ if (state == SCE_C_CHARACTER) {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ visibleChars = 0;
+ currentLine++;
+ styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+ }
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ if (state == SCE_C_DEFAULT) {
+ if (isTACLwordstart(ch)) {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_IDENTIFIER;
+ } else if (ch == '{') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENT;
+ } else if (ch == '{' && chNext == '*') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENTDOC;
+ } else if (ch == '=' && chNext == '=') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '"') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_STRING;
+ } else if (ch == '?' && visibleChars == 0) {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_PREPROCESSOR;
+ } else if (isTACLoperator(ch)) {
+ ColourTo(styler, i-1, state, bInAsm);
+ ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+ }
+ } else if (state == SCE_C_IDENTIFIER) {
+ if (!isTACLwordchar(ch)) {
+ int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+
+ if(lStateChange == 1) {
+ styler.SetLineState(currentLine, 1);
+ bInClassDefinition = true;
+ } else if(lStateChange == 2) {
+ bInAsm = true;
+ } else if(lStateChange == -1) {
+ styler.SetLineState(currentLine, 0);
+ bInClassDefinition = false;
+ bInAsm = false;
+ }
+
+ if (lStateChange == 3) {
+ state = SCE_C_COMMENTLINE;
+ }
+ else {
+ state = SCE_C_DEFAULT;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (ch == '{') {
+ state = SCE_C_COMMENT;
+ } else if (ch == '{' && chNext == '*') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENTDOC;
+ } else if (ch == '=' && chNext == '=') {
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '"') {
+ state = SCE_C_STRING;
+ } else if (isTACLoperator(ch)) {
+ ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+ }
+ }
+ }
+ } else {
+ if (state == SCE_C_PREPROCESSOR) {
+ if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_COMMENT) {
+ if (ch == '}' || (ch == '\r' || ch == '\n') ) {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_COMMENTDOC) {
+ if (ch == '}' || (ch == '\r' || ch == '\n')) {
+ if (((i > styler.GetStartSegment() + 2) || (
+ (initStyle == SCE_C_COMMENTDOC) &&
+ (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ } else if (state == SCE_C_COMMENTLINE) {
+ if (ch == '\r' || ch == '\n') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_STRING) {
+ if (ch == '"' || ch == '\r' || ch == '\n') {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ chPrev = ch;
+ }
+
+ // Process to end of document
+ if (state == SCE_C_IDENTIFIER) {
+ classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+ }
+ else
+ ColourTo(styler, lengthDoc - 1, state, bInAsm);
+}
+
+static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ bool section = false;
+
+ int lastStart = 0;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))
+ {
+ // Store last word start point.
+ lastStart = i;
+ }
+
+ if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {
+ if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {
+ char s[100];
+ getRange(lastStart, i, styler, s, sizeof(s));
+ if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
+ {
+ section = true;
+ levelCurrent = 1;
+ levelPrev = 0;
+ }
+ else if (stylePrev == SCE_C_WORD)
+ levelCurrent += classifyFoldPointTACL(s);
+ }
+ }
+
+ if (style == SCE_C_OPERATOR) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
+ }
+ if (foldComment && (style == SCE_C_COMMENTLINE)) {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelCurrent++;
+ } else if (chNext2 == '}') {
+ levelCurrent--;
+ }
+ }
+ }
+
+ if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+ if (ch == '{' && chNext == '$') {
+ unsigned int j=i+2; // skip {$
+ while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "region") || styler.Match(j, "if")) {
+ levelCurrent++;
+ } else if (styler.Match(j, "end")) {
+ levelCurrent--;
+ }
+ }
+ }
+
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelCurrent++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev | SC_FOLDLEVELBASE;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ section = false;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const TACLWordListDesc[] = {
+ "Builtins",
+ "Labels",
+ "Commands",
+ 0
+};
+
+LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, "TACL", FoldTACLDoc, TACLWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexTADS3.cxx
+ ** Lexer for TADS3.
+ **/
+// Copyright 1998-2006 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+/*
+ * TADS3 is a language designed by Michael J. Roberts for the writing of text
+ * based games. TADS comes from Text Adventure Development System. It has good
+ * support for the processing and outputting of formatted text and much of a
+ * TADS program listing consists of strings.
+ *
+ * TADS has two types of strings, those enclosed in single quotes (') and those
+ * enclosed in double quotes ("). These strings have different symantics and
+ * can be given different highlighting if desired.
+ *
+ * There can be embedded within both types of strings html tags
+ * ( <tag key=value> ), library directives ( <.directive> ), and message
+ * parameters ( {The doctor's/his} ).
+ *
+ * Double quoted strings can also contain interpolated expressions
+ * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions
+ * may themselves contain single or double quoted strings, although the double
+ * quoted strings may not contain interpolated expressions.
+ *
+ * These embedded constructs influence the output and formatting and are an
+ * important part of a program and require highlighting.
+ *
+ * LINKS
+ * http://www.tads.org/
+ */
+
+#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 const int T3_SINGLE_QUOTE = 1;
+static const int T3_INT_EXPRESSION = 2;
+static const int T3_INT_EXPRESSION_IN_TAG = 4;
+static const int T3_HTML_SQUOTE = 8;
+
+static inline bool IsEOL(const int ch, const int chNext) {
+ return (ch == '\r' && chNext != '\n') || (ch == '\n');
+}
+
+/*
+ * Test the current character to see if it's the START of an EOL sequence;
+ * if so, skip ahead to the last character of the sequence and return true,
+ * and if not just return false. There are a few places where we want to
+ * check to see if a newline sequence occurs at a particular point, but
+ * where a caller expects a subroutine to stop only upon reaching the END
+ * of a newline sequence (in particular, CR-LF on Windows). That's why
+ * IsEOL() above only returns true on CR if the CR isn't followed by an LF
+ * - it doesn't want to admit that there's a newline until reaching the END
+ * of the sequence. We meet both needs by saying that there's a newline
+ * when we see the CR in a CR-LF, but skipping the CR before returning so
+ * that the caller's caller will see that we've stopped at the LF.
+ */
+static inline bool IsEOLSkip(StyleContext &sc)
+{
+ /* test for CR-LF */
+ if (sc.ch == '\r' && sc.chNext == '\n')
+ {
+ /* got CR-LF - skip the CR and indicate that we're at a newline */
+ sc.Forward();
+ return true;
+ }
+
+ /*
+ * in other cases, we have at most a 1-character newline, so do the
+ * normal IsEOL test
+ */
+ return IsEOL(sc.ch, sc.chNext);
+}
+
+static inline bool IsATADS3Operator(const int ch) {
+ return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
+ || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
+ || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'
+ || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'
+ || ch == '@' || ch == '&' || ch == '~';
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return isalnum(ch) || ch == '_';
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return isalpha(ch) || ch == '_';
+}
+
+static inline bool IsAHexDigit(const int ch) {
+ int lch = tolower(ch);
+ return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c'
+ || lch == 'd' || lch == 'e' || lch == 'f';
+}
+
+static inline bool IsAnHTMLChar(int ch) {
+ return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';
+}
+
+static inline bool IsADirectiveChar(int ch) {
+ return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/';
+}
+
+static inline bool IsANumberStart(StyleContext &sc) {
+ return isdigit(sc.ch)
+ || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext));
+}
+
+inline static void ColouriseTADS3Operator(StyleContext &sc) {
+ int initState = sc.state;
+ int c = sc.ch;
+ sc.SetState(c == '{' || c == '}' ? SCE_T3_BRACE : SCE_T3_OPERATOR);
+ sc.ForwardSetState(initState);
+}
+
+static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = sc.ch;
+ int chString = (lineState & T3_SINGLE_QUOTE) ? '\'' : '"';
+ if (endState == SCE_T3_HTML_STRING) {
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chString = '\'';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ chString = '"';
+ } else {
+ endState = SCE_T3_HTML_DEFAULT;
+ chString = '"';
+ }
+ chQuote = (lineState & T3_HTML_SQUOTE) ? '\'' : '"';
+ } else {
+ sc.SetState(SCE_T3_HTML_STRING);
+ sc.Forward();
+ }
+ if (chQuote == '"')
+ lineState &= ~T3_HTML_SQUOTE;
+ else
+ lineState |= T3_HTML_SQUOTE;
+
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))) {
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.ch == chString) {
+ sc.SetState(SCE_T3_DEFAULT);
+ return;
+ }
+
+ if (sc.Match('<', '<')) {
+ lineState |= T3_INT_EXPRESSION | T3_INT_EXPRESSION_IN_TAG;
+ sc.SetState(SCE_T3_X_DEFAULT);
+ sc.Forward(2);
+ return;
+ }
+
+ if (sc.Match('\\', static_cast<char>(chQuote))
+ || sc.Match('\\', static_cast<char>(chString))
+ || sc.Match('\\', '\\')) {
+ sc.Forward(2);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3HTMLTagStart(StyleContext &sc) {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.Forward();
+ if (sc.ch == '/') {
+ sc.Forward();
+ }
+ while (IsAnHTMLChar(sc.ch)) {
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = '"';
+ int chString = '\'';
+ switch (endState) {
+ case SCE_T3_S_STRING:
+ ColouriseTADS3HTMLTagStart(sc);
+ sc.SetState(SCE_T3_HTML_DEFAULT);
+ chQuote = '\'';
+ chString = '"';
+ break;
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ ColouriseTADS3HTMLTagStart(sc);
+ sc.SetState(SCE_T3_HTML_DEFAULT);
+ break;
+ case SCE_T3_HTML_DEFAULT:
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ chString = '"';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ } else {
+ endState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.Match('/', '>')) {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.ch == '>') {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))) {
+ sc.Forward();
+ ColouriseTADSHTMLString(sc, lineState);
+ if (sc.state == SCE_T3_X_DEFAULT)
+ break;
+ } else if (sc.ch == chString) {
+ ColouriseTADSHTMLString(sc, lineState);
+ } else if (sc.ch == '=') {
+ ColouriseTADS3Operator(sc);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3Keyword(StyleContext &sc,
+ WordList *keywordlists[], unsigned int endPos) {
+ char s[250];
+ WordList &keywords = *keywordlists[0];
+ WordList &userwords1 = *keywordlists[1];
+ WordList &userwords2 = *keywordlists[2];
+ WordList &userwords3 = *keywordlists[3];
+ int initState = sc.state;
+ sc.SetState(SCE_T3_IDENTIFIER);
+ while (sc.More() && (IsAWordChar(sc.ch))) {
+ sc.Forward();
+ }
+ sc.GetCurrent(s, sizeof(s));
+ if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
+ // have to find if "in" is next
+ int n = 1;
+ while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))
+ n++;
+ if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {
+ sc.Forward(n+2);
+ sc.ChangeState(SCE_T3_KEYWORD);
+ }
+ } else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_T3_KEYWORD);
+ } else if (userwords3.InList(s)) {
+ sc.ChangeState(SCE_T3_USER3);
+ } else if (userwords2.InList(s)) {
+ sc.ChangeState(SCE_T3_USER2);
+ } else if (userwords1.InList(s)) {
+ sc.ChangeState(SCE_T3_USER1);
+ }
+ sc.SetState(initState);
+}
+
+static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = '"';
+ switch (endState) {
+ case SCE_T3_S_STRING:
+ sc.SetState(SCE_T3_MSG_PARAM);
+ sc.Forward();
+ chQuote = '\'';
+ break;
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ sc.SetState(SCE_T3_MSG_PARAM);
+ sc.Forward();
+ break;
+ case SCE_T3_MSG_PARAM:
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ } else {
+ endState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+ while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == '\\') {
+ sc.Forward();
+ }
+ sc.Forward();
+ }
+ if (sc.ch == chQuote) {
+ sc.SetState(endState);
+ } else {
+ sc.ForwardSetState(endState);
+ }
+}
+
+static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {
+ int initState = sc.state;
+ int chQuote = '"';
+ switch (initState) {
+ case SCE_T3_S_STRING:
+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
+ sc.Forward(2);
+ chQuote = '\'';
+ break;
+ case SCE_T3_D_STRING:
+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
+ sc.Forward(2);
+ break;
+ case SCE_T3_LIB_DIRECTIVE:
+ if (lineState&T3_SINGLE_QUOTE) {
+ initState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ } else {
+ initState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+ while (sc.More() && IsADirectiveChar(sc.ch)) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ sc.Forward();
+ };
+ if (sc.ch == '>' || !sc.More()) {
+ sc.ForwardSetState(initState);
+ } else if (sc.ch == chQuote) {
+ sc.SetState(initState);
+ } else {
+ sc.ChangeState(initState);
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3String(StyleContext &sc, int &lineState) {
+ int chQuote = sc.ch;
+ int endState = sc.state;
+ switch (sc.state) {
+ case SCE_T3_DEFAULT:
+ case SCE_T3_X_DEFAULT:
+ if (chQuote == '"') {
+ if (sc.state == SCE_T3_DEFAULT) {
+ sc.SetState(SCE_T3_D_STRING);
+ } else {
+ sc.SetState(SCE_T3_X_STRING);
+ }
+ lineState &= ~T3_SINGLE_QUOTE;
+ } else {
+ sc.SetState(SCE_T3_S_STRING);
+ lineState |= T3_SINGLE_QUOTE;
+ }
+ sc.Forward();
+ break;
+ case SCE_T3_S_STRING:
+ chQuote = '\'';
+ endState = lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;
+ break;
+ case SCE_T3_D_STRING:
+ chQuote = '"';
+ endState = SCE_T3_DEFAULT;
+ break;
+ case SCE_T3_X_STRING:
+ chQuote = '"';
+ endState = SCE_T3_X_DEFAULT;
+ break;
+ }
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
+ lineState |= T3_INT_EXPRESSION;
+ sc.SetState(SCE_T3_X_DEFAULT);
+ sc.Forward(2);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))
+ || sc.Match('\\', '\\')) {
+ sc.Forward(2);
+ } else if (sc.ch == '{') {
+ ColouriseTADS3MsgParam(sc, lineState);
+ } else if (sc.Match('<', '.')) {
+ ColouriseTADS3LibDirective(sc, lineState);
+ } else if (sc.ch == '<') {
+ ColouriseTADS3HTMLTag(sc, lineState);
+ if (sc.state == SCE_T3_X_DEFAULT)
+ return;
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3Comment(StyleContext &sc, int endState) {
+ sc.SetState(SCE_T3_BLOCK_COMMENT);
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.Match('*', '/')) {
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ sc.Forward();
+ }
+}
+
+static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
+ sc.SetState(initState);
+ while (sc.More()) {
+ if (sc.ch == '\\') {
+ sc.Forward();
+ if (IsEOLSkip(sc)) {
+ return;
+ }
+ }
+ if (IsEOL(sc.ch, sc.chNext)) {
+ sc.SetState(endState);
+ return;
+ }
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3Number(StyleContext &sc) {
+ int endState = sc.state;
+ bool inHexNumber = false;
+ bool seenE = false;
+ bool seenDot = sc.ch == '.';
+ sc.SetState(SCE_T3_NUMBER);
+ if (sc.More()) {
+ sc.Forward();
+ }
+ if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {
+ inHexNumber = true;
+ sc.Forward();
+ }
+ while (sc.More()) {
+ if (inHexNumber) {
+ if (!IsAHexDigit(sc.ch)) {
+ break;
+ }
+ } else if (!isdigit(sc.ch)) {
+ if (!seenE && tolower(sc.ch) == 'e') {
+ seenE = true;
+ seenDot = true;
+ if (sc.chNext == '+' || sc.chNext == '-') {
+ sc.Forward();
+ }
+ } else if (!seenDot && sc.ch == '.') {
+ seenDot = true;
+ } else {
+ break;
+ }
+ }
+ sc.Forward();
+ }
+ sc.SetState(endState);
+}
+
+static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ int visibleChars = 0;
+ int bracketLevel = 0;
+ int lineState = 0;
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ lineState = styler.GetLineState(lineCurrent-1);
+ }
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ while (sc.More()) {
+
+ if (IsEOL(sc.ch, sc.chNext)) {
+ styler.SetLineState(lineCurrent, lineState);
+ lineCurrent++;
+ visibleChars = 0;
+ sc.Forward();
+ if (sc.ch == '\n') {
+ sc.Forward();
+ }
+ }
+
+ switch(sc.state) {
+ case SCE_T3_PREPROCESSOR:
+ case SCE_T3_LINE_COMMENT:
+ ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
+ break;
+ case SCE_T3_S_STRING:
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ break;
+ case SCE_T3_MSG_PARAM:
+ ColouriseTADS3MsgParam(sc, lineState);
+ break;
+ case SCE_T3_LIB_DIRECTIVE:
+ ColouriseTADS3LibDirective(sc, lineState);
+ break;
+ case SCE_T3_HTML_DEFAULT:
+ ColouriseTADS3HTMLTag(sc, lineState);
+ break;
+ case SCE_T3_HTML_STRING:
+ ColouriseTADSHTMLString(sc, lineState);
+ break;
+ case SCE_T3_BLOCK_COMMENT:
+ ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
+ break;
+ case SCE_T3_DEFAULT:
+ case SCE_T3_X_DEFAULT:
+ if (IsASpaceOrTab(sc.ch)) {
+ sc.Forward();
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
+ } else if (sc.Match('/', '*')) {
+ ColouriseTADS3Comment(sc, sc.state);
+ visibleChars++;
+ } else if (sc.Match('/', '/')) {
+ ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
+ } else if (sc.ch == '"') {
+ bracketLevel = 0;
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ } else if (sc.ch == '\'') {
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
+ && sc.Match('>', '>')) {
+ sc.Forward(2);
+ sc.SetState(SCE_T3_D_STRING);
+ if (lineState & T3_INT_EXPRESSION_IN_TAG)
+ sc.SetState(SCE_T3_HTML_STRING);
+ lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION
+ |T3_INT_EXPRESSION_IN_TAG);
+ } else if (IsATADS3Operator(sc.ch)) {
+ if (sc.state == SCE_T3_X_DEFAULT) {
+ if (sc.ch == '(') {
+ bracketLevel++;
+ } else if (sc.ch == ')' && bracketLevel > 0) {
+ bracketLevel--;
+ }
+ }
+ ColouriseTADS3Operator(sc);
+ visibleChars++;
+ } else if (IsANumberStart(sc)) {
+ ColouriseTADS3Number(sc);
+ visibleChars++;
+ } else if (IsAWordStart(sc.ch)) {
+ ColouriseTADS3Keyword(sc, keywordlists, endPos);
+ visibleChars++;
+ } else if (sc.Match("...")) {
+ sc.SetState(SCE_T3_IDENTIFIER);
+ sc.Forward(3);
+ sc.SetState(SCE_T3_DEFAULT);
+ } else {
+ sc.Forward();
+ visibleChars++;
+ }
+ break;
+ default:
+ sc.SetState(SCE_T3_DEFAULT);
+ sc.Forward();
+ }
+ }
+ sc.Complete();
+}
+
+/*
+ TADS3 has two styles of top level block (TLB). Eg
+
+ // default style
+ silverKey : Key 'small silver key' 'small silver key'
+ "A small key glints in the sunlight. "
+ ;
+
+ and
+
+ silverKey : Key {
+ 'small silver key'
+ 'small silver key'
+ "A small key glints in the sunlight. "
+ }
+
+ Some constructs mandate one or the other, but usually the author has may choose
+ either.
+
+ T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
+ seen and is also used to match the closing ';' of the default style.
+
+ T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
+ what characters may be seen without incrementing the block level. The general
+ pattern is identifier <punc> identifier, acceptable punctuation characters
+ are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
+ characters are syntactically correct, eg parentheses match. A ')' always
+ signifies the start of a block. We just need to check if it is followed by a
+ '{', in which case we let the brace handling code handle the folding level.
+
+ expectingIdentifier == false && expectingIdentifier == false
+ Before the start of a TLB.
+
+ expectingIdentifier == true && expectingIdentifier == true
+ Currently in an identifier. Will accept identifier or punctuation.
+
+ expectingIdentifier == true && expectingIdentifier == false
+ Just seen a punctuation character & now waiting for an identifier to start.
+
+ expectingIdentifier == false && expectingIdentifier == truee
+ We were in an identifier and have seen space. Now waiting to see a punctuation
+ character
+
+ Space, comments & preprocessor directives are always acceptable and are
+ equivalent.
+*/
+
+static const int T3_SEENSTART = 1 << 12;
+static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
+static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
+
+static inline bool IsStringTransition(int s1, int s2) {
+ return s1 != s2
+ && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
+ || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT))
+ && s2 != SCE_T3_LIB_DIRECTIVE
+ && s2 != SCE_T3_MSG_PARAM
+ && s2 != SCE_T3_HTML_TAG
+ && s2 != SCE_T3_HTML_STRING;
+}
+
+static inline bool IsATADS3Punctuation(const int ch) {
+ return ch == ':' || ch == ',' || ch == '(' || ch == ')';
+}
+
+static inline bool IsAnIdentifier(const int style) {
+ return style == SCE_T3_IDENTIFIER
+ || style == SCE_T3_USER1
+ || style == SCE_T3_USER2
+ || style == SCE_T3_USER3;
+}
+
+static inline bool IsAnOperator(const int style) {
+ return style == SCE_T3_OPERATOR || style == SCE_T3_BRACE;
+}
+
+static inline bool IsSpaceEquivalent(const int ch, const int style) {
+ return isspace(ch)
+ || style == SCE_T3_BLOCK_COMMENT
+ || style == SCE_T3_LINE_COMMENT
+ || style == SCE_T3_PREPROCESSOR;
+}
+
+static char peekAhead(unsigned int startPos, unsigned int endPos,
+ Accessor &styler) {
+ for (unsigned int i = startPos; i < endPos; i++) {
+ int style = styler.StyleAt(i);
+ char ch = styler[i];
+ if (!IsSpaceEquivalent(ch, style)) {
+ if (IsAnIdentifier(style)) {
+ return 'a';
+ }
+ if (IsATADS3Punctuation(ch)) {
+ return ':';
+ }
+ if (ch == '{') {
+ return '{';
+ }
+ return '*';
+ }
+ }
+ return ' ';
+}
+
+static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int seenStart = levelCurrent & T3_SEENSTART;
+ int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;
+ int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;
+ levelCurrent &= SC_FOLDLEVELNUMBERMASK;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char ch = chNext;
+ int stylePrev = style;
+ bool redo = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ if (redo) {
+ redo = false;
+ i--;
+ } else {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ }
+ bool atEOL = IsEOL(ch, chNext);
+
+ if (levelNext == SC_FOLDLEVELBASE) {
+ if (IsSpaceEquivalent(ch, style)) {
+ if (expectingPunctuation) {
+ expectingIdentifier = 0;
+ }
+ if (style == SCE_T3_BLOCK_COMMENT) {
+ levelNext++;
+ }
+ } else if (ch == '{') {
+ levelNext++;
+ seenStart = 0;
+ } else if (ch == '\'' || ch == '"' || ch == '[') {
+ levelNext++;
+ if (seenStart) {
+ redo = true;
+ }
+ } else if (ch == ';') {
+ seenStart = 0;
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ } else if (expectingIdentifier && expectingPunctuation) {
+ if (IsATADS3Punctuation(ch)) {
+ if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
+ levelNext++;
+ } else {
+ expectingPunctuation = 0;
+ }
+ } else if (!IsAnIdentifier(style)) {
+ levelNext++;
+ }
+ } else if (expectingIdentifier && !expectingPunctuation) {
+ if (!IsAnIdentifier(style)) {
+ levelNext++;
+ } else {
+ expectingPunctuation = T3_EXPECTINGPUNCTUATION;
+ }
+ } else if (!expectingIdentifier && expectingPunctuation) {
+ if (!IsATADS3Punctuation(ch)) {
+ levelNext++;
+ } else {
+ if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
+ levelNext++;
+ } else {
+ expectingIdentifier = T3_EXPECTINGIDENTIFIER;
+ expectingPunctuation = 0;
+ }
+ }
+ } else if (!expectingIdentifier && !expectingPunctuation) {
+ if (IsAnIdentifier(style)) {
+ seenStart = T3_SEENSTART;
+ expectingIdentifier = T3_EXPECTINGIDENTIFIER;
+ expectingPunctuation = T3_EXPECTINGPUNCTUATION;
+ }
+ }
+
+ if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ }
+
+ } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart
+ && ch == ';' && IsAnOperator(style)) {
+ levelNext--;
+ seenStart = 0;
+ } else if (style == SCE_T3_BLOCK_COMMENT) {
+ if (stylePrev != SCE_T3_BLOCK_COMMENT) {
+ levelNext++;
+ } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ } else if (ch == '\'' || ch == '"') {
+ if (IsStringTransition(style, stylePrev)) {
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (IsStringTransition(style, styleNext)) {
+ levelNext--;
+ }
+ } else if (IsAnOperator(style)) {
+ if (ch == '{' || ch == '[') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}' || ch == ']') {
+ levelNext--;
+ }
+ }
+
+ if (atEOL) {
+ if (seenStart && levelNext == SC_FOLDLEVELBASE) {
+ switch (peekAhead(i+1, endPos, styler)) {
+ case ' ':
+ case '{':
+ break;
+ case '*':
+ levelNext++;
+ break;
+ case 'a':
+ if (expectingPunctuation) {
+ levelNext++;
+ }
+ break;
+ case ':':
+ if (expectingIdentifier) {
+ levelNext++;
+ }
+ break;
+ }
+ if (levelNext != SC_FOLDLEVELBASE) {
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ }
+ }
+ int lev = levelMinCurrent | (levelNext | expectingIdentifier
+ | expectingPunctuation | seenStart) << 16;
+ if (levelMinCurrent < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ }
+ }
+}
+
+static const char * const tads3WordList[] = {
+ "TADS3 Keywords",
+ "User defined 1",
+ "User defined 2",
+ "User defined 3",
+ 0
+};
+
+LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexTAL.cxx
+ ** Lexer for TAL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to TAL
+ **/
+
+#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
+
+inline bool isTALoperator(char ch)
+ {
+ return ch == '\'' || ch == '@' || ch == '#' || isoperator(ch);
+ }
+
+inline bool isTALwordchar(char ch)
+ {
+ return ch == '$' || ch == '^' || iswordchar(ch);
+ }
+
+inline bool isTALwordstart(char ch)
+ {
+ return ch == '$' || ch == '^' || iswordstart(ch);
+ }
+
+static void getRange(unsigned int start,
+ unsigned int end,
+ Accessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_C_COMMENT ||
+ style == SCE_C_COMMENTDOC ||
+ style == SCE_C_COMMENTDOCKEYWORD ||
+ style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
+ if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
+ styler.ColourTo(end, SCE_C_REGEX);
+ } else
+ styler.ColourTo(end, attr);
+}
+
+// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
+static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
+ int ret = 0;
+
+ WordList& keywords = *keywordlists[0];
+ WordList& builtins = *keywordlists[1];
+ WordList& nonreserved_keywords = *keywordlists[2];
+
+ char s[100];
+ getRange(start, end, styler, s, sizeof(s));
+
+ char chAttr = SCE_C_IDENTIFIER;
+ if (isdigit(s[0]) || (s[0] == '.')) {
+ chAttr = SCE_C_NUMBER;
+ }
+ else {
+ if (keywords.InList(s)) {
+ chAttr = SCE_C_WORD;
+
+ if (strcmp(s, "asm") == 0) {
+ ret = 2;
+ }
+ else if (strcmp(s, "end") == 0) {
+ ret = -1;
+ }
+ }
+ else if (s[0] == '$' || builtins.InList(s)) {
+ chAttr = SCE_C_WORD2;
+ }
+ else if (nonreserved_keywords.InList(s)) {
+ chAttr = SCE_C_UUID;
+ }
+ }
+ ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
+ return ret;
+}
+
+static int classifyFoldPointTAL(const char* s) {
+ int lev = 0;
+ if (!(isdigit(s[0]) || (s[0] == '.'))) {
+ if (strcmp(s, "begin") == 0 ||
+ strcmp(s, "block") == 0) {
+ lev=1;
+ } else if (strcmp(s, "end") == 0) {
+ lev=-1;
+ }
+ }
+ return lev;
+}
+
+static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ styler.StartAt(startPos);
+
+ int state = initStyle;
+ if (state == SCE_C_CHARACTER) // Does not leak onto next line
+ state = SCE_C_DEFAULT;
+ char chPrev = ' ';
+ char chNext = styler[startPos];
+ unsigned int lengthDoc = startPos + length;
+
+ bool bInClassDefinition;
+
+ int currentLine = styler.GetLine(startPos);
+ if (currentLine > 0) {
+ styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+ bInClassDefinition = (styler.GetLineState(currentLine) == 1);
+ } else {
+ styler.SetLineState(currentLine, 0);
+ bInClassDefinition = false;
+ }
+
+ bool bInAsm = (state == SCE_C_REGEX);
+ if (bInAsm)
+ state = SCE_C_DEFAULT;
+
+ styler.StartSegment(startPos);
+ int visibleChars = 0;
+ for (unsigned int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+ // Avoid triggering two times on Dos/Win
+ // End of line
+ if (state == SCE_C_CHARACTER) {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ visibleChars = 0;
+ currentLine++;
+ styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+ }
+
+ if (styler.IsLeadByte(ch)) {
+ chNext = styler.SafeGetCharAt(i + 2);
+ chPrev = ' ';
+ i += 1;
+ continue;
+ }
+
+ if (state == SCE_C_DEFAULT) {
+ if (isTALwordstart(ch)) {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_IDENTIFIER;
+ } else if (ch == '!' && chNext != '*') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENT;
+ } else if (ch == '!' && chNext == '*') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENTDOC;
+ } else if (ch == '-' && chNext == '-') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '"') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_STRING;
+ } else if (ch == '?' && visibleChars == 0) {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_PREPROCESSOR;
+ } else if (isTALoperator(ch)) {
+ ColourTo(styler, i-1, state, bInAsm);
+ ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+ }
+ } else if (state == SCE_C_IDENTIFIER) {
+ if (!isTALwordchar(ch)) {
+ int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+
+ if(lStateChange == 1) {
+ styler.SetLineState(currentLine, 1);
+ bInClassDefinition = true;
+ } else if(lStateChange == 2) {
+ bInAsm = true;
+ } else if(lStateChange == -1) {
+ styler.SetLineState(currentLine, 0);
+ bInClassDefinition = false;
+ bInAsm = false;
+ }
+
+ state = SCE_C_DEFAULT;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (ch == '!' && chNext != '*') {
+ state = SCE_C_COMMENT;
+ } else if (ch == '!' && chNext == '*') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_COMMENTDOC;
+ } else if (ch == '-' && chNext == '-') {
+ state = SCE_C_COMMENTLINE;
+ } else if (ch == '"') {
+ state = SCE_C_STRING;
+ } else if (isTALoperator(ch)) {
+ ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+ }
+ }
+ } else {
+ if (state == SCE_C_PREPROCESSOR) {
+ if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_COMMENT) {
+ if (ch == '!' || (ch == '\r' || ch == '\n') ) {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_COMMENTDOC) {
+ if (ch == '!' || (ch == '\r' || ch == '\n')) {
+ if (((i > styler.GetStartSegment() + 2) || (
+ (initStyle == SCE_C_COMMENTDOC) &&
+ (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ } else if (state == SCE_C_COMMENTLINE) {
+ if (ch == '\r' || ch == '\n') {
+ ColourTo(styler, i-1, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ } else if (state == SCE_C_STRING) {
+ if (ch == '"') {
+ ColourTo(styler, i, state, bInAsm);
+ state = SCE_C_DEFAULT;
+ }
+ }
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ chPrev = ch;
+ }
+ ColourTo(styler, lengthDoc - 1, state, bInAsm);
+}
+
+static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ bool was_end = false;
+ bool section = false;
+
+ int lastStart = 0;
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR))
+ {
+ // Store last word start point.
+ lastStart = i;
+ }
+
+ if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) {
+ if(isTALwordchar(ch) && !isTALwordchar(chNext)) {
+ char s[100];
+ getRange(lastStart, i, styler, s, sizeof(s));
+ if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
+ {
+ section = true;
+ levelCurrent = 1;
+ levelPrev = 0;
+ }
+ else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID)
+ {
+ if (strcmp(s, "block") == 0)
+ {
+ // block keyword is ignored immediately after end keyword
+ if (!was_end)
+ levelCurrent++;
+ }
+ else
+ levelCurrent += classifyFoldPointTAL(s);
+ if (strcmp(s, "end") == 0)
+ {
+ was_end = true;
+ }
+ else
+ {
+ was_end = false;
+ }
+ }
+ }
+ }
+
+ if (foldComment && (style == SCE_C_COMMENTLINE)) {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelCurrent++;
+ } else if (chNext2 == '}') {
+ levelCurrent--;
+ }
+ }
+ }
+
+ if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+ if (ch == '{' && chNext == '$') {
+ unsigned int j=i+2; // skip {$
+ while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "region") || styler.Match(j, "if")) {
+ levelCurrent++;
+ } else if (styler.Match(j, "end")) {
+ levelCurrent--;
+ }
+ }
+ }
+
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelCurrent++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelCurrent--;
+ }
+ }
+
+ if (atEOL) {
+ int lev = levelPrev | SC_FOLDLEVELBASE;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ section = false;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const TALWordListDesc[] = {
+ "Keywords",
+ "Builtins",
+ 0
+};
+
+LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, "TAL", FoldTALDoc, TALWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexTCL.cxx
+ ** Lexer for TCL language.
+ **/
+// Copyright 1998-2001 by Andre Arpin <arpin@kingston.net>
+// 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
+
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+ return ch >= 0x80 ||
+ (isalnum(ch) || ch == '_' || ch ==':' || ch=='.'); // : name space separator
+}
+
+static inline bool IsAWordStart(int ch) {
+ return ch >= 0x80 || (ch ==':' || isalpha(ch) || ch == '_');
+}
+
+static inline bool IsANumberChar(int ch) {
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases.
+ return (ch < 0x80) &&
+ (IsADigit(ch, 0x10) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
+}
+
+static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *keywordlists[], Accessor &styler) {
+#define isComment(s) (s==SCE_TCL_COMMENT || s==SCE_TCL_COMMENTLINE || s==SCE_TCL_COMMENT_BOX || s==SCE_TCL_BLOCK_COMMENT)
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool commentLevel = false;
+ bool subBrace = false; // substitution begin with a brace ${.....}
+ enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf,
+ LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32 } lineState = LS_DEFAULT;
+ bool prevSlash = false;
+ int currentLevel = 0;
+ bool expected = 0;
+ bool subParen = 0;
+
+ int currentLine = styler.GetLine(startPos);
+ if (currentLine > 0)
+ currentLine--;
+ length += startPos - styler.LineStart(currentLine);
+ // make sure lines overlap
+ startPos = styler.LineStart(currentLine);
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+ WordList &keywords9 = *keywordlists[8];
+
+ if (currentLine > 0) {
+ int ls = styler.GetLineState(currentLine - 1);
+ lineState = tLineState(ls & LS_MASK_STATE);
+ expected = LS_COMMAND_EXPECTED == tLineState(ls & LS_COMMAND_EXPECTED);
+ subBrace = LS_BRACE_ONLY == tLineState(ls & LS_BRACE_ONLY);
+ currentLevel = styler.LevelAt(currentLine - 1) >> 17;
+ commentLevel = (styler.LevelAt(currentLine - 1) >> 16) & 1;
+ } else
+ styler.SetLevel(0, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG);
+ bool visibleChars = false;
+
+ int previousLevel = currentLevel;
+ StyleContext sc(startPos, length, SCE_TCL_DEFAULT, styler);
+ for (; ; sc.Forward()) {
+next:
+ if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac
+ continue;
+ bool atEnd = !sc.More(); // make sure we coloured the last word
+ if (lineState != LS_DEFAULT) {
+ sc.SetState(SCE_TCL_DEFAULT);
+ if (lineState == LS_OPEN_COMMENT)
+ sc.SetState(SCE_TCL_COMMENTLINE);
+ else if (lineState == LS_OPEN_DOUBLE_QUOTE)
+ sc.SetState(SCE_TCL_IN_QUOTE);
+ else if (lineState == LS_COMMENT_BOX && (sc.ch == '#' || (sc.ch == ' ' && sc.chNext=='#')))
+ sc.SetState(SCE_TCL_COMMENT_BOX);
+ lineState = LS_DEFAULT;
+ }
+ if (subBrace) { // ${ overrides every thing even \ except }
+ if (sc.ch == '}') {
+ subBrace = false;
+ sc.SetState(SCE_TCL_OPERATOR);
+ sc.ForwardSetState(SCE_TCL_DEFAULT);
+ goto next;
+ }
+ else
+ sc.SetState(SCE_TCL_SUB_BRACE);
+ if (!sc.atLineEnd)
+ continue;
+ } else if (sc.state == SCE_TCL_DEFAULT || sc.state ==SCE_TCL_OPERATOR) {
+ expected &= isspacechar(static_cast<unsigned char>(sc.ch)) || IsAWordStart(sc.ch) || sc.ch =='#';
+ } else if (sc.state == SCE_TCL_SUBSTITUTION) {
+ switch(sc.ch) {
+ case '(':
+ subParen=true;
+ sc.SetState(SCE_TCL_OPERATOR);
+ sc.ForwardSetState(SCE_TCL_SUBSTITUTION);
+ continue;
+ case ')':
+ sc.SetState(SCE_TCL_OPERATOR);
+ subParen=false;
+ continue;
+ case '$':
+ continue;
+ case ',':
+ sc.SetState(SCE_TCL_OPERATOR);
+ if (subParen)
+ sc.ForwardSetState(SCE_TCL_SUBSTITUTION);
+ continue;
+ default :
+ // maybe spaces should be allowed ???
+ if (!IsAWordChar(sc.ch)) { // probably the code is wrong
+ sc.SetState(SCE_TCL_DEFAULT);
+ subParen = 0;
+ }
+ break;
+ }
+ } else if (isComment(sc.state)) {
+ } else if (!IsAWordChar(sc.ch)) {
+ if ((sc.state == SCE_TCL_IDENTIFIER && expected) || sc.state == SCE_TCL_MODIFIER) {
+ char w[100];
+ char *s=w;
+ sc.GetCurrent(w, sizeof(w));
+ if (w[strlen(w)-1]=='\r')
+ w[strlen(w)-1]=0;
+ while(*s == ':') // ignore leading : like in ::set a 10
+ ++s;
+ bool quote = sc.state == SCE_TCL_IN_QUOTE;
+ if (commentLevel || expected) {
+ if (keywords.InList(s)) {
+ sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD4);
+ } else if (sc.GetRelative(-static_cast<int>(strlen(s))-1) == '{' &&
+ keywords5.InList(s) && sc.ch == '}') { // {keyword} exactly no spaces
+ sc.ChangeState(SCE_TCL_EXPAND);
+ }
+ if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_TCL_WORD5);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_TCL_WORD6);
+ } else if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_TCL_WORD7);
+ } else if (keywords9.InList(s)) {
+ sc.ChangeState(SCE_TCL_WORD8);
+ }
+ }
+ expected = false;
+ sc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT);
+ } else if (sc.state == SCE_TCL_MODIFIER || sc.state == SCE_TCL_IDENTIFIER) {
+ sc.SetState(SCE_TCL_DEFAULT);
+ }
+ }
+ if (atEnd)
+ break;
+ if (sc.atLineEnd) {
+ lineState = LS_DEFAULT;
+ currentLine = styler.GetLine(sc.currentPos);
+ if (foldComment && sc.state!=SCE_TCL_COMMENT && isComment(sc.state)) {
+ if (currentLevel == 0) {
+ ++currentLevel;
+ commentLevel = true;
+ }
+ } else {
+ if (visibleChars && commentLevel) {
+ --currentLevel;
+ --previousLevel;
+ commentLevel = false;
+ }
+ }
+ int flag = 0;
+ if (!visibleChars)
+ flag = SC_FOLDLEVELWHITEFLAG;
+ if (currentLevel > previousLevel)
+ flag = SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(currentLine, flag + previousLevel + SC_FOLDLEVELBASE + (currentLevel << 17) + (commentLevel << 16));
+
+ // Update the line state, so it can be seen by next line
+ if (sc.state == SCE_TCL_IN_QUOTE)
+ lineState = LS_OPEN_DOUBLE_QUOTE;
+ else {
+ if (prevSlash) {
+ if (isComment(sc.state))
+ lineState = LS_OPEN_COMMENT;
+ } else if (sc.state == SCE_TCL_COMMENT_BOX)
+ lineState = LS_COMMENT_BOX;
+ }
+ styler.SetLineState(currentLine,
+ (subBrace ? LS_BRACE_ONLY : 0) |
+ (expected ? LS_COMMAND_EXPECTED : 0) | lineState);
+ if (lineState == LS_COMMENT_BOX)
+ sc.ForwardSetState(SCE_TCL_COMMENT_BOX);
+ else if (lineState == LS_OPEN_DOUBLE_QUOTE)
+ sc.ForwardSetState(SCE_TCL_IN_QUOTE);
+ else
+ sc.ForwardSetState(SCE_TCL_DEFAULT);
+ prevSlash = false;
+ previousLevel = currentLevel;
+ goto next;
+ }
+
+ if (prevSlash) {
+ prevSlash = false;
+ if (sc.ch == '#' && IsANumberChar(sc.chNext))
+ sc.ForwardSetState(SCE_TCL_NUMBER);
+ continue;
+ }
+ prevSlash = sc.ch == '\\';
+ if (isComment(sc.state))
+ continue;
+ if (sc.atLineStart) {
+ visibleChars = false;
+ if (sc.state!=SCE_TCL_IN_QUOTE && !isComment(sc.state))
+ {
+ sc.SetState(SCE_TCL_DEFAULT);
+ expected = IsAWordStart(sc.ch)|| isspacechar(static_cast<unsigned char>(sc.ch));
+ }
+ }
+
+ switch (sc.state) {
+ case SCE_TCL_NUMBER:
+ if (!IsANumberChar(sc.ch))
+ sc.SetState(SCE_TCL_DEFAULT);
+ break;
+ case SCE_TCL_IN_QUOTE:
+ if (sc.ch == '"') {
+ sc.ForwardSetState(SCE_TCL_DEFAULT);
+ visibleChars = true; // necessary if a " is the first and only character on a line
+ goto next;
+ } else if (sc.ch == '[' || sc.ch == ']' || sc.ch == '$') {
+ sc.SetState(SCE_TCL_OPERATOR);
+ expected = sc.ch == '[';
+ sc.ForwardSetState(SCE_TCL_IN_QUOTE);
+ goto next;
+ }
+ continue;
+ case SCE_TCL_OPERATOR:
+ sc.SetState(SCE_TCL_DEFAULT);
+ break;
+ }
+
+ if (sc.ch == '#') {
+ if (visibleChars) {
+ if (sc.state != SCE_TCL_IN_QUOTE && expected)
+ sc.SetState(SCE_TCL_COMMENT);
+ } else {
+ sc.SetState(SCE_TCL_COMMENTLINE);
+ if (sc.chNext == '~')
+ sc.SetState(SCE_TCL_BLOCK_COMMENT);
+ if (sc.atLineStart && (sc.chNext == '#' || sc.chNext == '-'))
+ sc.SetState(SCE_TCL_COMMENT_BOX);
+ }
+ }
+
+ if (!isspacechar(static_cast<unsigned char>(sc.ch))) {
+ visibleChars = true;
+ }
+
+ if (sc.ch == '\\') {
+ prevSlash = true;
+ continue;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_TCL_DEFAULT) {
+ if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_TCL_IDENTIFIER);
+ } else if (IsADigit(sc.ch) && !IsAWordChar(sc.chPrev)) {
+ sc.SetState(SCE_TCL_NUMBER);
+ } else {
+ switch (sc.ch) {
+ case '\"':
+ sc.SetState(SCE_TCL_IN_QUOTE);
+ break;
+ case '{':
+ sc.SetState(SCE_TCL_OPERATOR);
+ expected = true;
+ ++currentLevel;
+ break;
+ case '}':
+ sc.SetState(SCE_TCL_OPERATOR);
+ expected = true;
+ --currentLevel;
+ break;
+ case '[':
+ expected = true;
+ case ']':
+ case '(':
+ case ')':
+ sc.SetState(SCE_TCL_OPERATOR);
+ break;
+ case ';':
+ expected = true;
+ break;
+ case '$':
+ subParen = 0;
+ if (sc.chNext != '{') {
+ sc.SetState(SCE_TCL_SUBSTITUTION);
+ }
+ else {
+ sc.SetState(SCE_TCL_OPERATOR); // $
+ sc.Forward(); // {
+ sc.ForwardSetState(SCE_TCL_SUB_BRACE);
+ subBrace = true;
+ }
+ break;
+ case '#':
+ if ((isspacechar(static_cast<unsigned char>(sc.chPrev))||
+ isoperator(static_cast<char>(sc.chPrev))) && IsADigit(sc.chNext,0x10))
+ sc.SetState(SCE_TCL_NUMBER);
+ break;
+ case '-':
+ sc.SetState(IsADigit(sc.chNext)? SCE_TCL_NUMBER: SCE_TCL_MODIFIER);
+ break;
+ default:
+ if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_TCL_OPERATOR);
+ }
+ }
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static const char * const tclWordListDesc[] = {
+ "TCL Keywords",
+ "TK Keywords",
+ "iTCL Keywords",
+ "tkCommands",
+ "expand"
+ "user1",
+ "user2",
+ "user3",
+ "user4",
+ 0
+ };
+
+// this code supports folding in the colourizer
+LexerModule lmTCL(SCLEX_TCL, ColouriseTCLDoc, "tcl", 0, tclWordListDesc);
--- /dev/null
+// Scintilla\ source code edit control
+/** @file LexTCMD.cxx
+ ** Lexer for Take Command / TCC batch scripts (.bat, .btm, .cmd).
+ **/
+// Written by Rex Conn (rconn [at] jpsoft [dot] com)
+// based on the CMD lexer
+// 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 bool IsAlphabetic(int ch) {
+ return isascii(ch) && isalpha(ch);
+}
+
+static inline bool AtEOL(Accessor &styler, unsigned int i) {
+ return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
+}
+
+// Tests for BATCH Operators
+static bool IsBOperator(char ch) {
+ return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || (ch == '|') || (ch == '&') || (ch == '!') || (ch == '?') || (ch == '*') || (ch == '(') || (ch == ')');
+}
+
+// Tests for BATCH Separators
+static bool IsBSeparator(char ch) {
+ return (ch == '\\') || (ch == '.') || (ch == ';') || (ch == ' ') || (ch == '\t') || (ch == '[') || (ch == ']') || (ch == '\"') || (ch == '\'') || (ch == '/');
+}
+
+// Tests for Environment Variable symbol
+static inline bool IsEnvironmentVar(char ch) {
+ return isalpha(ch) || isdigit(ch) || (ch == '_') || (ch == '$');
+}
+
+// Find length of CMD FOR variable with modifier (%~...) or return 0
+static unsigned int GetBatchVarLen( char *wordBuffer )
+{
+ int nLength = 0;
+ if ( wordBuffer[0] == '%' ) {
+
+ if ( wordBuffer[1] == '~' )
+ nLength = 2;
+ else if (( wordBuffer[1] == '%' ) && ( wordBuffer[2] == '~' ))
+ nLength++;
+ else
+ return 0;
+
+ for ( ; ( wordBuffer[nLength] ); nLength++ ) {
+
+ switch ( toupper(wordBuffer[nLength]) ) {
+ case 'A':
+ // file attributes
+ case 'D':
+ // drive letter only
+ case 'F':
+ // fully qualified path name
+ case 'N':
+ // filename only
+ case 'P':
+ // path only
+ case 'S':
+ // short name
+ case 'T':
+ // date / time of file
+ case 'X':
+ // file extension only
+ case 'Z':
+ // file size
+ break;
+ default:
+ return nLength;
+ }
+ }
+ }
+
+ return nLength;
+}
+
+
+static void ColouriseTCMDLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList *keywordlists[], Accessor &styler)
+{
+ unsigned int offset = 0; // Line Buffer Offset
+ char wordBuffer[260]; // Word Buffer - large to catch long paths
+ unsigned int wbl; // Word Buffer Length
+ unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
+ WordList &keywords = *keywordlists[0]; // Internal Commands
+// WordList &keywords2 = *keywordlists[1]; // Aliases (optional)
+ bool isDelayedExpansion = 1; // !var!
+
+ bool continueProcessing = true; // Used to toggle Regular Keyword Checking
+ // Special Keywords are those that allow certain characters without whitespace after the command
+ // Examples are: cd. cd\ echo: echo. path=
+ bool inString = false; // Used for processing while ""
+ // Special Keyword Buffer used to determine if the first n characters is a Keyword
+ char sKeywordBuffer[260]; // Special Keyword Buffer
+ bool sKeywordFound; // Exit Special Keyword for-loop if found
+
+ // Skip leading whitespace
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT);
+
+ if ( offset >= lengthLine )
+ return;
+
+ // Check for Fake Label (Comment) or Real Label - return if found
+ if (lineBuffer[offset] == ':') {
+ if (lineBuffer[offset + 1] == ':') {
+ // Colorize Fake Label (Comment) - :: is the same as REM
+ styler.ColourTo(endPos, SCE_TCMD_COMMENT);
+ } else {
+ // Colorize Real Label
+ styler.ColourTo(endPos, SCE_TCMD_LABEL);
+ }
+ return;
+
+ // Check for Comment - return if found
+ } else if (( CompareNCaseInsensitive(lineBuffer+offset, "rem", 3) == 0 ) && (( lineBuffer[offset+3] == 0 ) || ( isspace(lineBuffer[offset+3] )))) {
+ styler.ColourTo(endPos, SCE_TCMD_COMMENT);
+ return;
+
+ // Check for Drive Change (Drive Change is internal command) - return if found
+ } else if ((IsAlphabetic(lineBuffer[offset])) &&
+ (lineBuffer[offset + 1] == ':') &&
+ ((isspacechar(lineBuffer[offset + 2])) ||
+ (((lineBuffer[offset + 2] == '\\')) &&
+ (isspacechar(lineBuffer[offset + 3]))))) {
+ // Colorize Regular Keyword
+ styler.ColourTo(endPos, SCE_TCMD_WORD);
+ return;
+ }
+
+ // Check for Hide Command (@ECHO OFF/ON)
+ if (lineBuffer[offset] == '@') {
+ styler.ColourTo(startLine + offset, SCE_TCMD_HIDE);
+ offset++;
+ }
+ // Skip whitespace
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+
+ // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
+ while (offset < lengthLine) {
+ if (offset > startLine) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT);
+ }
+ // Copy word from Line Buffer into Word Buffer
+ wbl = 0;
+ for (; offset < lengthLine && ( wbl < 260 ) && !isspacechar(lineBuffer[offset]); wbl++, offset++) {
+ wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
+ }
+ wordBuffer[wbl] = '\0';
+ wbo = 0;
+
+ // Check for Separator
+ if (IsBSeparator(wordBuffer[0])) {
+
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+
+ if (wordBuffer[0] == '"')
+ inString = !inString;
+
+ // Check for Regular expression
+ } else if (( wordBuffer[0] == ':' ) && ( wordBuffer[1] == ':' ) && (continueProcessing)) {
+
+ // Colorize Regular exoressuin
+ styler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT);
+ // No need to Reset Offset
+
+ // Check for Labels in text (... :label)
+ } else if (wordBuffer[0] == ':' && isspacechar(lineBuffer[offset - wbl - 1])) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);
+ // Colorize Label
+ styler.ColourTo(startLine + offset - 1, SCE_TCMD_CLABEL);
+ // No need to Reset Offset
+ // Check for delayed expansion Variable (!x...!)
+ } else if (isDelayedExpansion && wordBuffer[0] == '!') {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);
+ wbo++;
+ // Search to end of word for second !
+ while ((wbo < wbl) && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ if (wordBuffer[wbo] == '!') {
+ wbo++;
+ // Colorize Environment Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_EXPANSION);
+ } else {
+ wbo = 1;
+ // Colorize Symbol
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_DEFAULT);
+ }
+
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+
+ // Check for Regular Keyword in list
+ } else if ((keywords.InList(wordBuffer)) && (!inString) && (continueProcessing)) {
+
+ // ECHO, PATH, and PROMPT require no further Regular Keyword Checking
+ if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "echos") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "echoerr") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "echoserr") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "path") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "prompt") == 0)) {
+ continueProcessing = false;
+ }
+
+ // Colorize Regular keyword
+ styler.ColourTo(startLine + offset - 1, SCE_TCMD_WORD);
+ // No need to Reset Offset
+
+ } else if ((wordBuffer[0] != '%') && (wordBuffer[0] != '!') && (!IsBOperator(wordBuffer[0])) && (!inString) && (continueProcessing)) {
+
+ // a few commands accept "illegal" syntax -- cd\, echo., etc.
+ sscanf( wordBuffer, "%[^.<>|&=\\/]", sKeywordBuffer );
+ sKeywordFound = false;
+
+ if ((CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "echos") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "echoerr") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "echoserr") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "cd") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "path") == 0) ||
+ (CompareCaseInsensitive(sKeywordBuffer, "prompt") == 0)) {
+
+ // no further Regular Keyword Checking
+ continueProcessing = false;
+ sKeywordFound = true;
+ wbo = (unsigned int)strlen( sKeywordBuffer );
+
+ // Colorize Special Keyword as Regular Keyword
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_WORD);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+
+ // Check for Default Text
+ if (!sKeywordFound) {
+ wbo = 0;
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!isDelayedExpansion || wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+
+ // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
+ } else if (wordBuffer[0] == '%') {
+ unsigned int varlen;
+ unsigned int n = 1;
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);
+ wbo++;
+
+ // check for %[nn] syntax
+ if ( wordBuffer[1] == '[' ) {
+ n++;
+ while ((n < wbl) && (wordBuffer[n] != ']')) {
+ n++;
+ }
+ if ( wordBuffer[n] == ']' )
+ n++;
+ goto ColorizeArg;
+ }
+
+ // Search to end of word for second % or to the first terminator (can be a long path)
+ while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+
+ // Check for Argument (%n) or (%*)
+ if (((isdigit(wordBuffer[1])) || (wordBuffer[1] == '*')) && (wordBuffer[wbo] != '%')) {
+ while (( wordBuffer[n] ) && ( strchr( "%0123456789*#$", wordBuffer[n] ) != NULL ))
+ n++;
+ColorizeArg:
+ // Colorize Argument
+ styler.ColourTo(startLine + offset - 1 - (wbl - n), SCE_TCMD_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - n);
+
+ // Check for Variable with modifiers (%~...)
+ } else if ((varlen = GetBatchVarLen(wordBuffer)) != 0) {
+
+ // Colorize Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - varlen), SCE_TCMD_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - varlen);
+
+ // Check for Environment Variable (%x...%)
+ } else if (( wordBuffer[1] ) && ( wordBuffer[1] != '%')) {
+ if ( wordBuffer[wbo] == '%' )
+ wbo++;
+
+ // Colorize Environment Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_ENVIRONMENT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+
+ // Check for Local Variable (%%a)
+ } else if ( (wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] != '%') && (!IsBOperator(wordBuffer[2])) && (!IsBSeparator(wordBuffer[2]))) {
+
+ n = 2;
+ while (( wordBuffer[n] ) && (!IsBOperator(wordBuffer[n])) && (!IsBSeparator(wordBuffer[n])))
+ n++;
+
+ // Colorize Local Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - n), SCE_TCMD_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - n);
+
+ // Check for %%
+ } else if ((wbl > 1) && (wordBuffer[1] == '%')) {
+
+ // Colorize Symbols
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_TCMD_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ } else {
+
+ // Colorize Symbol
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ }
+
+ // Check for Operator
+ } else if (IsBOperator(wordBuffer[0])) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT);
+
+ // Check for Pipe, compound, or conditional Operator
+ if ((wordBuffer[0] == '|') || (wordBuffer[0] == '&')) {
+
+ // Colorize Pipe Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ continueProcessing = true;
+
+ // Check for Other Operator
+ } else {
+ // Check for > Operator
+ if ((wordBuffer[0] == '>') || (wordBuffer[0] == '<')) {
+ // Turn Keyword and External Command / Program checking back on
+ continueProcessing = true;
+ }
+ // Colorize Other Operator
+ if (!inString || !(wordBuffer[0] == '(' || wordBuffer[0] == ')'))
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ }
+
+ // Check for Default Text
+ } else {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!isDelayedExpansion || wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+
+ // Skip whitespace - nothing happens if Offset was Reset
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+ }
+ // Colorize Default Text for remainder of line - currently not lexed
+ styler.ColourTo(endPos, SCE_TCMD_DEFAULT);
+}
+
+static void ColouriseTCMDDoc( unsigned int startPos, int length, int /*initStyle*/, WordList *keywordlists[], Accessor &styler )
+{
+ char lineBuffer[16384];
+
+ 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';
+ ColouriseTCMDLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
+ linePos = 0;
+ startLine = i + 1;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ lineBuffer[linePos] = '\0';
+ ColouriseTCMDLine(lineBuffer, linePos, startLine, startPos + length - 1, keywordlists, styler);
+ }
+}
+
+// Convert string to upper case
+static void StrUpr(char *s) {
+ while (*s) {
+ *s = MakeUpperCase(*s);
+ s++;
+ }
+}
+
+// Folding support (for DO, IFF, SWITCH, TEXT, and command groups)
+static void FoldTCMDDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ int line = styler.GetLine(startPos);
+ int level = styler.LevelAt(line);
+ int levelIndent = 0;
+ unsigned int endPos = startPos + length;
+ char s[16];
+
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
+
+ // Scan for ( and )
+ for (unsigned int i = startPos; i < endPos; i++) {
+
+ int c = styler.SafeGetCharAt(i, '\n');
+ int style = styler.StyleAt(i);
+ bool bLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;
+
+ if (style == SCE_TCMD_OPERATOR) {
+ // CheckFoldPoint
+ if (c == '(') {
+ levelIndent += 1;
+ } else if (c == ')') {
+ levelIndent -= 1;
+ }
+ }
+
+ if (( bLineStart ) && ( style == SCE_TCMD_WORD )) {
+ for (unsigned int j = 0; j < 10; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = styler[i + j];
+ s[j + 1] = '\0';
+ }
+
+ StrUpr( s );
+ if ((strcmp(s, "DO") == 0) || (strcmp(s, "IFF") == 0) || (strcmp(s, "SWITCH") == 0) || (strcmp(s, "TEXT") == 0)) {
+ levelIndent++;
+ } else if ((strcmp(s, "ENDDO") == 0) || (strcmp(s, "ENDIFF") == 0) || (strcmp(s, "ENDSWITCH") == 0) || (strcmp(s, "ENDTEXT") == 0)) {
+ levelIndent--;
+ }
+ }
+
+ if (c == '\n') { // line end
+ if (levelIndent > 0) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (level != styler.LevelAt(line))
+ styler.SetLevel(line, level);
+ level += levelIndent;
+ if ((level & SC_FOLDLEVELNUMBERMASK) < SC_FOLDLEVELBASE)
+ level = SC_FOLDLEVELBASE;
+ line++;
+ // reset state
+ levelIndent = 0;
+ level &= ~SC_FOLDLEVELHEADERFLAG;
+ level &= ~SC_FOLDLEVELWHITEFLAG;
+ }
+
+ chPrev = c;
+ }
+}
+
+static const char *const tcmdWordListDesc[] = {
+ "Internal Commands",
+ "Aliases",
+ 0
+};
+
+LexerModule lmTCMD(SCLEX_TCMD, ColouriseTCMDDoc, "tcmd", FoldTCMDDoc, tcmdWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+
+// File: LexTeX.cxx - general context conformant tex coloring scheme
+// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
+// Version: September 28, 2003
+
+// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// This lexer is derived from the one written for the texwork environment (1999++) which in
+// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).
+
+// If you run into strange boundary cases, just tell me and I'll look into it.
+
+
+// TeX Folding code added by instanton (soft_share@126.com) with borrowed code from VisualTeX source by Alex Romanenko.
+// Version: June 22, 2007
+
+#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
+
+// val SCE_TEX_DEFAULT = 0
+// val SCE_TEX_SPECIAL = 1
+// val SCE_TEX_GROUP = 2
+// val SCE_TEX_SYMBOL = 3
+// val SCE_TEX_COMMAND = 4
+// val SCE_TEX_TEXT = 5
+
+// Definitions in SciTEGlobal.properties:
+//
+// TeX Highlighting
+//
+// # Default
+// style.tex.0=fore:#7F7F00
+// # Special
+// style.tex.1=fore:#007F7F
+// # Group
+// style.tex.2=fore:#880000
+// # Symbol
+// style.tex.3=fore:#7F7F00
+// # Command
+// style.tex.4=fore:#008800
+// # Text
+// style.tex.5=fore:#000000
+
+// lexer.tex.interface.default=0
+// lexer.tex.comment.process=0
+
+// todo: lexer.tex.auto.if
+
+// Auxiliary functions:
+
+static inline bool endOfLine(Accessor &styler, unsigned int i) {
+ return
+ (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
+}
+
+static inline bool isTeXzero(int ch) {
+ return
+ (ch == '%') ;
+}
+
+static inline bool isTeXone(int ch) {
+ return
+ (ch == '[') || (ch == ']') || (ch == '=') || (ch == '#') ||
+ (ch == '(') || (ch == ')') || (ch == '<') || (ch == '>') ||
+ (ch == '"') ;
+}
+
+static inline bool isTeXtwo(int ch) {
+ return
+ (ch == '{') || (ch == '}') || (ch == '$') ;
+}
+
+static inline bool isTeXthree(int ch) {
+ return
+ (ch == '~') || (ch == '^') || (ch == '_') || (ch == '&') ||
+ (ch == '-') || (ch == '+') || (ch == '\"') || (ch == '`') ||
+ (ch == '/') || (ch == '|') || (ch == '%') ;
+}
+
+static inline bool isTeXfour(int ch) {
+ return
+ (ch == '\\') ;
+}
+
+static inline bool isTeXfive(int ch) {
+ return
+ ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
+ (ch == '@') || (ch == '!') || (ch == '?') ;
+}
+
+static inline bool isTeXsix(int ch) {
+ return
+ (ch == ' ') ;
+}
+
+static inline bool isTeXseven(int ch) {
+ return
+ (ch == '^') ;
+}
+
+// Interface determination
+
+static int CheckTeXInterface(
+ unsigned int startPos,
+ int length,
+ Accessor &styler,
+ int defaultInterface) {
+
+ char lineBuffer[1024] ;
+ unsigned int linePos = 0 ;
+
+ // some day we can make something lexer.tex.mapping=(all,0)(nl,1)(en,2)...
+
+ if (styler.SafeGetCharAt(0) == '%') {
+ for (unsigned int i = 0; i < startPos + length; i++) {
+ lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
+ if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
+ lineBuffer[linePos] = '\0';
+ if (strstr(lineBuffer, "interface=all")) {
+ return 0 ;
+ } else if (strstr(lineBuffer, "interface=tex")) {
+ return 1 ;
+ } else if (strstr(lineBuffer, "interface=nl")) {
+ return 2 ;
+ } else if (strstr(lineBuffer, "interface=en")) {
+ return 3 ;
+ } else if (strstr(lineBuffer, "interface=de")) {
+ return 4 ;
+ } else if (strstr(lineBuffer, "interface=cz")) {
+ return 5 ;
+ } else if (strstr(lineBuffer, "interface=it")) {
+ return 6 ;
+ } else if (strstr(lineBuffer, "interface=ro")) {
+ return 7 ;
+ } else if (strstr(lineBuffer, "interface=latex")) {
+ // we will move latex cum suis up to 91+ when more keyword lists are supported
+ return 8 ;
+ } else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) {
+ // better would be to limit the search to just one line
+ return 3 ;
+ } else {
+ return defaultInterface ;
+ }
+ }
+ }
+ }
+
+ return defaultInterface ;
+}
+
+static void ColouriseTeXDoc(
+ unsigned int startPos,
+ int length,
+ int,
+ WordList *keywordlists[],
+ Accessor &styler) {
+
+ styler.StartAt(startPos) ;
+ styler.StartSegment(startPos) ;
+
+ bool processComment = styler.GetPropertyInt("lexer.tex.comment.process", 0) == 1 ;
+ bool useKeywords = styler.GetPropertyInt("lexer.tex.use.keywords", 1) == 1 ;
+ bool autoIf = styler.GetPropertyInt("lexer.tex.auto.if", 1) == 1 ;
+ int defaultInterface = styler.GetPropertyInt("lexer.tex.interface.default", 1) ;
+
+ char key[100] ;
+ int k ;
+ bool newifDone = false ;
+ bool inComment = false ;
+
+ int currentInterface = CheckTeXInterface(startPos,length,styler,defaultInterface) ;
+
+ if (currentInterface == 0) {
+ useKeywords = false ;
+ currentInterface = 1 ;
+ }
+
+ WordList &keywords = *keywordlists[currentInterface-1] ;
+
+ StyleContext sc(startPos, length, SCE_TEX_TEXT, styler);
+
+ bool going = sc.More() ; // needed because of a fuzzy end of file state
+
+ for (; going; sc.Forward()) {
+
+ if (! sc.More()) { going = false ; } // we need to go one behind the end of text
+
+ if (inComment) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_TEX_TEXT) ;
+ newifDone = false ;
+ inComment = false ;
+ }
+ } else {
+ if (! isTeXfive(sc.ch)) {
+ if (sc.state == SCE_TEX_COMMAND) {
+ if (sc.LengthCurrent() == 1) { // \<noncstoken>
+ if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {
+ sc.Forward(2) ; // \^^ and \^^<token>
+ }
+ sc.ForwardSetState(SCE_TEX_TEXT) ;
+ } else {
+ sc.GetCurrent(key, sizeof(key)-1) ;
+ k = static_cast<int>(strlen(key)) ;
+ memmove(key,key+1,k) ; // shift left over escape token
+ key[k] = '\0' ;
+ k-- ;
+ if (! keywords || ! useKeywords) {
+ sc.SetState(SCE_TEX_COMMAND) ;
+ newifDone = false ;
+ } else if (k == 1) { //\<cstoken>
+ sc.SetState(SCE_TEX_COMMAND) ;
+ newifDone = false ;
+ } else if (keywords.InList(key)) {
+ sc.SetState(SCE_TEX_COMMAND) ;
+ newifDone = autoIf && (strcmp(key,"newif") == 0) ;
+ } else if (autoIf && ! newifDone && (key[0] == 'i') && (key[1] == 'f') && keywords.InList("if")) {
+ sc.SetState(SCE_TEX_COMMAND) ;
+ } else {
+ sc.ChangeState(SCE_TEX_TEXT) ;
+ sc.SetState(SCE_TEX_TEXT) ;
+ newifDone = false ;
+ }
+ }
+ }
+ if (isTeXzero(sc.ch)) {
+ sc.SetState(SCE_TEX_SYMBOL);
+
+ if (!endOfLine(styler,sc.currentPos + 1))
+ sc.ForwardSetState(SCE_TEX_DEFAULT) ;
+
+ inComment = ! processComment ;
+ newifDone = false ;
+ } else if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {
+ sc.SetState(SCE_TEX_TEXT) ;
+ sc.ForwardSetState(SCE_TEX_TEXT) ;
+ } else if (isTeXone(sc.ch)) {
+ sc.SetState(SCE_TEX_SPECIAL) ;
+ newifDone = false ;
+ } else if (isTeXtwo(sc.ch)) {
+ sc.SetState(SCE_TEX_GROUP) ;
+ newifDone = false ;
+ } else if (isTeXthree(sc.ch)) {
+ sc.SetState(SCE_TEX_SYMBOL) ;
+ newifDone = false ;
+ } else if (isTeXfour(sc.ch)) {
+ sc.SetState(SCE_TEX_COMMAND) ;
+ } else if (isTeXsix(sc.ch)) {
+ sc.SetState(SCE_TEX_TEXT) ;
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_TEX_TEXT) ;
+ newifDone = false ;
+ inComment = false ;
+ } else {
+ sc.SetState(SCE_TEX_TEXT) ;
+ }
+ } else if (sc.state != SCE_TEX_COMMAND) {
+ sc.SetState(SCE_TEX_TEXT) ;
+ }
+ }
+ }
+ sc.ChangeState(SCE_TEX_TEXT) ;
+ sc.Complete();
+
+}
+
+
+static inline bool isNumber(int ch) {
+ return
+ (ch == '0') || (ch == '1') || (ch == '2') ||
+ (ch == '3') || (ch == '4') || (ch == '5') ||
+ (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9');
+}
+
+static inline bool isWordChar(int ch) {
+ return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'));
+}
+
+static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command)
+{
+ int length=0;
+ char ch=styler.SafeGetCharAt(pos+1);
+
+ if(ch==',' || ch==':' || ch==';' || ch=='%'){
+ command[0]=ch;
+ command[1]=0;
+ return 1;
+ }
+
+ // find end
+ while(isWordChar(ch) && !isNumber(ch) && ch!='_' && ch!='.' && length<100){
+ command[length]=ch;
+ length++;
+ ch=styler.SafeGetCharAt(pos+length+1);
+ }
+
+ command[length]='\0';
+ if(!length) return 0;
+ return length+1;
+}
+
+static int classifyFoldPointTeXPaired(const char* s) {
+ int lev=0;
+ if (!(isdigit(s[0]) || (s[0] == '.'))){
+ if (strcmp(s, "begin")==0||strcmp(s,"FoldStart")==0||
+ strcmp(s,"abstract")==0||strcmp(s,"unprotect")==0||
+ strcmp(s,"title")==0||strncmp(s,"start",5)==0||strncmp(s,"Start",5)==0||
+ strcmp(s,"documentclass")==0||strncmp(s,"if",2)==0
+ )
+ lev=1;
+ if (strcmp(s, "end")==0||strcmp(s,"FoldStop")==0||
+ strcmp(s,"maketitle")==0||strcmp(s,"protect")==0||
+ strncmp(s,"stop",4)==0||strncmp(s,"Stop",4)==0||
+ strcmp(s,"fi")==0
+ )
+ lev=-1;
+ }
+ return lev;
+}
+
+static int classifyFoldPointTeXUnpaired(const char* s) {
+ int lev=0;
+ if (!(isdigit(s[0]) || (s[0] == '.'))){
+ if (strcmp(s,"part")==0||
+ strcmp(s,"chapter")==0||
+ strcmp(s,"section")==0||
+ strcmp(s,"subsection")==0||
+ strcmp(s,"subsubsection")==0||
+ strcmp(s,"CJKfamily")==0||
+ strcmp(s,"appendix")==0||
+ strcmp(s,"Topic")==0||strcmp(s,"topic")==0||
+ strcmp(s,"subject")==0||strcmp(s,"subsubject")==0||
+ strcmp(s,"def")==0||strcmp(s,"gdef")==0||strcmp(s,"edef")==0||
+ strcmp(s,"xdef")==0||strcmp(s,"framed")==0||
+ strcmp(s,"frame")==0||
+ strcmp(s,"foilhead")==0||strcmp(s,"overlays")==0||strcmp(s,"slide")==0
+ ){
+ lev=1;
+ }
+ }
+ return lev;
+}
+
+static bool IsTeXCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+
+ int startpos = pos;
+
+ while (startpos<eol_pos){
+ char ch = styler[startpos];
+ if (ch!='%' && ch!=' ') return false;
+ else if (ch=='%') return true;
+ startpos++;
+ }
+
+ return false;
+}
+
+// FoldTeXDoc: borrowed from VisualTeX with modifications
+
+static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos+length;
+ int visibleChars=0;
+ int lineCurrent=styler.GetLine(startPos);
+ int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent=levelPrev;
+ char chNext=styler[startPos];
+ char buffer[100]="";
+
+ for (unsigned int i=startPos; i < endPos; i++) {
+ char ch=chNext;
+ chNext=styler.SafeGetCharAt(i+1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if(ch=='\\') {
+ ParseTeXCommand(i, styler, buffer);
+ levelCurrent += classifyFoldPointTeXPaired(buffer)+classifyFoldPointTeXUnpaired(buffer);
+ }
+
+ if (levelCurrent > SC_FOLDLEVELBASE && ((ch == '\r' || ch=='\n') && (chNext == '\\'))) {
+ ParseTeXCommand(i+1, styler, buffer);
+ levelCurrent -= classifyFoldPointTeXUnpaired(buffer);
+ }
+
+ char chNext2;
+ char chNext3;
+ char chNext4;
+ char chNext5;
+ chNext2=styler.SafeGetCharAt(i+2);
+ chNext3=styler.SafeGetCharAt(i+3);
+ chNext4=styler.SafeGetCharAt(i+4);
+ chNext5=styler.SafeGetCharAt(i+5);
+
+ bool atEOfold = (ch == '%') &&
+ (chNext == '%') && (chNext2=='}') &&
+ (chNext3=='}')&& (chNext4=='-')&& (chNext5=='-');
+
+ bool atBOfold = (ch == '%') &&
+ (chNext == '%') && (chNext2=='-') &&
+ (chNext3=='-')&& (chNext4=='{')&& (chNext5=='{');
+
+ if(atBOfold){
+ levelCurrent+=1;
+ }
+
+ if(atEOfold){
+ levelCurrent-=1;
+ }
+
+ if(ch=='\\' && chNext=='['){
+ levelCurrent+=1;
+ }
+
+ if(ch=='\\' && chNext==']'){
+ levelCurrent-=1;
+ }
+
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+ if (foldComment && atEOL && IsTeXCommentLine(lineCurrent, styler))
+ {
+ if (lineCurrent==0 && IsTeXCommentLine(lineCurrent + 1, styler)
+ )
+ levelCurrent++;
+ else if (lineCurrent!=0 && !IsTeXCommentLine(lineCurrent - 1, styler)
+ && IsTeXCommentLine(lineCurrent + 1, styler)
+ )
+ levelCurrent++;
+ else if (lineCurrent!=0 && IsTeXCommentLine(lineCurrent - 1, styler) &&
+ !IsTeXCommentLine(lineCurrent+1, styler))
+ levelCurrent--;
+ }
+
+//---------------------------------------------------------------------------------------------
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+
+
+
+static const char * const texWordListDesc[] = {
+ "TeX, eTeX, pdfTeX, Omega",
+ "ConTeXt Dutch",
+ "ConTeXt English",
+ "ConTeXt German",
+ "ConTeXt Czech",
+ "ConTeXt Italian",
+ "ConTeXt Romanian",
+ 0,
+} ;
+
+LexerModule lmTeX(SCLEX_TEX, ColouriseTeXDoc, "tex", FoldTexDoc, texWordListDesc);
--- /dev/null
+/******************************************************************
+ * LexTxt2tags.cxx
+ *
+ * A simple Txt2tags lexer for scintilla.
+ *
+ *
+ * Adapted by Eric Forgeot
+ * Based on the LexMarkdown.cxx by Jon Strait - jstrait@moonloop.net
+ *
+ * What could be improved:
+ * - Verbatim lines could be like for raw lines : when there is no space between the ``` and the following text, the first letter should be colored so the user would understand there must be a space for a valid tag.
+ * - marks such as bold, italic, strikeout, underline should begin to be highlighted only when they are closed and valid.
+ * - verbatim and raw area should be highlighted too.
+ *
+ * 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 "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 IsNewline(const int ch) {
+ return (ch == '\n' || ch == '\r');
+}
+
+// True if can follow ch down to the end with possibly trailing whitespace
+static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
+ unsigned int i = 0;
+ while (sc.GetRelative(++i) == ch)
+ ;
+ // Skip over whitespace
+ while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+ ++i;
+ if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
+ sc.Forward(i);
+ sc.ChangeState(state);
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ return true;
+ }
+ else return false;
+}
+
+// Does the previous line have more than spaces and tabs?
+static bool HasPrevLineContent(StyleContext &sc) {
+ int i = 0;
+ // Go back to the previous newline
+ while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
+ ;
+ while (--i + sc.currentPos) {
+ if (IsNewline(sc.GetRelative(i)))
+ break;
+ if (!IsASpaceOrTab(sc.GetRelative(i)))
+ return true;
+ }
+ return false;
+}
+
+// Separator line
+static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
+ int c, count = 1;
+ unsigned int i = 0;
+ while (++i) {
+ c = sc.GetRelative(i);
+ if (c == sc.ch)
+ ++count;
+ // hit a terminating character
+ else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
+ // Are we a valid HRULE
+ if ((IsNewline(c) || sc.currentPos + i == endPos) &&
+ count >= 20 && !HasPrevLineContent(sc)) {
+ sc.SetState(SCE_TXT2TAGS_HRULE);
+ sc.Forward(i);
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ return true;
+ }
+ else {
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+static void ColorizeTxt2tagsDoc(unsigned int startPos, int length, int initStyle,
+ WordList **, Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int precharCount = 0;
+ // Don't advance on a new loop iteration and retry at the same position.
+ // Useful in the corner case of having to start at the beginning file position
+ // in the default state.
+ bool freezeCursor = false;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ while (sc.More()) {
+ // Skip past escaped characters
+ if (sc.ch == '\\') {
+ sc.Forward();
+ continue;
+ }
+
+ // A blockquotes resets the line semantics
+ if (sc.state == SCE_TXT2TAGS_BLOCKQUOTE){
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ }
+ // An option colors the whole line
+ if (sc.state == SCE_TXT2TAGS_OPTION){
+ FollowToLineEnd('%', SCE_TXT2TAGS_OPTION, endPos, sc);
+ }
+ if (sc.state == SCE_TXT2TAGS_POSTPROC){
+ FollowToLineEnd('%', SCE_TXT2TAGS_POSTPROC, endPos, sc);
+ }
+ if (sc.state == SCE_TXT2TAGS_PREPROC){
+ FollowToLineEnd('%', SCE_TXT2TAGS_PREPROC, endPos, sc);
+ }
+ // A comment colors the whole line
+ if (sc.state == SCE_TXT2TAGS_COMMENT){
+ FollowToLineEnd('%', SCE_TXT2TAGS_COMMENT, endPos, sc);
+ }
+ // Conditional state-based actions
+ if (sc.state == SCE_TXT2TAGS_CODE2) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Table
+ else if (sc.state == SCE_TXT2TAGS_CODE) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.ch == '|' && sc.chPrev != ' ')
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ // Strong
+ else if (sc.state == SCE_TXT2TAGS_STRONG1) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("**") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Emphasis
+ else if (sc.state == SCE_TXT2TAGS_EM1) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("//") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Underline
+ else if (sc.state == SCE_TXT2TAGS_EM2) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("__") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // codeblock
+ else if (sc.state == SCE_TXT2TAGS_CODEBK) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.atLineStart && sc.Match("```")) {
+ int i = 1;
+ while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+ i++;
+ sc.Forward(i);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // strikeout
+ else if (sc.state == SCE_TXT2TAGS_STRIKEOUT) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("--") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Headers
+ else if (sc.state == SCE_TXT2TAGS_LINE_BEGIN) {
+ if (sc.Match("======"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER6);
+ sc.Forward();
+ }
+ else if (sc.Match("====="))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER5);
+ sc.Forward();
+ }
+ else if (sc.Match("===="))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER4);
+ sc.Forward();
+ }
+ else if (sc.Match("==="))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER3);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '=', sc);
+ else if (sc.Match("==")) {
+ sc.SetState(SCE_TXT2TAGS_HEADER2);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '=', sc);
+ else if (sc.Match("=")) {
+ // Catch the special case of an unordered list
+ if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ else
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER1);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER1, 1, '=', sc);
+ }
+
+ // Numbered title
+ else if (sc.Match("++++++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER6);
+ sc.Forward();
+ }
+ else if (sc.Match("+++++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER5);
+ sc.Forward();
+ }
+ else if (sc.Match("++++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER4);
+ sc.Forward();
+ }
+ else if (sc.Match("+++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER3);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '+', sc);
+ else if (sc.Match("++")) {
+ sc.SetState(SCE_TXT2TAGS_HEADER2);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '+', sc);
+ else if (sc.Match("+")) {
+ // Catch the special case of an unordered list
+ if (sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(1))) {
+ // if (IsNewline(sc.ch)) {
+ //precharCount = 0;
+ // sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ //sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ // }
+ // else {
+ // precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ // sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ // }
+ }
+ else
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER1);
+ sc.Forward();
+ }
+ }
+
+
+ // Codeblock
+ else if (sc.Match("```")) {
+ if (!HasPrevLineContent(sc))
+ // if (!FollowToLineEnd(sc))
+ sc.SetState(SCE_TXT2TAGS_CODEBK);
+ else
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+
+ // Preproc
+ else if (sc.Match("%!preproc")) {
+ sc.SetState(SCE_TXT2TAGS_PREPROC);
+ }
+ // Postproc
+ else if (sc.Match("%!postproc")) {
+ sc.SetState(SCE_TXT2TAGS_POSTPROC);
+ }
+ // Option
+ else if (sc.Match("%!")) {
+ sc.SetState(SCE_TXT2TAGS_OPTION);
+ }
+
+ // Comment
+ else if (sc.ch == '%') {
+ sc.SetState(SCE_TXT2TAGS_COMMENT);
+ }
+ // list
+ else if (sc.ch == '-') {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ // def list
+ else if (sc.ch == ':') {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ sc.Forward(1);
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ else if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ else {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ }
+
+ // The header lasts until the newline
+ else if (sc.state == SCE_TXT2TAGS_HEADER1 || sc.state == SCE_TXT2TAGS_HEADER2 ||
+ sc.state == SCE_TXT2TAGS_HEADER3 || sc.state == SCE_TXT2TAGS_HEADER4 ||
+ sc.state == SCE_TXT2TAGS_HEADER5 || sc.state == SCE_TXT2TAGS_HEADER6) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ }
+
+ // New state only within the initial whitespace
+ if (sc.state == SCE_TXT2TAGS_PRECHAR) {
+ // Blockquote
+ if (sc.Match("\"\"\"") && precharCount < 5){
+
+ sc.SetState(SCE_TXT2TAGS_BLOCKQUOTE);
+ sc.Forward(1);
+ }
+ /*
+ // Begin of code block
+ else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
+ sc.SetState(SCE_TXT2TAGS_CODEBK);
+ */
+ // HRule - Total of 20 or more hyphens, asterisks, or underscores
+ // on a line by themselves
+ else if ((sc.ch == '-' ) && IsValidHrule(endPos, sc))
+ ;
+ // Unordered list
+ else if ((sc.ch == '-') && IsASpaceOrTab(sc.chNext)) {
+ sc.SetState(SCE_TXT2TAGS_ULIST_ITEM);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ // Ordered list
+ else if (IsADigit(sc.ch)) {
+ int digitCount = 0;
+ while (IsADigit(sc.GetRelative(++digitCount)))
+ ;
+ if (sc.GetRelative(digitCount) == '.' &&
+ IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
+ sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ sc.Forward(digitCount + 1);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Alternate Ordered list
+ else if (sc.ch == '+' && sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(2))) {
+ // sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ // sc.Forward(2);
+ // sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ else if (sc.ch != ' ' || precharCount > 2)
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ else
+ ++precharCount;
+ }
+
+ // New state anywhere in doc
+ if (sc.state == SCE_TXT2TAGS_DEFAULT) {
+ // if (sc.atLineStart && sc.ch == '#') {
+ // sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ // freezeCursor = true;
+ // }
+ // Links and Images
+ if (sc.Match("![") || sc.ch == '[') {
+ int i = 0, j = 0, k = 0;
+ int len = endPos - sc.currentPos;
+ while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ']') {
+ j = i;
+ if (sc.GetRelative(++i) == '(') {
+ while (i < len && (sc.GetRelative(++i) != '(' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == '(')
+ k = i;
+ }
+
+ else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
+ while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ']')
+ k = i;
+ }
+ }
+ // At least a link text
+ if (j) {
+ sc.SetState(SCE_TXT2TAGS_LINK);
+ sc.Forward(j);
+ // Also has a URL or reference portion
+ if (k)
+ sc.Forward(k - j);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Code - also a special case for alternate inside spacing
+ if (sc.Match("``") && sc.GetRelative(3) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_CODE2);
+ sc.Forward();
+ }
+ else if (sc.ch == '|' && sc.GetRelative(3) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_CODE);
+ }
+ // Strong
+ else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_STRONG1);
+ sc.Forward();
+ }
+ // Emphasis
+ else if (sc.Match("//") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_EM1);
+ sc.Forward();
+ }
+ else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_EM2);
+ sc.Forward();
+ }
+ // Strikeout
+ else if (sc.Match("--") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_STRIKEOUT);
+ sc.Forward();
+ }
+
+ // Beginning of line
+ else if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ }
+ // Advance if not holding back the cursor for this iteration.
+ if (!freezeCursor)
+ sc.Forward();
+ freezeCursor = false;
+ }
+ sc.Complete();
+}
+
+LexerModule lmTxt2tags(SCLEX_TXT2TAGS, ColorizeTxt2tagsDoc, "txt2tags");
+
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexVB.cxx
+ ** Lexer for Visual Basic and VBScript.
+ **/
+// Copyright 1998-2005 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
+
+// Internal state, highlighted as number
+#define SCE_B_FILENUMBER SCE_B_DEFAULT+100
+
+
+static bool IsVBComment(Accessor &styler, int pos, int len) {
+ return len > 0 && styler[pos] == '\'';
+}
+
+static inline bool IsTypeCharacter(int ch) {
+ return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
+}
+
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+ return ch >= 0x80 ||
+ (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+ return ch >= 0x80 ||
+ (isalpha(ch) || ch == '_');
+}
+
+static inline bool IsANumberChar(int ch) {
+ // Not exactly following number definition (several dots are seen as OK, etc.)
+ // but probably enough in most cases.
+ return (ch < 0x80) &&
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
+}
+
+static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler, bool vbScriptSyntax) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ styler.StartAt(startPos);
+
+ int visibleChars = 0;
+ int fileNbDigits = 0;
+
+ // Do not leak onto next line
+ if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
+ initStyle = SCE_B_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_B_OPERATOR) {
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ // In Basic (except VBScript), a variable name or a function name
+ // can end with a special character indicating the type of the value
+ // held or returned.
+ bool skipType = false;
+ if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
+ sc.Forward(); // Skip it
+ skipType = true;
+ }
+ if (sc.ch == ']') {
+ sc.Forward();
+ }
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (skipType) {
+ s[strlen(s) - 1] = '\0';
+ }
+ if (strcmp(s, "rem") == 0) {
+ sc.ChangeState(SCE_B_COMMENT);
+ } else {
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD4);
+ } // Else, it is really an identifier...
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+ } else if (sc.state == SCE_B_NUMBER) {
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ // Also accepts A-F for hex. numbers
+ if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_STRING) {
+ // VB doubles quotes to preserve them, so just end this string
+ // state now as a following quote will start again
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ if (tolower(sc.chNext) == 'c') {
+ sc.Forward();
+ }
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.atLineEnd) {
+ visibleChars = 0;
+ sc.ChangeState(SCE_B_STRINGEOL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_COMMENT) {
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_PREPROCESSOR) {
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_FILENUMBER) {
+ if (IsADigit(sc.ch)) {
+ fileNbDigits++;
+ if (fileNbDigits > 3) {
+ sc.ChangeState(SCE_B_DATE);
+ }
+ } else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
+ // Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
+ // Too bad if date is format #27, Oct, 2003# or something like that...
+ // Use regular number state
+ sc.ChangeState(SCE_B_NUMBER);
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.ch == '#') {
+ sc.ChangeState(SCE_B_DATE);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else {
+ sc.ChangeState(SCE_B_DATE);
+ }
+ if (sc.state != SCE_B_FILENUMBER) {
+ fileNbDigits = 0;
+ }
+ } else if (sc.state == SCE_B_DATE) {
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ sc.ChangeState(SCE_B_STRINGEOL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else if (sc.ch == '#') {
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ }
+
+ if (sc.state == SCE_B_DEFAULT) {
+ if (sc.ch == '\'') {
+ sc.SetState(SCE_B_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_B_STRING);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_B_PREPROCESSOR);
+ } else if (sc.ch == '#') {
+ // It can be a date literal, ending with #, or a file number, from 1 to 511
+ // The date literal depends on the locale, so anything can go between #'s.
+ // Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
+ // So we set the FILENUMBER state, and switch to DATE if it isn't a file number
+ sc.SetState(SCE_B_FILENUMBER);
+ } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
+ // Hexadecimal number
+ sc.SetState(SCE_B_NUMBER);
+ sc.Forward();
+ } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
+ // Octal number
+ sc.SetState(SCE_B_NUMBER);
+ sc.Forward();
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_B_NUMBER);
+ } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division
+ sc.SetState(SCE_B_OPERATOR);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+
+ if (sc.state == SCE_B_IDENTIFIER && !IsAWordChar(sc.ch)) {
+ // In Basic (except VBScript), a variable name or a function name
+ // can end with a special character indicating the type of the value
+ // held or returned.
+ bool skipType = false;
+ if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
+ sc.Forward(); // Skip it
+ skipType = true;
+ }
+ if (sc.ch == ']') {
+ sc.Forward();
+ }
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (skipType) {
+ s[strlen(s) - 1] = '\0';
+ }
+ if (strcmp(s, "rem") == 0) {
+ sc.ChangeState(SCE_B_COMMENT);
+ } else {
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_B_KEYWORD4);
+ } // Else, it is really an identifier...
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+
+ sc.Complete();
+}
+
+static void FoldVBDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ int endPos = startPos + length;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);
+ char chNext = styler[startPos];
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ // Only non whitespace lines can be headers
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
+ // Line after is blank so check the next - maybe should continue further?
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+static void ColouriseVBNetDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+static const char * const vbWordListDesc[] = {
+ "Keywords",
+ "user1",
+ "user2",
+ "user3",
+ 0
+};
+
+LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
+LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexVHDL.cxx
+ ** Lexer for VHDL
+ ** Written by Phil Reid,
+ ** Based on:
+ ** - The Verilog Lexer by Avi Yegudin
+ ** - The Fortran Lexer by Chuan-jian Shen
+ ** - The C++ lexer by Neil Hodgson
+ **/
+// Copyright 1998-2002 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.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 void ColouriseVHDLDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+
+/***************************************/
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' );
+}
+
+/***************************************/
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+/***************************************/
+inline bool IsABlank(unsigned int ch) {
+ return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
+}
+
+/***************************************/
+static void ColouriseVHDLDoc(
+ unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ WordList &Keywords = *keywordlists[0];
+ WordList &Operators = *keywordlists[1];
+ WordList &Attributes = *keywordlists[2];
+ WordList &Functions = *keywordlists[3];
+ WordList &Packages = *keywordlists[4];
+ WordList &Types = *keywordlists[5];
+ WordList &User = *keywordlists[6];
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward())
+ {
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_VHDL_OPERATOR) {
+ sc.SetState(SCE_VHDL_DEFAULT);
+ } else if (sc.state == SCE_VHDL_NUMBER) {
+ if (!IsAWordChar(sc.ch) && (sc.ch != '#')) {
+ sc.SetState(SCE_VHDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_VHDL_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (Keywords.InList(s)) {
+ sc.ChangeState(SCE_VHDL_KEYWORD);
+ } else if (Operators.InList(s)) {
+ sc.ChangeState(SCE_VHDL_STDOPERATOR);
+ } else if (Attributes.InList(s)) {
+ sc.ChangeState(SCE_VHDL_ATTRIBUTE);
+ } else if (Functions.InList(s)) {
+ sc.ChangeState(SCE_VHDL_STDFUNCTION);
+ } else if (Packages.InList(s)) {
+ sc.ChangeState(SCE_VHDL_STDPACKAGE);
+ } else if (Types.InList(s)) {
+ sc.ChangeState(SCE_VHDL_STDTYPE);
+ } else if (User.InList(s)) {
+ sc.ChangeState(SCE_VHDL_USERWORD);
+ }
+ sc.SetState(SCE_VHDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_VHDL_COMMENTLINEBANG) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_VHDL_DEFAULT);
+ }
+ } else if (sc.state == SCE_VHDL_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_VHDL_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_VHDL_STRINGEOL);
+ sc.ForwardSetState(SCE_VHDL_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_VHDL_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_VHDL_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_VHDL_IDENTIFIER);
+ } else if (sc.Match('-', '-')) {
+ if (sc.Match("--!")) // Nice to have a different comment style
+ sc.SetState(SCE_VHDL_COMMENTLINEBANG);
+ else
+ sc.SetState(SCE_VHDL_COMMENT);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_VHDL_STRING);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_VHDL_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+//=============================================================================
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ char chNext = styler[i+1];
+ if ((ch == '-') && (chNext == '-'))
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+//=============================================================================
+// Folding the code
+static void FoldNoBoxVHDLDoc(
+ unsigned int startPos,
+ int length,
+ int,
+ Accessor &styler)
+{
+ // Decided it would be smarter to have the lexer have all keywords included. Therefore I
+ // don't check if the style for the keywords that I use to adjust the levels.
+ char words[] =
+ "architecture begin case component else elsif end entity generate loop package process record then "
+ "procedure function when";
+ WordList keywords;
+ keywords.Set(words);
+
+ bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 1) != 0;
+ bool foldAtBegin = styler.GetPropertyInt("fold.at.Begin", 1) != 0;
+ bool foldAtParenthese = styler.GetPropertyInt("fold.at.Parenthese", 1) != 0;
+ //bool foldAtWhen = styler.GetPropertyInt("fold.at.When", 1) != 0; //< fold at when in case statements
+
+ int visibleChars = 0;
+ unsigned int endPos = startPos + length;
+
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if(lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ //int levelMinCurrent = levelCurrent;
+ int levelMinCurrentElse = levelCurrent; //< Used for folding at 'else'
+ int levelMinCurrentBegin = levelCurrent; //< Used for folding at 'begin'
+ int levelNext = levelCurrent;
+
+ /***************************************/
+ int lastStart = 0;
+ char prevWord[32] = "";
+
+ /***************************************/
+ // Find prev word
+ // The logic for going up or down a level depends on a the previous keyword
+ // This code could be cleaned up.
+ int end = 0;
+ unsigned int j;
+ for(j = startPos; j>0; j--)
+ {
+ char ch = styler.SafeGetCharAt(j);
+ char chPrev = styler.SafeGetCharAt(j-1);
+ int style = styler.StyleAt(j);
+ int stylePrev = styler.StyleAt(j-1);
+ if ((stylePrev != SCE_VHDL_COMMENT) && (stylePrev != SCE_VHDL_STRING))
+ {
+ if(IsAWordChar(chPrev) && !IsAWordChar(ch))
+ {
+ end = j-1;
+ }
+ }
+ if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
+ {
+ if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0))
+ {
+ char s[32];
+ unsigned int k;
+ for(k=0; (k<31 ) && (k<end-j+1 ); k++) {
+ s[k] = static_cast<char>(tolower(styler[j+k]));
+ }
+ s[k] = '\0';
+
+ if(keywords.InList(s)) {
+ strcpy(prevWord, s);
+ break;
+ }
+ }
+ }
+ }
+ for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++)
+ {
+ char ch = styler.SafeGetCharAt(j);
+ int style = styler.StyleAt(j);
+ if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
+ {
+ if((ch == ';') && (strcmp(prevWord, "end") == 0))
+ {
+ strcpy(prevWord, ";");
+ }
+ }
+ }
+
+ char chNext = styler[startPos];
+ char chPrev = '\0';
+ char chNextNonBlank;
+ int styleNext = styler.StyleAt(startPos);
+ //Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent);
+
+ /***************************************/
+ for (unsigned int i = startPos; i < endPos; i++)
+ {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ chPrev = styler.SafeGetCharAt(i - 1);
+ chNextNonBlank = chNext;
+ unsigned int j = i+1;
+ while(IsABlank(chNextNonBlank) && j<endPos)
+ {
+ j ++ ;
+ chNextNonBlank = styler.SafeGetCharAt(j);
+ }
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+ {
+ if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler))
+ {
+ levelNext++;
+ }
+ else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler))
+ {
+ levelNext--;
+ }
+ }
+
+ if ((style == SCE_VHDL_OPERATOR) && foldAtParenthese)
+ {
+ if(ch == '(') {
+ levelNext++;
+ } else if (ch == ')') {
+ levelNext--;
+ }
+ }
+
+ if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
+ {
+ if((ch == ';') && (strcmp(prevWord, "end") == 0))
+ {
+ strcpy(prevWord, ";");
+ }
+
+ if(!IsAWordChar(chPrev) && IsAWordStart(ch))
+ {
+ lastStart = i;
+ }
+
+ if(iswordchar(ch) && !iswordchar(chNext)) {
+ char s[32];
+ unsigned int k;
+ for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
+ s[k] = static_cast<char>(tolower(styler[lastStart+k]));
+ }
+ s[k] = '\0';
+
+ if(keywords.InList(s))
+ {
+ if (
+ strcmp(s, "architecture") == 0 ||
+ strcmp(s, "case") == 0 ||
+ strcmp(s, "component") == 0 ||
+ strcmp(s, "entity") == 0 ||
+ strcmp(s, "generate") == 0 ||
+ strcmp(s, "loop") == 0 ||
+ strcmp(s, "package") ==0 ||
+ strcmp(s, "process") == 0 ||
+ strcmp(s, "record") == 0 ||
+ strcmp(s, "then") == 0)
+ {
+ if (strcmp(prevWord, "end") != 0)
+ {
+ if (levelMinCurrentElse > levelNext) {
+ levelMinCurrentElse = levelNext;
+ }
+ levelNext++;
+ }
+ } else if (
+ strcmp(s, "procedure") == 0 ||
+ strcmp(s, "function") == 0)
+ {
+ if (strcmp(prevWord, "end") != 0) // check for "end procedure" etc.
+ { // This code checks to see if the procedure / function is a definition within a "package"
+ // rather than the actual code in the body.
+ int BracketLevel = 0;
+ for(int j=i+1; j<styler.Length(); j++)
+ {
+ int LocalStyle = styler.StyleAt(j);
+ char LocalCh = styler.SafeGetCharAt(j);
+ if(LocalCh == '(') BracketLevel++;
+ if(LocalCh == ')') BracketLevel--;
+ if(
+ (BracketLevel == 0) &&
+ (LocalStyle != SCE_VHDL_COMMENT) &&
+ (LocalStyle != SCE_VHDL_STRING) &&
+ !iswordchar(styler.SafeGetCharAt(j-1)) &&
+ styler.Match(j, "is") &&
+ !iswordchar(styler.SafeGetCharAt(j+2)))
+ {
+ if (levelMinCurrentElse > levelNext) {
+ levelMinCurrentElse = levelNext;
+ }
+ levelNext++;
+ break;
+ }
+ if((BracketLevel == 0) && (LocalCh == ';'))
+ {
+ break;
+ }
+ }
+ }
+
+ } else if (strcmp(s, "end") == 0) {
+ levelNext--;
+ } else if(strcmp(s, "elsif") == 0) { // elsif is followed by then so folding occurs correctly
+ levelNext--;
+ } else if (strcmp(s, "else") == 0) {
+ if(strcmp(prevWord, "when") != 0) // ignore a <= x when y else z;
+ {
+ levelMinCurrentElse = levelNext - 1; // VHDL else is all on its own so just dec. the min level
+ }
+ } else if(
+ ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "architecture") == 0)) ||
+ ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) ||
+ ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0)))
+ {
+ levelMinCurrentBegin = levelNext - 1;
+ }
+ //Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent);
+ strcpy(prevWord, s);
+ }
+ }
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+
+ if (foldAtElse && (levelMinCurrentElse < levelUse)) {
+ levelUse = levelMinCurrentElse;
+ }
+ if (foldAtBegin && (levelMinCurrentBegin < levelUse)) {
+ levelUse = levelMinCurrentBegin;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ //Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent);
+ lineCurrent++;
+ levelCurrent = levelNext;
+ //levelMinCurrent = levelCurrent;
+ levelMinCurrentElse = levelCurrent;
+ levelMinCurrentBegin = levelCurrent;
+ visibleChars = 0;
+ }
+ /***************************************/
+ if (!isspacechar(ch)) visibleChars++;
+ }
+
+ /***************************************/
+// Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent);
+}
+
+//=============================================================================
+static void FoldVHDLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ FoldNoBoxVHDLDoc(startPos, length, initStyle, styler);
+}
+
+//=============================================================================
+static const char * const VHDLWordLists[] = {
+ "Keywords",
+ "Operators",
+ "Attributes",
+ "Standard Functions",
+ "Standard Packages",
+ "Standard Types",
+ "User Words",
+ 0,
+ };
+
+
+LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, "vhdl", FoldVHDLDoc, VHDLWordLists);
+
+
+// Keyword:
+// access after alias all architecture array assert attribute begin block body buffer bus case component
+// configuration constant disconnect downto else elsif end entity exit file for function generate generic
+// group guarded if impure in inertial inout is label library linkage literal loop map new next null of
+// on open others out package port postponed procedure process pure range record register reject report
+// return select severity shared signal subtype then to transport type unaffected units until use variable
+// wait when while with
+//
+// Operators:
+// abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor
+//
+// Attributes:
+// left right low high ascending image value pos val succ pred leftof rightof base range reverse_range
+// length delayed stable quiet transaction event active last_event last_active last_value driving
+// driving_value simple_name path_name instance_name
+//
+// Std Functions:
+// now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector
+// to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left
+// rotate_right resize to_integer to_unsigned to_signed std_match to_01
+//
+// Std Packages:
+// std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed
+// std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives
+// vital_timing
+//
+// Std Types:
+// boolean bit character severity_level integer real time delay_length natural positive string bit_vector
+// file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic
+// std_logic_vector X01 X01Z UX01 UX01Z unsigned signed
+//
+
--- /dev/null
+// Scintilla source code edit control
+/** @file LexVerilog.cxx
+ ** Lexer for Verilog.
+ ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson
+ **/
+// Copyright 1998-2002 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 IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '$');
+}
+
+static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_V_STRINGEOL)
+ initStyle = SCE_V_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineStart && (sc.state == SCE_V_STRING)) {
+ // Prevent SCE_V_STRINGEOL from leaking back to previous line
+ sc.SetState(SCE_V_STRING);
+ }
+
+ // Handle line continuation generically.
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\n' || sc.chNext == '\r') {
+ sc.Forward();
+ if (sc.ch == '\r' && sc.chNext == '\n') {
+ sc.Forward();
+ }
+ continue;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_V_OPERATOR) {
+ sc.SetState(SCE_V_DEFAULT);
+ } else if (sc.state == SCE_V_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_V_DEFAULT);
+ }
+ } else if (sc.state == SCE_V_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_V_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_V_WORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_V_WORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_V_USER);
+ }
+ sc.SetState(SCE_V_DEFAULT);
+ }
+ } else if (sc.state == SCE_V_PREPROCESSOR) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_V_DEFAULT);
+ }
+ } else if (sc.state == SCE_V_COMMENT) {
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_V_DEFAULT);
+ }
+ } else if (sc.state == SCE_V_COMMENTLINE || sc.state == SCE_V_COMMENTLINEBANG) {
+ if (sc.atLineStart) {
+ sc.SetState(SCE_V_DEFAULT);
+ }
+ } else if (sc.state == SCE_V_STRING) {
+ if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_V_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_V_STRINGEOL);
+ sc.ForwardSetState(SCE_V_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_V_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '\'') || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_V_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_V_IDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_V_COMMENT);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('/', '/')) {
+ if (sc.Match("//!")) // Nice to have a different comment style
+ sc.SetState(SCE_V_COMMENTLINEBANG);
+ else
+ sc.SetState(SCE_V_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_V_STRING);
+ } else if (sc.ch == '`') {
+ sc.SetState(SCE_V_PREPROCESSOR);
+ // Skip whitespace between ` and preprocessor word
+ do {
+ sc.Forward();
+ } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_V_DEFAULT);
+ }
+ } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') {
+ sc.SetState(SCE_V_OPERATOR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_V_COMMENT;
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eolPos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eolPos; i++) {
+ char ch = styler[i];
+ char chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ if (ch == '/' && chNext == '/' &&
+ (style == SCE_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG)) {
+ return true;
+ } else if (!IsASpaceOrTab(ch)) {
+ return false;
+ }
+ }
+ return false;
+}
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle,
+ Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ // Verilog specific folding options:
+ // fold_at_module -
+ // Generally used methodology in verilog code is
+ // one module per file, so folding at module definition is useless.
+ // fold_at_brace/parenthese -
+ // Folding of long port lists can be convenient.
+ bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0;
+ bool foldAtBrace = 1;
+ bool foldAtParenthese = 1;
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (foldComment && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+ {
+ if (!IsCommentLine(lineCurrent - 1, styler)
+ && IsCommentLine(lineCurrent + 1, styler))
+ levelNext++;
+ else if (IsCommentLine(lineCurrent - 1, styler)
+ && !IsCommentLine(lineCurrent+1, styler))
+ levelNext--;
+ }
+ if (foldComment && (style == SCE_V_COMMENTLINE)) {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ if (foldPreprocessor && (style == SCE_V_PREPROCESSOR)) {
+ if (ch == '`') {
+ unsigned int j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "if")) {
+ levelNext++;
+ } else if (styler.Match(j, "end")) {
+ levelNext--;
+ }
+ }
+ }
+ if (style == SCE_V_OPERATOR) {
+ if (foldAtParenthese) {
+ if (ch == '(') {
+ levelNext++;
+ } else if (ch == ')') {
+ levelNext--;
+ }
+ }
+ }
+ if (style == SCE_V_OPERATOR) {
+ if (foldAtBrace) {
+ if (ch == '{') {
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ }
+ if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) {
+ unsigned int j = i;
+ if (styler.Match(j, "case") ||
+ styler.Match(j, "casex") ||
+ styler.Match(j, "casez") ||
+ styler.Match(j, "class") ||
+ styler.Match(j, "function") ||
+ styler.Match(j, "generate") ||
+ styler.Match(j, "covergroup") ||
+ styler.Match(j, "package") ||
+ styler.Match(j, "primitive") ||
+ styler.Match(j, "program") ||
+ styler.Match(j, "sequence") ||
+ styler.Match(j, "specify") ||
+ styler.Match(j, "table") ||
+ styler.Match(j, "task") ||
+ styler.Match(j, "fork") ||
+ (styler.Match(j, "module") && foldAtModule) ||
+ styler.Match(j, "begin")) {
+ levelNext++;
+ } else if (styler.Match(j, "endcase") ||
+ styler.Match(j, "endclass") ||
+ styler.Match(j, "endfunction") ||
+ styler.Match(j, "endgenerate") ||
+ styler.Match(j, "endgroup") ||
+ styler.Match(j, "endpackage") ||
+ styler.Match(j, "endprimitive") ||
+ styler.Match(j, "endprogram") ||
+ styler.Match(j, "endsequence") ||
+ styler.Match(j, "endspecify") ||
+ styler.Match(j, "endtable") ||
+ styler.Match(j, "endtask") ||
+ styler.Match(j, "join") ||
+ styler.Match(j, "join_any") ||
+ styler.Match(j, "join_none") ||
+ (styler.Match(j, "endmodule") && foldAtModule) ||
+ (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
+ levelNext--;
+ }
+ }
+ if (atEOL) {
+ int levelUse = levelCurrent;
+ if (foldAtElse) {
+ levelUse = levelMinCurrent;
+ }
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+}
+
+static void FoldVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+ Accessor &styler) {
+ FoldNoBoxVerilogDoc(startPos, length, initStyle, styler);
+}
+
+static const char * const verilogWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "System Tasks",
+ "User defined tasks and identifiers",
+ "Unused",
+ 0,
+ };
+
+
+LexerModule lmVerilog(SCLEX_VERILOG, ColouriseVerilogDoc, "verilog", FoldVerilogDoc, verilogWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexVisualProlog.cxx
+** Lexer for Visual Prolog.
+**/
+// Author Thomas Linder Puls, Prolog Development Denter A/S, http://www.visual-prolog.com
+// Based on Lexer for C++, C, Java, and JavaScript.
+// Copyright 1998-2005 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#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"
+#include "OptionSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+// Options used for LexerVisualProlog
+struct OptionsVisualProlog {
+ OptionsVisualProlog() {
+ }
+};
+
+static const char *const visualPrologWordLists[] = {
+ "Major keywords (class, predicates, ...)",
+ "Minor keywords (if, then, try, ...)",
+ "Directive keywords without the '#' (include, requires, ...)",
+ "Documentation keywords without the '@' (short, detail, ...)",
+ 0,
+};
+
+struct OptionSetVisualProlog : public OptionSet<OptionsVisualProlog> {
+ OptionSetVisualProlog() {
+ DefineWordListSets(visualPrologWordLists);
+ }
+};
+
+class LexerVisualProlog : public ILexer {
+ WordList majorKeywords;
+ WordList minorKeywords;
+ WordList directiveKeywords;
+ WordList docKeywords;
+ OptionsVisualProlog options;
+ OptionSetVisualProlog osVisualProlog;
+public:
+ LexerVisualProlog() {
+ }
+ virtual ~LexerVisualProlog() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osVisualProlog.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osVisualProlog.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osVisualProlog.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osVisualProlog.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryVisualProlog() {
+ return new LexerVisualProlog();
+ }
+};
+
+int SCI_METHOD LexerVisualProlog::PropertySet(const char *key, const char *val) {
+ if (osVisualProlog.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerVisualProlog::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &majorKeywords;
+ break;
+ case 1:
+ wordListN = &minorKeywords;
+ break;
+ case 2:
+ wordListN = &directiveKeywords;
+ break;
+ case 3:
+ wordListN = &docKeywords;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+// Functor used to truncate history
+struct After {
+ int line;
+ After(int line_) : line(line_) {}
+};
+
+// Look ahead to see which colour "end" should have (takes colour after the following keyword)
+static void endLookAhead(char s[], LexAccessor &styler, int start, CharacterSet &setIdentifier) {
+ char ch = styler.SafeGetCharAt(start, '\n');
+ while (' ' == ch) {
+ start++;
+ ch = styler.SafeGetCharAt(start, '\n');
+ }
+ int i = 0;
+ while (i < 100 && setIdentifier.Contains(ch)){
+ s[i] = ch;
+ i++;
+ ch = styler.SafeGetCharAt(start + i, '\n');
+ }
+ s[i] = '\0';
+}
+
+static void forwardEscapeLiteral(StyleContext &sc, int OwnChar, int EscapeState) {
+ sc.Forward();
+ if (sc.ch == OwnChar || sc.ch == '\\' || sc.ch == 'n' || sc.ch == 'l' || sc.ch == 'r' || sc.ch == 't') {
+ sc.ChangeState(EscapeState);
+ } else if (sc.ch == 'u') {
+ if (IsADigit(sc.chNext, 16)) {
+ sc.Forward();
+ if (IsADigit(sc.chNext, 16)) {
+ sc.Forward();
+ if (IsADigit(sc.chNext, 16)) {
+ sc.Forward();
+ if (IsADigit(sc.chNext, 16)) {
+ sc.Forward();
+ sc.ChangeState(EscapeState);
+ }
+ }
+ }
+ }
+ }
+}
+
+void SCI_METHOD LexerVisualProlog::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
+ CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
+
+ CharacterSet setLowerStart(CharacterSet::setLower);
+ CharacterSet setVariableStart(CharacterSet::setUpper);
+ CharacterSet setIdentifier(CharacterSet::setAlphaNum, "_", 0x80, true);
+
+ int styleBeforeDocKeyword = SCE_VISUALPROLOG_DEFAULT;
+
+ int currentLine = styler.GetLine(startPos);
+
+ int nestLevel = 0;
+ if (currentLine >= 1)
+ {
+ nestLevel = styler.GetLineState(currentLine - 1);
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+
+ // Truncate ppDefineHistory before current line
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ styler.SetLineState(currentLine, nestLevel);
+ currentLine++;
+ }
+
+ if (sc.atLineStart) {
+ if ((sc.state == SCE_VISUALPROLOG_STRING) || (sc.state == SCE_VISUALPROLOG_CHARACTER)) {
+ // Prevent SCE_VISUALPROLOG_STRING_EOL from leaking back to previous line which
+ // ends with a line continuation by locking in the state upto this position.
+ sc.SetState(sc.state);
+ }
+ }
+
+ const bool atLineEndBeforeSwitch = sc.atLineEnd;
+
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_VISUALPROLOG_OPERATOR:
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ break;
+ case SCE_VISUALPROLOG_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (!(setIdentifier.Contains(sc.ch) || (sc.ch == '.') || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ break;
+ case SCE_VISUALPROLOG_IDENTIFIER:
+ if (!setIdentifier.Contains(sc.ch)) {
+ char s[1000];
+ sc.GetCurrent(s, sizeof(s));
+ if (0 == strcmp(s, "end")) {
+ endLookAhead(s, styler, sc.currentPos, setIdentifier);
+ }
+ if (majorKeywords.InList(s)) {
+ sc.ChangeState(SCE_VISUALPROLOG_KEY_MAJOR);
+ } else if (minorKeywords.InList(s)) {
+ sc.ChangeState(SCE_VISUALPROLOG_KEY_MINOR);
+ }
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ break;
+ case SCE_VISUALPROLOG_VARIABLE:
+ case SCE_VISUALPROLOG_ANONYMOUS:
+ if (!setIdentifier.Contains(sc.ch)) {
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ break;
+ case SCE_VISUALPROLOG_KEY_DIRECTIVE:
+ if (!setLowerStart.Contains(sc.ch)) {
+ char s[1000];
+ sc.GetCurrent(s, sizeof(s));
+ if (!directiveKeywords.InList(s+1)) {
+ sc.ChangeState(SCE_VISUALPROLOG_IDENTIFIER);
+ }
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ break;
+ case SCE_VISUALPROLOG_COMMENT_BLOCK:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ nestLevel--;
+ int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK;
+ sc.ForwardSetState(nextState);
+ } else if (sc.Match('/', '*')) {
+ sc.Forward();
+ nestLevel++;
+ } else if (sc.ch == '%') {
+ sc.SetState(SCE_VISUALPROLOG_COMMENT_LINE);
+ } else if (sc.ch == '@') {
+ styleBeforeDocKeyword = sc.state;
+ sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);
+ }
+ break;
+ case SCE_VISUALPROLOG_COMMENT_LINE:
+ if (sc.atLineEnd) {
+ int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK;
+ sc.SetState(nextState);
+ } else if (sc.ch == '@') {
+ styleBeforeDocKeyword = sc.state;
+ sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);
+ }
+ break;
+ case SCE_VISUALPROLOG_COMMENT_KEY_ERROR:
+ if (!setDoxygen.Contains(sc.ch)) {
+ char s[1000];
+ sc.GetCurrent(s, sizeof(s));
+ if (docKeywords.InList(s+1)) {
+ sc.ChangeState(SCE_VISUALPROLOG_COMMENT_KEY);
+ }
+ sc.SetState(styleBeforeDocKeyword);
+ }
+ if (SCE_VISUALPROLOG_COMMENT_LINE == styleBeforeDocKeyword && sc.atLineStart) {
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ } else if (SCE_VISUALPROLOG_COMMENT_BLOCK == styleBeforeDocKeyword && sc.atLineStart) {
+ sc.SetState(SCE_VISUALPROLOG_COMMENT_BLOCK);
+ }
+ break;
+ case SCE_VISUALPROLOG_STRING_ESCAPE:
+ case SCE_VISUALPROLOG_STRING_ESCAPE_ERROR:
+ // return to SCE_VISUALPROLOG_STRING and treat as such (fall-through)
+ sc.SetState(SCE_VISUALPROLOG_STRING);
+ case SCE_VISUALPROLOG_STRING:
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_VISUALPROLOG_STRING_EOL_OPEN);
+ } else if (sc.ch == '"') {
+ sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
+ } else if (sc.ch == '\\') {
+ sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR);
+ forwardEscapeLiteral(sc, '"', SCE_VISUALPROLOG_STRING_ESCAPE);
+ }
+ break;
+ case SCE_VISUALPROLOG_CHARACTER_TOO_MANY:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_VISUALPROLOG_CHARACTER);
+ sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ break;
+ case SCE_VISUALPROLOG_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_VISUALPROLOG_STRING_EOL_OPEN); // reuse STRING_EOL_OPEN for this
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR);
+ sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
+ } else {
+ if (sc.ch == '\\') {
+ sc.SetState(SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR);
+ forwardEscapeLiteral(sc, '\'', SCE_VISUALPROLOG_CHARACTER);
+ }
+ sc.ForwardSetState(SCE_VISUALPROLOG_CHARACTER);
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
+ } else {
+ sc.SetState(SCE_VISUALPROLOG_CHARACTER_TOO_MANY);
+ }
+ }
+ break;
+ case SCE_VISUALPROLOG_STRING_EOL_OPEN:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ break;
+ case SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL:
+ case SCE_VISUALPROLOG_STRING_VERBATIM_EOL:
+ // return to SCE_VISUALPROLOG_STRING_VERBATIM and treat as such (fall-through)
+ sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM);
+ case SCE_VISUALPROLOG_STRING_VERBATIM:
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM_EOL);
+ } else if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL);
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
+ }
+ }
+ break;
+ }
+
+ if (sc.atLineEnd && !atLineEndBeforeSwitch) {
+ // State exit processing consumed characters up to end of line.
+ currentLine++;
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_VISUALPROLOG_DEFAULT) {
+ if (sc.Match('@', '\"')) {
+ sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM);
+ sc.Forward();
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_VISUALPROLOG_NUMBER);
+ } else if (setLowerStart.Contains(sc.ch)) {
+ sc.SetState(SCE_VISUALPROLOG_IDENTIFIER);
+ } else if (setVariableStart.Contains(sc.ch)) {
+ sc.SetState(SCE_VISUALPROLOG_VARIABLE);
+ } else if (sc.ch == '_') {
+ sc.SetState(SCE_VISUALPROLOG_ANONYMOUS);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_VISUALPROLOG_COMMENT_BLOCK);
+ nestLevel = 1;
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.ch == '%') {
+ sc.SetState(SCE_VISUALPROLOG_COMMENT_LINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_VISUALPROLOG_STRING);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_VISUALPROLOG_CHARACTER);
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_VISUALPROLOG_KEY_DIRECTIVE);
+ } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '\\') {
+ sc.SetState(SCE_VISUALPROLOG_OPERATOR);
+ }
+ }
+
+ }
+ sc.Complete();
+ styler.Flush();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+
+void SCI_METHOD LexerVisualProlog::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+ LexAccessor styler(pAccess);
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int currentLine = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (currentLine > 0)
+ levelCurrent = styler.LevelAt(currentLine-1) >> 16;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_VISUALPROLOG_OPERATOR) {
+ if (ch == '{') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}') {
+ levelNext--;
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(currentLine)) {
+ styler.SetLevel(currentLine, lev);
+ }
+ currentLine++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+ // There is an empty line at end of file so give it same level and empty
+ styler.SetLevel(currentLine, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+ }
+ visibleChars = 0;
+ }
+ }
+}
+
+LexerModule lmVisualProlog(SCLEX_VISUALPROLOG, LexerVisualProlog::LexerFactoryVisualProlog, "visualprolog", visualPrologWordLists);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexYAML.cxx
+ ** Lexer for YAML.
+ **/
+// Copyright 2003- by Sean O'Dell <sean@celsoft.com>
+// 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 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));
+ const int comment_continue = (comment && prevComment);
+ if (!comment)
+ indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+ if (indentNext & SC_FOLDLEVELWHITEFLAG)
+ indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+ if (comment_start) {
+ // Place fold point at start of a block of comments
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (comment_continue) {
+ // Add level to rest of lines in the block
+ lev = lev + 1;
+ }
+
+ // Skip past any blank lines for next indent level info; we skip also
+ // comments (all comments, not just those starting in column 0)
+ // which effectively folds them into surrounding code rather
+ // than screwing up folding.
+
+ while ((lineNext < docLines) &&
+ ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
+ (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
+
+ lineNext++;
+ indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+ }
+
+ const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+ const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);
+
+ // Now set all the indent levels on the lines we skipped
+ // Do this from end to start. Once we encounter one line
+ // which is indented more than the line after the end of
+ // the comment-block, use the level of the block before
+
+ int skipLine = lineNext;
+ int skipLevel = levelAfterComments;
+
+ while (--skipLine > lineCurrent) {
+ int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+ if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+ skipLevel = levelBeforeComments;
+
+ int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+ styler.SetLevel(skipLine, skipLevel | whiteFlag);
+ }
+
+ // Set fold header on non-comment line
+ if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+
+ // Keep track of block comment state of previous line
+ prevComment = comment_start || comment_continue;
+
+ // Set fold level for this line and move to next line
+ styler.SetLevel(lineCurrent, lev);
+ indentCurrent = indentNext;
+ lineCurrent = lineNext;
+ }
+
+ // NOTE: Cannot set level of last line here because indentCurrent doesn't have
+ // header flag set; the loop above is crafted to take care of this case!
+ //styler.SetLevel(lineCurrent, indentCurrent);
+}
+
+LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, "yaml", FoldYAMLDoc, yamlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 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 "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) {
+}
+
+int Accessor::GetPropertyInt(const char *key, int defaultValue) {
+ return pprops->GetInt(key, defaultValue);
+}
+
+int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
+ int end = Length();
+ int spaceFlags = 0;
+
+ // Determines the indentation level of the current line and also checks for consistent
+ // indentation compared to the previous line.
+ // Indentation is judged consistent when the indentation whitespace of each line lines
+ // the same or the indentation of one line is a prefix of the other.
+
+ int pos = LineStart(line);
+ char ch = (*this)[pos];
+ int indent = 0;
+ bool inPrevPrefix = line > 0;
+ int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
+ while ((ch == ' ' || ch == '\t') && (pos < end)) {
+ if (inPrevPrefix) {
+ char chPrev = (*this)[posPrev++];
+ if (chPrev == ' ' || chPrev == '\t') {
+ if (chPrev != ch)
+ spaceFlags |= wsInconsistent;
+ } else {
+ inPrevPrefix = false;
+ }
+ }
+ if (ch == ' ') {
+ spaceFlags |= wsSpace;
+ indent++;
+ } else { // Tab
+ spaceFlags |= wsTab;
+ if (spaceFlags & wsSpace)
+ spaceFlags |= wsSpaceTab;
+ indent = (indent / 8 + 1) * 8;
+ }
+ ch = (*this)[++pos];
+ }
+
+ *flags = spaceFlags;
+ indent += SC_FOLDLEVELBASE;
+ // if completely empty line or the start of a comment...
+ if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
+ (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
+ return indent | SC_FOLDLEVELWHITEFLAG;
+ else
+ return indent;
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file Accessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ACCESSOR_H
+#define ACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
+
+class Accessor;
+class WordList;
+class PropSetSimple;
+
+typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
+
+class Accessor : public LexAccessor {
+public:
+ PropSetSimple *pprops;
+ Accessor(IDocument *pAccess_, PropSetSimple *pprops_);
+ int GetPropertyInt(const char *, int defaultValue=0);
+ int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file CharacterSet.cxx
+ ** Simple case functions for ASCII.
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 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 <ctype.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+int CompareCaseInsensitive(const char *a, const char *b) {
+ while (*a && *b) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ }
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
+ while (*a && *b && len) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ len--;
+ }
+ if (len == 0)
+ return 0;
+ else
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+#ifdef SCI_NAMESPACE
+}
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file CharacterSet.h
+ ** Encapsulates a set of characters. Used to test if a character is within a set.
+ **/
+// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef CHARACTERSET_H
+#define CHARACTERSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class CharacterSet {
+ int size;
+ bool valueAfter;
+ bool *bset;
+public:
+ enum setBase {
+ setNone=0,
+ setLower=1,
+ setUpper=2,
+ setDigits=4,
+ setAlpha=setLower|setUpper,
+ setAlphaNum=setAlpha|setDigits
+ };
+ CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) {
+ size = size_;
+ valueAfter = valueAfter_;
+ bset = new bool[size];
+ for (int i=0; i < size; i++) {
+ bset[i] = false;
+ }
+ AddString(initialSet);
+ if (base & setLower)
+ AddString("abcdefghijklmnopqrstuvwxyz");
+ if (base & setUpper)
+ AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ if (base & setDigits)
+ AddString("0123456789");
+ }
+ CharacterSet(const CharacterSet &other) {
+ size = other.size;
+ valueAfter = other.valueAfter;
+ bset = new bool[size];
+ for (int i=0; i < size; i++) {
+ bset[i] = other.bset[i];
+ }
+ }
+ ~CharacterSet() {
+ delete []bset;
+ bset = 0;
+ size = 0;
+ }
+ CharacterSet &operator=(const CharacterSet &other) {
+ if (this != &other) {
+ bool *bsetNew = new bool[other.size];
+ for (int i=0; i < other.size; i++) {
+ bsetNew[i] = other.bset[i];
+ }
+ delete []bset;
+ size = other.size;
+ valueAfter = other.valueAfter;
+ bset = bsetNew;
+ }
+ return *this;
+ }
+ void Add(int val) {
+ assert(val >= 0);
+ assert(val < size);
+ bset[val] = true;
+ }
+ void AddString(const char *setToAdd) {
+ for (const char *cp=setToAdd; *cp; cp++) {
+ int val = static_cast<unsigned char>(*cp);
+ assert(val >= 0);
+ assert(val < size);
+ bset[val] = true;
+ }
+ }
+ bool Contains(int val) const {
+ assert(val >= 0);
+ if (val < 0) return false;
+ return (val < size) ? bset[val] : valueAfter;
+ }
+};
+
+// Functions for classifying characters
+
+inline bool IsASpace(int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool IsASpaceOrTab(int ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+inline bool IsADigit(int ch) {
+ return (ch >= '0') && (ch <= '9');
+}
+
+inline bool IsADigit(int ch, int base) {
+ if (base <= 10) {
+ return (ch >= '0') && (ch < '0' + base);
+ } else {
+ return ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'A') && (ch < 'A' + base - 10)) ||
+ ((ch >= 'a') && (ch < 'a' + base - 10));
+ }
+}
+
+inline bool IsASCII(int ch) {
+ return (ch >= 0) && (ch < 0x80);
+}
+
+inline bool IsLowerCase(int ch) {
+ return (ch >= 'a') && (ch <= 'z');
+}
+
+inline bool IsUpperCase(int ch) {
+ return (ch >= 'A') && (ch <= 'Z');
+}
+
+inline bool IsAlphaNumeric(int ch) {
+ return
+ ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= 'A') && (ch <= 'Z'));
+}
+
+/**
+ * Check if a character is a space.
+ * This is ASCII specific but is safe with chars >= 0x80.
+ */
+inline bool isspacechar(int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool iswordchar(int ch) {
+ return IsAlphaNumeric(ch) || ch == '.' || ch == '_';
+}
+
+inline bool iswordstart(int ch) {
+ return IsAlphaNumeric(ch) || ch == '_';
+}
+
+inline bool isoperator(int ch) {
+ if (IsAlphaNumeric(ch))
+ return false;
+ if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
+ ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
+ ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
+ ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
+ ch == '?' || ch == '!' || ch == '.' || ch == '~')
+ return true;
+ return false;
+}
+
+// Simple case functions for ASCII.
+
+inline char MakeUpperCase(char ch) {
+ if (ch < 'a' || ch > 'z')
+ return ch;
+ else
+ return static_cast<char>(ch - 'a' + 'A');
+}
+
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file LexAccessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXACCESSOR_H
+#define LEXACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexAccessor {
+private:
+ IDocument *pAccess;
+ enum {extremePosition=0x7FFFFFFF};
+ /** @a bufferSize is a trade off between time taken to copy the characters
+ * and retrieval overhead.
+ * @a slopSize positions the buffer before the desired position
+ * in case there is some backtracking. */
+ enum {bufferSize=4000, slopSize=bufferSize/8};
+ char buf[bufferSize+1];
+ int startPos;
+ int endPos;
+ int codePage;
+ int lenDoc;
+ int mask;
+ char styleBuf[bufferSize];
+ int validLen;
+ char chFlags;
+ char chWhile;
+ unsigned int startSeg;
+ int startPosStyling;
+
+ void Fill(int position) {
+ startPos = position - slopSize;
+ if (startPos + bufferSize > lenDoc)
+ startPos = lenDoc - bufferSize;
+ if (startPos < 0)
+ startPos = 0;
+ endPos = startPos + bufferSize;
+ if (endPos > lenDoc)
+ endPos = lenDoc;
+
+ pAccess->GetCharRange(buf, startPos, endPos-startPos);
+ buf[endPos-startPos] = '\0';
+ }
+
+public:
+ LexAccessor(IDocument *pAccess_) :
+ pAccess(pAccess_), startPos(extremePosition), endPos(0),
+ codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
+ mask(127), validLen(0), chFlags(0), chWhile(0),
+ startSeg(0), startPosStyling(0) {
+ }
+ char operator[](int position) {
+ if (position < startPos || position >= endPos) {
+ Fill(position);
+ }
+ return buf[position - startPos];
+ }
+ /** Safe version of operator[], returning a defined value for invalid position. */
+ char SafeGetCharAt(int position, char chDefault=' ') {
+ if (position < startPos || position >= endPos) {
+ Fill(position);
+ if (position < startPos || position >= endPos) {
+ // Position is outside range of document
+ return chDefault;
+ }
+ }
+ return buf[position - startPos];
+ }
+ bool IsLeadByte(char ch) {
+ return pAccess->IsDBCSLeadByte(ch);
+ }
+
+ bool Match(int pos, const char *s) {
+ for (int i=0; *s; i++) {
+ if (*s != SafeGetCharAt(pos+i))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ char StyleAt(int position) {
+ return static_cast<char>(pAccess->StyleAt(position) & mask);
+ }
+ int GetLine(int position) {
+ return pAccess->LineFromPosition(position);
+ }
+ int LineStart(int line) {
+ return pAccess->LineStart(line);
+ }
+ int LevelAt(int line) {
+ return pAccess->GetLevel(line);
+ }
+ int Length() const {
+ return lenDoc;
+ }
+ void Flush() {
+ startPos = extremePosition;
+ if (validLen > 0) {
+ pAccess->SetStyles(validLen, styleBuf);
+ startPosStyling += validLen;
+ validLen = 0;
+ }
+ }
+ int GetLineState(int line) {
+ return pAccess->GetLineState(line);
+ }
+ int SetLineState(int line, int state) {
+ return pAccess->SetLineState(line, state);
+ }
+ // Style setting
+ void StartAt(unsigned int start, char chMask=31) {
+ // Store the mask specified for use with StyleAt.
+ mask = chMask;
+ pAccess->StartStyling(start, chMask);
+ startPosStyling = start;
+ }
+ void SetFlags(char chFlags_, char chWhile_) {
+ chFlags = chFlags_;
+ chWhile = chWhile_;
+ }
+ unsigned int GetStartSegment() const {
+ return startSeg;
+ }
+ void StartSegment(unsigned int pos) {
+ startSeg = pos;
+ }
+ void ColourTo(unsigned int pos, int chAttr) {
+ // Only perform styling if non empty range
+ if (pos != startSeg - 1) {
+ assert(pos >= startSeg);
+ if (pos < startSeg) {
+ return;
+ }
+
+ if (validLen + (pos - startSeg + 1) >= bufferSize)
+ Flush();
+ if (validLen + (pos - startSeg + 1) >= bufferSize) {
+ // Too big for buffer so send directly
+ pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
+ } else {
+ if (chAttr != chWhile)
+ chFlags = 0;
+ chAttr = static_cast<char>(chAttr | chFlags);
+ for (unsigned int i = startSeg; i <= pos; i++) {
+ assert((startPosStyling + validLen) < Length());
+ styleBuf[validLen++] = static_cast<char>(chAttr);
+ }
+ }
+ }
+ startSeg = pos+1;
+ }
+ void SetLevel(int line, int level) {
+ pAccess->SetLevel(line, level);
+ }
+ void IndicatorFill(int start, int end, int indicator, int value) {
+ pAccess->DecorationSetCurrentIndicator(indicator);
+ pAccess->DecorationFillRange(start, value, end - start);
+ }
+
+ void ChangeLexerState(int start, int end) {
+ pAccess->ChangeLexerState(start, end);
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 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 "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerBase::LexerBase() {
+ for (int wl = 0; wl < numWordLists; wl++)
+ keyWordLists[wl] = new WordList;
+ keyWordLists[numWordLists] = 0;
+}
+
+LexerBase::~LexerBase() {
+ for (int wl = 0; wl < numWordLists; wl++) {
+ delete keyWordLists[wl];
+ keyWordLists[wl] = 0;
+ }
+ keyWordLists[numWordLists] = 0;
+}
+
+void SCI_METHOD LexerBase::Release() {
+ delete this;
+}
+
+int SCI_METHOD LexerBase::Version() const {
+ return lvOriginal;
+}
+
+const char * SCI_METHOD LexerBase::PropertyNames() {
+ return "";
+}
+
+int SCI_METHOD LexerBase::PropertyType(const char *) {
+ return SC_TYPE_BOOLEAN;
+}
+
+const char * SCI_METHOD LexerBase::DescribeProperty(const char *) {
+ return "";
+}
+
+int SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) {
+ const char *valOld = props.Get(key);
+ if (strcmp(val, valOld) != 0) {
+ props.Set(key, val);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+const char * SCI_METHOD LexerBase::DescribeWordListSets() {
+ return "";
+}
+
+int SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {
+ if (n < numWordLists) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*keyWordLists[n] != wlNew) {
+ keyWordLists[n]->Set(wl);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void * SCI_METHOD LexerBase::PrivateCall(int, void *) {
+ return 0;
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerBase.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERBASE_H
+#define LEXERBASE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerBase : public ILexer {
+protected:
+ PropSetSimple props;
+ enum {numWordLists=KEYWORDSET_MAX+1};
+ WordList *keyWordLists[numWordLists+1];
+public:
+ LexerBase();
+ virtual ~LexerBase();
+ void SCI_METHOD Release();
+ int SCI_METHOD Version() const;
+ const char * SCI_METHOD PropertyNames();
+ int SCI_METHOD PropertyType(const char *name);
+ const char * SCI_METHOD DescribeProperty(const char *name);
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets();
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ void * SCI_METHOD PrivateCall(int operation, void *pointer);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerModule.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2010 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 <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerModule::LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_,
+ LexerFunction fnFolder_,
+ const char *const wordListDescriptions_[],
+ int styleBits_) :
+ language(language_),
+ fnLexer(fnLexer_),
+ fnFolder(fnFolder_),
+ fnFactory(0),
+ wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
+ languageName(languageName_) {
+}
+
+LexerModule::LexerModule(int language_,
+ LexerFactoryFunction fnFactory_,
+ const char *languageName_,
+ const char * const wordListDescriptions_[],
+ int styleBits_) :
+ language(language_),
+ fnLexer(0),
+ fnFolder(0),
+ fnFactory(fnFactory_),
+ wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
+ languageName(languageName_) {
+}
+
+int LexerModule::GetNumWordLists() const {
+ if (wordListDescriptions == NULL) {
+ return -1;
+ } else {
+ int numWordLists = 0;
+
+ while (wordListDescriptions[numWordLists]) {
+ ++numWordLists;
+ }
+
+ return numWordLists;
+ }
+}
+
+const char *LexerModule::GetWordListDescription(int index) const {
+ static const char *emptyStr = "";
+
+ assert(index < GetNumWordLists());
+ if (index >= GetNumWordLists()) {
+ return emptyStr;
+ } else {
+ return wordListDescriptions[index];
+ }
+}
+
+int LexerModule::GetStyleBitsNeeded() const {
+ return styleBits;
+}
+
+ILexer *LexerModule::Create() const {
+ if (fnFactory)
+ return fnFactory();
+ else
+ return new LexerSimple(this);
+}
+
+void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const {
+ if (fnLexer)
+ fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
+}
+
+void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const {
+ if (fnFolder) {
+ int lineCurrent = styler.GetLine(startPos);
+ // Move back one line in case deletion wrecked current line fold state
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ int newStartPos = styler.LineStart(lineCurrent);
+ lengthDoc += startPos - newStartPos;
+ startPos = newStartPos;
+ initStyle = 0;
+ if (startPos > 0) {
+ initStyle = styler.StyleAt(startPos - 1);
+ }
+ }
+ fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
+ }
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerModule.h
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERMODULE_H
+#define LEXERMODULE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Accessor;
+class WordList;
+
+typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler);
+typedef ILexer *(*LexerFactoryFunction)();
+
+/**
+ * A LexerModule is responsible for lexing and folding a particular language.
+ * The class maintains a list of LexerModules which can be searched to find a
+ * module appropriate to a particular language.
+ */
+class LexerModule {
+protected:
+ int language;
+ LexerFunction fnLexer;
+ LexerFunction fnFolder;
+ LexerFactoryFunction fnFactory;
+ const char * const * wordListDescriptions;
+ int styleBits;
+
+public:
+ const char *languageName;
+ LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_=0,
+ LexerFunction fnFolder_=0,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=5);
+ LexerModule(int language_,
+ LexerFactoryFunction fnFactory_,
+ const char *languageName_,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=8);
+ virtual ~LexerModule() {
+ }
+ int GetLanguage() const { return language; }
+
+ // -1 is returned if no WordList information is available
+ int GetNumWordLists() const;
+ const char *GetWordListDescription(int index) const;
+
+ int GetStyleBitsNeeded() const;
+
+ ILexer *Create() const;
+
+ virtual void Lex(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const;
+ virtual void Fold(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const;
+
+ friend class Catalogue;
+};
+
+inline int Maximum(int a, int b) {
+ return (a > b) ? a : b;
+}
+
+// Shut up annoying Visual C++ warnings:
+#ifdef _MSC_VER
+#pragma warning(disable: 4244 4309 4514 4710)
+#endif
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerNoExceptions.cxx
+ ** A simple lexer with no state which does not throw exceptions so can be used in an external lexer.
+ **/
+// Copyright 1998-2010 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 "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerNoExceptions.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+int SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) {
+ try {
+ return LexerBase::PropertySet(key, val);
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) {
+ try {
+ return LexerBase::WordListSet(n, wl);
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ }
+ return -1;
+}
+
+void SCI_METHOD LexerNoExceptions::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ try {
+ Accessor astyler(pAccess, &props);
+ Lexer(startPos, length, initStyle, pAccess, astyler);
+ astyler.Flush();
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+ }
+}
+void SCI_METHOD LexerNoExceptions::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ try {
+ Accessor astyler(pAccess, &props);
+ Folder(startPos, length, initStyle, pAccess, astyler);
+ astyler.Flush();
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+ }
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerNoExceptions.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LexerNoExceptions_H
+#define LexerNoExceptions_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerNoExceptions : public LexerBase {
+public:
+ // TODO Also need to prevent exceptions in constructor and destructor
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *);
+
+ virtual void Lexer(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+ virtual void Folder(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 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 <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) {
+ for (int wl = 0; wl < module->GetNumWordLists(); wl++) {
+ if (!wordLists.empty())
+ wordLists += "\n";
+ wordLists += module->GetWordListDescription(wl);
+ }
+}
+
+const char * SCI_METHOD LexerSimple::DescribeWordListSets() {
+ return wordLists.c_str();
+}
+
+void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+ Accessor astyler(pAccess, &props);
+ module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+ astyler.Flush();
+}
+
+void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+ if (props.GetInt("fold")) {
+ Accessor astyler(pAccess, &props);
+ module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+ astyler.Flush();
+ }
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file LexerSimple.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERSIMPLE_H
+#define LEXERSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerSimple : public LexerBase {
+ const LexerModule *module;
+ std::string wordLists;
+public:
+ LexerSimple(const LexerModule *module_);
+ const char * SCI_METHOD DescribeWordListSets();
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file OptionSet.h
+ ** Manage descriptive information about an options struct for a lexer.
+ ** Hold the names, positions, and descriptions of boolean, integer and string options and
+ ** allow setting options and retrieving metadata about the options.
+ **/
+// Copyright 2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef OPTIONSET_H
+#define OPTIONSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class OptionSet {
+ typedef T Target;
+ typedef bool T::*plcob;
+ typedef int T::*plcoi;
+ typedef std::string T::*plcos;
+ struct Option {
+ int opType;
+ union {
+ plcob pb;
+ plcoi pi;
+ plcos ps;
+ };
+ std::string description;
+ Option() :
+ opType(SC_TYPE_BOOLEAN), pb(0), description("") {
+ }
+ Option(plcob pb_, std::string description_="") :
+ opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
+ }
+ Option(plcoi pi_, std::string description_) :
+ opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
+ }
+ Option(plcos ps_, std::string description_) :
+ opType(SC_TYPE_STRING), ps(ps_), description(description_) {
+ }
+ bool Set(T *base, const char *val) {
+ switch (opType) {
+ case SC_TYPE_BOOLEAN: {
+ bool option = atoi(val) != 0;
+ if ((*base).*pb != option) {
+ (*base).*pb = option;
+ return true;
+ }
+ break;
+ }
+ case SC_TYPE_INTEGER: {
+ int option = atoi(val);
+ if ((*base).*pi != option) {
+ (*base).*pi = option;
+ return true;
+ }
+ break;
+ }
+ case SC_TYPE_STRING: {
+ if ((*base).*ps != val) {
+ (*base).*ps = val;
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+ };
+ typedef std::map<std::string, Option> OptionMap;
+ OptionMap nameToDef;
+ std::string names;
+ std::string wordLists;
+
+ void AppendName(const char *name) {
+ if (!names.empty())
+ names += "\n";
+ names += name;
+ }
+public:
+ virtual ~OptionSet() {
+ }
+ void DefineProperty(const char *name, plcob pb, std::string description="") {
+ nameToDef[name] = Option(pb, description);
+ AppendName(name);
+ }
+ void DefineProperty(const char *name, plcoi pi, std::string description="") {
+ nameToDef[name] = Option(pi, description);
+ AppendName(name);
+ }
+ void DefineProperty(const char *name, plcos ps, std::string description="") {
+ nameToDef[name] = Option(ps, description);
+ AppendName(name);
+ }
+ const char *PropertyNames() {
+ return names.c_str();
+ }
+ int PropertyType(const char *name) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.opType;
+ }
+ return SC_TYPE_BOOLEAN;
+ }
+ const char *DescribeProperty(const char *name) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.description.c_str();
+ }
+ return "";
+ }
+
+ bool PropertySet(T *base, const char *name, const char *val) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.Set(base, val);
+ }
+ return false;
+ }
+
+ void DefineWordListSets(const char * const wordListDescriptions[]) {
+ if (wordListDescriptions) {
+ for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
+ if (!wordLists.empty())
+ wordLists += "\n";
+ wordLists += wordListDescriptions[wl];
+ }
+ }
+ }
+
+ const char *DescribeWordListSets() {
+ return wordLists.c_str();
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// SciTE - Scintilla based Text Editor
+/** @file PropSetSimple.cxx
+ ** A Java style properties file module.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// Maintain a dictionary of properties
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef _MSC_VER
+// Visual C++ doesn't like unreachable code in its own headers.
+#pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702)
+#endif
+
+#include <string>
+#include <map>
+
+#include "PropSetSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+typedef std::map<std::string, std::string> mapss;
+
+PropSetSimple::PropSetSimple() {
+ mapss *props = new mapss;
+ impl = static_cast<void *>(props);
+}
+
+PropSetSimple::~PropSetSimple() {
+ mapss *props = static_cast<mapss *>(impl);
+ delete props;
+ impl = 0;
+}
+
+void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
+ mapss *props = static_cast<mapss *>(impl);
+ if (!*key) // Empty keys are not supported
+ return;
+ if (lenKey == -1)
+ lenKey = static_cast<int>(strlen(key));
+ if (lenVal == -1)
+ lenVal = static_cast<int>(strlen(val));
+ (*props)[std::string(key, lenKey)] = std::string(val, lenVal);
+}
+
+static bool IsASpaceCharacter(unsigned int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+void PropSetSimple::Set(const char *keyVal) {
+ while (IsASpaceCharacter(*keyVal))
+ keyVal++;
+ const char *endVal = keyVal;
+ while (*endVal && (*endVal != '\n'))
+ endVal++;
+ const char *eqAt = strchr(keyVal, '=');
+ if (eqAt) {
+ Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal),
+ static_cast<int>(endVal - eqAt - 1));
+ } else if (*keyVal) { // No '=' so assume '=1'
+ Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1);
+ }
+}
+
+void PropSetSimple::SetMultiple(const char *s) {
+ const char *eol = strchr(s, '\n');
+ while (eol) {
+ Set(s);
+ s = eol + 1;
+ eol = strchr(s, '\n');
+ }
+ Set(s);
+}
+
+const char *PropSetSimple::Get(const char *key) const {
+ mapss *props = static_cast<mapss *>(impl);
+ mapss::const_iterator keyPos = props->find(std::string(key));
+ if (keyPos != props->end()) {
+ return keyPos->second.c_str();
+ } else {
+ return "";
+ }
+}
+
+// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)").
+// A solution is to keep a stack of variables that have been expanded, so that
+// recursive expansions can be skipped. For now I'll just use the C++ stack
+// for that, through a recursive function and a simple chain of pointers.
+
+struct VarChain {
+ VarChain(const char *var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
+
+ bool contains(const char *testVar) const {
+ return (var && (0 == strcmp(var, testVar)))
+ || (link && link->contains(testVar));
+ }
+
+ const char *var;
+ const VarChain *link;
+};
+
+static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
+ size_t varStart = withVars.find("$(");
+ while ((varStart != std::string::npos) && (maxExpands > 0)) {
+ size_t varEnd = withVars.find(")", varStart+2);
+ if (varEnd == std::string::npos) {
+ break;
+ }
+
+ // For consistency, when we see '$(ab$(cde))', expand the inner variable first,
+ // regardless whether there is actually a degenerate variable named 'ab$(cde'.
+ size_t innerVarStart = withVars.find("$(", varStart+2);
+ while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
+ varStart = innerVarStart;
+ innerVarStart = withVars.find("$(", varStart+2);
+ }
+
+ std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
+ std::string val = props.Get(var.c_str());
+
+ if (blankVars.contains(var.c_str())) {
+ val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
+ }
+
+ if (--maxExpands >= 0) {
+ maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
+ }
+
+ withVars.erase(varStart, varEnd-varStart+1);
+ withVars.insert(varStart, val.c_str(), val.length());
+
+ varStart = withVars.find("$(");
+ }
+
+ return maxExpands;
+}
+
+char *PropSetSimple::Expanded(const char *key) const {
+ std::string val = Get(key);
+ ExpandAllInPlace(*this, val, 100, VarChain(key));
+ char *ret = new char [val.size() + 1];
+ strcpy(ret, val.c_str());
+ return ret;
+}
+
+int PropSetSimple::GetExpanded(const char *key, char *result) const {
+ char *val = Expanded(key);
+ const int n = static_cast<int>(strlen(val));
+ if (result) {
+ strcpy(result, val);
+ }
+ delete []val;
+ return n; // Not including NUL
+}
+
+int PropSetSimple::GetInt(const char *key, int defaultValue) const {
+ char *val = Expanded(key);
+ if (val) {
+ int retVal = val[0] ? atoi(val) : defaultValue;
+ delete []val;
+ return retVal;
+ }
+ return defaultValue;
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file PropSetSimple.h
+ ** A basic string to string map.
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef PROPSETSIMPLE_H
+#define PROPSETSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class PropSetSimple {
+ void *impl;
+ void Set(const char *keyVal);
+public:
+ PropSetSimple();
+ virtual ~PropSetSimple();
+ void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
+ void SetMultiple(const char *);
+ const char *Get(const char *key) const;
+ char *Expanded(const char *key) const;
+ int GetExpanded(const char *key, char *result) const;
+ int GetInt(const char *key, int defaultValue=0) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file SparseState.h
+ ** Hold lexer state that may change rarely.
+ ** This is often per-line state such as whether a particular type of section has been entered.
+ ** A state continues until it is changed.
+ **/
+// Copyright 2011 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SPARSESTATE_H
+#define SPARSESTATE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class SparseState {
+ struct State {
+ int position;
+ T value;
+ State(int position_, T value_) : position(position_), value(value_) {
+ }
+ inline bool operator<(const State &other) const {
+ return position < other.position;
+ }
+ inline bool operator==(const State &other) const {
+ return (position == other.position) && (value == other.value);
+ }
+ };
+ int positionFirst;
+ typedef std::vector<State> stateVector;
+ stateVector states;
+
+ typename stateVector::iterator Find(int position) {
+ State searchValue(position, T());
+ return std::lower_bound(states.begin(), states.end(), searchValue);
+ }
+
+public:
+ SparseState(int positionFirst_=-1) {
+ positionFirst = positionFirst_;
+ }
+ void Set(int position, T value) {
+ Delete(position);
+ if (states.empty() || (value != states[states.size()-1].value)) {
+ states.push_back(State(position, value));
+ }
+ }
+ T ValueAt(int position) {
+ if (states.empty())
+ return T();
+ if (position < states[0].position)
+ return T();
+ typename stateVector::iterator low = Find(position);
+ if (low == states.end()) {
+ return states[states.size()-1].value;
+ } else {
+ if (low->position > position) {
+ --low;
+ }
+ return low->value;
+ }
+ }
+ bool Delete(int position) {
+ typename stateVector::iterator low = Find(position);
+ if (low != states.end()) {
+ states.erase(low, states.end());
+ return true;
+ }
+ return false;
+ }
+ size_t size() const {
+ return states.size();
+ }
+
+ // Returns true if Merge caused a significant change
+ bool Merge(const SparseState<T> &other, int ignoreAfter) {
+ // Changes caused beyond ignoreAfter are not significant
+ Delete(ignoreAfter+1);
+
+ bool different = true;
+ bool changed = false;
+ typename stateVector::iterator low = Find(other.positionFirst);
+ if (static_cast<size_t>(states.end() - low) == other.states.size()) {
+ // Same number in other as after positionFirst in this
+ different = !std::equal(low, states.end(), other.states.begin());
+ }
+ if (different) {
+ if (low != states.end()) {
+ states.erase(low, states.end());
+ changed = true;
+ }
+ typename stateVector::const_iterator startOther = other.states.begin();
+ if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
+ ++startOther;
+ if (startOther != other.states.end()) {
+ states.insert(states.end(), startOther, other.states.end());
+ changed = true;
+ }
+ }
+ return changed;
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file StyleContext.cxx
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// This file is in the public domain.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "ILexer.h"
+
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static void getRange(unsigned int start,
+ unsigned int end,
+ LexAccessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = styler[start + i];
+ i++;
+ }
+ s[i] = '\0';
+}
+
+void StyleContext::GetCurrent(char *s, unsigned int len) {
+ getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len);
+}
+
+static void getRangeLowered(unsigned int start,
+ unsigned int end,
+ LexAccessor &styler,
+ char *s,
+ unsigned int len) {
+ unsigned int i = 0;
+ while ((i < end - start + 1) && (i < len-1)) {
+ s[i] = static_cast<char>(tolower(styler[start + i]));
+ i++;
+ }
+ s[i] = '\0';
+}
+
+void StyleContext::GetCurrentLowered(char *s, unsigned int len) {
+ getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file StyleContext.cxx
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// This file is in the public domain.
+
+#ifndef STYLECONTEXT_H
+#define STYLECONTEXT_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+static inline int MakeLowerCase(int ch) {
+ if (ch < 'A' || ch > 'Z')
+ return ch;
+ else
+ return ch - 'A' + 'a';
+}
+
+// All languages handled so far can treat all characters >= 0x80 as one class
+// which just continues the current token or starts an identifier if in default.
+// DBCS treated specially as the second character can be < 0x80 and hence
+// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
+class StyleContext {
+ LexAccessor &styler;
+ unsigned int endPos;
+ StyleContext &operator=(const StyleContext &);
+ void GetNextChar(unsigned int pos) {
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
+ if (styler.IsLeadByte(static_cast<char>(chNext))) {
+ chNext = chNext << 8;
+ chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+ }
+ // End of line?
+ // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
+ // or on LF alone (Unix). Avoid triggering two times on Dos/Win.
+ atLineEnd = (ch == '\r' && chNext != '\n') ||
+ (ch == '\n') ||
+ (currentPos >= endPos);
+ }
+
+public:
+ unsigned int currentPos;
+ bool atLineStart;
+ bool atLineEnd;
+ int state;
+ int chPrev;
+ int ch;
+ int chNext;
+
+ StyleContext(unsigned int startPos, unsigned int length,
+ int initStyle, LexAccessor &styler_, char chMask=31) :
+ styler(styler_),
+ endPos(startPos + length),
+ currentPos(startPos),
+ atLineEnd(false),
+ state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
+ chPrev(0),
+ ch(0),
+ chNext(0) {
+ styler.StartAt(startPos, chMask);
+ styler.StartSegment(startPos);
+ atLineStart = static_cast<unsigned int>(styler.LineStart(styler.GetLine(startPos))) == startPos;
+ unsigned int pos = currentPos;
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ if (styler.IsLeadByte(static_cast<char>(ch))) {
+ pos++;
+ ch = ch << 8;
+ ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ }
+ GetNextChar(pos);
+ }
+ void Complete() {
+ styler.ColourTo(currentPos - 1, state);
+ styler.Flush();
+ }
+ bool More() const {
+ return currentPos < endPos;
+ }
+ void Forward() {
+ if (currentPos < endPos) {
+ atLineStart = atLineEnd;
+ chPrev = ch;
+ currentPos++;
+ if (ch >= 0x100)
+ currentPos++;
+ ch = chNext;
+ GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
+ } else {
+ atLineStart = false;
+ chPrev = ' ';
+ ch = ' ';
+ chNext = ' ';
+ atLineEnd = true;
+ }
+ }
+ void Forward(int nb) {
+ for (int i = 0; i < nb; i++) {
+ Forward();
+ }
+ }
+ void ChangeState(int state_) {
+ state = state_;
+ }
+ void SetState(int state_) {
+ styler.ColourTo(currentPos - 1, state);
+ state = state_;
+ }
+ void ForwardSetState(int state_) {
+ Forward();
+ styler.ColourTo(currentPos - 1, state);
+ state = state_;
+ }
+ int LengthCurrent() {
+ return currentPos - styler.GetStartSegment();
+ }
+ int GetRelative(int n) {
+ return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
+ }
+ bool Match(char ch0) const {
+ return ch == static_cast<unsigned char>(ch0);
+ }
+ bool Match(char ch0, char ch1) const {
+ return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
+ }
+ bool Match(const char *s) {
+ if (ch != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ if (!*s)
+ return true;
+ if (chNext != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ for (int n=2; *s; n++) {
+ if (*s != styler.SafeGetCharAt(currentPos+n))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ bool MatchIgnoreCase(const char *s) {
+ if (MakeLowerCase(ch) != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))
+ return false;
+ s++;
+ for (int n=2; *s; n++) {
+ if (static_cast<unsigned char>(*s) !=
+ MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ // Non-inline
+ void GetCurrent(char *s, unsigned int len);
+ void GetCurrentLowered(char *s, unsigned int len);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
--- /dev/null
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <algorithm>
+
+#include "WordList.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/**
+ * Creates an array that points into each word in the string and puts \0 terminators
+ * after each word.
+ */
+static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
+ int prev = '\n';
+ int words = 0;
+ // For rapid determination of whether a character is a separator, build
+ // a look up table.
+ bool wordSeparator[256];
+ for (int i=0; i<256; i++) {
+ wordSeparator[i] = false;
+ }
+ wordSeparator['\r'] = true;
+ wordSeparator['\n'] = true;
+ if (!onlyLineEnds) {
+ wordSeparator[' '] = true;
+ wordSeparator['\t'] = true;
+ }
+ for (int j = 0; wordlist[j]; j++) {
+ int curr = static_cast<unsigned char>(wordlist[j]);
+ if (!wordSeparator[curr] && wordSeparator[prev])
+ words++;
+ prev = curr;
+ }
+ char **keywords = new char *[words + 1];
+ if (keywords) {
+ words = 0;
+ prev = '\0';
+ size_t slen = strlen(wordlist);
+ for (size_t k = 0; k < slen; k++) {
+ if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
+ if (!prev) {
+ keywords[words] = &wordlist[k];
+ words++;
+ }
+ } else {
+ wordlist[k] = '\0';
+ }
+ prev = wordlist[k];
+ }
+ keywords[words] = &wordlist[slen];
+ *len = words;
+ } else {
+ *len = 0;
+ }
+ return keywords;
+}
+
+bool WordList::operator!=(const WordList &other) const {
+ if (len != other.len)
+ return true;
+ for (int i=0; i<len; i++) {
+ if (strcmp(words[i], other.words[i]) != 0)
+ return true;
+ }
+ return false;
+}
+
+void WordList::Clear() {
+ if (words) {
+ delete []list;
+ delete []words;
+ }
+ words = 0;
+ list = 0;
+ len = 0;
+}
+
+#ifdef _MSC_VER
+
+static bool cmpWords(const char *a, const char *b) {
+ return strcmp(a, b) == -1;
+}
+
+#else
+
+static int cmpWords(const void *a, const void *b) {
+ return strcmp(*static_cast<const char * const *>(a), *static_cast<const char * const *>(b));
+}
+
+static void SortWordList(char **words, unsigned int len) {
+ qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords);
+}
+
+#endif
+
+void WordList::Set(const char *s) {
+ Clear();
+ list = new char[strlen(s) + 1];
+ strcpy(list, s);
+ words = ArrayFromWordList(list, &len, onlyLineEnds);
+#ifdef _MSC_VER
+ std::sort(words, words + len, cmpWords);
+#else
+ SortWordList(words, len);
+#endif
+ for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+ starts[k] = -1;
+ for (int l = len - 1; l >= 0; l--) {
+ unsigned char indexChar = words[l][0];
+ starts[indexChar] = l;
+ }
+}
+
+/** Check whether a string is in the list.
+ * List elements are either exact matches or prefixes.
+ * Prefix elements start with '^' and match all strings that start with the rest of the element
+ * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.
+ */
+bool WordList::InList(const char *s) const {
+ if (0 == words)
+ return false;
+ unsigned char firstChar = s[0];
+ int j = starts[firstChar];
+ if (j >= 0) {
+ while (static_cast<unsigned char>(words[j][0]) == firstChar) {
+ if (s[1] == words[j][1]) {
+ const char *a = words[j] + 1;
+ const char *b = s + 1;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a && !*b)
+ return true;
+ }
+ j++;
+ }
+ }
+ j = starts['^'];
+ if (j >= 0) {
+ while (words[j][0] == '^') {
+ const char *a = words[j] + 1;
+ const char *b = s;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a)
+ return true;
+ j++;
+ }
+ }
+ return false;
+}
+
+/** similar to InList, but word s can be a substring of keyword.
+ * eg. the keyword define is defined as def~ine. This means the word must start
+ * with def to be a keyword, but also defi, defin and define are valid.
+ * The marker is ~ in this case.
+ */
+bool WordList::InListAbbreviated(const char *s, const char marker) const {
+ if (0 == words)
+ return false;
+ unsigned char firstChar = s[0];
+ int j = starts[firstChar];
+ if (j >= 0) {
+ while (static_cast<unsigned char>(words[j][0]) == firstChar) {
+ bool isSubword = false;
+ int start = 1;
+ if (words[j][1] == marker) {
+ isSubword = true;
+ start++;
+ }
+ if (s[1] == words[j][start]) {
+ const char *a = words[j] + start;
+ const char *b = s + 1;
+ while (*a && *a == *b) {
+ a++;
+ if (*a == marker) {
+ isSubword = true;
+ a++;
+ }
+ b++;
+ }
+ if ((!*a || isSubword) && !*b)
+ return true;
+ }
+ j++;
+ }
+ }
+ j = starts['^'];
+ if (j >= 0) {
+ while (words[j][0] == '^') {
+ const char *a = words[j] + 1;
+ const char *b = s;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a)
+ return true;
+ j++;
+ }
+ }
+ return false;
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file WordList.h
+ ** Hold a list of words.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef WORDLIST_H
+#define WORDLIST_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+/**
+ */
+class WordList {
+public:
+ // Each word contains at least one character - a empty word acts as sentinel at the end.
+ char **words;
+ char *list;
+ int len;
+ bool onlyLineEnds; ///< Delimited by any white space or only line ends
+ int starts[256];
+ WordList(bool onlyLineEnds_ = false) :
+ words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_)
+ {}
+ ~WordList() { Clear(); }
+ operator bool() const { return len ? true : false; }
+ bool operator!=(const WordList &other) const;
+ void Clear();
+ void Set(const char *s);
+ bool InList(const char *s) const;
+ bool InListAbbreviated(const char *s, const char marker) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <assert.h>
+
+#include <string>
#include "Platform.h"
-#include "CharClassify.h"
+#include "CharacterSet.h"
#include "AutoComplete.h"
+#include "Scintilla.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
startLen(0),
cancelAtStartPos(true),
autoHide(true),
- dropRestOfWord(false) {
+ dropRestOfWord(false),
+ ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
lb = ListBox::Allocate();
stopChars[0] = '\0';
fillUpChars[0] = '\0';
}
}
-bool AutoComplete::Active() {
+bool AutoComplete::Active() const {
return active;
}
-void AutoComplete::Start(Window &parent, int ctrlID,
- int position, Point location, int startLen_,
- int lineHeight, bool unicodeMode) {
+void AutoComplete::Start(Window &parent, int ctrlID,
+ int position, Point location, int startLen_,
+ int lineHeight, bool unicodeMode, int technology) {
if (active) {
Cancel();
}
- lb->Create(parent, ctrlID, location, lineHeight, unicodeMode);
+ lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology);
lb->Clear();
active = true;
startLen = startLen_;
separator = separator_;
}
-char AutoComplete::GetSeparator() {
+char AutoComplete::GetSeparator() const {
return separator;
}
typesep = separator_;
}
-char AutoComplete::GetTypesep() {
+char AutoComplete::GetTypesep() const {
return typesep;
}
lb->SetList(list, separator, typesep);
}
+int AutoComplete::GetSelection() const {
+ return lb->GetSelection();
+}
+
+std::string AutoComplete::GetValue(int item) const {
+ char value[maxItemLen];
+ lb->GetValue(item, value, sizeof(value));
+ return std::string(value);
+}
+
void AutoComplete::Show(bool show) {
lb->Show(show);
if (show)
void AutoComplete::Select(const char *word) {
size_t lenWord = strlen(word);
int location = -1;
- const int maxItemLen=1000;
- char item[maxItemLen];
int start = 0; // lower bound of the api array block to search
int end = lb->Length() - 1; // upper bound of the api array block to search
while ((start <= end) && (location == -1)) { // Binary searching loop
int pivot = (start + end) / 2;
+ char item[maxItemLen];
lb->GetValue(pivot, item, maxItemLen);
int cond;
if (ignoreCase)
--pivot;
}
location = pivot;
- if (ignoreCase) {
+ if (ignoreCase
+ && ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
// Check for exact-case match
for (; pivot <= end; pivot++) {
lb->GetValue(pivot, item, maxItemLen);
char fillUpChars[256];
char separator;
char typesep; // Type seperator
+ enum { maxItemLen=1000 };
public:
+
bool ignoreCase;
bool chooseSingle;
ListBox *lb;
bool cancelAtStartPos;
bool autoHide;
bool dropRestOfWord;
+ unsigned int ignoreCaseBehaviour;
AutoComplete();
~AutoComplete();
/// Is the auto completion list displayed?
- bool Active();
+ bool Active() const;
/// Display the auto completion list positioned to be near a character position
void Start(Window &parent, int ctrlID, int position, Point location,
- int startLen_, int lineHeight, bool unicodeMode);
+ int startLen_, int lineHeight, bool unicodeMode, int technology);
/// The stop chars are characters which, when typed, cause the auto completion list to disappear
void SetStopChars(const char *stopChars_);
/// The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_);
- char GetSeparator();
+ char GetSeparator() const;
/// The typesep character is used for seperating the word from the type
void SetTypesep(char separator_);
- char GetTypesep();
+ char GetTypesep() const;
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
+
+ /// Return the position of the currently selected list item
+ int GetSelection() const;
+
+ /// Return the value of an item in the list
+ std::string GetValue(int item) const;
void Show(bool show);
void Cancel();
rectUp = PRectangle(0,0,0,0);
rectDown = PRectangle(0,0,0,0);
lineHeight = 1;
+ offsetMain = 0;
startHighlight = 0;
endHighlight = 0;
tabSize = 0;
+ above = false;
useStyleCallTip = false; // for backwards compatibility
#ifdef __APPLE__
// proper apple colours for the default
- colourBG.desired = ColourDesired(0xff, 0xff, 0xc6);
- colourUnSel.desired = ColourDesired(0, 0, 0);
+ colourBG = ColourDesired(0xff, 0xff, 0xc6);
+ colourUnSel = ColourDesired(0, 0, 0);
#else
- colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
- colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
+ colourBG = ColourDesired(0xff, 0xff, 0xff);
+ colourUnSel = ColourDesired(0x80, 0x80, 0x80);
#endif
- colourSel.desired = ColourDesired(0, 0, 0x80);
- colourShade.desired = ColourDesired(0, 0, 0);
- colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+ colourSel = ColourDesired(0, 0, 0x80);
+ colourShade = ColourDesired(0, 0, 0);
+ colourLight = ColourDesired(0xc0, 0xc0, 0xc0);
+ codePage = 0;
+ clickPlace = 0;
}
CallTip::~CallTip() {
val = 0;
}
-void CallTip::RefreshColourPalette(Palette &pal, bool want) {
- pal.WantFind(colourBG, want);
- pal.WantFind(colourUnSel, want);
- pal.WantFind(colourSel, want);
- pal.WantFind(colourShade, want);
- pal.WantFind(colourLight, want);
-}
-
// Although this test includes 0, we should never see a \0 character.
static bool IsArrowCharacter(char ch) {
return (ch == 0) || (ch == '\001') || (ch == '\002');
}
// We ignore tabs unless a tab width has been set.
-bool CallTip::IsTabCharacter(char ch) {
+bool CallTip::IsTabCharacter(char ch) const {
return (tabSize > 0) && (ch == '\t');
}
int maxEnd = 0;
const int numEnds = 10;
int ends[numEnds + 2];
- for (int i=0;i<len;i++) {
+ for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) &&
- (IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
+ (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;
const int halfWidth = widthArrow / 2 - 3;
const int centreX = rcClient.left + widthArrow / 2 - 1;
const int centreY = (rcClient.top + rcClient.bottom) / 2;
- surface->FillRectangle(rcClient, colourBG.allocated);
+ surface->FillRectangle(rcClient, colourBG);
PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1,
rcClient.right - 2, rcClient.bottom - 1);
- surface->FillRectangle(rcClientInner, colourUnSel.allocated);
+ surface->FillRectangle(rcClientInner, colourUnSel);
if (upArrow) { // Up arrow
Point pts[] = {
Point(centreX, centreY - halfWidth + halfWidth / 2),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- colourBG.allocated, colourBG.allocated);
+ colourBG, colourBG);
} else { // Down arrow
Point pts[] = {
Point(centreX - halfWidth, centreY - halfWidth / 2),
Point(centreX, centreY + halfWidth - halfWidth / 2),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- colourBG.allocated, colourBG.allocated);
+ colourBG, colourBG);
}
}
xEnd = rcClient.right;
rcClient.right = xEnd;
surface->DrawTextTransparent(rcClient, font, ytext,
s+startSeg, endSeg - startSeg,
- highlight ? colourSel.allocated : colourUnSel.allocated);
+ highlight ? colourSel : colourUnSel);
}
}
x = xEnd;
rcClientPos.bottom - rcClientPos.top);
PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
- surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
+ surfaceWindow->FillRectangle(rcClient, colourBG);
offsetMain = insetX; // initial alignment assuming no arrows
PaintContents(surfaceWindow, true);
// OSX doesn't put borders on "help tags"
// Draw a raised border around the edges of the window
surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
- surfaceWindow->PenColour(colourShade.allocated);
+ surfaceWindow->PenColour(colourShade);
surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
surfaceWindow->LineTo(rcClientSize.right - 1, 0);
- surfaceWindow->PenColour(colourLight.allocated);
+ surfaceWindow->PenColour(colourLight);
surfaceWindow->LineTo(0, 0);
surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
#endif
clickPlace = 2;
}
-PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
+PRectangle CallTip::CallTipStart(int pos, Point pt, int textHeight, const char *defn,
const char *faceName, int size,
- int codePage_, int characterSet, Window &wParent) {
+ int codePage_, int characterSet,
+ int technology, Window &wParent) {
clickPlace = 0;
delete []val;
val = 0;
val = new char[strlen(defn) + 1];
strcpy(val, defn);
codePage = codePage_;
- Surface *surfaceMeasure = Surface::Allocate();
+ Surface *surfaceMeasure = Surface::Allocate(technology);
if (!surfaceMeasure)
return PRectangle();
surfaceMeasure->Init(wParent.GetID());
inCallTipMode = true;
posStartCallTip = pos;
int deviceHeight = surfaceMeasure->DeviceHeightFont(size);
- font.Create(faceName, characterSet, deviceHeight, false, false);
+ FontParameters fp(faceName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, SC_WEIGHT_NORMAL, false, 0, technology, characterSet);
+ font.Create(fp);
// Look for multiple lines in the text
// Only support \n here - simply means container must avoid \r!
int numLines = 1;
// the tip text, else to the tip text left edge.
int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
delete surfaceMeasure;
- return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
+ if (above) {
+ return PRectangle(pt.x - offsetMain, pt.y - 1 - height, pt.x + width - offsetMain, pt.y - 1);
+ } else {
+ return PRectangle(pt.x - offsetMain, pt.y + 1 + textHeight, pt.x + width - offsetMain, pt.y + 1 + textHeight + height);
+ }
}
void CallTip::CallTipCancel() {
useStyleCallTip = true;
}
+// Set the calltip position, below the text by default or if above is false
+// else above the text.
+void CallTip::SetPosition(bool aboveText) {
+ above = aboveText;
+}
+
// It might be better to have two access functions for this and to use
// them for all settings of colours.
-void CallTip::SetForeBack(const ColourPair &fore, const ColourPair &back) {
+void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) {
colourBG = back;
colourUnSel = fore;
}
int offsetMain; // The alignment point of the call tip
int tabSize; // Tab size in pixels, <=0 no TAB expand
bool useStyleCallTip; // if true, STYLE_CALLTIP should be used
+ bool above; // if true, display calltip above text
// Private so CallTip objects can not be copied
CallTip(const CallTip &);
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw);
int PaintContents(Surface *surfaceWindow, bool draw);
- bool IsTabCharacter(char c);
+ bool IsTabCharacter(char c) const;
int NextTabPos(int x);
public:
Window wDraw;
bool inCallTipMode;
int posStartCallTip;
- ColourPair colourBG;
- ColourPair colourUnSel;
- ColourPair colourSel;
- ColourPair colourShade;
- ColourPair colourLight;
+ ColourDesired colourBG;
+ ColourDesired colourUnSel;
+ ColourDesired colourSel;
+ ColourDesired colourShade;
+ ColourDesired colourLight;
int codePage;
int clickPlace;
CallTip();
~CallTip();
- /// Claim or accept palette entries for the colours required to paint a calltip.
- void RefreshColourPalette(Palette &pal, bool want);
-
void PaintCT(Surface *surfaceWindow);
void MouseClick(Point pt);
/// Setup the calltip and return a rectangle of the area required.
- PRectangle CallTipStart(int pos, Point pt, const char *defn,
- const char *faceName, int size, int codePage_,
- int characterSet, Window &wParent);
+ PRectangle CallTipStart(int pos, Point pt, int textHeight, const char *defn,
+ const char *faceName, int size, int codePage_,
+ int characterSet, int technology, Window &wParent);
void CallTipCancel();
/// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand.
void SetTabSize(int tabSz);
+ /// Set calltip position.
+ void SetPosition(bool aboveText);
+
/// Used to determine which STYLE_xxxx to use for call tip information
bool UseStyleCallTip() const { return useStyleCallTip;}
// Modify foreground and background colours
- void SetForeBack(const ColourPair &fore, const ColourPair &back);
+ void SetForeBack(const ColourDesired &fore, const ColourDesired &back);
};
#ifdef SCI_NAMESPACE
--- /dev/null
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 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 <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include <vector>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static std::vector<LexerModule *> lexerCatalogue;
+static int nextLanguage = SCLEX_AUTOMATIC+1;
+
+const LexerModule *Catalogue::Find(int language) {
+ Scintilla_LinkLexers();
+ for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
+ it != lexerCatalogue.end(); ++it) {
+ if ((*it)->GetLanguage() == language) {
+ return *it;
+ }
+ }
+ return 0;
+}
+
+const LexerModule *Catalogue::Find(const char *languageName) {
+ Scintilla_LinkLexers();
+ if (languageName) {
+ for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
+ it != lexerCatalogue.end(); ++it) {
+ if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) {
+ return *it;
+ }
+ }
+ }
+ return 0;
+}
+
+void Catalogue::AddLexerModule(LexerModule *plm) {
+ if (plm->GetLanguage() == SCLEX_AUTOMATIC) {
+ plm->language = nextLanguage;
+ nextLanguage++;
+ }
+ lexerCatalogue.push_back(plm);
+}
+
+// Alternative historical name for Scintilla_LinkLexers
+int wxForceScintillaLexers(void) {
+ return Scintilla_LinkLexers();
+}
+
+// To add or remove a lexer, add or remove its file and run LexGen.py.
+
+// Force a reference to all of the Scintilla lexers so that the linker will
+// not remove the code of the lexers.
+int Scintilla_LinkLexers() {
+
+ static int initialised = 0;
+ if (initialised)
+ return 0;
+ initialised = 1;
+
+// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
+#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer);
+
+//++Autogenerated -- run src/LexGen.py to regenerate
+//**\(\tLINK_LEXER(\*);\n\)
+ LINK_LEXER(lmA68k);
+ LINK_LEXER(lmAbaqus);
+ LINK_LEXER(lmAda);
+ LINK_LEXER(lmAns1);
+ LINK_LEXER(lmAPDL);
+ LINK_LEXER(lmAsm);
+ LINK_LEXER(lmASY);
+ LINK_LEXER(lmAU3);
+ LINK_LEXER(lmAVE);
+ LINK_LEXER(lmAVS);
+ LINK_LEXER(lmBaan);
+ LINK_LEXER(lmBash);
+ LINK_LEXER(lmBatch);
+ LINK_LEXER(lmBlitzBasic);
+ LINK_LEXER(lmBullant);
+ LINK_LEXER(lmCaml);
+ LINK_LEXER(lmClw);
+ LINK_LEXER(lmClwNoCase);
+ LINK_LEXER(lmCmake);
+ LINK_LEXER(lmCOBOL);
+ LINK_LEXER(lmCoffeeScript);
+ LINK_LEXER(lmConf);
+ LINK_LEXER(lmCPP);
+ LINK_LEXER(lmCPPNoCase);
+ LINK_LEXER(lmCsound);
+ LINK_LEXER(lmCss);
+ LINK_LEXER(lmD);
+ LINK_LEXER(lmDiff);
+ LINK_LEXER(lmECL);
+ LINK_LEXER(lmEiffel);
+ LINK_LEXER(lmEiffelkw);
+ LINK_LEXER(lmErlang);
+ LINK_LEXER(lmErrorList);
+ LINK_LEXER(lmESCRIPT);
+ LINK_LEXER(lmF77);
+ LINK_LEXER(lmFlagShip);
+ LINK_LEXER(lmForth);
+ LINK_LEXER(lmFortran);
+ LINK_LEXER(lmFreeBasic);
+ LINK_LEXER(lmGAP);
+ LINK_LEXER(lmGui4Cli);
+ LINK_LEXER(lmHaskell);
+ LINK_LEXER(lmHTML);
+ LINK_LEXER(lmInno);
+ LINK_LEXER(lmKix);
+ LINK_LEXER(lmLatex);
+ LINK_LEXER(lmLISP);
+ LINK_LEXER(lmLot);
+ LINK_LEXER(lmLout);
+ LINK_LEXER(lmLua);
+ LINK_LEXER(lmMagikSF);
+ LINK_LEXER(lmMake);
+ LINK_LEXER(lmMarkdown);
+ LINK_LEXER(lmMatlab);
+ LINK_LEXER(lmMETAPOST);
+ LINK_LEXER(lmMMIXAL);
+ LINK_LEXER(lmModula);
+ LINK_LEXER(lmMSSQL);
+ LINK_LEXER(lmMySQL);
+ LINK_LEXER(lmNimrod);
+ LINK_LEXER(lmNncrontab);
+ LINK_LEXER(lmNsis);
+ LINK_LEXER(lmNull);
+ LINK_LEXER(lmOctave);
+ LINK_LEXER(lmOpal);
+ LINK_LEXER(lmOScript);
+ LINK_LEXER(lmPascal);
+ LINK_LEXER(lmPB);
+ LINK_LEXER(lmPerl);
+ LINK_LEXER(lmPHPSCRIPT);
+ LINK_LEXER(lmPLM);
+ LINK_LEXER(lmPo);
+ LINK_LEXER(lmPOV);
+ LINK_LEXER(lmPowerPro);
+ LINK_LEXER(lmPowerShell);
+ LINK_LEXER(lmProgress);
+ LINK_LEXER(lmProps);
+ LINK_LEXER(lmPS);
+ LINK_LEXER(lmPureBasic);
+ LINK_LEXER(lmPython);
+ LINK_LEXER(lmR);
+ LINK_LEXER(lmREBOL);
+ LINK_LEXER(lmRuby);
+ LINK_LEXER(lmScriptol);
+ LINK_LEXER(lmSmalltalk);
+ LINK_LEXER(lmSML);
+ LINK_LEXER(lmSorc);
+ LINK_LEXER(lmSpecman);
+ LINK_LEXER(lmSpice);
+ LINK_LEXER(lmSQL);
+ LINK_LEXER(lmTACL);
+ LINK_LEXER(lmTADS3);
+ LINK_LEXER(lmTAL);
+ LINK_LEXER(lmTCL);
+ LINK_LEXER(lmTCMD);
+ LINK_LEXER(lmTeX);
+ LINK_LEXER(lmTxt2tags);
+ LINK_LEXER(lmVB);
+ LINK_LEXER(lmVBScript);
+ LINK_LEXER(lmVerilog);
+ LINK_LEXER(lmVHDL);
+ LINK_LEXER(lmVisualProlog);
+ LINK_LEXER(lmXML);
+ LINK_LEXER(lmYAML);
+
+//--Autogenerated -- end of automatically generated section
+
+ return 1;
+}
--- /dev/null
+// Scintilla source code edit control
+/** @file Catalogue.h
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef CATALOGUE_H
+#define CATALOGUE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Catalogue {
+public:
+ static const LexerModule *Find(int language);
+ static const LexerModule *Find(const char *languageName);
+ static void AddLexerModule(LexerModule *plm);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
starts.InsertText(line, delta);
}
-void LineVector::InsertLine(int line, int position) {
+void LineVector::InsertLine(int line, int position, bool lineStart) {
starts.InsertPartition(line, position);
if (perLine) {
+ if ((line > 0) && lineStart)
+ line--;
perLine->InsertLine(line);
}
}
// Insertions must be immediately after to coalesce
currentAction++;
} else if (at == removeAction) {
- if ((lengthData == 1) || (lengthData == 2)){
+ if ((lengthData == 1) || (lengthData == 2)) {
if ((position + lengthData) == actPrevious->position) {
; // Backspace -> OK
} else if (position == actPrevious->position) {
return substance.ValueAt(position);
}
-void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {
+void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const {
if (lengthRetrieve < 0)
return;
if (position < 0)
lengthRetrieve, substance.Length());
return;
}
-
- for (int i=0; i<lengthRetrieve; i++) {
- *buffer++ = substance.ValueAt(position + i);
- }
+ substance.GetRange(buffer, position, lengthRetrieve);
}
-char CellBuffer::StyleAt(int position) {
+char CellBuffer::StyleAt(int position) const {
return style.ValueAt(position);
}
-const char *CellBuffer::BufferPointer() {
+void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
+ if (lengthRetrieve < 0)
+ return;
+ if (position < 0)
+ return;
+ if ((position + lengthRetrieve) > style.Length()) {
+ Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position,
+ lengthRetrieve, style.Length());
+ return;
+ }
+ style.GetRange(reinterpret_cast<char *>(buffer), position, lengthRetrieve);
+}
+
+const char *CellBuffer::BufferPointer() {
return substance.BufferPointer();
}
+const char *CellBuffer::RangePointer(int position, int rangeLength) {
+ return substance.RangePointer(position, rangeLength);
+}
+
+int CellBuffer::GapPosition() const {
+ return substance.GapPosition();
+}
+
// The char* returned is to an allocation owned by the undo history
const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) {
char *data = 0;
return lv.LineStart(line);
}
-bool CellBuffer::IsReadOnly() {
+bool CellBuffer::IsReadOnly() const {
return readOnly;
}
// Without undo
-void CellBuffer::InsertLine(int line, int position) {
- lv.InsertLine(line, position);
+void CellBuffer::InsertLine(int line, int position, bool lineStart) {
+ lv.InsertLine(line, position, lineStart);
}
void CellBuffer::RemoveLine(int line) {
style.InsertValue(position, insertLength, 0);
int lineInsert = lv.LineFromPosition(position) + 1;
+ bool atLineStart = lv.LineStart(lineInsert-1) == position;
// Point all the lines after the insertion point further along in the buffer
lv.InsertText(lineInsert-1, insertLength);
char chPrev = substance.ValueAt(position - 1);
char chAfter = substance.ValueAt(position + insertLength);
if (chPrev == '\r' && chAfter == '\n') {
// Splitting up a crlf pair at position
- InsertLine(lineInsert, position);
+ InsertLine(lineInsert, position, false);
lineInsert++;
}
char ch = ' ';
for (int i = 0; i < insertLength; i++) {
ch = s[i];
if (ch == '\r') {
- InsertLine(lineInsert, (position + i) + 1);
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
lineInsert++;
} else if (ch == '\n') {
if (chPrev == '\r') {
// Patch up what was end of line
lv.SetLineStart(lineInsert - 1, (position + i) + 1);
} else {
- InsertLine(lineInsert, (position + i) + 1);
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
lineInsert++;
}
}
return collectingUndo;
}
-bool CellBuffer::IsCollectingUndo() {
+bool CellBuffer::IsCollectingUndo() const {
return collectingUndo;
}
void SetPerLine(PerLine *pl);
void InsertText(int line, int delta);
- void InsertLine(int line, int position);
+ void InsertLine(int line, int position, bool lineStart);
void SetLineStart(int line, int position);
void RemoveLine(int line);
int Lines() const {
LineVector lv;
+ /// Actions without undo
+ void BasicInsertString(int position, const char *s, int insertLength);
+ void BasicDeleteChars(int position, int deleteLength);
+
public:
CellBuffer();
/// Retrieving positions outside the range of the buffer works and returns 0
char CharAt(int position) const;
- void GetCharRange(char *buffer, int position, int lengthRetrieve);
- char StyleAt(int position);
+ void GetCharRange(char *buffer, int position, int lengthRetrieve) const;
+ char StyleAt(int position) const;
+ void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const;
const char *BufferPointer();
+ const char *RangePointer(int position, int rangeLength);
+ int GapPosition() const;
int Length() const;
void Allocate(int newSize);
int Lines() const;
int LineStart(int line) const;
int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
- void InsertLine(int line, int position);
+ void InsertLine(int line, int position, bool lineStart);
void RemoveLine(int line);
const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
const char *DeleteChars(int position, int deleteLength, bool &startSequence);
- bool IsReadOnly();
+ bool IsReadOnly() const;
void SetReadOnly(bool set);
/// The save point is a marker in the undo stack where the container has stated that
void SetSavePoint();
bool IsSavePoint();
- /// Actions without undo
- void BasicInsertString(int position, const char *s, int insertLength);
- void BasicDeleteChars(int position, int deleteLength);
-
bool SetUndoCollection(bool collectUndo);
- bool IsCollectingUndo();
+ bool IsCollectingUndo() const;
void BeginUndoAction();
void EndUndoAction();
void AddUndoAction(int token, bool mayCoalesce);
#include "CharClassify.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4514)
}
}
-int CompareCaseInsensitive(const char *a, const char *b) {
- while (*a && *b) {
- if (*a != *b) {
- char upperA = MakeUpperCase(*a);
- char upperB = MakeUpperCase(*b);
- if (upperA != upperB)
- return upperA - upperB;
- }
- a++;
- b++;
- }
- // Either *a or *b is nul
- return *a - *b;
-}
-
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
- while (*a && *b && len) {
- if (*a != *b) {
- char upperA = MakeUpperCase(*a);
- char upperB = MakeUpperCase(*b);
- if (upperA != upperB)
- return upperA - upperB;
+int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) {
+ // Get characters belonging to the given char class; return the number
+ // of characters (if the buffer is NULL, don't write to it).
+ int count = 0;
+ for (int ch = maxChar - 1; ch >= 0; --ch) {
+ if (charClass[ch] == characterClass) {
+ ++count;
+ if (buffer) {
+ *buffer = static_cast<unsigned char>(ch);
+ buffer++;
+ }
}
- a++;
- b++;
- len--;
}
- if (len == 0)
- return 0;
- else
- // Either *a or *b is nul
- return *a - *b;
+ return count;
}
#ifndef CHARCLASSIFY_H
#define CHARCLASSIFY_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class CharClassify {
public:
CharClassify();
enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation };
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, cc newCharClass);
+ int GetCharsOfClass(cc charClass, unsigned char *buffer);
cc GetClass(unsigned char ch) const { return static_cast<cc>(charClass[ch]);}
bool IsWord(unsigned char ch) const { return static_cast<cc>(charClass[ch]) == ccWord;}
unsigned char charClass[maxChar]; // not type cc to save space
};
-// These functions are implemented because each platform calls them something different.
-int CompareCaseInsensitive(const char *a, const char *b);
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
-
-inline char MakeUpperCase(char ch) {
- if (ch < 'a' || ch > 'z')
- return ch;
- else
- return static_cast<char>(ch - 'a' + 'A');
+#ifdef SCI_NAMESPACE
}
+#endif
#endif
+++ /dev/null
-// Scintilla source code edit control
-/** @file CharacterSet.h
- ** Encapsulates a set of characters. Used to test if a character is within a set.
- **/
-// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-class CharacterSet {
- int size;
- bool valueAfter;
- bool *bset;
-public:
- enum setBase {
- setNone=0,
- setLower=1,
- setUpper=2,
- setDigits=4,
- setAlpha=setLower|setUpper,
- setAlphaNum=setAlpha|setDigits
- };
- CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) {
- size = size_;
- valueAfter = valueAfter_;
- bset = new bool[size];
- for (int i=0; i < size; i++) {
- bset[i] = false;
- }
- AddString(initialSet);
- if (base & setLower)
- AddString("abcdefghijklmnopqrstuvwxyz");
- if (base & setUpper)
- AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- if (base & setDigits)
- AddString("0123456789");
- }
- ~CharacterSet() {
- delete []bset;
- bset = 0;
- size = 0;
- }
- void Add(int val) {
- PLATFORM_ASSERT(val >= 0);
- PLATFORM_ASSERT(val < size);
- bset[val] = true;
- }
- void AddString(const char *CharacterSet) {
- for (const char *cp=CharacterSet; *cp; cp++) {
- int val = static_cast<unsigned char>(*cp);
- PLATFORM_ASSERT(val >= 0);
- PLATFORM_ASSERT(val < size);
- bset[val] = true;
- }
- }
- bool Contains(int val) const {
- PLATFORM_ASSERT(val >= 0);
- return (val < size) ? bset[val] : valueAfter;
- }
-};
}
}
+bool ContractionState::HiddenLines() const {
+ if (OneToOne()) {
+ return false;
+ } else {
+ return !visible->AllSameAs(1);
+ }
+}
+
bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) {
return true;
}
}
+int ContractionState::ContractedNext(int lineDocStart) const {
+ if (OneToOne()) {
+ return -1;
+ } else {
+ Check();
+ if (!expanded->ValueAt(lineDocStart)) {
+ return lineDocStart;
+ } else {
+ int lineDocNextChange = expanded->EndRun(lineDocStart);
+ if (lineDocNextChange < LinesInDoc())
+ return lineDocNextChange;
+ else
+ return -1;
+ }
+ }
+}
+
int ContractionState::GetHeight(int lineDoc) const {
if (OneToOne()) {
return 1;
bool ContractionState::SetHeight(int lineDoc, int height) {
if (OneToOne() && (height == 1)) {
return false;
- } else {
+ } else if (lineDoc < LinesInDoc()) {
EnsureData();
if (GetHeight(lineDoc) != height) {
if (GetVisible(lineDoc)) {
Check();
return false;
}
+ } else {
+ return false;
}
}
void ContractionState::Check() const {
#ifdef CHECK_CORRECTNESS
- for (int vline = 0;vline < LinesDisplayed(); vline++) {
+ for (int vline = 0; vline < LinesDisplayed(); vline++) {
const int lineDoc = DocFromDisplay(vline);
PLATFORM_ASSERT(GetVisible(lineDoc));
}
- for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) {
+ for (int lineDoc = 0; lineDoc < LinesInDoc(); lineDoc++) {
const int displayThis = DisplayFromDoc(lineDoc);
const int displayNext = DisplayFromDoc(lineDoc + 1);
const int height = displayNext - displayThis;
bool GetVisible(int lineDoc) const;
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
+ bool HiddenLines() const;
bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded);
+ int ContractedNext(int lineDocStart) const;
int GetHeight(int lineDoc) const;
bool SetHeight(int lineDoc, int height);
}
bool Decoration::Empty() {
- return rs.starts->Partitions() == 1;
+ return (rs.Runs() == 1) && (rs.AllSameAs(0));
}
DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
}
void DecorationList::InsertSpace(int position, int insertLength) {
+ const bool atEnd = position == lengthDocument;
lengthDocument += insertLength;
for (Decoration *deco=root; deco; deco = deco->next) {
deco->rs.InsertSpace(position, insertLength);
+ if (atEnd) {
+ deco->rs.FillRange(position, 0, insertLength);
+ }
}
}
void DecorationList::DeleteAnyEmpty() {
Decoration *deco = root;
while (deco) {
- if (deco->Empty()) {
+ if ((lengthDocument == 0) || deco->Empty()) {
Delete(deco->indicator);
deco = root;
} else {
~DecorationList();
void SetCurrentIndicator(int indicator);
- int GetCurrentIndicator() { return currentIndicator; }
+ int GetCurrentIndicator() const { return currentIndicator; }
void SetCurrentValue(int value);
- int GetCurrentValue() { return currentValue; }
+ int GetCurrentValue() const { return currentValue; }
// Returns true if some values may have changed
bool FillRange(int &position, int value, int &fillLength);
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2011 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 <ctype.h>
+#include <assert.h>
+
+#include <string>
+#include <vector>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
+
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "CellBuffer.h"
#include "PerLine.h"
#include "CharClassify.h"
+#include "CharacterSet.h"
#include "Decoration.h"
#include "Document.h"
#include "RESearch.h"
+#include "UniConversion.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
-// This is ASCII specific but is safe with chars >= 0x80
-static inline bool isspacechar(unsigned char ch) {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
static inline bool IsPunctuation(char ch) {
return isascii(ch) && ispunct(ch);
}
-static inline bool IsADigit(char ch) {
- return isascii(ch) && isdigit(ch);
-}
+void LexInterface::Colourise(int start, int end) {
+ if (pdoc && instance && !performingStyle) {
+ // Protect against reentrance, which may occur, for example, when
+ // fold points are discovered while performing styling and the folding
+ // code looks for child lines which may trigger styling.
+ performingStyle = true;
-static inline bool IsLowerCase(char ch) {
- return isascii(ch) && islower(ch);
-}
+ int lengthDoc = pdoc->Length();
+ if (end == -1)
+ end = lengthDoc;
+ int len = end - start;
+
+ PLATFORM_ASSERT(len >= 0);
+ PLATFORM_ASSERT(start + len <= lengthDoc);
-static inline bool IsUpperCase(char ch) {
- return isascii(ch) && isupper(ch);
+ int styleStart = 0;
+ if (start > 0)
+ styleStart = pdoc->StyleAt(start - 1) & pdoc->stylingBitsMask;
+
+ if (len > 0) {
+ instance->Lex(start, len, styleStart, pdoc);
+ instance->Fold(start, len, styleStart, pdoc);
+ }
+
+ performingStyle = false;
+ }
}
Document::Document() {
refCount = 0;
-#ifdef unix
- eolMode = SC_EOL_LF;
-#else
+#ifdef _WIN32
eolMode = SC_EOL_CRLF;
+#else
+ eolMode = SC_EOL_LF;
#endif
dbcsCodePage = 0;
stylingBits = 5;
matchesValid = false;
regex = 0;
+ UTF8BytesOfLeadInitialise();
+
perLineData[ldMarkers] = new LineMarkers();
perLineData[ldLevels] = new LineLevels();
perLineData[ldState] = new LineState();
perLineData[ldAnnotation] = new LineAnnotation();
cb.SetPerLine(this);
+
+ pli = 0;
}
Document::~Document() {
lenWatchers = 0;
delete regex;
regex = 0;
+ delete pli;
+ pli = 0;
}
void Document::Init() {
// Decrease reference count and return its previous value.
// Delete the document if reference count reaches zero.
-int Document::Release() {
+int SCI_METHOD Document::Release() {
int curRefCount = --refCount;
if (curRefCount == 0)
delete this;
NotifySavePoint(true);
}
-int Document::GetMark(int line) {
- return static_cast<LineMarkers*>(perLineData[ldMarkers])->MarkValue(line);
+int Document::GetMark(int line) {
+ return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkValue(line);
+}
+
+int Document::MarkerNext(int lineStart, int mask) const {
+ return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkerNext(lineStart, mask);
}
int Document::AddMark(int line, int markerNum) {
- if (line <= LinesTotal()) {
- int prev = static_cast<LineMarkers*>(perLineData[ldMarkers])->
+ if (line >= 0 && line <= LinesTotal()) {
+ int prev = static_cast<LineMarkers *>(perLineData[ldMarkers])->
AddMark(line, markerNum, LinesTotal());
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::AddMarkSet(int line, int valueSet) {
+ if (line < 0 || line > LinesTotal()) {
+ return;
+ }
unsigned int m = valueSet;
for (int i = 0; m; i++, m >>= 1)
if (m & 1)
- static_cast<LineMarkers*>(perLineData[ldMarkers])->
+ static_cast<LineMarkers *>(perLineData[ldMarkers])->
AddMark(line, i, LinesTotal());
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::DeleteMark(int line, int markerNum) {
- static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
+ static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::DeleteMarkFromHandle(int markerHandle) {
- static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
+ static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
mh.line = -1;
NotifyModified(mh);
}
void Document::DeleteAllMarks(int markerNum) {
+ bool someChanges = false;
for (int line = 0; line < LinesTotal(); line++) {
- static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true);
+ if (static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true))
+ someChanges = true;
+ }
+ if (someChanges) {
+ DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+ mh.line = -1;
+ NotifyModified(mh);
}
- DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
- mh.line = -1;
- NotifyModified(mh);
}
-int Document::LineFromHandle(int markerHandle) {
- return static_cast<LineMarkers*>(perLineData[ldMarkers])->LineFromHandle(markerHandle);
+int Document::LineFromHandle(int markerHandle) {
+ return static_cast<LineMarkers *>(perLineData[ldMarkers])->LineFromHandle(markerHandle);
}
-int Document::LineStart(int line) const {
+int SCI_METHOD Document::LineStart(int line) const {
return cb.LineStart(line);
}
}
}
-int Document::LineFromPosition(int pos) const {
+void SCI_METHOD Document::SetErrorStatus(int status) {
+ // Tell the watchers the lexer has changed.
+ for (int i = 0; i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyErrorOccurred(this, watchers[i].userData, status);
+ }
+}
+
+int SCI_METHOD Document::LineFromPosition(int pos) const {
return cb.LineFromPosition(pos);
}
int startPosition = LineStart(line);
int endLine = LineEnd(line);
int startText = startPosition;
- while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t' ) )
+ while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t'))
startText++;
if (position == startText)
return startPosition;
return startText;
}
-int Document::SetLevel(int line, int level) {
- int prev = static_cast<LineLevels*>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
+int SCI_METHOD Document::SetLevel(int line, int level) {
+ int prev = static_cast<LineLevels *>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
if (prev != level) {
DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
LineStart(line), 0, 0, 0, line);
return prev;
}
-int Document::GetLevel(int line) {
- return static_cast<LineLevels*>(perLineData[ldLevels])->GetLevel(line);
+int SCI_METHOD Document::GetLevel(int line) const {
+ return static_cast<LineLevels *>(perLineData[ldLevels])->GetLevel(line);
}
-void Document::ClearLevels() {
- static_cast<LineLevels*>(perLineData[ldLevels])->ClearLevels();
+void Document::ClearLevels() {
+ static_cast<LineLevels *>(perLineData[ldLevels])->ClearLevels();
}
static bool IsSubordinate(int levelStart, int levelTry) {
return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK);
}
-int Document::GetLastChild(int lineParent, int level) {
+int Document::GetLastChild(int lineParent, int level, int lastLine) {
if (level == -1)
level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK;
int maxLine = LinesTotal();
+ int lookLastLine = (lastLine != -1) ? Platform::Minimum(LinesTotal() - 1, lastLine) : -1;
int lineMaxSubord = lineParent;
while (lineMaxSubord < maxLine - 1) {
EnsureStyledTo(LineStart(lineMaxSubord + 2));
if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1)))
break;
+ if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG))
+ break;
lineMaxSubord++;
}
if (lineMaxSubord > lineParent) {
}
}
+void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int lastLine) {
+ int level = GetLevel(line);
+ int lookLastLine = Platform::Maximum(line, lastLine) + 1;
+
+ int lookLine = line;
+ int lookLineLevel = level;
+ int lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
+ while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) ||
+ ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))))) {
+ lookLineLevel = GetLevel(--lookLine);
+ lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
+ }
+
+ int beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine);
+ if (beginFoldBlock == -1) {
+ highlightDelimiter.Clear();
+ return;
+ }
+
+ int endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine);
+ int firstChangeableLineBefore = -1;
+ if (endFoldBlock < line) {
+ lookLine = beginFoldBlock - 1;
+ lookLineLevel = GetLevel(lookLine);
+ lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
+ while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) {
+ if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) {
+ if (GetLastChild(lookLine, -1, lookLastLine) == line) {
+ beginFoldBlock = lookLine;
+ endFoldBlock = line;
+ firstChangeableLineBefore = line - 1;
+ }
+ }
+ if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && ((GetLevel(lookLine - 1) & SC_FOLDLEVELNUMBERMASK) > lookLineLevelNum))
+ break;
+ lookLineLevel = GetLevel(--lookLine);
+ lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
+ }
+ }
+ if (firstChangeableLineBefore == -1) {
+ for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
+ lookLine >= beginFoldBlock;
+ lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
+ if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > (level & SC_FOLDLEVELNUMBERMASK))) {
+ firstChangeableLineBefore = lookLine;
+ break;
+ }
+ }
+ }
+ if (firstChangeableLineBefore == -1)
+ firstChangeableLineBefore = beginFoldBlock - 1;
+
+ int firstChangeableLineAfter = -1;
+ for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
+ lookLine <= endFoldBlock;
+ lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
+ if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))) {
+ firstChangeableLineAfter = lookLine;
+ break;
+ }
+ }
+ if (firstChangeableLineAfter == -1)
+ firstChangeableLineAfter = endFoldBlock + 1;
+
+ highlightDelimiter.beginFoldBlock = beginFoldBlock;
+ highlightDelimiter.endFoldBlock = endFoldBlock;
+ highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore;
+ highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter;
+}
+
int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length());
}
return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
}
-static const int maxBytesInDBCSCharacter=5;
-
int Document::LenChar(int pos) {
if (pos < 0) {
return 1;
} else if (IsCrLf(pos)) {
return 2;
} else if (SC_CP_UTF8 == dbcsCodePage) {
- unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
- if (ch < 0x80)
- return 1;
- int len = 2;
- if (ch >= (0x80 + 0x40 + 0x20 + 0x10))
- len = 4;
- else if (ch >= (0x80 + 0x40 + 0x20))
- len = 3;
+ const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(pos));
+ const int widthCharBytes = UTF8BytesOfLead[leadByte];
int lengthDoc = Length();
- if ((pos + len) > lengthDoc)
- return lengthDoc -pos;
+ if ((pos + widthCharBytes) > lengthDoc)
+ return lengthDoc - pos;
else
- return len;
+ return widthCharBytes;
} else if (dbcsCodePage) {
- char mbstr[maxBytesInDBCSCharacter+1];
- int i;
- for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
- mbstr[i] = cb.CharAt(pos+i);
- }
- mbstr[i] = '\0';
- return Platform::DBCSCharLength(dbcsCodePage, mbstr);
+ return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
} else {
return 1;
}
}
-static bool IsTrailByte(int ch) {
- return (ch >= 0x80) && (ch < (0x80 + 0x40));
-}
+bool Document::InGoodUTF8(int pos, int &start, int &end) const {
+ int trail = pos;
+ while ((trail>0) && (pos-trail < UTF8MaxBytes) && UTF8IsTrailByte(static_cast<unsigned char>(cb.CharAt(trail-1))))
+ trail--;
+ start = (trail > 0) ? trail-1 : trail;
-static int BytesFromLead(int leadByte) {
- if (leadByte > 0xF4) {
- // Characters longer than 4 bytes not possible in current UTF-8
- return 0;
- } else if (leadByte >= 0xF0) {
- return 4;
- } else if (leadByte >= 0xE0) {
- return 3;
- } else if (leadByte >= 0xC2) {
- return 2;
- }
- return 0;
-}
-
-bool Document::InGoodUTF8(int pos, int &start, int &end) {
- int lead = pos;
- while ((lead>0) && (pos-lead < 4) && IsTrailByte(static_cast<unsigned char>(cb.CharAt(lead-1))))
- lead--;
- start = 0;
- if (lead > 0) {
- start = lead-1;
- }
- int leadByte = static_cast<unsigned char>(cb.CharAt(start));
- int bytes = BytesFromLead(leadByte);
- if (bytes == 0) {
+ const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(start));
+ const int widthCharBytes = UTF8BytesOfLead[leadByte];
+ if (widthCharBytes == 1) {
return false;
} else {
- int trailBytes = bytes - 1;
- int len = pos - lead + 1;
+ int trailBytes = widthCharBytes - 1;
+ int len = pos - start;
if (len > trailBytes)
// pos too far from lead
return false;
- // Check that there are enough trails for this lead
- int trail = pos + 1;
- while ((trail-lead<trailBytes) && (trail < Length())) {
- if (!IsTrailByte(static_cast<unsigned char>(cb.CharAt(trail)))) {
- return false;
- }
- trail++;
- }
- end = start + bytes;
+ char charBytes[UTF8MaxBytes] = {static_cast<char>(leadByte),0,0,0};
+ for (int b=1; b<widthCharBytes && ((start+b) < Length()); b++)
+ charBytes[b] = cb.CharAt(static_cast<int>(start+b));
+ int utf8status = UTF8Classify(reinterpret_cast<const unsigned char *>(charBytes), widthCharBytes);
+ if (utf8status & UTF8MaskInvalid)
+ return false;
+ end = start + widthCharBytes;
return true;
}
}
return pos - 1;
}
- // Not between CR and LF
-
if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
- int startUTF = pos;
- int endUTF = pos;
- if (IsTrailByte(ch) && InGoodUTF8(pos, startUTF, endUTF)) {
- // ch is a trail byte within a UTF-8 character
- if (moveDir > 0)
- pos = endUTF;
- else
- pos = startUTF;
+ // If ch is not a trail byte then pos is valid intercharacter position
+ if (UTF8IsTrailByte(ch)) {
+ int startUTF = pos;
+ int endUTF = pos;
+ if (InGoodUTF8(pos, startUTF, endUTF)) {
+ // ch is a trail byte within a UTF-8 character
+ if (moveDir > 0)
+ pos = endUTF;
+ else
+ pos = startUTF;
+ }
+ // Else invalid UTF-8 so return position of isolated trail byte
}
} else {
// Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte.
- int posCheck = LineStart(LineFromPosition(pos));
- while (posCheck < pos) {
- char mbstr[maxBytesInDBCSCharacter+1];
- int i;
- for(i=0;i<Platform::DBCSCharMaxLength();i++) {
- mbstr[i] = cb.CharAt(posCheck+i);
- }
- mbstr[i] = '\0';
+ int posStartLine = LineStart(LineFromPosition(pos));
+ if (pos == posStartLine)
+ return pos;
+
+ // Step back until a non-lead-byte is found.
+ int posCheck = pos;
+ while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1)))
+ posCheck--;
- int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+ // Check from known start of character.
+ while (posCheck < pos) {
+ int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1;
if (posCheck + mbsize == pos) {
return pos;
} else if (posCheck + mbsize > pos) {
return pos;
}
+// NextPosition moves between valid positions - it can not handle a position in the middle of a
+// multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar.
+// A \r\n pair is treated as two characters.
+int Document::NextPosition(int pos, int moveDir) const {
+ // If out of range, just return minimum/maximum value.
+ int increment = (moveDir > 0) ? 1 : -1;
+ if (pos + increment <= 0)
+ return 0;
+ if (pos + increment >= Length())
+ return Length();
+
+ if (dbcsCodePage) {
+ if (SC_CP_UTF8 == dbcsCodePage) {
+ if (increment == 1) {
+ // Simple forward movement case so can avoid some checks
+ const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(pos));
+ if (UTF8IsAscii(leadByte)) {
+ // Single byte character or invalid
+ pos++;
+ } else {
+ const int widthCharBytes = UTF8BytesOfLead[leadByte];
+ char charBytes[UTF8MaxBytes] = {static_cast<char>(leadByte),0,0,0};
+ for (int b=1; b<widthCharBytes; b++)
+ charBytes[b] = cb.CharAt(static_cast<int>(pos+b));
+ int utf8status = UTF8Classify(reinterpret_cast<const unsigned char *>(charBytes), widthCharBytes);
+ if (utf8status & UTF8MaskInvalid)
+ pos++;
+ else
+ pos += utf8status & UTF8MaskWidth;
+ }
+ } else {
+ // Examine byte before position
+ pos--;
+ unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
+ // If ch is not a trail byte then pos is valid intercharacter position
+ if (UTF8IsTrailByte(ch)) {
+ // If ch is a trail byte in a valid UTF-8 character then return start of character
+ int startUTF = pos;
+ int endUTF = pos;
+ if (InGoodUTF8(pos, startUTF, endUTF)) {
+ pos = startUTF;
+ }
+ // Else invalid UTF-8 so return position of isolated trail byte
+ }
+ }
+ } else {
+ if (moveDir > 0) {
+ int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
+ pos += mbsize;
+ if (pos > Length())
+ pos = Length();
+ } else {
+ // Anchor DBCS calculations at start of line because start of line can
+ // not be a DBCS trail byte.
+ int posStartLine = LineStart(LineFromPosition(pos));
+ // See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
+ // http://msdn.microsoft.com/en-us/library/cc194790.aspx
+ if ((pos - 1) <= posStartLine) {
+ return pos - 1;
+ } else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
+ // Must actually be trail byte
+ return pos - 2;
+ } else {
+ // Otherwise, step back until a non-lead-byte is found.
+ int posTemp = pos - 1;
+ while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp)))
+ ;
+ // Now posTemp+1 must point to the beginning of a character,
+ // so figure out whether we went back an even or an odd
+ // number of bytes and go back 1 or 2 bytes, respectively.
+ return (pos - 1 - ((pos - posTemp) & 1));
+ }
+ }
+ }
+ } else {
+ pos += increment;
+ }
+
+ return pos;
+}
+
+bool Document::NextCharacter(int &pos, int moveDir) {
+ // Returns true if pos changed
+ int posNext = NextPosition(pos, moveDir);
+ if (posNext == pos) {
+ return false;
+ } else {
+ pos = posNext;
+ return true;
+ }
+}
+
+int SCI_METHOD Document::CodePage() const {
+ return dbcsCodePage;
+}
+
+bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
+ // Byte ranges found in Wikipedia articles with relevant search strings in each case
+ unsigned char uch = static_cast<unsigned char>(ch);
+ switch (dbcsCodePage) {
+ case 932:
+ // Shift_jis
+ return ((uch >= 0x81) && (uch <= 0x9F)) ||
+ ((uch >= 0xE0) && (uch <= 0xFC));
+ // Lead bytes F0 to FC may be a Microsoft addition.
+ case 936:
+ // GBK
+ return (uch >= 0x81) && (uch <= 0xFE);
+ case 949:
+ // Korean Wansung KS C-5601-1987
+ return (uch >= 0x81) && (uch <= 0xFE);
+ case 950:
+ // Big5
+ return (uch >= 0x81) && (uch <= 0xFE);
+ case 1361:
+ // Korean Johab KS C-5601-1992
+ return
+ ((uch >= 0x84) && (uch <= 0xD3)) ||
+ ((uch >= 0xD8) && (uch <= 0xDE)) ||
+ ((uch >= 0xE0) && (uch <= 0xF9));
+ }
+ return false;
+}
+
+static inline bool IsSpaceOrTab(int ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+// Need to break text into segments near lengthSegment but taking into
+// account the encoding to not break inside a UTF-8 or DBCS character
+// and also trying to avoid breaking inside a pair of combining characters.
+// The segment length must always be long enough (more than 4 bytes)
+// so that there will be at least one whole character to make a segment.
+// For UTF-8, text must consist only of valid whole characters.
+// In preference order from best to worst:
+// 1) Break after space
+// 2) Break before punctuation
+// 3) Break after whole character
+
+int Document::SafeSegment(const char *text, int length, int lengthSegment) {
+ if (length <= lengthSegment)
+ return length;
+ int lastSpaceBreak = -1;
+ int lastPunctuationBreak = -1;
+ int lastEncodingAllowedBreak = -1;
+ for (int j=0; j < lengthSegment;) {
+ unsigned char ch = static_cast<unsigned char>(text[j]);
+ if (j > 0) {
+ if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
+ lastSpaceBreak = j;
+ }
+ if (ch < 'A') {
+ lastPunctuationBreak = j;
+ }
+ }
+ lastEncodingAllowedBreak = j;
+
+ if (dbcsCodePage == SC_CP_UTF8) {
+ j += UTF8BytesOfLead[ch];
+ } else if (dbcsCodePage) {
+ j += IsDBCSLeadByte(ch) ? 2 : 1;
+ } else {
+ j++;
+ }
+ }
+ if (lastSpaceBreak >= 0) {
+ return lastSpaceBreak;
+ } else if (lastPunctuationBreak >= 0) {
+ return lastPunctuationBreak;
+ }
+ return lastEncodingAllowedBreak;
+}
+
void Document::ModifiedAt(int pos) {
if (endStyled > pos)
endStyled = pos;
// SetStyleAt does not change the persistent state of a document
bool Document::DeleteChars(int pos, int len) {
- if (len == 0)
+ if (len <= 0)
return false;
if ((pos + len) > Length())
return false;
return !cb.IsReadOnly();
}
+int SCI_METHOD Document::AddData(char *data, int length) {
+ try {
+ int position = Length();
+ InsertString(position,data, length);
+ } catch (std::bad_alloc &) {
+ return SC_STATUS_BADALLOC;
+ } catch (...) {
+ return SC_STATUS_FAILURE;
+ }
+ return 0;
+}
+
+void * SCI_METHOD Document::ConvertToDocument() {
+ return this;
+}
+
int Document::Undo() {
int newPos = -1;
CheckReadOnly();
bool multiLine = false;
int steps = cb.StartUndo();
//Platform::DebugPrintf("Steps=%d\n", steps);
+ int coalescedRemovePos = -1;
+ int coalescedRemoveLen = 0;
+ int prevRemoveActionPos = -1;
+ int prevRemoveActionLen = 0;
for (int step = 0; step < steps; step++) {
const int prevLinesTotal = LinesTotal();
const Action &action = cb.GetUndoStep();
DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO);
dm.token = action.position;
NotifyModified(dm);
+ if (!action.mayCoalesce) {
+ coalescedRemovePos = -1;
+ coalescedRemoveLen = 0;
+ prevRemoveActionPos = -1;
+ prevRemoveActionLen = 0;
+ }
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
}
cb.PerformUndoStep();
- int cellPosition = action.position;
if (action.at != containerAction) {
- ModifiedAt(cellPosition);
- newPos = cellPosition;
+ ModifiedAt(action.position);
+ newPos = action.position;
}
int modFlags = SC_PERFORMED_UNDO;
if (action.at == removeAction) {
newPos += action.lenData;
modFlags |= SC_MOD_INSERTTEXT;
+ if ((coalescedRemoveLen > 0) &&
+ (action.position == prevRemoveActionPos || action.position == (prevRemoveActionPos + prevRemoveActionLen))) {
+ coalescedRemoveLen += action.lenData;
+ newPos = coalescedRemovePos + coalescedRemoveLen;
+ } else {
+ coalescedRemovePos = action.position;
+ coalescedRemoveLen = action.lenData;
+ }
+ prevRemoveActionPos = action.position;
+ prevRemoveActionLen = action.lenData;
} else if (action.at == insertAction) {
modFlags |= SC_MOD_DELETETEXT;
+ coalescedRemovePos = -1;
+ coalescedRemoveLen = 0;
+ prevRemoveActionPos = -1;
+ prevRemoveActionLen = 0;
}
if (steps > 1)
modFlags |= SC_MULTISTEPUNDOREDO;
if (multiLine)
modFlags |= SC_MULTILINEUNDOREDO;
}
- NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
+ NotifyModified(DocModification(modFlags, action.position, action.lenData,
linesAdded, action.data));
}
* Insert a null terminated string.
*/
bool Document::InsertCString(int position, const char *s) {
- return InsertString(position, s, strlen(s));
+ return InsertString(position, s, static_cast<int>(s ? strlen(s) : 0));
}
void Document::ChangeChar(int pos, char ch) {
} else if (IsCrLf(pos - 2)) {
DeleteChars(pos - 2, 2);
} else if (dbcsCodePage) {
- int startChar = MovePositionOutsideChar(pos - 1, -1, false);
+ int startChar = NextPosition(pos, -1);
DeleteChars(startChar, pos - startChar);
} else {
DeleteChars(pos - 1, 1);
}
}
-static bool isindentchar(char ch) {
- return (ch == ' ') || (ch == '\t');
-}
-
static int NextTab(int pos, int tabSize) {
return ((pos / tabSize) + 1) * tabSize;
}
-static void CreateIndentation(char *linebuf, int length, int indent, int tabSize, bool insertSpaces) {
- length--; // ensure space for \0
+static std::string CreateIndentation(int indent, int tabSize, bool insertSpaces) {
+ std::string indentation;
if (!insertSpaces) {
- while ((indent >= tabSize) && (length > 0)) {
- *linebuf++ = '\t';
+ while (indent >= tabSize) {
+ indentation += '\t';
indent -= tabSize;
- length--;
}
}
- while ((indent > 0) && (length > 0)) {
- *linebuf++ = ' ';
+ while (indent > 0) {
+ indentation += ' ';
indent--;
- length--;
}
- *linebuf = '\0';
+ return indentation;
}
-int Document::GetLineIndentation(int line) {
+int SCI_METHOD Document::GetLineIndentation(int line) {
int indent = 0;
if ((line >= 0) && (line < LinesTotal())) {
int lineStart = LineStart(line);
int length = Length();
- for (int i = lineStart;i < length;i++) {
+ for (int i = lineStart; i < length; i++) {
char ch = cb.CharAt(i);
if (ch == ' ')
indent++;
if (indent < 0)
indent = 0;
if (indent != indentOfLine) {
- char linebuf[1000];
- CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
+ std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
UndoGroup ug(this);
DeleteChars(thisLineStart, indentPos - thisLineStart);
- InsertCString(thisLineStart, linebuf);
+ InsertCString(thisLineStart, linebuf.c_str());
}
}
return 0;
int pos = LineStart(line);
int length = Length();
- while ((pos < length) && isindentchar(cb.CharAt(pos))) {
+ while ((pos < length) && IsSpaceOrTab(cb.CharAt(pos))) {
pos++;
}
return pos;
int column = 0;
int line = LineFromPosition(pos);
if ((line >= 0) && (line < LinesTotal())) {
- for (int i = LineStart(line);i < pos;) {
+ for (int i = LineStart(line); i < pos;) {
char ch = cb.CharAt(i);
if (ch == '\t') {
column = NextTab(column, tabInChars);
return column;
} else {
column++;
- i = MovePositionOutsideChar(i + 1, 1, false);
+ i = NextPosition(i, 1);
}
}
}
return column;
}
+int Document::CountCharacters(int startPos, int endPos) {
+ startPos = MovePositionOutsideChar(startPos, 1, false);
+ endPos = MovePositionOutsideChar(endPos, -1, false);
+ int count = 0;
+ int i = startPos;
+ while (i < endPos) {
+ count++;
+ if (IsCrLf(i))
+ i++;
+ i = NextPosition(i, 1);
+ }
+ return count;
+}
+
int Document::FindColumn(int line, int column) {
int position = LineStart(line);
if ((line >= 0) && (line < LinesTotal())) {
char ch = cb.CharAt(position);
if (ch == '\t') {
columnCurrent = NextTab(columnCurrent, tabInChars);
+ if (columnCurrent > column)
+ return position;
position++;
} else if (ch == '\r') {
return position;
return position;
} else {
columnCurrent++;
- position = MovePositionOutsideChar(position + 1, 1, false);
+ position = NextPosition(position, 1);
}
}
}
// Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found.
// Caller must delete the returned pointer.
-char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode) {
+char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted) {
char *dest = new char[2 * len + 1];
const char *sptr = s;
char *dptr = dest;
for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) {
if (*sptr == '\n' || *sptr == '\r') {
- if (eolMode == SC_EOL_CR) {
+ if (eolModeWanted == SC_EOL_CR) {
*dptr++ = '\r';
- } else if (eolMode == SC_EOL_LF) {
+ } else if (eolModeWanted == SC_EOL_LF) {
*dptr++ = '\n';
- } else { // eolMode == SC_EOL_CRLF
+ } else { // eolModeWanted == SC_EOL_CRLF
*dptr++ = '\r';
*dptr++ = '\n';
}
}
CharClassify::cc Document::WordCharClass(unsigned char ch) {
- if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))
+ if ((SC_CP_UTF8 == dbcsCodePage) && (!UTF8IsAscii(ch)))
return CharClassify::ccWord;
return charClass.GetClass(ch);
}
while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart))
pos++;
}
- return MovePositionOutsideChar(pos, delta);
+ return MovePositionOutsideChar(pos, delta, true);
}
/**
return static_cast<char>(ch - 'A' + 'a');
}
+CaseFolderTable::CaseFolderTable() {
+ for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
+ mapping[iChar] = static_cast<char>(iChar);
+ }
+}
+
+CaseFolderTable::~CaseFolderTable() {
+}
+
+size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+ if (lenMixed > sizeFolded) {
+ return 0;
+ } else {
+ for (size_t i=0; i<lenMixed; i++) {
+ folded[i] = mapping[static_cast<unsigned char>(mixed[i])];
+ }
+ return lenMixed;
+ }
+}
+
+void CaseFolderTable::SetTranslation(char ch, char chTranslation) {
+ mapping[static_cast<unsigned char>(ch)] = chTranslation;
+}
+
+void CaseFolderTable::StandardASCII() {
+ for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
+ if (iChar >= 'A' && iChar <= 'Z') {
+ mapping[iChar] = static_cast<char>(iChar - 'A' + 'a');
+ } else {
+ mapping[iChar] = static_cast<char>(iChar);
+ }
+ }
+}
+
+bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length) {
+ return (!word && !wordStart) ||
+ (word && IsWordAt(pos, pos + length)) ||
+ (wordStart && IsWordStartAt(pos));
+}
+
/**
* Find text in document, supporting both forward and backward
* searches (just pass minPos > maxPos to do a backward search)
* Has not been tested with backwards DBCS searches yet.
*/
-long Document::FindText(int minPos, int maxPos, const char *s,
+long Document::FindText(int minPos, int maxPos, const char *search,
bool caseSensitive, bool word, bool wordStart, bool regExp, int flags,
- int *length) {
+ int *length, CaseFolder *pcf) {
+ if (*length <= 0)
+ return minPos;
if (regExp) {
if (!regex)
regex = CreateRegexSearch(&charClass);
- return regex->FindText(this, minPos, maxPos, s, caseSensitive, word, wordStart, flags, length);
+ return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length);
} else {
- bool forward = minPos <= maxPos;
- int increment = forward ? 1 : -1;
+ const bool forward = minPos <= maxPos;
+ const int increment = forward ? 1 : -1;
// Range endpoints should not be inside DBCS characters, but just in case, move them.
- int startPos = MovePositionOutsideChar(minPos, increment, false);
- int endPos = MovePositionOutsideChar(maxPos, increment, false);
+ const int startPos = MovePositionOutsideChar(minPos, increment, false);
+ const int endPos = MovePositionOutsideChar(maxPos, increment, false);
// Compute actual search ranges needed
- int lengthFind = *length;
- if (lengthFind == -1)
- lengthFind = static_cast<int>(strlen(s));
- int endSearch = endPos;
- if (startPos <= endPos) {
- endSearch = endPos - lengthFind + 1;
- }
+ const int lengthFind = *length;
+
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
- char firstChar = s[0];
- if (!caseSensitive)
- firstChar = static_cast<char>(MakeUpperCase(firstChar));
- int pos = forward ? startPos : (startPos - 1);
- while (forward ? (pos < endSearch) : (pos >= endSearch)) {
- char ch = CharAt(pos);
- if (caseSensitive) {
- if (ch == firstChar) {
- bool found = true;
- if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
- for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
- ch = CharAt(pos + posMatch);
- if (ch != s[posMatch])
- found = false;
+ const int limitPos = Platform::Maximum(startPos, endPos);
+ int pos = startPos;
+ if (!forward) {
+ // Back all of a character
+ pos = NextPosition(pos, increment);
+ }
+ if (caseSensitive) {
+ const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
+ const char charStartSearch = search[0];
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ if (CharAt(pos) == charStartSearch) {
+ bool found = (pos + lengthFind) <= limitPos;
+ for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) {
+ found = CharAt(pos + indexSearch) == search[indexSearch];
}
- if (found) {
- if ((!word && !wordStart) ||
- (word && IsWordAt(pos, pos + lengthFind)) ||
- (wordStart && IsWordStartAt(pos)))
- return pos;
+ if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
+ return pos;
}
}
- } else {
- if (MakeUpperCase(ch) == firstChar) {
- bool found = true;
- if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
- for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
- ch = CharAt(pos + posMatch);
- if (MakeUpperCase(ch) != MakeUpperCase(s[posMatch]))
- found = false;
+ if (!NextCharacter(pos, increment))
+ break;
+ }
+ } else if (SC_CP_UTF8 == dbcsCodePage) {
+ const size_t maxFoldingExpansion = 4;
+ std::vector<char> searchThing(lengthFind * UTF8MaxBytes * maxFoldingExpansion + 1);
+ const int lenSearch = static_cast<int>(
+ pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
+ char bytes[UTF8MaxBytes + 1];
+ char folded[UTF8MaxBytes * maxFoldingExpansion + 1];
+ while (forward ? (pos < endPos) : (pos >= endPos)) {
+ int widthFirstCharacter = 0;
+ int posIndexDocument = pos;
+ int indexSearch = 0;
+ bool characterMatches = true;
+ for (;;) {
+ const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(posIndexDocument));
+ bytes[0] = leadByte;
+ int widthChar = 1;
+ if (!UTF8IsAscii(leadByte)) {
+ const int widthCharBytes = UTF8BytesOfLead[leadByte];
+ for (int b=1; b<widthCharBytes; b++) {
+ bytes[b] = cb.CharAt(posIndexDocument+b);
+ }
+ widthChar = UTF8Classify(reinterpret_cast<const unsigned char *>(bytes), widthCharBytes) & UTF8MaskWidth;
}
- if (found) {
- if ((!word && !wordStart) ||
- (word && IsWordAt(pos, pos + lengthFind)) ||
- (wordStart && IsWordStartAt(pos)))
- return pos;
+ if (!widthFirstCharacter)
+ widthFirstCharacter = widthChar;
+ if ((posIndexDocument + widthChar) > limitPos)
+ break;
+ const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
+ folded[lenFlat] = 0;
+ // Does folded match the buffer
+ characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
+ if (!characterMatches)
+ break;
+ posIndexDocument += widthChar;
+ indexSearch += lenFlat;
+ if (indexSearch >= lenSearch)
+ break;
+ }
+ if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
+ if (MatchesWordOptions(word, wordStart, pos, posIndexDocument - pos)) {
+ *length = posIndexDocument - pos;
+ return pos;
}
}
+ if (forward) {
+ pos += widthFirstCharacter;
+ } else {
+ if (!NextCharacter(pos, increment))
+ break;
+ }
}
- pos += increment;
- if (dbcsCodePage && (pos >= 0)) {
- // Ensure trying to match from start of character
- pos = MovePositionOutsideChar(pos, increment, false);
+ } else if (dbcsCodePage) {
+ const size_t maxBytesCharacter = 2;
+ const size_t maxFoldingExpansion = 4;
+ std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
+ const int lenSearch = static_cast<int>(
+ pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
+ while (forward ? (pos < endPos) : (pos >= endPos)) {
+ int indexDocument = 0;
+ int indexSearch = 0;
+ bool characterMatches = true;
+ while (characterMatches &&
+ ((pos + indexDocument) < limitPos) &&
+ (indexSearch < lenSearch)) {
+ char bytes[maxBytesCharacter + 1];
+ bytes[0] = cb.CharAt(pos + indexDocument);
+ const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
+ if (widthChar == 2)
+ bytes[1] = cb.CharAt(pos + indexDocument + 1);
+ if ((pos + indexDocument + widthChar) > limitPos)
+ break;
+ char folded[maxBytesCharacter * maxFoldingExpansion + 1];
+ const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
+ folded[lenFlat] = 0;
+ // Does folded match the buffer
+ characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
+ indexDocument += widthChar;
+ indexSearch += lenFlat;
+ }
+ if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
+ if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
+ *length = indexDocument;
+ return pos;
+ }
+ }
+ if (!NextCharacter(pos, increment))
+ break;
+ }
+ } else {
+ const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
+ std::vector<char> searchThing(lengthFind + 1);
+ pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ bool found = (pos + lengthFind) <= limitPos;
+ for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
+ char ch = CharAt(pos + indexSearch);
+ char folded[2];
+ pcf->Fold(folded, sizeof(folded), &ch, 1);
+ found = folded[0] == searchThing[indexSearch];
+ }
+ if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
+ return pos;
+ }
+ if (!NextCharacter(pos, increment))
+ break;
}
}
}
}
const char *Document::SubstituteByPosition(const char *text, int *length) {
- return regex->SubstituteByPosition(this, text, length);
+ if (regex)
+ return regex->SubstituteByPosition(this, text, length);
+ else
+ return 0;
}
int Document::LinesTotal() const {
charClass.SetCharClasses(chars, newCharClass);
}
+int Document::GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) {
+ return charClass.GetCharsOfClass(characterClass, buffer);
+}
+
void Document::SetStylingBits(int bits) {
stylingBits = bits;
stylingBitsMask = (1 << stylingBits) - 1;
}
-void Document::StartStyling(int position, char mask) {
+void SCI_METHOD Document::StartStyling(int position, char mask) {
stylingMask = mask;
endStyled = position;
}
-bool Document::SetStyleFor(int length, char style) {
+bool SCI_METHOD Document::SetStyleFor(int length, char style) {
if (enteredStyling != 0) {
return false;
} else {
}
}
-bool Document::SetStyles(int length, const char *styles) {
+bool SCI_METHOD Document::SetStyles(int length, const char *styles) {
if (enteredStyling != 0) {
return false;
} else {
void Document::EnsureStyledTo(int pos) {
if ((enteredStyling == 0) && (pos > GetEndStyled())) {
IncrementStyleClock();
- // Ask the watchers to style, and stop as soon as one responds.
- for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
- watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+ if (pli && !pli->UseContainerLexing()) {
+ int lineEndStyled = LineFromPosition(GetEndStyled());
+ int endStyledTo = LineStart(lineEndStyled);
+ pli->Colourise(endStyledTo, pos);
+ } else {
+ // Ask the watchers to style, and stop as soon as one responds.
+ for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+ }
}
}
}
-int Document::SetLineState(int line, int state) {
- int statePrevious = static_cast<LineState*>(perLineData[ldState])->SetLineState(line, state);
+void Document::LexerChanged() {
+ // Tell the watchers the lexer has changed.
+ for (int i = 0; i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyLexerChanged(this, watchers[i].userData);
+ }
+}
+
+int SCI_METHOD Document::SetLineState(int line, int state) {
+ int statePrevious = static_cast<LineState *>(perLineData[ldState])->SetLineState(line, state);
if (state != statePrevious) {
- DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
+ DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
return statePrevious;
}
-int Document::GetLineState(int line) {
- return static_cast<LineState*>(perLineData[ldState])->GetLineState(line);
+int SCI_METHOD Document::GetLineState(int line) const {
+ return static_cast<LineState *>(perLineData[ldState])->GetLineState(line);
+}
+
+int Document::GetMaxLineState() {
+ return static_cast<LineState *>(perLineData[ldState])->GetMaxLineState();
}
-int Document::GetMaxLineState() {
- return static_cast<LineState*>(perLineData[ldState])->GetMaxLineState();
+void SCI_METHOD Document::ChangeLexerState(int start, int end) {
+ DocModification mh(SC_MOD_LEXERSTATE, start, end-start, 0, 0, 0);
+ NotifyModified(mh);
}
StyledText Document::MarginStyledText(int line) {
- LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldMargin]);
- return StyledText(pla->Length(line), pla->Text(line),
+ LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldMargin]);
+ return StyledText(pla->Length(line), pla->Text(line),
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
}
void Document::MarginSetText(int line, const char *text) {
- static_cast<LineAnnotation*>(perLineData[ldMargin])->SetText(line, text);
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->SetText(line, text);
DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::MarginSetStyle(int line, int style) {
- static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyle(line, style);
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyle(line, style);
+ NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line));
}
void Document::MarginSetStyles(int line, const unsigned char *styles) {
- static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyles(line, styles);
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyles(line, styles);
+ NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line));
}
int Document::MarginLength(int line) const {
- return static_cast<LineAnnotation*>(perLineData[ldMargin])->Length(line);
+ return static_cast<LineAnnotation *>(perLineData[ldMargin])->Length(line);
}
void Document::MarginClearAll() {
int maxEditorLine = LinesTotal();
- for (int l=0;l<maxEditorLine;l++)
+ for (int l=0; l<maxEditorLine; l++)
MarginSetText(l, 0);
// Free remaining data
- static_cast<LineAnnotation*>(perLineData[ldMargin])->ClearAll();
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->ClearAll();
}
bool Document::AnnotationAny() const {
- return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->AnySet();
+ return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->AnySet();
}
StyledText Document::AnnotationStyledText(int line) {
- LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldAnnotation]);
- return StyledText(pla->Length(line), pla->Text(line),
+ LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldAnnotation]);
+ return StyledText(pla->Length(line), pla->Text(line),
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
}
void Document::AnnotationSetText(int line, const char *text) {
- const int linesBefore = AnnotationLines(line);
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetText(line, text);
- const int linesAfter = AnnotationLines(line);
- DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
- mh.annotationLinesAdded = linesAfter - linesBefore;
- NotifyModified(mh);
+ if (line >= 0 && line < LinesTotal()) {
+ const int linesBefore = AnnotationLines(line);
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetText(line, text);
+ const int linesAfter = AnnotationLines(line);
+ DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+ mh.annotationLinesAdded = linesAfter - linesBefore;
+ NotifyModified(mh);
+ }
}
void Document::AnnotationSetStyle(int line, int style) {
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyle(line, style);
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyle(line, style);
+ DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+ NotifyModified(mh);
}
void Document::AnnotationSetStyles(int line, const unsigned char *styles) {
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyles(line, styles);
+ if (line >= 0 && line < LinesTotal()) {
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyles(line, styles);
+ }
}
int Document::AnnotationLength(int line) const {
- return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Length(line);
+ return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Length(line);
}
int Document::AnnotationLines(int line) const {
- return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Lines(line);
+ return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Lines(line);
}
void Document::AnnotationClearAll() {
int maxEditorLine = LinesTotal();
- for (int l=0;l<maxEditorLine;l++)
+ for (int l=0; l<maxEditorLine; l++)
AnnotationSetText(l, 0);
// Free remaining data
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->ClearAll();
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->ClearAll();
}
void Document::IncrementStyleClock() {
styleClock = (styleClock + 1) % 0x100000;
}
-void Document::DecorationFillRange(int position, int value, int fillLength) {
+void SCI_METHOD Document::DecorationFillRange(int position, int value, int fillLength) {
if (decorations.FillRange(position, value, fillLength)) {
DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER,
position, fillLength);
int Document::ExtendStyleRange(int pos, int delta, bool singleLine) {
int sStart = cb.StyleAt(pos);
if (delta < 0) {
- while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))) )
+ while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))))
pos--;
pos++;
} else {
- while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))) )
+ while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))))
pos++;
}
return pos;
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1;
int depth = 1;
- position = position + direction;
+ position = NextPosition(position, direction);
while ((position >= 0) && (position < Length())) {
- position = MovePositionOutsideChar(position, direction);
char chAtPos = CharAt(position);
char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
if (depth == 0)
return position;
}
- position = position + direction;
+ int positionBeforeMove = position;
+ position = NextPosition(position, direction);
+ if (position == positionBeforeMove)
+ break;
}
return - 1;
}
bool caseSensitive, bool word, bool wordStart, int flags,
int *length);
- virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length);
+ virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length);
private:
RESearch search;
// the start position is at end of line or between line end characters.
lineRangeStart++;
startPos = doc->LineStart(lineRangeStart);
+ } else if ((increment == -1) &&
+ (startPos <= doc->LineStart(lineRangeStart)) &&
+ (lineRangeStart > lineRangeEnd)) {
+ // the start position is at beginning of line.
+ lineRangeStart--;
+ startPos = doc->LineEnd(lineRangeStart);
}
int pos = -1;
int lenRet = 0;
char searchEnd = s[*length - 1];
+ char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
int lineRangeBreak = lineRangeEnd + increment;
for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
int startOfLine = doc->LineStart(line);
startOfLine = startPos;
}
if (line == lineRangeEnd) {
- if ((endPos != endOfLine) && (searchEnd == '$'))
+ if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if end position before end of line
endOfLine = endPos;
}
startOfLine = endPos;
}
if (line == lineRangeStart) {
- if ((startPos != endOfLine) && (searchEnd == '$'))
+ if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if start position before end of line
endOfLine = startPos;
}
if (success) {
pos = search.bopat[0];
lenRet = search.eopat[0] - search.bopat[0];
- if (increment == -1) {
+ // There can be only one start of a line, so no need to look for last match in line
+ if ((increment == -1) && (s[0] != '^')) {
// Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {
return pos;
}
-const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text, int *length) {
+const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, int *length) {
delete []substituted;
substituted = 0;
DocumentIndexer di(doc, doc->Length());
unsigned int lenResult = 0;
for (int i = 0; i < *length; i++) {
if (text[i] == '\\') {
- if (text[i + 1] >= '1' && text[i + 1] <= '9') {
+ if (text[i + 1] >= '0' && text[i + 1] <= '9') {
unsigned int patNum = text[i + 1] - '0';
lenResult += search.eopat[patNum] - search.bopat[patNum];
i++;
case 'r':
case 't':
case 'v':
+ case '\\':
i++;
}
lenResult++;
char *o = substituted;
for (int j = 0; j < *length; j++) {
if (text[j] == '\\') {
- if (text[j + 1] >= '1' && text[j + 1] <= '9') {
+ if (text[j + 1] >= '0' && text[j + 1] <= '9') {
unsigned int patNum = text[j + 1] - '0';
unsigned int len = search.eopat[patNum] - search.bopat[patNum];
if (search.pat[patNum]) // Will be null if try for a match that did not occur
case 'v':
*o++ = '\v';
break;
+ case '\\':
+ *o++ = '\\';
+ break;
default:
*o++ = '\\';
j--;
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
Range(Position pos=0) :
start(pos), end(pos) {
- };
+ }
Range(Position start_, Position end_) :
start(start_), end(end_) {
- };
+ }
bool Valid() const {
return (start != invalidPosition) && (end != invalidPosition);
*/
class RegexSearchBase {
public:
- virtual ~RegexSearchBase(){}
+ virtual ~RegexSearchBase() {}
- virtual long FindText(Document* doc, int minPos, int maxPos, const char *s,
+ virtual long FindText(Document *doc, int minPos, int maxPos, const char *s,
bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0;
///@return String with the substitutions, must remain valid until the next call or destruction
- virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length) = 0;
+ virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length) = 0;
};
/// Factory function for RegexSearchBase
-extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
+extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable);
struct StyledText {
size_t length;
bool multipleStyles;
size_t style;
const unsigned char *styles;
- StyledText( size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) :
+ StyledText(size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) :
length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
}
// Return number of bytes from start to before '\n' or end of text.
}
};
+class HighlightDelimiter {
+public:
+ HighlightDelimiter() : isEnabled(false) {
+ Clear();
+ }
+
+ void Clear() {
+ beginFoldBlock = -1;
+ endFoldBlock = -1;
+ firstChangeableLineBefore = -1;
+ firstChangeableLineAfter = -1;
+ }
+
+ bool NeedsDrawing(int line) {
+ return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter);
+ }
+
+ bool IsFoldBlockHighlighted(int line) {
+ return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
+ }
+
+ bool IsHeadOfFoldBlock(int line) {
+ return beginFoldBlock == line && line < endFoldBlock;
+ }
+
+ bool IsBodyOfFoldBlock(int line) {
+ return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
+ }
+
+ bool IsTailOfFoldBlock(int line) {
+ return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
+ }
+
+ int beginFoldBlock; // Begin of current fold block
+ int endFoldBlock; // End of current fold block
+ int firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block
+ int firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block
+ bool isEnabled;
+};
+
+class CaseFolder {
+public:
+ virtual ~CaseFolder() {
+ }
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0;
+};
+
+class CaseFolderTable : public CaseFolder {
+protected:
+ char mapping[256];
+public:
+ CaseFolderTable();
+ virtual ~CaseFolderTable();
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed);
+ void SetTranslation(char ch, char chTranslation);
+ void StandardASCII();
+};
+
+class Document;
+
+class LexInterface {
+protected:
+ Document *pdoc;
+ ILexer *instance;
+ bool performingStyle; ///< Prevent reentrance
+public:
+ LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) {
+ }
+ virtual ~LexInterface() {
+ }
+ void Colourise(int start, int end);
+ bool UseContainerLexing() const {
+ return instance == 0;
+ }
+};
+
/**
*/
-class Document : PerLine {
+class Document : PerLine, public IDocument, public ILoader {
public:
/** Used to pair watcher pointer with user data. */
int lenWatchers;
// ldSize is not real data - it is for dimensions and loops
- enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };
+ enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };
PerLine *perLineData[ldSize];
bool matchesValid;
- RegexSearchBase* regex;
+ RegexSearchBase *regex;
public:
+
+ LexInterface *pli;
+
int stylingBits;
int stylingBitsMask;
virtual ~Document();
int AddRef();
- int Release();
+ int SCI_METHOD Release();
virtual void Init();
virtual void InsertLine(int line);
virtual void RemoveLine(int line);
- int LineFromPosition(int pos) const;
+ int SCI_METHOD Version() const {
+ return dvOriginal;
+ }
+
+ void SCI_METHOD SetErrorStatus(int status);
+
+ int SCI_METHOD LineFromPosition(int pos) const;
int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos);
int LenChar(int pos);
- bool InGoodUTF8(int pos, int &start, int &end);
+ bool InGoodUTF8(int pos, int &start, int &end) const;
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
+ int NextPosition(int pos, int moveDir) const;
+ bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
+ int SCI_METHOD CodePage() const;
+ bool SCI_METHOD IsDBCSLeadByte(char ch) const;
+ int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document
void ModifiedAt(int pos);
void CheckReadOnly();
bool DeleteChars(int pos, int len);
bool InsertString(int position, const char *s, int insertLength);
+ int SCI_METHOD AddData(char *data, int length);
+ void * SCI_METHOD ConvertToDocument();
int Undo();
int Redo();
bool CanUndo() { return cb.CanUndo(); }
void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); }
- const char *BufferPointer() { return cb.BufferPointer(); }
+ const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); }
+ const char *RangePointer(int position, int rangeLength) { return cb.RangePointer(position, rangeLength); }
+ int GapPosition() const { return cb.GapPosition(); }
- int GetLineIndentation(int line);
+ int SCI_METHOD GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
int GetLineIndentPosition(int line) const;
int GetColumn(int position);
+ int CountCharacters(int startPos, int endPos);
int FindColumn(int line, int column);
void Indent(bool forwards, int lineBottom, int lineTop);
- static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode);
+ static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted);
void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() { return cb.IsReadOnly(); }
void DelCharBack(int pos);
char CharAt(int position) { return cb.CharAt(position); }
- void GetCharRange(char *buffer, int position, int lengthRetrieve) {
+ void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const {
cb.GetCharRange(buffer, position, lengthRetrieve);
}
- char StyleAt(int position) { return cb.StyleAt(position); }
+ char SCI_METHOD StyleAt(int position) const { return cb.StyleAt(position); }
+ void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
+ cb.GetStyleRange(buffer, position, lengthRetrieve);
+ }
int GetMark(int line);
+ int MarkerNext(int lineStart, int mask) const;
int AddMark(int line, int markerNum);
void AddMarkSet(int line, int valueSet);
void DeleteMark(int line, int markerNum);
void DeleteMarkFromHandle(int markerHandle);
void DeleteAllMarks(int markerNum);
int LineFromHandle(int markerHandle);
- int LineStart(int line) const;
+ int SCI_METHOD LineStart(int line) const;
int LineEnd(int line) const;
int LineEndPosition(int position) const;
bool IsLineEndPosition(int position) const;
int VCHomePosition(int position) const;
- int SetLevel(int line, int level);
- int GetLevel(int line);
+ int SCI_METHOD SetLevel(int line, int level);
+ int SCI_METHOD GetLevel(int line) const;
void ClearLevels();
- int GetLastChild(int lineParent, int level=-1);
+ int GetLastChild(int lineParent, int level=-1, int lastLine=-1);
int GetFoldParent(int line);
+ void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int lastLine);
void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
int NextWordStart(int pos, int delta);
int NextWordEnd(int pos, int delta);
- int Length() const { return cb.Length(); }
+ int SCI_METHOD Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
- long FindText(int minPos, int maxPos, const char *s,
- bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, int *length);
- long FindText(int iMessage, unsigned long wParam, long lParam);
+ bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
+ long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word,
+ bool wordStart, bool regExp, int flags, int *length, CaseFolder *pcf);
const char *SubstituteByPosition(const char *text, int *length);
int LinesTotal() const;
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
+ int GetCharsOfClass(CharClassify::cc charClass, unsigned char *buffer);
void SetStylingBits(int bits);
- void StartStyling(int position, char mask);
- bool SetStyleFor(int length, char style);
- bool SetStyles(int length, const char *styles);
+ void SCI_METHOD StartStyling(int position, char mask);
+ bool SCI_METHOD SetStyleFor(int length, char style);
+ bool SCI_METHOD SetStyles(int length, const char *styles);
int GetEndStyled() { return endStyled; }
void EnsureStyledTo(int pos);
+ void LexerChanged();
int GetStyleClock() { return styleClock; }
void IncrementStyleClock();
- void DecorationFillRange(int position, int value, int fillLength);
+ void SCI_METHOD DecorationSetCurrentIndicator(int indicator) {
+ decorations.SetCurrentIndicator(indicator);
+ }
+ void SCI_METHOD DecorationFillRange(int position, int value, int fillLength);
- int SetLineState(int line, int state);
- int GetLineState(int line);
+ int SCI_METHOD SetLineState(int line, int state);
+ int SCI_METHOD GetLineState(int line) const;
int GetMaxLineState();
+ void SCI_METHOD ChangeLexerState(int start, int end);
StyledText MarginStyledText(int line);
void MarginSetStyle(int line, int style);
const WatcherWithUserData *GetWatchers() const { return watchers; }
int GetLenWatchers() const { return lenWatchers; }
+ CharClassify::cc WordCharClass(unsigned char ch);
bool IsWordPartSeparator(char ch);
int WordPartLeft(int pos);
int WordPartRight(int pos);
int BraceMatch(int position, int maxReStyle);
private:
- CharClassify::cc WordCharClass(unsigned char ch);
bool IsWordStartAt(int pos);
bool IsWordEndAt(int pos);
bool IsWordAt(int start, int end);
Document *pdoc;
bool groupNeeded;
public:
- UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
+ UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
pdoc(pdoc_), groupNeeded(groupNeeded_) {
if (groupNeeded) {
pdoc->BeginUndoAction();
virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
virtual void NotifyDeleted(Document *doc, void *userData) = 0;
virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0;
+ virtual void NotifyLexerChanged(Document *doc, void *userData) = 0;
+ virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0;
};
#ifdef SCI_NAMESPACE
+++ /dev/null
-// Scintilla source code edit control
-/** @file DocumentAccessor.cxx
- ** Rapid easy access to contents of a Scintilla.
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "SplitVector.h"
-#include "Partitioning.h"
-#include "RunStyles.h"
-#include "CellBuffer.h"
-#include "Scintilla.h"
-#include "CharClassify.h"
-#include "Decoration.h"
-#include "Document.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-DocumentAccessor::~DocumentAccessor() {
-}
-
-bool DocumentAccessor::InternalIsLeadByte(char ch) {
- if (SC_CP_UTF8 == codePage)
- // For lexing, all characters >= 0x80 are treated the
- // same so none is considered a lead byte.
- return false;
- else
- return Platform::IsDBCSLeadByte(codePage, ch);
-}
-
-void DocumentAccessor::Fill(int position) {
- if (lenDoc == -1)
- lenDoc = pdoc->Length();
- startPos = position - slopSize;
- if (startPos + bufferSize > lenDoc)
- startPos = lenDoc - bufferSize;
- if (startPos < 0)
- startPos = 0;
- endPos = startPos + bufferSize;
- if (endPos > lenDoc)
- endPos = lenDoc;
-
- pdoc->GetCharRange(buf, startPos, endPos-startPos);
- buf[endPos-startPos] = '\0';
-}
-
-bool DocumentAccessor::Match(int pos, const char *s) {
- for (int i=0; *s; i++) {
- if (*s != SafeGetCharAt(pos+i))
- return false;
- s++;
- }
- return true;
-}
-
-char DocumentAccessor::StyleAt(int position) {
- // Mask off all bits which aren't in the 'mask'.
- return static_cast<char>(pdoc->StyleAt(position) & mask);
-}
-
-int DocumentAccessor::GetLine(int position) {
- return pdoc->LineFromPosition(position);
-}
-
-int DocumentAccessor::LineStart(int line) {
- return pdoc->LineStart(line);
-}
-
-int DocumentAccessor::LevelAt(int line) {
- return pdoc->GetLevel(line);
-}
-
-int DocumentAccessor::Length() {
- if (lenDoc == -1)
- lenDoc = pdoc->Length();
- return lenDoc;
-}
-
-int DocumentAccessor::GetLineState(int line) {
- return pdoc->GetLineState(line);
-}
-
-int DocumentAccessor::SetLineState(int line, int state) {
- return pdoc->SetLineState(line, state);
-}
-
-void DocumentAccessor::StartAt(unsigned int start, char chMask) {
- // Store the mask specified for use with StyleAt.
- mask = chMask;
- pdoc->StartStyling(start, chMask);
- startPosStyling = start;
-}
-
-void DocumentAccessor::StartSegment(unsigned int pos) {
- startSeg = pos;
-}
-
-void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {
- // Only perform styling if non empty range
- if (pos != startSeg - 1) {
- PLATFORM_ASSERT(pos >= startSeg);
- if (pos < startSeg) {
- return;
- }
-
- if (validLen + (pos - startSeg + 1) >= bufferSize)
- Flush();
- if (validLen + (pos - startSeg + 1) >= bufferSize) {
- // Too big for buffer so send directly
- pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
- } else {
- if (chAttr != chWhile)
- chFlags = 0;
- chAttr |= chFlags;
- for (unsigned int i = startSeg; i <= pos; i++) {
- PLATFORM_ASSERT((startPosStyling + validLen) < Length());
- styleBuf[validLen++] = static_cast<char>(chAttr);
- }
- }
- }
- startSeg = pos+1;
-}
-
-void DocumentAccessor::SetLevel(int line, int level) {
- pdoc->SetLevel(line, level);
-}
-
-void DocumentAccessor::Flush() {
- startPos = extremePosition;
- lenDoc = -1;
- if (validLen > 0) {
- pdoc->SetStyles(validLen, styleBuf);
- startPosStyling += validLen;
- validLen = 0;
- }
-}
-
-int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
- int end = Length();
- int spaceFlags = 0;
-
- // Determines the indentation level of the current line and also checks for consistent
- // indentation compared to the previous line.
- // Indentation is judged consistent when the indentation whitespace of each line lines
- // the same or the indentation of one line is a prefix of the other.
-
- int pos = LineStart(line);
- char ch = (*this)[pos];
- int indent = 0;
- bool inPrevPrefix = line > 0;
- int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
- while ((ch == ' ' || ch == '\t') && (pos < end)) {
- if (inPrevPrefix) {
- char chPrev = (*this)[posPrev++];
- if (chPrev == ' ' || chPrev == '\t') {
- if (chPrev != ch)
- spaceFlags |= wsInconsistent;
- } else {
- inPrevPrefix = false;
- }
- }
- if (ch == ' ') {
- spaceFlags |= wsSpace;
- indent++;
- } else { // Tab
- spaceFlags |= wsTab;
- if (spaceFlags & wsSpace)
- spaceFlags |= wsSpaceTab;
- indent = (indent / 8 + 1) * 8;
- }
- ch = (*this)[++pos];
- }
-
- *flags = spaceFlags;
- indent += SC_FOLDLEVELBASE;
- // if completely empty line or the start of a comment...
- if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
- (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
- return indent | SC_FOLDLEVELWHITEFLAG;
- else
- return indent;
-}
-
-void DocumentAccessor::IndicatorFill(int start, int end, int indicator, int value) {
- pdoc->decorations.SetCurrentIndicator(indicator);
- pdoc->DecorationFillRange(start, value, end - start);
-}
+++ /dev/null
-// Scintilla source code edit control
-/** @file DocumentAccessor.h
- ** Implementation of BufferAccess and StylingAccess on a Scintilla
- ** rapid easy access to contents of a Scintilla.
- **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-class Document;
-
-/**
- */
-
-class DocumentAccessor : public Accessor {
- // Private so DocumentAccessor objects can not be copied
- DocumentAccessor(const DocumentAccessor &source);
- DocumentAccessor &operator=(const DocumentAccessor &);
-
-protected:
- Document *pdoc;
- PropertyGet &props;
- WindowID id;
- int lenDoc;
-
- char styleBuf[bufferSize];
- int validLen;
- char chFlags;
- char chWhile;
- unsigned int startSeg;
- int startPosStyling;
- int mask;
-
- bool InternalIsLeadByte(char ch);
- void Fill(int position);
-
-public:
- DocumentAccessor(Document *pdoc_, PropertyGet &props_, WindowID id_=0) :
- Accessor(), pdoc(pdoc_), props(props_), id(id_),
- lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
- startSeg(0), startPosStyling(0),
- mask(127) { // Initialize the mask to be big enough for any lexer.
- }
- ~DocumentAccessor();
- bool Match(int pos, const char *s);
- char StyleAt(int position);
- int GetLine(int position);
- int LineStart(int line);
- int LevelAt(int line);
- int Length();
- void Flush();
- int GetLineState(int line);
- int SetLineState(int line, int state);
- int GetPropertyInt(const char *key, int defaultValue=0) {
- return props.GetInt(key, defaultValue);
- }
- char *GetProperties() {
- return props.ToString();
- }
- WindowID GetWindow() { return id; }
-
- void StartAt(unsigned int start, char chMask=31);
- void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
- unsigned int GetStartSegment() { return startSeg; }
- void StartSegment(unsigned int pos);
- void ColourTo(unsigned int pos, int chAttr);
- void SetLevel(int line, int level);
- int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
- void IndicatorFill(int start, int end, int indicator, int value);
-};
-
-#ifdef SCI_NAMESPACE
-}
-#endif
/** @file Editor.cxx
** Main code for the edit control.
**/
-// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2011 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 <ctype.h>
+#include <assert.h>
#include <string>
-
-// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
-// FindText to FindTextA which makes calls here to Document::FindText fail.
-#ifdef __BORLANDC__
-#ifdef FindText
-#undef FindText
-#endif
-#endif
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <memory>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
#include "SplitVector.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
+#include "UniConversion.h"
#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
return whether this modification represents an operation that
may reasonably be deferred (not done now OR [possibly] at all)
*/
-static bool CanDeferToLastStep(const DocModification& mh) {
+static bool CanDeferToLastStep(const DocModification &mh) {
if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE))
return true; // CAN skip
if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)))
return false; // PRESUMABLY must do
}
-static bool CanEliminate(const DocModification& mh) {
+static bool CanEliminate(const DocModification &mh) {
return
(mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0;
}
return whether this modification represents the FINAL step
in a [possibly lengthy] multi-step Undo/Redo sequence
*/
-static bool IsLastStep(const DocModification& mh) {
+static bool IsLastStep(const DocModification &mh) {
return
(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0
&& (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
return ch >= 0 && ch < ' ';
}
+static inline bool IsAllSpacesOrTabs(char *s, unsigned int len) {
+ for (unsigned int i = 0; i < len; i++) {
+ // This is safe because IsSpaceOrTab() will return false for null terminators
+ if (!IsSpaceOrTab(s[i]))
+ return false;
+ }
+ return true;
+}
+
Editor::Editor() {
ctrlID = 0;
stylesValid = false;
-
+ technology = SC_TECHNOLOGY_DEFAULT;
+
printMagnification = 0;
printColourMode = SC_PRINT_NORMAL;
printWrapState = eWrapWord;
dropWentOutside = false;
posDrag = SelectionPosition(invalidPosition);
posDrop = SelectionPosition(invalidPosition);
+ hotSpotClickPos = INVALID_POSITION;
selectionType = selChar;
lastXChosen = 0;
- lineAnchor = 0;
+ lineAnchorPos = 0;
originalAnchorPos = 0;
+ wordSelectAnchorStartPos = 0;
+ wordSelectAnchorEndPos = 0;
+ wordSelectInitialCaretPos = -1;
primarySelection = true;
caretYPolicy = CARET_EVEN;
caretYSlop = 0;
+
+ visiblePolicy = 0;
+ visibleSlop = 0;
searchAnchor = 0;
lineWidthMaxSeen = 0;
verticalScrollBarVisible = true;
endAtLastLine = true;
- caretSticky = false;
+ caretSticky = SC_CARETSTICKY_OFF;
+ marginOptions = SC_MARGINOPTION_NONE;
multipleSelection = false;
additionalSelectionTyping = false;
+ multiPasteMode = SC_MULTIPASTE_ONCE;
additionalCaretsBlink = true;
additionalCaretsVisible = true;
virtualSpaceOptions = SCVS_NONE;
- pixmapLine = Surface::Allocate();
- pixmapSelMargin = Surface::Allocate();
- pixmapSelPattern = Surface::Allocate();
- pixmapIndentGuide = Surface::Allocate();
- pixmapIndentGuideHighlight = Surface::Allocate();
+ pixmapLine = 0;
+ pixmapSelMargin = 0;
+ pixmapSelPattern = 0;
+ pixmapIndentGuide = 0;
+ pixmapIndentGuideHighlight = 0;
targetStart = 0;
targetEnd = 0;
lengthForEncode = -1;
- needUpdateUI = true;
+ needUpdateUI = 0;
+ ContainerNeedsUpdate(SC_UPDATE_CONTENT);
braces[0] = invalidPosition;
braces[1] = invalidPosition;
bracesMatchStyle = STYLE_BRACEBAD;
theEdge = 0;
paintState = notPainting;
+ willRedrawAll = false;
modEventMask = SC_MODEVENTMASKALL;
wrapVisualFlagsLocation = 0;
wrapVisualStartIndent = 0;
wrapIndentMode = SC_WRAPINDENT_FIXED;
- wrapAddIndent = 0;
convertPastes = true;
pdoc->RemoveWatcher(this, 0);
pdoc->Release();
pdoc = 0;
- DropGraphics();
- delete pixmapLine;
- delete pixmapSelMargin;
- delete pixmapSelPattern;
- delete pixmapIndentGuide;
- delete pixmapIndentGuideHighlight;
+ DropGraphics(true);
}
void Editor::Finalise() {
CancelModes();
}
-void Editor::DropGraphics() {
- pixmapLine->Release();
- pixmapSelMargin->Release();
- pixmapSelPattern->Release();
- pixmapIndentGuide->Release();
- pixmapIndentGuideHighlight->Release();
+void Editor::DropGraphics(bool freeObjects) {
+ if (freeObjects) {
+ delete pixmapLine;
+ pixmapLine = 0;
+ delete pixmapSelMargin;
+ pixmapSelMargin = 0;
+ delete pixmapSelPattern;
+ pixmapSelPattern = 0;
+ delete pixmapIndentGuide;
+ pixmapIndentGuide = 0;
+ delete pixmapIndentGuideHighlight;
+ pixmapIndentGuideHighlight = 0;
+ } else {
+ if (pixmapLine)
+ pixmapLine->Release();
+ if (pixmapSelMargin)
+ pixmapSelMargin->Release();
+ if (pixmapSelPattern)
+ pixmapSelPattern->Release();
+ if (pixmapIndentGuide)
+ pixmapIndentGuide->Release();
+ if (pixmapIndentGuideHighlight)
+ pixmapIndentGuideHighlight->Release();
+ }
+}
+
+void Editor::AllocateGraphics() {
+ if (!pixmapLine)
+ pixmapLine = Surface::Allocate(technology);
+ if (!pixmapSelMargin)
+ pixmapSelMargin = Surface::Allocate(technology);
+ if (!pixmapSelPattern)
+ pixmapSelPattern = Surface::Allocate(technology);
+ if (!pixmapIndentGuide)
+ pixmapIndentGuide = Surface::Allocate(technology);
+ if (!pixmapIndentGuideHighlight)
+ pixmapIndentGuideHighlight = Surface::Allocate(technology);
}
void Editor::InvalidateStyleData() {
stylesValid = false;
- DropGraphics();
- palette.Release();
+ vs.technology = technology;
+ DropGraphics(false);
+ AllocateGraphics();
llc.Invalidate(LineLayout::llInvalid);
posCache.Clear();
}
Redraw();
}
-void Editor::RefreshColourPalette(Palette &pal, bool want) {
- vs.RefreshColourPalette(pal, want);
-}
-
void Editor::RefreshStyleData() {
if (!stylesValid) {
stylesValid = true;
AutoSurface surface(this);
if (surface) {
vs.Refresh(*surface);
- RefreshColourPalette(palette, true);
- palette.Allocate(wMain);
- RefreshColourPalette(palette, false);
- }
- if (wrapIndentMode == SC_WRAPINDENT_INDENT) {
- wrapAddIndent = pdoc->IndentSize() * vs.spaceWidth;
- } else if (wrapIndentMode == SC_WRAPINDENT_SAME) {
- wrapAddIndent = 0;
- } else { //SC_WRAPINDENT_FIXED
- wrapAddIndent = wrapVisualStartIndent * vs.aveCharWidth;
- if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (wrapAddIndent <= 0))
- wrapAddIndent = vs.aveCharWidth; // must indent to show start visual
}
SetScrollBars();
SetRectangularRange();
}
pt.x += vs.fixedColumnWidth - xOffset;
}
- pt.x += pos.VirtualSpace() * static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+ pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth;
return pt;
}
}
void Editor::SetTopLine(int topLineNew) {
- topLine = topLineNew;
+ if (topLine != topLineNew) {
+ topLine = topLineNew;
+ ContainerNeedsUpdate(SC_UPDATE_V_SCROLL);
+ }
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
}
pt.x = pt.x - vs.fixedColumnWidth + xOffset;
int visibleLine = pt.y / vs.lineHeight + topLine;
if (pt.y < 0) { // Division rounds towards 0
- visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
+ visibleLine = (static_cast<int>(pt.y) - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
}
if (!canReturnInvalid && (visibleLine < 0))
visibleLine = 0;
if (subLine < ll->lines) {
int lineStart = ll->LineStart(subLine);
int lineEnd = ll->LineLastVisible(subLine);
- int subLineStart = ll->positions[lineStart];
+ XYPOSITION subLineStart = ll->positions[lineStart];
if (ll->wrapIndent != 0) {
if (lineStart != 0) // Wrapped
i++;
}
if (virtualSpace) {
- const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+ const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth;
int spaceOffset = (pt.x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) /
spaceWidth;
return SelectionPosition(lineEnd + posLineStart, spaceOffset);
return SPositionFromLocation(pt, canReturnInvalid, charPosition, false).Position();
}
-/**
- * Find the document position corresponding to an x coordinate on a particular document line.
- * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
- */
-int Editor::PositionFromLineX(int lineDoc, int x) {
- RefreshStyleData();
- if (lineDoc >= pdoc->LinesTotal())
- return pdoc->Length();
- //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
- AutoSurface surface(this);
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
- int retVal = 0;
- if (surface && ll) {
- unsigned int posLineStart = pdoc->LineStart(lineDoc);
- LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
- retVal = ll->numCharsBeforeEOL + posLineStart;
- int subLine = 0;
- int lineStart = ll->LineStart(subLine);
- int lineEnd = ll->LineLastVisible(subLine);
- int subLineStart = ll->positions[lineStart];
-
- if (ll->wrapIndent != 0) {
- if (lineStart != 0) // Wrapped
- x -= ll->wrapIndent;
- }
- int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
- while (i < lineEnd) {
- if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
- retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
- break;
- }
- i++;
- }
- }
- return retVal;
-}
-
/**
* Find the document position corresponding to an x coordinate on a particular document line.
* Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
int subLine = 0;
int lineStart = ll->LineStart(subLine);
int lineEnd = ll->LineLastVisible(subLine);
- int subLineStart = ll->positions[lineStart];
+ XYPOSITION subLineStart = ll->positions[lineStart];
+ XYPOSITION newX = x;
if (ll->wrapIndent != 0) {
if (lineStart != 0) // Wrapped
- x -= ll->wrapIndent;
+ newX -= ll->wrapIndent;
}
- int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
+ int i = ll->FindBefore(newX + subLineStart, lineStart, lineEnd);
while (i < lineEnd) {
- if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+ if ((newX + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
return SelectionPosition(retVal);
}
i++;
}
- const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
- int spaceOffset = (x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth;
+ const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth;
+ int spaceOffset = (newX + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth;
return SelectionPosition(lineEnd + posLineStart, spaceOffset);
}
return SelectionPosition(retVal);
}
+int Editor::PositionFromLineX(int lineDoc, int x) {
+ return SPositionFromLineX(lineDoc, x).Position();
+}
+
/**
* If painting then abandon the painting because a wider redraw is needed.
* @return true if calling code should stop drawing.
//wMain.InvalidateAll();
}
-void Editor::RedrawSelMargin(int line) {
+void Editor::RedrawSelMargin(int line, bool allAfter) {
if (!AbandonPaint()) {
if (vs.maskInLine) {
Redraw();
if (line != -1) {
int position = pdoc->LineStart(line);
PRectangle rcLine = RectangleFromRange(position, position);
+
+ // Inflate line rectangle if there are image markers with height larger than line height
+ if (vs.largestMarkerHeight > vs.lineHeight) {
+ int delta = (vs.largestMarkerHeight - vs.lineHeight + 1) / 2;
+ rcLine.top -= delta;
+ rcLine.bottom += delta;
+ if (rcLine.top < rcSelMargin.top)
+ rcLine.top = rcSelMargin.top;
+ if (rcLine.bottom > rcSelMargin.bottom)
+ rcLine.bottom = rcSelMargin.bottom;
+ }
+
rcSelMargin.top = rcLine.top;
- rcSelMargin.bottom = rcLine.bottom;
+ if (!allAfter)
+ rcSelMargin.bottom = rcLine.bottom;
}
wMain.InvalidateRectangle(rcSelMargin);
}
int maxLine = cs.DisplayFromDoc(lineDocMax) + cs.GetHeight(lineDocMax) - 1;
PRectangle rcClient = GetTextRectangle();
PRectangle rc;
- rc.left = vs.fixedColumnWidth;
+ const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0;
+ rc.left = vs.fixedColumnWidth - leftTextOverlap;
rc.top = (minLine - topLine) * vs.lineHeight;
if (rc.top < 0)
rc.top = 0;
if (line == lineAnchorRect)
sel.SetSelection(range);
else
- sel.AddSelection(range);
+ sel.AddSelectionWithoutTrim(range);
}
}
}
lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
}
}
- needUpdateUI = true;
+ ContainerNeedsUpdate(SC_UPDATE_SELECTION);
InvalidateRange(firstAffected, lastAffected);
}
void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
- SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_),
- ClampPositionIntoDocument(anchor_));
+ currentPos_ = ClampPositionIntoDocument(currentPos_);
+ anchor_ = ClampPositionIntoDocument(anchor_);
+ int currentLine = pdoc->LineFromPosition(currentPos_.Position());
+ /* For Line selection - ensure the anchor and caret are always
+ at the beginning and end of the region lines. */
+ if (sel.selType == Selection::selLines) {
+ if (currentPos_ > anchor_) {
+ anchor_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(anchor_.Position())));
+ currentPos_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(currentPos_.Position())));
+ } else {
+ currentPos_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(currentPos_.Position())));
+ anchor_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(anchor_.Position())));
+ }
+ }
+ SelectionRange rangeNew(currentPos_, anchor_);
if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
InvalidateSelection(rangeNew);
}
sel.RangeMain() = rangeNew;
SetRectangularRange();
ClaimSelection();
+
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
+ }
}
void Editor::SetSelection(int currentPos_, int anchor_) {
// Just move the caret on the main selection
void Editor::SetSelection(SelectionPosition currentPos_) {
currentPos_ = ClampPositionIntoDocument(currentPos_);
+ int currentLine = pdoc->LineFromPosition(currentPos_.Position());
if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
InvalidateSelection(SelectionRange(currentPos_));
}
SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
}
ClaimSelection();
+
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
+ }
}
void Editor::SetSelection(int currentPos_) {
}
void Editor::SetEmptySelection(SelectionPosition currentPos_) {
+ int currentLine = pdoc->LineFromPosition(currentPos_.Position());
SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
InvalidateSelection(rangeNew);
SetRectangularRange();
ClaimSelection();
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
+ }
}
void Editor::SetEmptySelection(int currentPos_) {
}
int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) {
+ bool simpleCaret = (sel.Count() == 1) && sel.Empty();
+ SelectionPosition spCaret = sel.Last();
+
int delta = newPos.Position() - sel.MainCaret();
newPos = ClampPositionIntoDocument(newPos);
newPos = MovePositionOutsideChar(newPos, delta);
+ if (!multipleSelection && sel.IsRectangular() && (selt == Selection::selStream)) {
+ // Can't turn into multiple selection so clear additional selections
+ InvalidateSelection(SelectionRange(newPos), true);
+ SelectionRange rangeMain = sel.RangeMain();
+ sel.SetSelection(rangeMain);
+ }
if (!sel.IsRectangular() && (selt == Selection::selRectangle)) {
// Switching to rectangular
SelectionRange rangeMain = sel.RangeMain();
SetEmptySelection(newPos);
}
ShowCaretAtCurrentPosition();
+
+ int currentLine = pdoc->LineFromPosition(newPos.Position());
if (ensureVisible) {
- EnsureCaretVisible();
+ // In case in need of wrapping to ensure DisplayFromDoc works.
+ if (currentLine >= wrapStart)
+ WrapLines(true, -1);
+ XYScrollPosition newXY = XYScrollToMakeVisible(true, true, true);
+ if (simpleCaret && (newXY.xOffset == xOffset)) {
+ // simple vertical scroll then invalidate
+ ScrollTo(newXY.topLine);
+ InvalidateSelection(SelectionRange(spCaret), true);
+ } else {
+ SetXYScroll(newXY);
+ }
+ }
+
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
}
return 0;
}
*/
void Editor::SetLastXChosen() {
Point pt = PointMainCaret();
- lastXChosen = pt.x;
+ lastXChosen = pt.x + xOffset;
}
void Editor::ScrollTo(int line, bool moveThumb) {
int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());
if (topLineNew != topLine) {
// Try to optimise small scrolls
+#ifndef UNDER_CE
int linesToMove = topLine - topLineNew;
+ bool performBlit = (abs(linesToMove) <= 10) && (paintState == notPainting);
+ willRedrawAll = !performBlit;
+#endif
SetTopLine(topLineNew);
- ShowCaretAtCurrentPosition();
- // Perform redraw rather than scroll if many lines would be redrawn anyway.
+ // Optimize by styling the view as this will invalidate any needed area
+ // which could abort the initial paint if discovered later.
+ StyleToPositionInView(PositionAfterArea(GetClientRectangle()));
#ifndef UNDER_CE
- if ((abs(linesToMove) <= 10) && (paintState == notPainting)) {
+ // Perform redraw rather than scroll if many lines would be redrawn anyway.
+ if (performBlit) {
ScrollText(linesToMove);
} else {
Redraw();
}
+ willRedrawAll = false;
#else
Redraw();
#endif
xPos = 0;
if ((wrapState == eWrapNone) && (xOffset != xPos)) {
xOffset = xPos;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
SetHorizontalScrollPos();
RedrawRect(GetClientRectangle());
}
}
+void Editor::VerticalCentreCaret() {
+ int lineDoc = pdoc->LineFromPosition(sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret());
+ int lineDisplay = cs.DisplayFromDoc(lineDoc);
+ int newTop = lineDisplay - (LinesOnScreen() / 2);
+ if (topLine != newTop) {
+ SetTopLine(newTop > 0 ? newTop : 0);
+ RedrawRect(GetClientRectangle());
+ }
+}
+
+// Avoid 64 bit compiler warnings.
+// Scintilla does not support text buffers larger than 2**31
+static int istrlen(const char *s) {
+ return static_cast<int>(strlen(s));
+}
+
+void Editor::MoveSelectedLines(int lineDelta) {
+
+ // if selection doesn't start at the beginning of the line, set the new start
+ int selectionStart = SelectionStart().Position();
+ int startLine = pdoc->LineFromPosition(selectionStart);
+ int beginningOfStartLine = pdoc->LineStart(startLine);
+ selectionStart = beginningOfStartLine;
+
+ // if selection doesn't end at the beginning of a line greater than that of the start,
+ // then set it at the beginning of the next one
+ int selectionEnd = SelectionEnd().Position();
+ int endLine = pdoc->LineFromPosition(selectionEnd);
+ int beginningOfEndLine = pdoc->LineStart(endLine);
+ bool appendEol = false;
+ if (selectionEnd > beginningOfEndLine
+ || selectionStart == selectionEnd) {
+ selectionEnd = pdoc->LineStart(endLine + 1);
+ appendEol = (selectionEnd == pdoc->Length() && pdoc->LineFromPosition(selectionEnd) == endLine);
+ }
+
+ // if there's nowhere for the selection to move
+ // (i.e. at the beginning going up or at the end going down),
+ // stop it right there!
+ if ((selectionStart == 0 && lineDelta < 0)
+ || (selectionEnd == pdoc->Length() && lineDelta > 0)
+ || selectionStart == selectionEnd) {
+ return;
+ }
+
+ UndoGroup ug(pdoc);
+
+ if (lineDelta > 0 && selectionEnd == pdoc->LineStart(pdoc->LinesTotal() - 1)) {
+ SetSelection(pdoc->MovePositionOutsideChar(selectionEnd - 1, -1), selectionEnd);
+ ClearSelection();
+ selectionEnd = CurrentPosition();
+ }
+ SetSelection(selectionStart, selectionEnd);
+
+ SelectionText selectedText;
+ CopySelectionRange(&selectedText);
+
+ int selectionLength = SelectionRange(selectionStart, selectionEnd).Length();
+ Point currentLocation = LocationFromPosition(CurrentPosition());
+ int currentLine = LineFromLocation(currentLocation);
+
+ if (appendEol)
+ SetSelection(pdoc->MovePositionOutsideChar(selectionStart - 1, -1), selectionEnd);
+ ClearSelection();
+
+ const char *eol = StringFromEOLMode(pdoc->eolMode);
+ if (currentLine + lineDelta >= pdoc->LinesTotal())
+ pdoc->InsertCString(pdoc->Length(), eol);
+ GoToLine(currentLine + lineDelta);
+
+ pdoc->InsertCString(CurrentPosition(), selectedText.s);
+ if (appendEol) {
+ pdoc->InsertCString(CurrentPosition() + selectionLength, eol);
+ selectionLength += istrlen(eol);
+ }
+ SetSelection(CurrentPosition(), CurrentPosition() + selectionLength);
+}
+
+void Editor::MoveSelectedLinesUp() {
+ MoveSelectedLines(-1);
+}
+
+void Editor::MoveSelectedLinesDown() {
+ MoveSelectedLines(1);
+}
+
void Editor::MoveCaretInsideView(bool ensureVisible) {
PRectangle rcClient = GetTextRectangle();
Point pt = PointMainCaret();
if (pt.y < rcClient.top) {
MovePositionTo(SPositionFromLocation(
- Point(lastXChosen, rcClient.top)),
+ Point(lastXChosen - xOffset, rcClient.top),
+ false, false, UserVirtualSpace()),
Selection::noSel, ensureVisible);
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
MovePositionTo(SPositionFromLocation(
- Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
+ Point(lastXChosen - xOffset, rcClient.top + yOfLastLineFullyDisplayed),
+ false, false, UserVirtualSpace()),
Selection::noSel, ensureVisible);
}
}
1 | 1 | 0 | 1 | No, kept out of UZ | moved by one position
1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin
*/
-void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
- //Platform::DebugPrintf("EnsureCaretVisible %d %s\n", xOffset, useMargin ? " margin" : " ");
+
+Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz) {
PRectangle rcClient = GetTextRectangle();
- //int rcClientFullWidth = rcClient.Width();
- SelectionPosition posCaret = sel.RangeMain().caret;
- if (posDrag.IsValid()) {
- posCaret = posDrag;
- }
- Point pt = LocationFromPosition(posCaret);
- Point ptBottomCaret = pt;
- ptBottomCaret.y += vs.lineHeight - 1;
- int lineCaret = DisplayFromPosition(posCaret.Position());
- bool bSlop, bStrict, bJump, bEven;
+ const SelectionPosition posCaret = posDrag.IsValid() ? posDrag : sel.RangeMain().caret;
+ const Point pt = LocationFromPosition(posCaret);
+ const Point ptBottomCaret(pt.x, pt.y + vs.lineHeight - 1);
+ const int lineCaret = DisplayFromPosition(posCaret.Position());
+
+ XYScrollPosition newXY(xOffset, topLine);
// Vertical positioning
- if (vert && (pt.y < rcClient.top || ptBottomCaret.y > rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) {
- int linesOnScreen = LinesOnScreen();
- int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
- int newTopLine = topLine;
- bSlop = (caretYPolicy & CARET_SLOP) != 0;
- bStrict = (caretYPolicy & CARET_STRICT) != 0;
- bJump = (caretYPolicy & CARET_JUMPS) != 0;
- bEven = (caretYPolicy & CARET_EVEN) != 0;
+ if (vert && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) {
+ const int linesOnScreen = LinesOnScreen();
+ const int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
+ const bool bSlop = (caretYPolicy & CARET_SLOP) != 0;
+ const bool bStrict = (caretYPolicy & CARET_STRICT) != 0;
+ const bool bJump = (caretYPolicy & CARET_JUMPS) != 0;
+ const bool bEven = (caretYPolicy & CARET_EVEN) != 0;
// It should be possible to scroll the window to show the caret,
// but this fails to remove the caret on GTK+
}
if (lineCaret < topLine + yMarginT) {
// Caret goes too high
- newTopLine = lineCaret - yMoveT;
+ newXY.topLine = lineCaret - yMoveT;
} else if (lineCaret > topLine + linesOnScreen - 1 - yMarginB) {
// Caret goes too low
- newTopLine = lineCaret - linesOnScreen + 1 + yMoveB;
+ newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB;
}
} else { // Not strict
yMoveT = bJump ? caretYSlop * 3 : caretYSlop;
}
if (lineCaret < topLine) {
// Caret goes too high
- newTopLine = lineCaret - yMoveT;
+ newXY.topLine = lineCaret - yMoveT;
} else if (lineCaret > topLine + linesOnScreen - 1) {
// Caret goes too low
- newTopLine = lineCaret - linesOnScreen + 1 + yMoveB;
+ newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB;
}
}
} else { // No slop
// Minimal move
if (lineCaret < topLine) {
// Caret goes too high
- newTopLine = lineCaret;
+ newXY.topLine = lineCaret;
} else if (lineCaret > topLine + linesOnScreen - 1) {
// Caret goes too low
if (bEven) {
- newTopLine = lineCaret - linesOnScreen + 1;
+ newXY.topLine = lineCaret - linesOnScreen + 1;
} else {
- newTopLine = lineCaret;
+ newXY.topLine = lineCaret;
}
}
} else { // Strict or going out of display
if (bEven) {
// Always center caret
- newTopLine = lineCaret - halfScreen;
+ newXY.topLine = lineCaret - halfScreen;
} else {
// Always put caret on top of display
- newTopLine = lineCaret;
+ newXY.topLine = lineCaret;
}
}
}
- newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
- if (newTopLine != topLine) {
- Redraw();
- SetTopLine(newTopLine);
- SetVerticalScrollPos();
- }
+ newXY.topLine = Platform::Clamp(newXY.topLine, 0, MaxScrollPos());
}
// Horizontal positioning
if (horiz && (wrapState == eWrapNone)) {
- int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
- int xOffsetNew = xOffset;
- bSlop = (caretXPolicy & CARET_SLOP) != 0;
- bStrict = (caretXPolicy & CARET_STRICT) != 0;
- bJump = (caretXPolicy & CARET_JUMPS) != 0;
- bEven = (caretXPolicy & CARET_EVEN) != 0;
+ const int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
+ const bool bSlop = (caretXPolicy & CARET_SLOP) != 0;
+ const bool bStrict = (caretXPolicy & CARET_STRICT) != 0;
+ const bool bJump = (caretXPolicy & CARET_JUMPS) != 0;
+ const bool bEven = (caretXPolicy & CARET_EVEN) != 0;
if (bSlop) { // A margin is defined
int xMoveL, xMoveR;
if (pt.x < rcClient.left + xMarginL) {
// Caret is on the left of the display
if (bJump && bEven) {
- xOffsetNew -= xMoveL;
+ newXY.xOffset -= xMoveL;
} else {
// Move just enough to allow to display the caret
- xOffsetNew -= (rcClient.left + xMarginL) - pt.x;
+ newXY.xOffset -= (rcClient.left + xMarginL) - pt.x;
}
} else if (pt.x >= rcClient.right - xMarginR) {
// Caret is on the right of the display
if (bJump && bEven) {
- xOffsetNew += xMoveR;
+ newXY.xOffset += xMoveR;
} else {
// Move just enough to allow to display the caret
- xOffsetNew += pt.x - (rcClient.right - xMarginR) + 1;
+ newXY.xOffset += pt.x - (rcClient.right - xMarginR) + 1;
}
}
} else { // Not strict
}
if (pt.x < rcClient.left) {
// Caret is on the left of the display
- xOffsetNew -= xMoveL;
+ newXY.xOffset -= xMoveL;
} else if (pt.x >= rcClient.right) {
// Caret is on the right of the display
- xOffsetNew += xMoveR;
+ newXY.xOffset += xMoveR;
}
}
} else { // No slop
// Strict or going out of display
if (bEven) {
// Center caret
- xOffsetNew += pt.x - rcClient.left - halfScreen;
+ newXY.xOffset += pt.x - rcClient.left - halfScreen;
} else {
// Put caret on right
- xOffsetNew += pt.x - rcClient.right + 1;
+ newXY.xOffset += pt.x - rcClient.right + 1;
}
} else {
// Move just enough to allow to display the caret
if (pt.x < rcClient.left) {
// Caret is on the left of the display
if (bEven) {
- xOffsetNew -= rcClient.left - pt.x;
+ newXY.xOffset -= rcClient.left - pt.x;
} else {
- xOffsetNew += pt.x - rcClient.right + 1;
+ newXY.xOffset += pt.x - rcClient.right + 1;
}
} else if (pt.x >= rcClient.right) {
// Caret is on the right of the display
- xOffsetNew += pt.x - rcClient.right + 1;
+ newXY.xOffset += pt.x - rcClient.right + 1;
}
}
}
// In case of a jump (find result) largely out of display, adjust the offset to display the caret
- if (pt.x + xOffset < rcClient.left + xOffsetNew) {
- xOffsetNew = pt.x + xOffset - rcClient.left;
- } else if (pt.x + xOffset >= rcClient.right + xOffsetNew) {
- xOffsetNew = pt.x + xOffset - rcClient.right + 1;
+ if (pt.x + xOffset < rcClient.left + newXY.xOffset) {
+ newXY.xOffset = pt.x + xOffset - rcClient.left;
+ } else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) {
+ newXY.xOffset = pt.x + xOffset - rcClient.right + 1;
if (vs.caretStyle == CARETSTYLE_BLOCK) {
// Ensure we can see a good portion of the block caret
- xOffsetNew += vs.aveCharWidth;
+ newXY.xOffset += static_cast<int>(vs.aveCharWidth);
}
}
- if (xOffsetNew < 0) {
- xOffsetNew = 0;
+ if (newXY.xOffset < 0) {
+ newXY.xOffset = 0;
+ }
+ }
+
+ return newXY;
+}
+
+void Editor::SetXYScroll(XYScrollPosition newXY) {
+ if ((newXY.topLine != topLine) || (newXY.xOffset != xOffset)) {
+ if (newXY.topLine != topLine) {
+ SetTopLine(newXY.topLine);
+ SetVerticalScrollPos();
}
- if (xOffset != xOffsetNew) {
- xOffset = xOffsetNew;
- if (xOffsetNew > 0) {
+ if (newXY.xOffset != xOffset) {
+ xOffset = newXY.xOffset;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
+ if (newXY.xOffset > 0) {
PRectangle rcText = GetTextRectangle();
if (horizontalScrollBarVisible &&
- rcText.Width() + xOffset > scrollWidth) {
+ rcText.Width() + xOffset > scrollWidth) {
scrollWidth = xOffset + rcText.Width();
SetScrollBars();
}
}
SetHorizontalScrollPos();
- Redraw();
}
+ Redraw();
+ UpdateSystemCaret();
}
- UpdateSystemCaret();
+}
+
+void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
+ SetXYScroll(XYScrollToMakeVisible(useMargin, vert, horiz));
}
void Editor::ShowCaretAtCurrentPosition() {
bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
// If there are any pending wraps, do them during idle if possible.
int linesInOneCall = LinesOnScreen() + 100;
+ if (priorityWrapLineStart >= 0) {
+ // Using DocFromDisplay() here may result in chicken and egg problem in certain corner cases,
+ // which will hopefully be handled by added 100 lines. If some lines are still missed, idle wrapping will catch on.
+ int docLinesInOneCall = cs.DocFromDisplay(topLine + LinesOnScreen() + 100) - cs.DocFromDisplay(topLine);
+ linesInOneCall = Platform::Maximum(linesInOneCall, docLinesInOneCall);
+ }
if (wrapState != eWrapNone) {
if (wrapStart < wrapEnd) {
if (!SetIdle(true)) {
rcTextArea.left = vs.fixedColumnWidth;
rcTextArea.right -= vs.rightMarginWidth;
wrapWidth = rcTextArea.Width();
- // Ensure all of the document is styled.
- pdoc->EnsureStyledTo(pdoc->Length());
RefreshStyleData();
AutoSurface surface(this);
if (surface) {
lastLineToWrap = wrapEnd;
} // else do a fullWrap.
+ // Ensure all lines being wrapped are styled.
+ pdoc->EnsureStyledTo(pdoc->LineEnd(lastLineToWrap));
+
// Platform::DebugPrintf("Wraplines: full = %d, priorityStart = %d (wrapping: %d to %d)\n", fullWrap, priorityWrapLineStart, lineToWrap, lastLineToWrap);
// Platform::DebugPrintf("Pending wraps: %d to %d\n", wrapStart, wrapEnd);
while (lineToWrap < lastLineToWrap) {
unsigned int posLineStart = pdoc->LineStart(line);
LayoutLine(line, surface, vs, ll, pixelWidth);
for (int subLine = 1; subLine < ll->lines; subLine++) {
- pdoc->InsertCString(posLineStart + (subLine - 1) * strlen(eol) +
- ll->LineStart(subLine), eol);
+ pdoc->InsertCString(
+ static_cast<int>(posLineStart + (subLine - 1) * strlen(eol) +
+ ll->LineStart(subLine)),
+ eol);
targetEnd += static_cast<int>(strlen(eol));
}
}
return markerCheck;
}
-// Avoid 64 bit compiler warnings.
-// Scintilla does not support text buffers larger than 2**31
-static int istrlen(const char *s) {
- return static_cast<int>(strlen(s));
-}
-
bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) {
if (st.multipleStyles) {
- for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+ for (size_t iStyle=0; iStyle<st.length; iStyle++) {
if (!vs.ValidStyle(styleOffset + st.styles[iStyle]))
return false;
}
size_t endSegment = start;
while ((endSegment+1 < len) && (static_cast<size_t>(styles[endSegment+1]) == style))
endSegment++;
- width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, endSegment - start + 1);
+ width += surface->WidthText(vs.styles[style+styleOffset].font, text + start,
+ static_cast<int>(endSegment - start + 1));
start = endSegment + 1;
}
return width;
if (st.multipleStyles) {
widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine);
} else {
- widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font, st.text + start, lenLine);
+ widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font,
+ st.text + start, static_cast<int>(lenLine));
}
if (widthSubLine > widthMax)
widthMax = widthSubLine;
while (end < length-1 && st.styles[start+end+1] == style)
end++;
style += styleOffset;
- int width = surface->WidthText(vs.styles[style].font, st.text + start + i, end - i + 1);
+ int width = surface->WidthText(vs.styles[style].font,
+ st.text + start + i, static_cast<int>(end - i + 1));
PRectangle rcSegment = rcText;
rcSegment.left = x;
rcSegment.right = x + width + 1;
surface->DrawTextNoClip(rcSegment, vs.styles[style].font,
- ascent, st.text + start + i, end - i + 1,
- vs.styles[style].fore.allocated,
- vs.styles[style].back.allocated);
+ ascent, st.text + start + i,
+ static_cast<int>(end - i + 1),
+ vs.styles[style].fore,
+ vs.styles[style].back);
x += width;
i = end + 1;
}
} else {
- int style = st.style + styleOffset;
+ size_t style = st.style + styleOffset;
surface->DrawTextNoClip(rcText, vs.styles[style].font,
- rcText.top + vs.maxAscent, st.text + start, length,
- vs.styles[style].fore.allocated,
- vs.styles[style].back.allocated);
+ rcText.top + vs.maxAscent, st.text + start,
+ static_cast<int>(length),
+ vs.styles[style].fore,
+ vs.styles[style].back);
}
}
surface = surfWindow;
}
+ // Clip vertically to paint area to avoid drawing line numbers
+ if (rcMargin.bottom > rc.bottom)
+ rcMargin.bottom = rc.bottom;
+ if (rcMargin.top < rc.top)
+ rcMargin.top = rc.top;
+
PRectangle rcSelMargin = rcMargin;
rcSelMargin.right = rcMargin.left;
rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width;
if (vs.ms[margin].style != SC_MARGIN_NUMBER) {
- /* alternate scheme:
- if (vs.ms[margin].mask & SC_MASK_FOLDERS)
- surface->FillRectangle(rcSelMargin, vs.styles[STYLE_DEFAULT].back.allocated);
- else
- // Required because of special way brush is created for selection margin
- surface->FillRectangle(rcSelMargin, pixmapSelPattern);
- */
if (vs.ms[margin].mask & SC_MASK_FOLDERS)
// Required because of special way brush is created for selection margin
surface->FillRectangle(rcSelMargin, *pixmapSelPattern);
else {
- ColourAllocated colour;
+ ColourDesired colour;
switch (vs.ms[margin].style) {
case SC_MARGIN_BACK:
- colour = vs.styles[STYLE_DEFAULT].back.allocated;
+ colour = vs.styles[STYLE_DEFAULT].back;
break;
case SC_MARGIN_FORE:
- colour = vs.styles[STYLE_DEFAULT].fore.allocated;
+ colour = vs.styles[STYLE_DEFAULT].fore;
break;
default:
- colour = vs.styles[STYLE_LINENUMBER].back.allocated;
+ colour = vs.styles[STYLE_LINENUMBER].back;
break;
}
surface->FillRectangle(rcSelMargin, colour);
}
} else {
- surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated);
+ surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back);
}
- int visibleLine = topLine;
- int yposScreen = 0;
-
+ const int lineStartPaint = rcMargin.top / vs.lineHeight;
+ int visibleLine = topLine + lineStartPaint;
+ int yposScreen = lineStartPaint * vs.lineHeight;
// Work out whether the top line is whitespace located after a
// lessening of fold level which implies a 'fold tail' but which should not
// be displayed until the last of a sequence of whitespace.
bool needWhiteClosure = false;
- int level = pdoc->GetLevel(cs.DocFromDisplay(topLine));
- if (level & SC_FOLDLEVELWHITEFLAG) {
- int lineBack = cs.DocFromDisplay(topLine);
- int levelPrev = level;
- while ((lineBack > 0) && (levelPrev & SC_FOLDLEVELWHITEFLAG)) {
- lineBack--;
- levelPrev = pdoc->GetLevel(lineBack);
+ if (vs.ms[margin].mask & SC_MASK_FOLDERS) {
+ int level = pdoc->GetLevel(cs.DocFromDisplay(visibleLine));
+ if (level & SC_FOLDLEVELWHITEFLAG) {
+ int lineBack = cs.DocFromDisplay(visibleLine);
+ int levelPrev = level;
+ while ((lineBack > 0) && (levelPrev & SC_FOLDLEVELWHITEFLAG)) {
+ lineBack--;
+ levelPrev = pdoc->GetLevel(lineBack);
+ }
+ if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) {
+ if ((level & SC_FOLDLEVELNUMBERMASK) < (levelPrev & SC_FOLDLEVELNUMBERMASK))
+ needWhiteClosure = true;
+ }
}
- if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) {
- if ((level & SC_FOLDLEVELNUMBERMASK) < (levelPrev & SC_FOLDLEVELNUMBERMASK))
- needWhiteClosure = true;
+ if (highlightDelimiter.isEnabled) {
+ int lastLine = cs.DocFromDisplay(topLine + LinesOnScreen()) + 1;
+ pdoc->GetHighlightDelimiters(highlightDelimiter, pdoc->LineFromPosition(CurrentPosition()), lastLine);
}
}
while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
PLATFORM_ASSERT(visibleLine < cs.LinesDisplayed());
-
int lineDoc = cs.DocFromDisplay(visibleLine);
PLATFORM_ASSERT(cs.GetVisible(lineDoc));
bool firstSubLine = visibleLine == cs.DisplayFromDoc(lineDoc);
+ bool lastSubLine = visibleLine == (cs.DisplayFromDoc(lineDoc + 1) - 1);
- // Decide which fold indicator should be displayed
- level = pdoc->GetLevel(lineDoc);
- int levelNext = pdoc->GetLevel(lineDoc + 1);
int marks = pdoc->GetMark(lineDoc);
if (!firstSubLine)
marks = 0;
- int levelNum = level & SC_FOLDLEVELNUMBERMASK;
- int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK;
- if (level & SC_FOLDLEVELHEADERFLAG) {
- if (firstSubLine) {
- if (cs.GetExpanded(lineDoc)) {
- if (levelNum == SC_FOLDLEVELBASE)
- marks |= 1 << SC_MARKNUM_FOLDEROPEN;
- else
- marks |= 1 << folderOpenMid;
+
+ bool headWithTail = false;
+
+ if (vs.ms[margin].mask & SC_MASK_FOLDERS) {
+ // Decide which fold indicator should be displayed
+ int level = pdoc->GetLevel(lineDoc);
+ int levelNext = pdoc->GetLevel(lineDoc + 1);
+ int levelNum = level & SC_FOLDLEVELNUMBERMASK;
+ int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK;
+ if (level & SC_FOLDLEVELHEADERFLAG) {
+ if (firstSubLine) {
+ if (levelNum < levelNextNum) {
+ if (cs.GetExpanded(lineDoc)) {
+ if (levelNum == SC_FOLDLEVELBASE)
+ marks |= 1 << SC_MARKNUM_FOLDEROPEN;
+ else
+ marks |= 1 << folderOpenMid;
+ } else {
+ if (levelNum == SC_FOLDLEVELBASE)
+ marks |= 1 << SC_MARKNUM_FOLDER;
+ else
+ marks |= 1 << folderEnd;
+ }
+ } else if (levelNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
} else {
- if (levelNum == SC_FOLDLEVELBASE)
- marks |= 1 << SC_MARKNUM_FOLDER;
- else
- marks |= 1 << folderEnd;
+ if (levelNum < levelNextNum) {
+ if (cs.GetExpanded(lineDoc)) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ } else if (levelNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
+ } else if (levelNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
}
- } else {
- marks |= 1 << SC_MARKNUM_FOLDERSUB;
- }
- needWhiteClosure = false;
- } else if (level & SC_FOLDLEVELWHITEFLAG) {
- if (needWhiteClosure) {
- if (levelNext & SC_FOLDLEVELWHITEFLAG) {
- marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ needWhiteClosure = false;
+ int firstFollowupLine = cs.DocFromDisplay(cs.DisplayFromDoc(lineDoc + 1));
+ int firstFollowupLineLevel = pdoc->GetLevel(firstFollowupLine);
+ int secondFollowupLineLevelNum = pdoc->GetLevel(firstFollowupLine + 1) & SC_FOLDLEVELNUMBERMASK;
+ if (!cs.GetExpanded(lineDoc)) {
+ if ((firstFollowupLineLevel & SC_FOLDLEVELWHITEFLAG) &&
+ (levelNum > secondFollowupLineLevelNum))
+ needWhiteClosure = true;
+
+ if (highlightDelimiter.IsFoldBlockHighlighted(firstFollowupLine))
+ headWithTail = true;
+ }
+ } else if (level & SC_FOLDLEVELWHITEFLAG) {
+ if (needWhiteClosure) {
+ if (levelNext & SC_FOLDLEVELWHITEFLAG) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ } else if (levelNextNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+ needWhiteClosure = false;
+ } else {
+ marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+ needWhiteClosure = false;
+ }
} else if (levelNum > SC_FOLDLEVELBASE) {
- marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
- needWhiteClosure = false;
- } else {
- marks |= 1 << SC_MARKNUM_FOLDERTAIL;
- needWhiteClosure = false;
+ if (levelNextNum < levelNum) {
+ if (levelNextNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+ } else {
+ marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+ }
+ } else {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
}
} else if (levelNum > SC_FOLDLEVELBASE) {
if (levelNextNum < levelNum) {
- if (levelNextNum > SC_FOLDLEVELBASE) {
- marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+ needWhiteClosure = false;
+ if (levelNext & SC_FOLDLEVELWHITEFLAG) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ needWhiteClosure = true;
+ } else if (lastSubLine) {
+ if (levelNextNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+ } else {
+ marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+ }
} else {
- marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
} else {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
}
- } else if (levelNum > SC_FOLDLEVELBASE) {
- if (levelNextNum < levelNum) {
- needWhiteClosure = false;
- if (levelNext & SC_FOLDLEVELWHITEFLAG) {
- marks |= 1 << SC_MARKNUM_FOLDERSUB;
- needWhiteClosure = true;
- } else if (levelNextNum > SC_FOLDLEVELBASE) {
- marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
- } else {
- marks |= 1 << SC_MARKNUM_FOLDERTAIL;
- }
- } else {
- marks |= 1 << SC_MARKNUM_FOLDERSUB;
- }
}
marks &= vs.ms[margin].mask;
+
PRectangle rcMarker = rcSelMargin;
rcMarker.top = yposScreen;
rcMarker.bottom = yposScreen + vs.lineHeight;
if (vs.ms[margin].style == SC_MARGIN_NUMBER) {
- char number[100];
- number[0] = '\0';
- if (firstSubLine)
+ if (firstSubLine) {
+ char number[100];
sprintf(number, "%d", lineDoc + 1);
- if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) {
- int lev = pdoc->GetLevel(lineDoc);
- sprintf(number, "%c%c %03X %03X",
- (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_',
- (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_',
- lev & SC_FOLDLEVELNUMBERMASK,
- lev >> 16
- );
+ if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) {
+ int lev = pdoc->GetLevel(lineDoc);
+ sprintf(number, "%c%c %03X %03X",
+ (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_',
+ (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_',
+ lev & SC_FOLDLEVELNUMBERMASK,
+ lev >> 16
+ );
+ }
+ PRectangle rcNumber = rcMarker;
+ // Right justify
+ XYPOSITION width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, istrlen(number));
+ XYPOSITION xpos = rcNumber.right - width - 3;
+ rcNumber.left = xpos;
+ surface->DrawTextNoClip(rcNumber, vs.styles[STYLE_LINENUMBER].font,
+ rcNumber.top + vs.maxAscent, number, istrlen(number),
+ vs.styles[STYLE_LINENUMBER].fore,
+ vs.styles[STYLE_LINENUMBER].back);
+ } else if (wrapVisualFlags & SC_WRAPVISUALFLAG_MARGIN) {
+ PRectangle rcWrapMarker = rcMarker;
+ rcWrapMarker.right -= 3;
+ rcWrapMarker.left = rcWrapMarker.right - vs.styles[STYLE_LINENUMBER].aveCharWidth;
+ DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore);
}
- PRectangle rcNumber = rcMarker;
- // Right justify
- int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, istrlen(number));
- int xpos = rcNumber.right - width - 3;
- rcNumber.left = xpos;
- surface->DrawTextNoClip(rcNumber, vs.styles[STYLE_LINENUMBER].font,
- rcNumber.top + vs.maxAscent, number, istrlen(number),
- vs.styles[STYLE_LINENUMBER].fore.allocated,
- vs.styles[STYLE_LINENUMBER].back.allocated);
} else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) {
if (firstSubLine) {
const StyledText stMargin = pdoc->MarginStyledText(lineDoc);
if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) {
surface->FillRectangle(rcMarker,
- vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back.allocated);
+ vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back);
if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin);
rcMarker.left = rcMarker.right - width - 3;
if (marks) {
for (int markBit = 0; (markBit < 32) && marks; markBit++) {
if (marks & 1) {
- vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font);
+ LineMarker::typeOfFold tFold = LineMarker::undefined;
+ if ((vs.ms[margin].mask & SC_MASK_FOLDERS) && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) {
+ if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) {
+ tFold = LineMarker::body;
+ } else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) {
+ if (firstSubLine) {
+ tFold = headWithTail ? LineMarker::headWithTail : LineMarker::head;
+ } else {
+ if (cs.GetExpanded(lineDoc) || headWithTail) {
+ tFold = LineMarker::body;
+ } else {
+ tFold = LineMarker::undefined;
+ }
+ }
+ } else if (highlightDelimiter.IsTailOfFoldBlock(lineDoc)) {
+ tFold = LineMarker::tail;
+ }
+ }
+ vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font, tFold, vs.ms[margin].style);
}
marks >>= 1;
}
PRectangle rcBlankMargin = rcMargin;
rcBlankMargin.left = rcSelMargin.right;
- surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back.allocated);
+ surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back);
if (bufferedDraw) {
- surfWindow->Copy(rcMargin, Point(), *pixmapSelMargin);
+ surfWindow->Copy(rcMargin, Point(rcMargin.left, rcMargin.top), *pixmapSelMargin);
}
}
LinesOnScreen() + 1, pdoc->LinesTotal());
}
-static bool GoodTrailByte(int v) {
- return (v >= 0x80) && (v < 0xc0);
-}
-
bool BadUTF(const char *s, int len, int &trailBytes) {
+ // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
if (trailBytes) {
trailBytes--;
return false;
}
- const unsigned char *us = reinterpret_cast<const unsigned char *>(s);
- if (*us < 0x80) {
- // Single bytes easy
- return false;
- } else if (*us > 0xF4) {
- // Characters longer than 4 bytes not possible in current UTF-8
- return true;
- } else if (*us >= 0xF0) {
- // 4 bytes
- if (len < 4)
- return true;
- if (GoodTrailByte(us[1]) && GoodTrailByte(us[2]) && GoodTrailByte(us[3])) {
- trailBytes = 3;
- return false;
- } else {
- return true;
- }
- } else if (*us >= 0xE0) {
- // 3 bytes
- if (len < 3)
- return true;
- if (GoodTrailByte(us[1]) && GoodTrailByte(us[2])) {
- trailBytes = 2;
- return false;
- } else {
- return true;
- }
- } else if (*us >= 0xC2) {
- // 2 bytes
- if (len < 2)
- return true;
- if (GoodTrailByte(us[1])) {
- trailBytes = 1;
- return false;
- } else {
- return true;
- }
- } else if (*us >= 0xC0) {
- // Overlong encoding
+ int utf8status = UTF8Classify(reinterpret_cast<const unsigned char *>(s), len);
+ if (utf8status & UTF8MaskInvalid) {
return true;
} else {
- // Trail byte
- return true;
+ trailBytes = (utf8status & UTF8MaskWidth) - 1;
+ return false;
}
}
if (ll->validity == LineLayout::llCheckTextAndStyle) {
int lineLength = posLineEnd - posLineStart;
if (!vstyle.viewEOL) {
- int cid = posLineEnd - 1;
- while ((cid > posLineStart) && IsEOLChar(pdoc->CharAt(cid))) {
- cid--;
- lineLength--;
- }
+ lineLength = pdoc->LineEnd(line) - posLineStart;
}
if (lineLength == ll->numCharsInLine) {
// See if chars, styles, indicators, are all the same
if (ll->validity == LineLayout::llInvalid) {
ll->widthLine = LineLayout::wrapWidthInfinite;
ll->lines = 1;
- int numCharsInLine = 0;
- int numCharsBeforeEOL = 0;
if (vstyle.edgeState == EDGE_BACKGROUND) {
ll->edgeColumn = pdoc->FindColumn(line, theEdge);
if (ll->edgeColumn >= posLineStart) {
ll->edgeColumn = -1;
}
- char styleByte = 0;
- int styleMask = pdoc->stylingBitsMask;
+ char styleByte;
+ const int styleMask = pdoc->stylingBitsMask;
ll->styleBitsSet = 0;
// Fill base line layout
- for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
- char chDoc = pdoc->CharAt(charInDoc);
- styleByte = pdoc->StyleAt(charInDoc);
+ const int lineLength = posLineEnd - posLineStart;
+ pdoc->GetCharRange(ll->chars, posLineStart, lineLength);
+ pdoc->GetStyleRange(ll->styles, posLineStart, lineLength);
+ int numCharsBeforeEOL = pdoc->LineEnd(line) - posLineStart;
+ const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL;
+ for (int styleInLine = 0; styleInLine < numCharsInLine; styleInLine++) {
+ styleByte = ll->styles[styleInLine];
ll->styleBitsSet |= styleByte;
- if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
- ll->chars[numCharsInLine] = chDoc;
- ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
- ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
- if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
- ll->chars[numCharsInLine] = static_cast<char>(toupper(chDoc));
- else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
- ll->chars[numCharsInLine] = static_cast<char>(tolower(chDoc));
- numCharsInLine++;
- if (!IsEOLChar(chDoc))
- numCharsBeforeEOL++;
+ ll->styles[styleInLine] = static_cast<char>(styleByte & styleMask);
+ ll->indicators[styleInLine] = static_cast<char>(styleByte & ~styleMask);
+ }
+ styleByte = static_cast<char>(((lineLength > 0) ? ll->styles[lineLength-1] : 0) & styleMask);
+ if (vstyle.someStylesForceCase) {
+ for (int charInLine = 0; charInLine<lineLength; charInLine++) {
+ char chDoc = ll->chars[charInLine];
+ if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper)
+ ll->chars[charInLine] = static_cast<char>(toupper(chDoc));
+ else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower)
+ ll->chars[charInLine] = static_cast<char>(tolower(chDoc));
}
}
ll->xHighlightGuide = 0;
// Layout the line, determining the position of each character,
// with an extra element at the end for the end of the line.
int startseg = 0; // Start of the current segment, in char. number
- int startsegx = 0; // Start of the current segment, in pixels
+ XYACCUMULATOR startsegx = 0; // Start of the current segment, in pixels
ll->positions[0] = 0;
- unsigned int tabWidth = vstyle.spaceWidth * pdoc->tabInChars;
+ XYPOSITION tabWidth = vstyle.spaceWidth * pdoc->tabInChars;
bool lastSegItalics = false;
Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font;
- int ctrlCharWidth[32] = {0};
+ XYPOSITION ctrlCharWidth[32] = {0};
bool isControlNext = IsControlCharacter(ll->chars[0]);
int trailBytes = 0;
bool isBadUTFNext = IsUnicodeMode() && BadUTF(ll->chars, numCharsInLine, trailBytes);
if (vstyle.styles[ll->styles[charInLine]].visible) {
if (isControl) {
if (ll->chars[charInLine] == '\t') {
- ll->positions[charInLine + 1] = ((((startsegx + 2) /
- tabWidth) + 1) * tabWidth) - startsegx;
+ ll->positions[charInLine + 1] =
+ ((static_cast<int>((startsegx + 2) / tabWidth) + 1) * tabWidth) - startsegx;
} else if (controlCharSymbol < 32) {
if (ctrlCharWidth[ll->chars[charInLine]] == 0) {
const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
}
lastSegItalics = false;
} else if (isBadUTF) {
- char hexits[3];
- sprintf(hexits, "%2X", ll->chars[charInLine] & 0xff);
+ char hexits[4];
+ sprintf(hexits, "x%2X", ll->chars[charInLine] & 0xff);
ll->positions[charInLine + 1] =
surface->WidthText(ctrlCharsFont, hexits, istrlen(hexits)) + 3;
} else { // Regular character
} else {
lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg,
- lenSeg, ll->positions + startseg + 1);
+ lenSeg, ll->positions + startseg + 1, pdoc);
}
}
} else { // invisible
ll->lines = 1;
} else {
if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) {
- width -= vstyle.aveCharWidth; // take into account the space for end wrap mark
+ width -= static_cast<int>(vstyle.aveCharWidth); // take into account the space for end wrap mark
+ }
+ XYPOSITION wrapAddIndent = 0; // This will be added to initial indent of line
+ if (wrapIndentMode == SC_WRAPINDENT_INDENT) {
+ wrapAddIndent = pdoc->IndentSize() * vstyle.spaceWidth;
+ } else if (wrapIndentMode == SC_WRAPINDENT_FIXED) {
+ wrapAddIndent = wrapVisualStartIndent * vstyle.aveCharWidth;
}
ll->wrapIndent = wrapAddIndent;
if (wrapIndentMode != SC_WRAPINDENT_FIXED)
if (ll->wrapIndent > width - static_cast<int>(vstyle.aveCharWidth) * 15)
ll->wrapIndent = wrapAddIndent;
// Check for wrapIndent minimum
- if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < static_cast<int>(vstyle.aveCharWidth)))
+ if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < vstyle.aveCharWidth))
ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual
ll->lines = 0;
// Calculate line start positions based upon width.
int lastGoodBreak = 0;
int lastLineStart = 0;
- int startOffset = 0;
+ XYACCUMULATOR startOffset = 0;
int p = 0;
while (p < ll->numCharsInLine) {
if ((ll->positions[p + 1] - startOffset) >= width) {
}
}
-ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw, bool main) {
+ColourDesired Editor::SelectionBackground(ViewStyle &vsDraw, bool main) {
return main ?
- (primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated) :
- vsDraw.selAdditionalBackground.allocated;
+ (primarySelection ? vsDraw.selbackground : vsDraw.selbackground2) :
+ vsDraw.selAdditionalBackground;
}
-ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
- ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+ColourDesired Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
+ ColourDesired background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
if (inSelection == 1) {
if (vsDraw.selbackset && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
return SelectionBackground(vsDraw, true);
} else {
if ((vsDraw.edgeState == EDGE_BACKGROUND) &&
(i >= ll->edgeColumn) &&
- !IsEOLChar(ll->chars[i]))
- return vsDraw.edgecolour.allocated;
+ (i < ll->numCharsBeforeEOL))
+ return vsDraw.edgecolour;
if (inHotspot && vsDraw.hotspotBackgroundSet)
- return vsDraw.hotspotBackground.allocated;
- if (overrideBackground && (styleMain != STYLE_BRACELIGHT) && (styleMain != STYLE_BRACEBAD))
- return background;
+ return vsDraw.hotspotBackground;
+ }
+ if (overrideBackground && (styleMain != STYLE_BRACELIGHT) && (styleMain != STYLE_BRACEBAD)) {
+ return background;
+ } else {
+ return vsDraw.styles[styleMain].back;
}
- return vsDraw.styles[styleMain].back.allocated;
}
void Editor::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight) {
}
void Editor::DrawWrapMarker(Surface *surface, PRectangle rcPlace,
- bool isEndMarker, ColourAllocated wrapColour) {
+ bool isEndMarker, ColourDesired wrapColour) {
surface->PenColour(wrapColour);
enum { xa = 1 }; // gap before start
y - 2 * dy);
}
-static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourAllocated fill, int alpha) {
+static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourDesired fill, int alpha) {
if (alpha != SC_ALPHA_NOALPHA) {
surface->AlphaRectangle(rc, 0, fill, alpha, fill, alpha, 0);
}
}
void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
- const char *s, ColourAllocated textBack, ColourAllocated textFore, bool twoPhaseDraw) {
+ const char *s, ColourDesired textBack, ColourDesired textFore, bool twoPhaseDraw) {
if (!twoPhaseDraw) {
surface->FillRectangle(rcSegment, textBack);
}
}
void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
- int line, int lineEnd, int xStart, int subLine, int subLineStart,
- bool overrideBackground, ColourAllocated background,
- bool drawWrapMarkEnd, ColourAllocated wrapColour) {
+ int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart,
+ bool overrideBackground, ColourDesired background,
+ bool drawWrapMarkEnd, ColourDesired wrapColour) {
const int posLineStart = pdoc->LineStart(line);
const int styleMask = pdoc->stylingBitsMask;
PRectangle rcSegment = rcLine;
const bool lastSubLine = subLine == (ll->lines - 1);
- int virtualSpace = 0;
+ XYPOSITION virtualSpace = 0;
if (lastSubLine) {
- const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
virtualSpace = sel.VirtualSpaceFor(pdoc->LineEnd(line)) * spaceWidth;
}
-
- // Fill in a PRectangle representing the end of line characters
-
- int xEol = ll->positions[lineEnd] - subLineStart;
+ XYPOSITION xEol = ll->positions[lineEnd] - subLineStart;
// Fill the virtual space and show selections within it
if (virtualSpace) {
rcSegment.left = xEol + xStart;
rcSegment.right = xEol + xStart + virtualSpace;
- surface->FillRectangle(rcSegment, overrideBackground ? background : vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ surface->FillRectangle(rcSegment, overrideBackground ? background : vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back);
if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) {
SelectionSegment virtualSpaceRange(SelectionPosition(pdoc->LineEnd(line)), SelectionPosition(pdoc->LineEnd(line), sel.VirtualSpaceFor(pdoc->LineEnd(line))));
for (size_t r=0; r<sel.Count(); r++) {
if (alpha == SC_ALPHA_NOALPHA) {
SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
if (!portion.Empty()) {
- const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
- rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
- rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+ rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left;
+ rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right;
surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == sel.Main()));
}
}
}
}
- int posAfterLineEnd = pdoc->LineStart(line + 1);
- int eolInSelection = (subLine == (ll->lines - 1)) ? sel.InSelectionForEOL(posAfterLineEnd) : 0;
- int alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+ int eolInSelection = 0;
+ int alpha = SC_ALPHA_NOALPHA;
+ if (!hideSelection) {
+ int posAfterLineEnd = pdoc->LineStart(line + 1);
+ eolInSelection = (subLine == (ll->lines - 1)) ? sel.InSelectionForEOL(posAfterLineEnd) : 0;
+ alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+ }
// Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on
- int blobsWidth = 0;
+ XYPOSITION blobsWidth = 0;
if (lastSubLine) {
for (int eolPos=ll->numCharsBeforeEOL; eolPos<ll->numCharsInLine; eolPos++) {
rcSegment.left = xStart + ll->positions[eolPos] - subLineStart + virtualSpace;
rcSegment.right = xStart + ll->positions[eolPos+1] - subLineStart + virtualSpace;
blobsWidth += rcSegment.Width();
const char *ctrlChar = ControlCharacterString(ll->chars[eolPos]);
- int inSelection = 0;
- bool inHotspot = false;
int styleMain = ll->styles[eolPos];
- ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, eolPos, ll);
- ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
- if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) {
+ ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, eolInSelection, false, styleMain, eolPos, ll);
+ ColourDesired textFore = vsDraw.styles[styleMain].fore;
+ if (eolInSelection && vsDraw.selforeset) {
+ textFore = (eolInSelection == 1) ? vsDraw.selforeground : vsDraw.selAdditionalForeground;
+ }
+ if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) {
if (alpha == SC_ALPHA_NOALPHA) {
surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
} else {
surface->FillRectangle(rcSegment, textBack);
- SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
}
} else {
surface->FillRectangle(rcSegment, textBack);
}
DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw);
+ if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
+ }
}
}
// Draw the eol-is-selected rectangle
rcSegment.left = xEol + xStart + virtualSpace + blobsWidth;
- rcSegment.right = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+ rcSegment.right = rcSegment.left + vsDraw.aveCharWidth;
- if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+ if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
} else {
if (overrideBackground) {
surface->FillRectangle(rcSegment, background);
} else if (line < pdoc->LinesTotal() - 1) {
- surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back);
} else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
- surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back);
} else {
- surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back);
}
- if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+ if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
}
}
// Fill the remainder of the line
- rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+ rcSegment.left = rcSegment.right;
+ if (rcSegment.left < rcLine.left)
+ rcSegment.left = rcLine.left;
rcSegment.right = rcLine.right;
- if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+ if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
} else {
if (overrideBackground) {
surface->FillRectangle(rcSegment, background);
} else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
- surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back);
} else {
- surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back);
}
- if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+ if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
}
}
rcPlace.left = xEol + xStart + virtualSpace;
rcPlace.right = rcPlace.left + vsDraw.aveCharWidth;
} else {
- // draw left of the right text margin, to avoid clipping by the current clip rect
- rcPlace.right = rcLine.right - vs.rightMarginWidth;
+ // rcLine is clipped to text area
+ rcPlace.right = rcLine.right;
rcPlace.left = rcPlace.right - vsDraw.aveCharWidth;
}
DrawWrapMarker(surface, rcPlace, true, wrapColour);
}
}
+void Editor::DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
+ int xStart, PRectangle rcLine, LineLayout *ll, int subLine) {
+ const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)];
+ PRectangle rcIndic(
+ ll->positions[startPos] + xStart - subLineStart,
+ rcLine.top + vsDraw.maxAscent,
+ ll->positions[endPos] + xStart - subLineStart,
+ rcLine.top + vsDraw.maxAscent + 3);
+ vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine);
+}
+
void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) {
// Draw decorators
const int posLineStart = pdoc->LineStart(line);
const int lineStart = ll->LineStart(subLine);
- const int subLineStart = ll->positions[lineStart];
const int posLineEnd = posLineStart + lineEnd;
if (!under) {
// IN indicator run, looking for END
if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) {
// AT end of indicator run, DRAW it!
- PRectangle rcIndic(
- ll->positions[startPos] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent,
- ll->positions[indicPos] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent + 3);
- vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine);
+ DrawIndicator(indicnum, startPos, indicPos, surface, vsDraw, xStart, rcLine, ll, subLine);
// RESET control var
startPos = -1;
}
int endPos = deco->rs.EndRun(startPos);
if (endPos > posLineEnd)
endPos = posLineEnd;
- PRectangle rcIndic(
- ll->positions[startPos - posLineStart] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent,
- ll->positions[endPos - posLineStart] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent + 3);
- vsDraw.indicators[deco->indicator].Draw(surface, rcIndic, rcLine);
+ DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart,
+ surface, vsDraw, xStart, rcLine, ll, subLine);
startPos = deco->rs.EndRun(endPos);
}
}
}
+
+ // Use indicators to highlight matching braces
+ if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
+ (vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
+ int braceIndicator = (bracesMatchStyle == STYLE_BRACELIGHT) ? vs.braceHighlightIndicator : vs.braceBadLightIndicator;
+ if (under == vsDraw.indicators[braceIndicator].under) {
+ Range rangeLine(posLineStart + lineStart, posLineEnd);
+ if (rangeLine.ContainsCharacter(braces[0])) {
+ int braceOffset = braces[0] - posLineStart;
+ if (braceOffset < ll->numCharsInLine) {
+ DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
+ }
+ }
+ if (rangeLine.ContainsCharacter(braces[1])) {
+ int braceOffset = braces[1] - posLineStart;
+ if (braceOffset < ll->numCharsInLine) {
+ DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
+ }
+ }
+ }
+ }
}
void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
int annotationLine = subLine - ll->lines;
const StyledText stAnnotation = pdoc->AnnotationStyledText(line);
if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) {
- surface->FillRectangle(rcSegment, vsDraw.styles[0].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[0].back);
if (vs.annotationVisible == ANNOTATION_BOXED) {
// Only care about calculating width if need to draw box
int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation);
widthAnnotation += vsDraw.spaceWidth * 2; // Margins
rcSegment.left = xStart + indent;
rcSegment.right = rcSegment.left + widthAnnotation;
- surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore.allocated);
} else {
rcSegment.left = xStart;
}
PRectangle rcText = rcSegment;
if (vs.annotationVisible == ANNOTATION_BOXED) {
surface->FillRectangle(rcText,
- vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back.allocated);
+ vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back);
rcText.left += vsDraw.spaceWidth;
}
DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent,
stAnnotation, start, lengthAnnotation);
if (vs.annotationVisible == ANNOTATION_BOXED) {
+ surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore);
surface->MoveTo(rcSegment.left, rcSegment.top);
surface->LineTo(rcSegment.left, rcSegment.bottom);
surface->MoveTo(rcSegment.right, rcSegment.top);
surface->LineTo(rcSegment.right, rcSegment.bottom);
- if (subLine == ll->lines){
+ if (subLine == ll->lines) {
surface->MoveTo(rcSegment.left, rcSegment.top);
surface->LineTo(rcSegment.right, rcSegment.top);
}
// with the earlier taking precedence. When multiple markers cause background override,
// the color for the highest numbered one is used.
bool overrideBackground = false;
- ColourAllocated background;
+ ColourDesired background;
if (caret.active && vsDraw.showCaretLineBackground && (vsDraw.caretLineAlpha == SC_ALPHA_NOALPHA) && ll->containsCaret) {
overrideBackground = true;
- background = vsDraw.caretLineBackground.allocated;
+ background = vsDraw.caretLineBackground;
}
if (!overrideBackground) {
int marks = pdoc->GetMark(line);
for (int markBit = 0; (markBit < 32) && marks; markBit++) {
if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND) &&
(vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
- background = vsDraw.markers[markBit].back.allocated;
+ background = vsDraw.markers[markBit].back;
overrideBackground = true;
}
marks >>= 1;
if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY) &&
(vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
overrideBackground = true;
- background = vsDraw.markers[markBit].back.allocated;
+ background = vsDraw.markers[markBit].back;
}
marksMasked >>= 1;
}
(!overrideBackground) && (vsDraw.whitespaceBackgroundSet);
bool inIndentation = subLine == 0; // Do not handle indentation except on first subline.
- int indentWidth = pdoc->IndentSize() * vsDraw.spaceWidth;
+ const XYPOSITION indentWidth = pdoc->IndentSize() * vsDraw.spaceWidth;
+ const XYPOSITION epsilon = 0.0001f; // A small nudge to avoid floating point precision issues
int posLineStart = pdoc->LineStart(line);
int startseg = ll->LineStart(subLine);
- int subLineStart = ll->positions[startseg];
+ XYACCUMULATOR subLineStart = ll->positions[startseg];
if (subLine >= ll->lines) {
DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine);
return; // No further drawing
}
}
- ColourAllocated wrapColour = vsDraw.styles[STYLE_DEFAULT].fore.allocated;
+ ColourDesired wrapColour = vsDraw.styles[STYLE_DEFAULT].fore;
if (vsDraw.whitespaceForegroundSet)
- wrapColour = vsDraw.whitespaceForeground.allocated;
+ wrapColour = vsDraw.whitespaceForeground;
bool drawWrapMarkEnd = false;
// default bgnd here..
surface->FillRectangle(rcSegment, overrideBackground ? background :
- vsDraw.styles[STYLE_DEFAULT].back.allocated);
+ vsDraw.styles[STYLE_DEFAULT].back);
// main line style would be below but this would be inconsistent with end markers
// also would possibly not be the style at wrap point
//int styleMain = ll->styles[lineStart];
- //surface->FillRectangle(rcPlace, vsDraw.styles[styleMain].back.allocated);
+ //surface->FillRectangle(rcPlace, vsDraw.styles[styleMain].back);
if (wrapVisualFlags & SC_WRAPVISUALFLAG_START) {
DrawWrapMarker(surface, rcPlace, false, wrapColour);
}
- xStart += ll->wrapIndent;
+ xStart += static_cast<int>(ll->wrapIndent);
}
}
((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA));
// Does not take margin into account but not significant
- int xStartVisible = subLineStart - xStart;
+ int xStartVisible = static_cast<int>(subLineStart) - xStart;
ll->psel = &sel;
- BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible, selBackDrawn);
+ BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc);
int next = bfBack.First();
// Background drawing loop
// draw strings that are completely past the right side of the window.
if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) {
// Clip to line rectangle, since may have a huge position which will not work with some platforms
- rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
- rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+ if (rcSegment.left < rcLine.left)
+ rcSegment.left = rcLine.left;
+ if (rcSegment.right > rcLine.right)
+ rcSegment.right = rcLine.right;
int styleMain = ll->styles[i];
const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
- ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
+ ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
if (ll->chars[i] == '\t') {
// Tab display
if (drawWhitespaceBackground &&
(!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
- textBack = vsDraw.whitespaceBackground.allocated;
+ textBack = vsDraw.whitespaceBackground;
surface->FillRectangle(rcSegment, textBack);
} else if (IsControlCharacter(ll->chars[i])) {
// Control character display
rcSegment.top,
ll->positions[cpos + startseg + 1] + xStart - subLineStart,
rcSegment.bottom);
- surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated);
+ surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground);
}
} else {
inIndentation = false;
if (vsDraw.edgeState == EDGE_LINE) {
int edgeX = theEdge * vsDraw.spaceWidth;
rcSegment.left = edgeX + xStart;
+ if ((ll->wrapIndent != 0) && (lineStart != 0))
+ rcSegment.left -= ll->wrapIndent;
rcSegment.right = rcSegment.left + 1;
- surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.edgecolour);
}
// Draw underline mark as part of background if not transparent
(vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
PRectangle rcUnderline = rcLine;
rcUnderline.top = rcUnderline.bottom - 2;
- surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back.allocated);
+ surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back);
}
marks >>= 1;
}
inIndentation = subLine == 0; // Do not handle indentation except on first subline.
// Foreground drawing loop
- BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible,
- ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset));
+ BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible,
+ ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset), pdoc);
next = bfFore.First();
while (next < lineEnd) {
// draw strings that are completely past the right side of the window.
if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) {
int styleMain = ll->styles[i];
- ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
+ ColourDesired textFore = vsDraw.styles[styleMain].fore;
Font &textFont = vsDraw.styles[styleMain].font;
//hotspot foreground
if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) {
if (vsDraw.hotspotForegroundSet)
- textFore = vsDraw.hotspotForeground.allocated;
+ textFore = vsDraw.hotspotForeground;
}
const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
if (inSelection && (vsDraw.selforeset)) {
- textFore = (inSelection == 1) ? vsDraw.selforeground.allocated : vsDraw.selAdditionalForeground.allocated;
+ textFore = (inSelection == 1) ? vsDraw.selforeground : vsDraw.selAdditionalForeground;
}
bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
- ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
+ ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
if (ll->chars[i] == '\t') {
// Tab display
if (!twoPhaseDraw) {
if (drawWhitespaceBackground &&
(!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
- textBack = vsDraw.whitespaceBackground.allocated;
+ textBack = vsDraw.whitespaceBackground;
surface->FillRectangle(rcSegment, textBack);
}
if ((vsDraw.viewWhitespace != wsInvisible) ||
(inIndentation && vsDraw.viewIndentationGuides != ivNone)) {
if (vsDraw.whitespaceForegroundSet)
- textFore = vsDraw.whitespaceForeground.allocated;
+ textFore = vsDraw.whitespaceForeground;
surface->PenColour(textFore);
}
if (inIndentation && vsDraw.viewIndentationGuides == ivReal) {
- for (int xIG = ll->positions[i] / indentWidth * indentWidth; xIG < ll->positions[i + 1]; xIG += indentWidth) {
- if (xIG >= ll->positions[i] && xIG > 0) {
- DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIG + xStart, rcSegment,
- (ll->xHighlightGuide == xIG));
+ for (int indentCount = (ll->positions[i] + epsilon) / indentWidth;
+ indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth;
+ indentCount++) {
+ if (indentCount > 0) {
+ int xIndent = indentCount * indentWidth;
+ DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
+ (ll->xHighlightGuide == xIndent));
}
}
}
cc, 1, textBack, textFore);
}
} else if ((i == startseg) && (static_cast<unsigned char>(ll->chars[i]) >= 0x80) && IsUnicodeMode()) {
- char hexits[3];
- sprintf(hexits, "%2X", ll->chars[i] & 0xff);
+ // A single byte >= 0x80 in UTF-8 is a bad byte and is displayed as its hex value
+ char hexits[4];
+ sprintf(hexits, "x%2X", ll->chars[i] & 0xff);
DrawTextBlob(surface, vsDraw, rcSegment, hexits, textBack, textFore, twoPhaseDraw);
} else {
// Normal text display
if (ll->chars[cpos + startseg] == ' ') {
if (vsDraw.viewWhitespace != wsInvisible) {
if (vsDraw.whitespaceForegroundSet)
- textFore = vsDraw.whitespaceForeground.allocated;
+ textFore = vsDraw.whitespaceForeground;
if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
- int xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2;
+ XYPOSITION xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2;
if (!twoPhaseDraw && drawWhitespaceBackground &&
(!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) {
- textBack = vsDraw.whitespaceBackground.allocated;
+ textBack = vsDraw.whitespaceBackground;
PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart,
rcSegment.top,
ll->positions[cpos + startseg + 1] + xStart - subLineStart,
}
}
if (inIndentation && vsDraw.viewIndentationGuides == ivReal) {
- int startSpace = ll->positions[cpos + startseg];
- if (startSpace > 0 && (startSpace % indentWidth == 0)) {
- DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, startSpace + xStart, rcSegment,
- (ll->xHighlightGuide == ll->positions[cpos + startseg]));
+ for (int indentCount = (ll->positions[cpos + startseg] + epsilon) / indentWidth;
+ indentCount <= (ll->positions[cpos + startseg + 1] - epsilon) / indentWidth;
+ indentCount++) {
+ if (indentCount > 0) {
+ int xIndent = indentCount * indentWidth;
+ DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
+ (ll->xHighlightGuide == xIndent));
+ }
}
}
} else {
}
}
}
- if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) {
+ if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd) {
PRectangle rcUL = rcSegment;
rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
rcUL.bottom = rcUL.top + 1;
if (vsDraw.hotspotForegroundSet)
- surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated);
+ surface->FillRectangle(rcUL, vsDraw.hotspotForeground);
else
surface->FillRectangle(rcUL, textFore);
} else if (vsDraw.styles[styleMain].underline) {
lineNextWithText++;
}
if (lineNextWithText > line) {
- // This line is empty, so use indentation of last line with text
+ xStartText = 100000; // Don't limit to visible indentation on empty line
+ // This line is empty, so use indentation of first next line with text
indentSpace = Platform::Maximum(indentSpace,
pdoc->GetLineIndentation(lineNextWithText));
}
if (subLine == (ll->lines - 1)) {
virtualSpaces = sel.VirtualSpaceFor(pdoc->LineEnd(line));
}
- SelectionPosition posStart(posLineStart);
+ SelectionPosition posStart(posLineStart + lineStart);
SelectionPosition posEnd(posLineStart + lineEnd, virtualSpaces);
SelectionSegment virtualSpaceRange(posStart, posEnd);
for (size_t r=0; r<sel.Count(); r++) {
if (alpha != SC_ALPHA_NOALPHA) {
SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
if (!portion.Empty()) {
- const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
- rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
- rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
- SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == sel.Main()), alpha);
+ if ((ll->wrapIndent != 0) && (lineStart != 0)) {
+ if ((portion.start.Position() - posLineStart) == lineStart && sel.Range(r).ContainsCharacter(portion.start.Position() - 1))
+ rcSegment.left -= static_cast<int>(ll->wrapIndent); // indentation added to xStart was truncated to int, so we do the same here
+ }
+ rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left;
+ rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right;
+ if (rcSegment.right > rcLine.left)
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == sel.Main()), alpha);
}
}
}
}
// Draw any translucent whole line states
- rcSegment.left = xStart;
- rcSegment.right = rcLine.right - 1;
+ rcSegment = rcLine;
if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
- SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
+ SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground, vsDraw.caretLineAlpha);
}
marks = pdoc->GetMark(line);
for (markBit = 0; (markBit < 32) && marks; markBit++) {
if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND)) {
- SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
+ SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha);
} else if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE)) {
PRectangle rcUnderline = rcSegment;
rcUnderline.top = rcUnderline.bottom - 2;
- SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
+ SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha);
}
marks >>= 1;
}
if (marksMasked) {
for (markBit = 0; (markBit < 32) && marksMasked; markBit++) {
if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY)) {
- SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
+ SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha);
}
marksMasked >>= 1;
}
}
void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
- int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour) {
+ int xStart, int offset, int posCaret, PRectangle rcCaret, ColourDesired caretColour) {
int lineStart = ll->LineStart(subLine);
int posBefore = posCaret;
// glyph / combining character. If so we'll need to draw that too.
int offsetFirstChar = offset;
int offsetLastChar = offset + (posAfter - posCaret);
- while ((offsetLastChar - numCharsToDraw) >= lineStart) {
+ while ((posBefore > 0) && ((offsetLastChar - numCharsToDraw) >= lineStart)) {
if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - numCharsToDraw]) > 0) {
// The char does not share horizontal space
break;
// See if the next character shares horizontal space, if so we'll
// need to draw that too.
+ if (offsetFirstChar < 0)
+ offsetFirstChar = 0;
numCharsToDraw = offsetLastChar - offsetFirstChar;
while ((offsetLastChar < ll->LineStart(subLine + 1)) && (offsetLastChar <= ll->numCharsInLine)) {
// Update posAfter to point to the 2nd next char, this is where
// Adjust caret position to take into account any word wrapping symbols.
if ((ll->wrapIndent != 0) && (lineStart != 0)) {
- int wordWrapCharWidth = ll->wrapIndent;
+ XYPOSITION wordWrapCharWidth = ll->wrapIndent;
rcCaret.left += wordWrapCharWidth;
rcCaret.right += wordWrapCharWidth;
}
int styleMain = ll->styles[offsetFirstChar];
surface->DrawTextClipped(rcCaret, vsDraw.styles[styleMain].font,
rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar,
- numCharsToDraw, vsDraw.styles[styleMain].back.allocated,
+ numCharsToDraw, vsDraw.styles[styleMain].back,
caretColour);
}
PRectangle rcPattern(0, 0, patternSize, patternSize);
// Initialize default colours based on the chrome colour scheme. Typically the highlight is white.
- ColourAllocated colourFMFill = vs.selbar.allocated;
- ColourAllocated colourFMStripes = vs.selbarlight.allocated;
+ ColourDesired colourFMFill = vs.selbar;
+ ColourDesired colourFMStripes = vs.selbarlight;
- if (!(vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff))) {
+ if (!(vs.selbarlight == ColourDesired(0xff, 0xff, 0xff))) {
// User has chosen an unusual chrome colour scheme so just use the highlight edge colour.
// (Typically, the highlight colour is white.)
- colourFMFill = vs.selbarlight.allocated;
+ colourFMFill = vs.selbarlight;
}
if (vs.foldmarginColourSet) {
// override default fold margin colour
- colourFMFill = vs.foldmarginColour.allocated;
+ colourFMFill = vs.foldmarginColour;
}
if (vs.foldmarginHighlightColourSet) {
// override default fold margin highlight colour
- colourFMStripes = vs.foldmarginHighlightColour.allocated;
+ colourFMStripes = vs.foldmarginHighlightColour;
}
pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
- pixmapSelPattern->PenColour(colourFMStripes);
- for (int stripe = 0; stripe < patternSize; stripe++) {
- // Alternating 1 pixel stripes is same as checkerboard.
- pixmapSelPattern->MoveTo(0, stripe * 2);
- pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
+ for (int y = 0; y < patternSize; y++) {
+ for (int x = y % 2; x < patternSize; x+=2) {
+ PRectangle rcPixel(x, y, x+1, y+1);
+ pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes);
+ }
}
}
pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID());
pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID());
PRectangle rcIG(0, 0, 1, vs.lineHeight);
- pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated);
- pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated);
- pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
- pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
+ pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back);
+ pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore);
+ pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back);
+ pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore);
for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) {
- pixmapIndentGuide->MoveTo(0, stripe);
- pixmapIndentGuide->LineTo(2, stripe);
- pixmapIndentGuideHighlight->MoveTo(0, stripe);
- pixmapIndentGuideHighlight->LineTo(2, stripe);
+ PRectangle rcPixel(0, stripe, 1, stripe+1);
+ pixmapIndentGuide->FillRectangle(rcPixel, vs.styles[STYLE_INDENTGUIDE].fore);
+ pixmapIndentGuideHighlight->FillRectangle(rcPixel, vs.styles[STYLE_BRACELIGHT].fore);
}
}
const bool mainCaret = r == sel.Main();
const SelectionPosition posCaret = (drawDrag ? posDrag : sel.Range(r).caret);
const int offset = posCaret.Position() - posLineStart;
- const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
- const int virtualOffset = posCaret.VirtualSpace() * spaceWidth;
+ const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
+ const XYPOSITION virtualOffset = posCaret.VirtualSpace() * spaceWidth;
if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) {
- int xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)];
+ XYPOSITION xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)];
if (ll->wrapIndent != 0) {
int lineStart = ll->LineStart(subLine);
if (lineStart != 0) // Wrapped
bool caretAtEOF = false;
bool caretAtEOL = false;
bool drawBlockCaret = false;
- int widthOverstrikeCaret;
+ XYPOSITION widthOverstrikeCaret;
int caretWidthOffset = 0;
PRectangle rcCaret = rcLine;
rcCaret.left = xposCaret - caretWidthOffset;
rcCaret.right = rcCaret.left + vsDraw.caretWidth;
}
- ColourAllocated caretColour = mainCaret ? vsDraw.caretcolour.allocated : vsDraw.additionalCaretColour.allocated;
+ ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour;
if (drawBlockCaret) {
DrawBlockCaret(surface, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour);
} else {
void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
//Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
// paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
+ AllocateGraphics();
- pixmapLine->Release();
RefreshStyleData();
RefreshPixMaps(surfaceWindow);
+ StyleToPositionInView(PositionAfterArea(rcArea));
+
PRectangle rcClient = GetClientRectangle();
//Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n",
// rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
- surfaceWindow->SetPalette(&palette, true);
- pixmapLine->SetPalette(&palette, !hasFocus);
-
int screenLinePaintFirst = rcArea.top / vs.lineHeight;
- // The area to be painted plus one extra line is styled.
- // The extra line is to determine when a style change, such as starting a comment flows on to other lines.
- int lineStyleLast = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1;
- //Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast);
- int endPosPaint = pdoc->Length();
- if (lineStyleLast < cs.LinesDisplayed())
- endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast) + 1);
int xStart = vs.fixedColumnWidth - xOffset;
int ypos = 0;
ypos += screenLinePaintFirst * vs.lineHeight;
int yposScreen = screenLinePaintFirst * vs.lineHeight;
- // Ensure we are styled as far as we are painting.
- pdoc->EnsureStyledTo(endPosPaint);
bool paintAbandonedByStyling = paintState == paintAbandoned;
if (needUpdateUI) {
- // Deselect palette by selecting a temporary palette
- Palette palTemp;
- surfaceWindow->SetPalette(&palTemp, true);
-
NotifyUpdateUI();
- needUpdateUI = false;
+ needUpdateUI = 0;
RefreshStyleData();
RefreshPixMaps(surfaceWindow);
- surfaceWindow->SetPalette(&palette, true);
- pixmapLine->SetPalette(&palette, !hasFocus);
}
// Call priority lines wrap on a window of lines which are likely
}
PLATFORM_ASSERT(pixmapSelPattern->Initialised());
- PaintSelMargin(surfaceWindow, rcArea);
+ if (!bufferedDraw)
+ surfaceWindow->SetClip(rcArea);
+
+ if (paintState != paintAbandoned) {
+ PaintSelMargin(surfaceWindow, rcArea);
- PRectangle rcRightMargin = rcClient;
- rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
- if (rcArea.Intersects(rcRightMargin)) {
- surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated);
+ PRectangle rcRightMargin = rcClient;
+ rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
+ if (rcArea.Intersects(rcRightMargin)) {
+ surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back);
+ }
}
if (paintState == paintAbandoned) {
}
//Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset);
+ // Allow text at start of line to overlap 1 pixel into the margin as this displays
+ // serifs and italic stems for aliased text.
+ const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0;
+
// Do the painting
- if (rcArea.right > vs.fixedColumnWidth) {
+ if (rcArea.right > vs.fixedColumnWidth - leftTextOverlap) {
Surface *surface = surfaceWindow;
if (bufferedDraw) {
posCaret = posDrag;
int lineCaret = pdoc->LineFromPosition(posCaret.Position());
- // Remove selection margin from drawing area so text will not be drawn
- // on it in unbuffered mode.
PRectangle rcTextArea = rcClient;
rcTextArea.left = vs.fixedColumnWidth;
rcTextArea.right -= vs.rightMarginWidth;
- surfaceWindow->SetClip(rcTextArea);
+
+ // Remove selection margin from drawing area so text will not be drawn
+ // on it in unbuffered mode.
+ if (!bufferedDraw) {
+ PRectangle rcClipText = rcTextArea;
+ rcClipText.left -= leftTextOverlap;
+ surfaceWindow->SetClip(rcClipText);
+ }
// Loop on visible lines
//double durLayout = 0.0;
GetHotSpotRange(ll->hsStart, ll->hsEnd);
- PRectangle rcLine = rcClient;
+ PRectangle rcLine = rcTextArea;
rcLine.top = ypos;
rcLine.bottom = ypos + vs.lineHeight;
+ bool bracesIgnoreStyle = false;
+ if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
+ (vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
+ bracesIgnoreStyle = true;
+ }
Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
// Highlight the current braces if any
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
- highlightGuideColumn * vs.spaceWidth);
+ highlightGuideColumn * vs.spaceWidth, bracesIgnoreStyle);
+
+ if (leftTextOverlap && bufferedDraw) {
+ PRectangle rcSpacer = rcLine;
+ rcSpacer.right = rcSpacer.left;
+ rcSpacer.left -= 1;
+ surface->FillRectangle(rcSpacer, vs.styles[STYLE_DEFAULT].back);
+ }
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
//durPaint += et.Duration(true);
// Restore the previous styles for the brace highlights in case layout is in cache.
- ll->RestoreBracesHighlight(rangeLine, braces);
+ ll->RestoreBracesHighlight(rangeLine, braces, bracesIgnoreStyle);
bool expanded = cs.GetExpanded(lineDoc);
- // Paint the line above the fold
- if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
- ||
- (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
- if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+ const int level = pdoc->GetLevel(lineDoc);
+ const int levelNext = pdoc->GetLevel(lineDoc + 1);
+ if ((level & SC_FOLDLEVELHEADERFLAG) &&
+ ((level & SC_FOLDLEVELNUMBERMASK) < (levelNext & SC_FOLDLEVELNUMBERMASK))) {
+ // Paint the line above the fold
+ if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
+ ||
+ (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
PRectangle rcFoldLine = rcLine;
rcFoldLine.bottom = rcFoldLine.top + 1;
- surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+ surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore);
}
- }
- // Paint the line below the fold
- if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
- ||
- (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
- if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+ // Paint the line below the fold
+ if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
+ ||
+ (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
PRectangle rcFoldLine = rcLine;
rcFoldLine.top = rcFoldLine.bottom - 1;
- surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+ surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore);
}
}
DrawCarets(surface, vs, lineDoc, xStart, rcLine, ll, subLine);
if (bufferedDraw) {
- Point from(vs.fixedColumnWidth, 0);
- PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen,
- rcClient.right, yposScreen + vs.lineHeight);
+ Point from(vs.fixedColumnWidth-leftTextOverlap, 0);
+ PRectangle rcCopyArea(vs.fixedColumnWidth-leftTextOverlap, yposScreen,
+ rcClient.right - vs.rightMarginWidth, yposScreen + vs.lineHeight);
surfaceWindow->Copy(rcCopyArea, from, *pixmapLine);
}
// Right column limit indicator
PRectangle rcBeyondEOF = rcClient;
rcBeyondEOF.left = vs.fixedColumnWidth;
- rcBeyondEOF.right = rcBeyondEOF.right;
+ rcBeyondEOF.right = rcBeyondEOF.right - vs.rightMarginWidth;
rcBeyondEOF.top = (cs.LinesDisplayed() - topLine) * vs.lineHeight;
if (rcBeyondEOF.top < rcBeyondEOF.bottom) {
- surfaceWindow->FillRectangle(rcBeyondEOF, vs.styles[STYLE_DEFAULT].back.allocated);
+ surfaceWindow->FillRectangle(rcBeyondEOF, vs.styles[STYLE_DEFAULT].back);
if (vs.edgeState == EDGE_LINE) {
int edgeX = theEdge * vs.spaceWidth;
rcBeyondEOF.left = edgeX + xStart;
rcBeyondEOF.right = rcBeyondEOF.left + 1;
- surfaceWindow->FillRectangle(rcBeyondEOF, vs.edgecolour.allocated);
+ surfaceWindow->FillRectangle(rcBeyondEOF, vs.edgecolour);
}
}
//Platform::DebugPrintf(
if (!pfr)
return 0;
- AutoSurface surface(pfr->hdc, this);
+ AutoSurface surface(pfr->hdc, this, SC_TECHNOLOGY_DEFAULT);
if (!surface)
return 0;
- AutoSurface surfaceMeasure(pfr->hdcTarget, this);
+ AutoSurface surfaceMeasure(pfr->hdcTarget, this, SC_TECHNOLOGY_DEFAULT);
if (!surfaceMeasure) {
return 0;
}
posCache.Clear();
ViewStyle vsPrint(vs);
+ vsPrint.technology = SC_TECHNOLOGY_DEFAULT;
// Modify the view style for printing as do not normally want any of the transient features to be printed
// Printing supports only the line number margin.
vsPrint.ms[margin].width = 0;
}
}
- vsPrint.showMarkedLines = false;
vsPrint.fixedColumnWidth = 0;
vsPrint.zoomLevel = printMagnification;
+ // Don't show indentation guides
+ // If this ever gets changed, cached pixmap would need to be recreated if technology != SC_TECHNOLOGY_DEFAULT
vsPrint.viewIndentationGuides = ivNone;
// Don't show the selection when printing
vsPrint.selbackset = false;
vsPrint.whitespaceBackgroundSet = false;
vsPrint.whitespaceForegroundSet = false;
vsPrint.showCaretLineBackground = false;
+ // Don't highlight matching braces using indicators
+ vsPrint.braceHighlightIndicatorSet = false;
+ vsPrint.braceBadLightIndicatorSet = false;
// Set colours for printing according to users settings
- for (size_t sty = 0;sty < vsPrint.stylesSize;sty++) {
+ for (size_t sty = 0; sty < vsPrint.stylesSize; sty++) {
if (printColourMode == SC_PRINT_INVERTLIGHT) {
- vsPrint.styles[sty].fore.desired = InvertedLight(vsPrint.styles[sty].fore.desired);
- vsPrint.styles[sty].back.desired = InvertedLight(vsPrint.styles[sty].back.desired);
+ vsPrint.styles[sty].fore = InvertedLight(vsPrint.styles[sty].fore);
+ vsPrint.styles[sty].back = InvertedLight(vsPrint.styles[sty].back);
} else if (printColourMode == SC_PRINT_BLACKONWHITE) {
- vsPrint.styles[sty].fore.desired = ColourDesired(0, 0, 0);
- vsPrint.styles[sty].back.desired = ColourDesired(0xff, 0xff, 0xff);
+ vsPrint.styles[sty].fore = ColourDesired(0, 0, 0);
+ vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff);
} else if (printColourMode == SC_PRINT_COLOURONWHITE) {
- vsPrint.styles[sty].back.desired = ColourDesired(0xff, 0xff, 0xff);
+ vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff);
} else if (printColourMode == SC_PRINT_COLOURONWHITEDEFAULTBG) {
if (sty <= STYLE_DEFAULT) {
- vsPrint.styles[sty].back.desired = ColourDesired(0xff, 0xff, 0xff);
+ vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff);
}
}
}
// White background for the line numbers
- vsPrint.styles[STYLE_LINENUMBER].back.desired = ColourDesired(0xff, 0xff, 0xff);
+ vsPrint.styles[STYLE_LINENUMBER].back = ColourDesired(0xff, 0xff, 0xff);
+
+ // Printing uses different margins, so reset screen margins
+ vsPrint.leftMarginWidth = 0;
+ vsPrint.rightMarginWidth = 0;
vsPrint.Refresh(*surfaceMeasure);
// Determining width must hapen after fonts have been realised in Refresh
vsPrint.ms[lineNumberIndex].width = lineNumberWidth;
vsPrint.Refresh(*surfaceMeasure); // Recalculate fixedColumnWidth
}
- // Ensure colours are set up
- vsPrint.RefreshColourPalette(palette, true);
- vsPrint.RefreshColourPalette(palette, false);
int linePrintStart = pdoc->LineFromPosition(pfr->chrg.cpMin);
int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1;
int nPrintPos = pfr->chrg.cpMin;
int visibleLine = 0;
- int widthPrint = pfr->rc.Width() - vsPrint.fixedColumnWidth;
+ int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth;
if (printWrapState == eWrapNone)
widthPrint = LineLayout::wrapWidthInfinite;
surface->FlushCachedState();
surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
ypos + vsPrint.maxAscent, number, istrlen(number),
- vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
- vsPrint.styles[STYLE_LINENUMBER].back.allocated);
+ vsPrint.styles[STYLE_LINENUMBER].fore,
+ vsPrint.styles[STYLE_LINENUMBER].back);
}
// Draw the line
}
void Editor::ChangeSize() {
- DropGraphics();
+ DropGraphics(false);
SetScrollBars();
if (wrapState != eWrapNone) {
PRectangle rcTextArea = GetClientRectangle();
}
}
+static bool cmpSelPtrs(const SelectionRange *a, const SelectionRange *b) {
+ return *a < *b;
+}
+
// AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
FilterSelections();
{
UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
- for (size_t r=0; r<sel.Count(); r++) {
- if (!RangeContainsProtected(sel.Range(r).Start().Position(),
- sel.Range(r).End().Position())) {
- int positionInsert = sel.Range(r).Start().Position();
- if (!sel.Range(r).Empty()) {
- if (sel.Range(r).Length()) {
- pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
- sel.Range(r).ClearVirtualSpace();
+
+ std::vector<SelectionRange *> selPtrs;
+ for (size_t r = 0; r < sel.Count(); r++) {
+ selPtrs.push_back(&sel.Range(r));
+ }
+ std::sort(selPtrs.begin(), selPtrs.end(), cmpSelPtrs);
+
+ for (std::vector<SelectionRange *>::reverse_iterator rit = selPtrs.rbegin();
+ rit != selPtrs.rend(); ++rit) {
+ SelectionRange *currentSel = *rit;
+ if (!RangeContainsProtected(currentSel->Start().Position(),
+ currentSel->End().Position())) {
+ int positionInsert = currentSel->Start().Position();
+ if (!currentSel->Empty()) {
+ if (currentSel->Length()) {
+ pdoc->DeleteChars(positionInsert, currentSel->Length());
+ currentSel->ClearVirtualSpace();
} else {
// Range is all virtual so collapse to start of virtual space
- sel.Range(r).MinimizeVirtualSpace();
+ currentSel->MinimizeVirtualSpace();
}
} else if (inOverstrike) {
if (positionInsert < pdoc->Length()) {
if (!IsEOLChar(pdoc->CharAt(positionInsert))) {
pdoc->DelChar(positionInsert);
- sel.Range(r).ClearVirtualSpace();
+ currentSel->ClearVirtualSpace();
}
}
}
- positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+ positionInsert = InsertSpace(positionInsert, currentSel->caret.VirtualSpace());
if (pdoc->InsertString(positionInsert, s, len)) {
- sel.Range(r).caret.SetPosition(positionInsert + len);
- sel.Range(r).anchor.SetPosition(positionInsert + len);
+ currentSel->caret.SetPosition(positionInsert + len);
+ currentSel->anchor.SetPosition(positionInsert + len);
}
- sel.Range(r).ClearVirtualSpace();
+ currentSel->ClearVirtualSpace();
// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
if (wrapState != eWrapNone) {
AutoSurface surface(this);
if (surface) {
- WrapOneLine(surface, pdoc->LineFromPosition(positionInsert));
+ if (WrapOneLine(surface, pdoc->LineFromPosition(positionInsert))) {
+ SetScrollBars();
+ SetVerticalScrollPos();
+ Redraw();
+ }
}
}
}
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) ||
+ ((caretSticky == SC_CARETSTICKY_WHITESPACE) && !IsAllSpacesOrTabs(s, len))) {
SetLastXChosen();
}
}
}
-void Editor::ClearSelection() {
- if (!sel.IsRectangular())
+void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) {
+ if (multiPasteMode == SC_MULTIPASTE_ONCE) {
+ selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace()));
+ if (pdoc->InsertString(selStart.Position(), text, len)) {
+ SetEmptySelection(selStart.Position() + len);
+ }
+ } else {
+ // SC_MULTIPASTE_EACH
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (!RangeContainsProtected(sel.Range(r).Start().Position(),
+ sel.Range(r).End().Position())) {
+ int positionInsert = sel.Range(r).Start().Position();
+ if (!sel.Range(r).Empty()) {
+ if (sel.Range(r).Length()) {
+ pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
+ sel.Range(r).ClearVirtualSpace();
+ } else {
+ // Range is all virtual so collapse to start of virtual space
+ sel.Range(r).MinimizeVirtualSpace();
+ }
+ }
+ positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+ if (pdoc->InsertString(positionInsert, text, len)) {
+ sel.Range(r).caret.SetPosition(positionInsert + len);
+ sel.Range(r).anchor.SetPosition(positionInsert + len);
+ }
+ sel.Range(r).ClearVirtualSpace();
+ }
+ }
+ }
+}
+
+void Editor::ClearSelection(bool retainMultipleSelections) {
+ if (!sel.IsRectangular() && !retainMultipleSelections)
FilterSelections();
UndoGroup ug(pdoc);
for (size_t r=0; r<sel.Count(); r++) {
}
void Editor::Clear() {
- UndoGroup ug(pdoc);
// If multiple selections, don't delete EOLS
if (sel.Empty()) {
+ bool singleVirtual = false;
+ if ((sel.Count() == 1) &&
+ !RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1) &&
+ sel.RangeMain().Start().VirtualSpace()) {
+ singleVirtual = true;
+ }
+ UndoGroup ug(pdoc, (sel.Count() > 1) || singleVirtual);
for (size_t r=0; r<sel.Count(); r++) {
if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
if (sel.Range(r).Start().VirtualSpace()) {
UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty());
if (sel.Empty()) {
for (size_t r=0; r<sel.Count(); r++) {
- if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+ if (!RangeContainsProtected(sel.Range(r).caret.Position() - 1, sel.Range(r).caret.Position())) {
if (sel.Range(r).caret.VirtualSpace()) {
sel.Range(r).caret.SetVirtualSpace(sel.Range(r).caret.VirtualSpace() - 1);
sel.Range(r).anchor.SetVirtualSpace(sel.Range(r).caret.VirtualSpace());
void Editor::NotifyFocus(bool) {}
+void Editor::SetCtrlID(int identifier) {
+ ctrlID = identifier;
+}
+
void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
SCNotification scn = {0};
scn.nmhdr.code = SCN_STYLENEEDED;
NotifyParent(scn);
}
-void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) {
+void Editor::NotifyStyleNeeded(Document *, void *, int endStyleNeeded) {
NotifyStyleToNeeded(endStyleNeeded);
}
+void Editor::NotifyLexerChanged(Document *, void *) {
+}
+
+void Editor::NotifyErrorOccurred(Document *, void *, int status) {
+ errorStatus = status;
+}
+
void Editor::NotifyChar(int ch) {
SCNotification scn = {0};
scn.nmhdr.code = SCN_CHARADDED;
NotifyParent(scn);
}
+void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) {
+ SCNotification scn = {0};
+ scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK;
+ scn.position = position;
+ scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+ (alt ? SCI_ALT : 0);
+ NotifyParent(scn);
+}
+
void Editor::NotifyUpdateUI() {
SCNotification scn = {0};
scn.nmhdr.code = SCN_UPDATEUI;
+ scn.updated = needUpdateUI;
NotifyParent(scn);
}
int marginClicked = -1;
int x = 0;
for (int margin = 0; margin < ViewStyle::margins; margin++) {
- if ((pt.x > x) && (pt.x < x + vs.ms[margin].width))
+ if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
marginClicked = margin;
x += vs.ms[margin].width;
}
}
// Notifications from document
-void Editor::NotifyModifyAttempt(Document*, void *) {
+void Editor::NotifyModifyAttempt(Document *, void *) {
//Platform::DebugPrintf("** Modify Attempt\n");
NotifyModifyAttempt();
}
-void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
+void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) {
//Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off");
NotifySavePoint(atSavePoint);
}
void Editor::CheckModificationForWrap(DocModification mh) {
if (mh.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) {
llc.Invalidate(LineLayout::llCheckTextAndStyle);
+ int lineDoc = pdoc->LineFromPosition(mh.position);
+ int lines = Platform::Maximum(0, mh.linesAdded);
if (wrapState != eWrapNone) {
- int lineDoc = pdoc->LineFromPosition(mh.position);
- int lines = Platform::Maximum(0, mh.linesAdded);
NeedWrapping(lineDoc, lineDoc + lines + 1);
}
+ RefreshStyleData();
// Fix up annotation heights
- int lineDoc = pdoc->LineFromPosition(mh.position);
- int lines = Platform::Maximum(0, mh.linesAdded);
SetAnnotationHeights(lineDoc, lineDoc + lines + 2);
}
}
}
}
-void Editor::NotifyModified(Document*, DocModification mh, void *) {
- needUpdateUI = true;
+void Editor::NotifyModified(Document *, DocModification mh, void *) {
+ ContainerNeedsUpdate(SC_UPDATE_CONTENT);
if (paintState == painting) {
CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
}
if (mh.modificationType & SC_MOD_CHANGELINESTATE) {
if (paintState == painting) {
CheckForChangeOutsidePaint(
- Range(pdoc->LineStart(mh.line), pdoc->LineStart(mh.line + 1)));
+ Range(pdoc->LineStart(mh.line), pdoc->LineStart(mh.line + 1)));
+ } else {
+ // Could check that change is before last visible line.
+ Redraw();
+ }
+ }
+ if (mh.modificationType & SC_MOD_LEXERSTATE) {
+ if (paintState == painting) {
+ CheckForChangeOutsidePaint(
+ Range(mh.position, mh.position + mh.length));
} else {
- // Could check that change is before last visible line.
Redraw();
}
}
braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length);
braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length);
}
- if (cs.LinesDisplayed() < cs.LinesInDoc()) {
+ if ((mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) && cs.HiddenLines()) {
// Some lines are hidden so may need shown.
// TODO: check if the modified area is hidden.
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
- NotifyNeedShown(mh.position, 0);
+ int lineOfPos = pdoc->LineFromPosition(mh.position);
+ bool insertingNewLine = false;
+ for (int i=0; i < mh.length; i++) {
+ if ((mh.text[i] == '\n') || (mh.text[i] == '\r'))
+ insertingNewLine = true;
+ }
+ if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos)))
+ NotifyNeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position);
+ else
+ NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length);
}
int lineDoc = pdoc->LineFromPosition(mh.position);
if (vs.annotationVisible) {
cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded);
+ Redraw();
}
}
CheckModificationForWrap(mh);
// TODO: could invalidate from mh.startModification to end of screen
//InvalidateRange(mh.position, mh.position + mh.length);
if (paintState == notPainting && !CanDeferToLastStep(mh)) {
+ QueueStyling(pdoc->Length());
Redraw();
}
} else {
//Platform::DebugPrintf("** %x Line Changed %d .. %d\n", this,
// mh.position, mh.position + mh.length);
if (paintState == notPainting && mh.length && !CanEliminate(mh)) {
+ QueueStyling(mh.position + mh.length);
InvalidateRange(mh.position, mh.position + mh.length);
}
}
}
if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) {
- if ((paintState == notPainting) || !PaintContainsMargin()) {
+ if ((!willRedrawAll) && ((paintState == notPainting) || !PaintContainsMargin())) {
if (mh.modificationType & SC_MOD_CHANGEFOLD) {
// Fold changes can affect the drawing of following lines so redraw whole margin
- RedrawSelMargin();
+ RedrawSelMargin(highlightDelimiter.isEnabled ? -1 : mh.line-1, true);
} else {
RedrawSelMargin(mh.line);
}
case SCI_PAGEDOWNRECTEXTEND:
case SCI_SELECTIONDUPLICATE:
case SCI_COPYALLOWLINE:
+ case SCI_VERTICALCENTRECARET:
+ case SCI_MOVESELECTEDLINESUP:
+ case SCI_MOVESELECTEDLINESDOWN:
+ case SCI_SCROLLTOSTART:
+ case SCI_SCROLLTOEND:
break;
// Filter out all others like display changes. Also, newlines are redundant
NotifyParent(scn);
}
+// Something has changed that the container should know about
+void Editor::ContainerNeedsUpdate(int flags) {
+ needUpdateUI |= flags;
+}
+
/**
* Force scroll and keep position relative to top of window.
*
* If stuttered = true and already at first/last row, scroll as normal.
*/
void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) {
- int topLineNew, newPos;
+ int topLineNew;
+ SelectionPosition newPos;
- // I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem?
int currentLine = pdoc->LineFromPosition(sel.MainCaret());
int topStutterLine = topLine + caretYSlop;
int bottomStutterLine =
pdoc->LineFromPosition(PositionFromLocation(
- Point(lastXChosen, direction * vs.lineHeight * LinesToScroll())))
+ Point(lastXChosen - xOffset, direction * vs.lineHeight * LinesToScroll())))
- caretYSlop - 1;
if (stuttered && (direction < 0 && currentLine > topStutterLine)) {
topLineNew = topLine;
- newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * caretYSlop));
+ newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * caretYSlop),
+ false, false, UserVirtualSpace());
} else if (stuttered && (direction > 0 && currentLine < bottomStutterLine)) {
topLineNew = topLine;
- newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * (LinesToScroll() - caretYSlop)));
+ newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * (LinesToScroll() - caretYSlop)),
+ false, false, UserVirtualSpace());
} else {
Point pt = LocationFromPosition(sel.MainCaret());
topLineNew = Platform::Clamp(
topLine + direction * LinesToScroll(), 0, MaxScrollPos());
- newPos = PositionFromLocation(
- Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll())));
+ newPos = SPositionFromLocation(
+ Point(lastXChosen - xOffset, pt.y + direction * (vs.lineHeight * LinesToScroll())),
+ false, false, UserVirtualSpace());
}
if (topLineNew != topLine) {
SetTopLine(topLineNew);
- MovePositionTo(SelectionPosition(newPos), selt);
+ MovePositionTo(newPos, selt);
Redraw();
SetVerticalScrollPos();
} else {
- MovePositionTo(SelectionPosition(newPos), selt);
+ MovePositionTo(newPos, selt);
}
}
-void Editor::ChangeCaseOfSelection(bool makeUpperCase) {
+void Editor::ChangeCaseOfSelection(int caseMapping) {
UndoGroup ug(pdoc);
for (size_t r=0; r<sel.Count(); r++) {
SelectionRange current = sel.Range(r);
- pdoc->ChangeCase(Range(current.Start().Position(), current.End().Position()),
- makeUpperCase);
- // Automatic movement cuts off last character so reset to exactly the same as it was.
- sel.Range(r) = current;
+ SelectionRange currentNoVS = current;
+ currentNoVS.ClearVirtualSpace();
+ char *text = CopyRange(currentNoVS.Start().Position(), currentNoVS.End().Position());
+ size_t rangeBytes = currentNoVS.Length();
+ if (rangeBytes > 0) {
+ std::string sText(text, rangeBytes);
+
+ std::string sMapped = CaseMapString(sText, caseMapping);
+
+ if (sMapped != sText) {
+ size_t firstDifference = 0;
+ while (sMapped[firstDifference] == sText[firstDifference])
+ firstDifference++;
+ size_t lastDifference = sMapped.size() - 1;
+ while (sMapped[lastDifference] == sText[lastDifference])
+ lastDifference--;
+ size_t endSame = sMapped.size() - 1 - lastDifference;
+ pdoc->DeleteChars(
+ static_cast<int>(currentNoVS.Start().Position() + firstDifference),
+ static_cast<int>(rangeBytes - firstDifference - endSame));
+ pdoc->InsertString(
+ static_cast<int>(currentNoVS.Start().Position() + firstDifference),
+ sMapped.c_str() + firstDifference,
+ static_cast<int>(lastDifference - firstDifference + 1));
+ // Automatic movement changes selection so reset to exactly the same as it was.
+ sel.Range(r) = current;
+ }
+ }
+ delete []text;
}
}
if (sel.Empty()) {
forLine = true;
}
- UndoGroup ug(pdoc, sel.Count() > 1);
- SelectionPosition last;
+ UndoGroup ug(pdoc);
const char *eol = "";
int eolLen = 0;
if (forLine) {
}
void Editor::NewLine() {
- ClearSelection();
+ // Remove non-main ranges
+ InvalidateSelection(sel.RangeMain(), true);
+ sel.SetSelection(sel.RangeMain());
+
+ // Clear main range and insert line end
+ bool needGroupUndo = !sel.Empty();
+ if (needGroupUndo)
+ pdoc->BeginUndoAction();
+
+ if (!sel.Empty())
+ ClearSelection();
const char *eol = "\n";
if (pdoc->eolMode == SC_EOL_CRLF) {
eol = "\r\n";
} else if (pdoc->eolMode == SC_EOL_CR) {
eol = "\r";
} // else SC_EOL_LF -> "\n" already set
- if (pdoc->InsertCString(sel.MainCaret(), eol)) {
+ bool inserted = pdoc->InsertCString(sel.MainCaret(), eol);
+ // Want to end undo group before NotifyChar as applications often modify text here
+ if (needGroupUndo)
+ pdoc->EndUndoAction();
+ if (inserted) {
SetEmptySelection(sel.MainCaret() + istrlen(eol));
while (*eol) {
NotifyChar(*eol);
caretToUse = sel.Rectangular().caret;
}
}
+
Point pt = LocationFromPosition(caretToUse);
- int lineDoc = pdoc->LineFromPosition(caretToUse.Position());
- Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc));
- int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
- int commentLines = vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0;
- SelectionPosition posNew = SPositionFromLocation(
- Point(lastXChosen, pt.y + direction * vs.lineHeight), false, false, UserVirtualSpace());
- if ((direction > 0) && (subLine >= (cs.GetHeight(lineDoc) - 1 - commentLines))) {
- posNew = SPositionFromLocation(
- Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
+ int skipLines = 0;
+
+ if (vs.annotationVisible) {
+ int lineDoc = pdoc->LineFromPosition(caretToUse.Position());
+ Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc));
+ int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
+
+ if (direction < 0 && subLine == 0) {
+ int lineDisplay = cs.DisplayFromDoc(lineDoc);
+ if (lineDisplay > 0) {
+ skipLines = pdoc->AnnotationLines(cs.DocFromDisplay(lineDisplay - 1));
+ }
+ } else if (direction > 0 && subLine >= (cs.GetHeight(lineDoc) - 1 - pdoc->AnnotationLines(lineDoc))) {
+ skipLines = pdoc->AnnotationLines(lineDoc);
+ }
}
+
+ int newY = pt.y + (1 + skipLines) * direction * vs.lineHeight;
+ SelectionPosition posNew = SPositionFromLocation(
+ Point(lastXChosen - xOffset, newY), false, false, UserVirtualSpace());
+
if (direction < 0) {
// Line wrapping may lead to a location on the same line, so
// seek back if that is the case.
- // There is an equivalent case when moving down which skips
- // over a line but as that does not trap the user it is fine.
Point ptNew = LocationFromPosition(posNew.Position());
while ((posNew.Position() > 0) && (pt.y == ptNew.y)) {
- posNew.Add(- 1);
+ posNew.Add(-1);
+ posNew.SetVirtualSpace(0);
+ ptNew = LocationFromPosition(posNew.Position());
+ }
+ } else if (direction > 0 && posNew.Position() != pdoc->Length()) {
+ // There is an equivalent case when moving down which skips
+ // over a line.
+ Point ptNew = LocationFromPosition(posNew.Position());
+ while ((posNew.Position() > caretToUse.Position()) && (ptNew.y > newY)) {
+ posNew.Add(-1);
posNew.SetVirtualSpace(0);
ptNew = LocationFromPosition(posNew.Position());
}
}
- MovePositionTo(posNew, selt);
+
+ MovePositionTo(MovePositionSoVisible(posNew, direction), selt);
}
void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) {
inOverstrike = !inOverstrike;
DropCaret();
ShowCaretAtCurrentPosition();
+ ContainerNeedsUpdate(SC_UPDATE_CONTENT);
NotifyUpdateUI();
break;
case SCI_CANCEL: // Cancel any modes - handled in subclass
break;
case SCI_DELETEBACK:
DelCharBack(true);
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
break;
case SCI_DELETEBACKNOTLINE:
DelCharBack(false);
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
break;
case SCI_TAB:
Indent(true);
- if (!caretSticky) {
+ if (caretSticky == SC_CARETSTICKY_OFF) {
SetLastXChosen();
}
EnsureCaretVisible();
break;
case SCI_BACKTAB:
Indent(false);
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
UndoGroup ug(pdoc);
sel.RangeMain().caret = SelectionPosition(
InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+ sel.RangeMain().anchor = sel.RangeMain().caret;
int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
}
Duplicate(false);
break;
case SCI_LOWERCASE:
- ChangeCaseOfSelection(false);
+ ChangeCaseOfSelection(cmLower);
break;
case SCI_UPPERCASE:
- ChangeCaseOfSelection(true);
+ ChangeCaseOfSelection(cmUpper);
break;
case SCI_WORDPARTLEFT:
MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1));
StartEndDisplayLine(sel.MainCaret(), false), 1), Selection::selStream);
SetLastXChosen();
break;
+ case SCI_SCROLLTOSTART:
+ ScrollTo(0);
+ break;
+ case SCI_SCROLLTOEND:
+ ScrollTo(MaxScrollPos());
+ break;
}
return 0;
}
return 0;
}
-int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
+int Editor::KeyDownWithModifiers(int key, int modifiers, bool *consumed) {
DwellEnd(false);
- int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
- (alt ? SCI_ALT : 0);
int msg = kmap.Find(key, modifiers);
if (msg) {
if (consumed)
}
}
-void Editor::SetWhitespaceVisible(int view) {
- vs.viewWhitespace = static_cast<WhiteSpaceVisibility>(view);
-}
-
-int Editor::GetWhitespaceVisible() {
- return vs.viewWhitespace;
+int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
+ int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+ (alt ? SCI_ALT : 0);
+ return KeyDownWithModifiers(key, modifiers, consumed);
}
void Editor::Indent(bool forwards) {
int indentation = pdoc->GetLineIndentation(lineCurrentPos);
int indentationStep = pdoc->IndentSize();
pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
- SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+ sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos));
} else {
int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) *
pdoc->tabInChars;
}
}
+class CaseFolderASCII : public CaseFolderTable {
+public:
+ CaseFolderASCII() {
+ StandardASCII();
+ }
+ ~CaseFolderASCII() {
+ }
+};
+
+
+CaseFolder *Editor::CaseFolderForEncoding() {
+ // Simple default that only maps ASCII upper case to lower case.
+ return new CaseFolderASCII();
+}
+
/**
* Search of a text in the document, in the given range.
* @return The position of the found text, -1 if not found.
Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
int lengthFound = istrlen(ft->lpstrText);
+ std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound);
+ &lengthFound,
+ pcf.get());
if (pos != -1) {
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
searchAnchor = SelectionStart().Position();
}
+// Simple RAII wrapper for CaseFolder as std::auto_ptr is now deprecated
+class ScopedCaseFolder {
+ CaseFolder *pcf;
+public:
+ ScopedCaseFolder(CaseFolder *pcf_) : pcf(pcf_) {
+ }
+ ~ScopedCaseFolder() {
+ delete pcf;
+ pcf = 0;
+ }
+ CaseFolder *get() const { return pcf; }
+};
+
/**
* Find text from current search anchor: Must call @c SearchAnchor first.
* Used for next text and previous text requests.
const char *txt = reinterpret_cast<char *>(lParam);
int pos;
int lengthFound = istrlen(txt);
+ ScopedCaseFolder pcf(CaseFolderForEncoding());
if (iMessage == SCI_SEARCHNEXT) {
pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound);
+ &lengthFound,
+ pcf.get());
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound);
+ &lengthFound,
+ pcf.get());
}
-
if (pos != -1) {
SetSelection(pos, pos + lengthFound);
}
return pos;
}
+std::string Editor::CaseMapString(const std::string &s, int caseMapping) {
+ std::string ret(s);
+ for (size_t i=0; i<ret.size(); i++) {
+ switch (caseMapping) {
+ case cmUpper:
+ if (ret[i] >= 'a' && ret[i] <= 'z')
+ ret[i] = static_cast<char>(ret[i] - 'a' + 'A');
+ break;
+ case cmLower:
+ if (ret[i] >= 'A' && ret[i] <= 'Z')
+ ret[i] = static_cast<char>(ret[i] - 'A' + 'a');
+ break;
+ }
+ }
+ return ret;
+}
+
/**
* Search for text in the target range of the document.
* @return The position of the found text, -1 if not found.
*/
long Editor::SearchInTarget(const char *text, int length) {
int lengthFound = length;
+
+ ScopedCaseFolder pcf(CaseFolderForEncoding());
int pos = pdoc->FindText(targetStart, targetEnd, text,
(searchFlags & SCFIND_MATCHCASE) != 0,
(searchFlags & SCFIND_WHOLEWORD) != 0,
(searchFlags & SCFIND_WORDSTART) != 0,
(searchFlags & SCFIND_REGEXP) != 0,
searchFlags,
- &lengthFound);
+ &lengthFound,
+ pcf.get());
if (pos != -1) {
targetStart = pos;
targetEnd = pos + lengthFound;
return text;
}
+std::string Editor::RangeText(int start, int end) const {
+ if (start < end) {
+ int len = end - start;
+ std::string ret(len, '\0');
+ for (int i = 0; i < len; i++) {
+ ret[i] = pdoc->CharAt(start + i);
+ }
+ return ret;
+ }
+ return std::string();
+}
+
void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
if (sel.Empty()) {
if (allowLineCopy) {
int end = pdoc->LineEnd(currentLine);
char *text = CopyRange(start, end);
- int textLen = text ? strlen(text) : 0;
+ size_t textLen = text ? strlen(text) : 0;
// include room for \r\n\0
textLen += 3;
char *textWithEndl = new char[textLen];
strncat(textWithEndl, "\r", textLen);
if (pdoc->eolMode != SC_EOL_CR)
strncat(textWithEndl, "\n", textLen);
- ss->Set(textWithEndl, strlen(textWithEndl) + 1,
+ ss->Set(textWithEndl, static_cast<int>(strlen(textWithEndl) + 1),
pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, true);
delete []text;
}
delimiterLength = 1;
}
}
- int size = sel.Length() + delimiterLength * sel.Count();
+ size_t size = sel.Length() + delimiterLength * sel.Count();
char *text = new char[size + 1];
int j = 0;
- wxVector<SelectionRange> rangesInOrder = sel.RangesCopy();
+ std::vector<SelectionRange> rangesInOrder = sel.RangesCopy();
if (sel.selType == Selection::selRectangle)
- wxVectorSort(rangesInOrder);
+ std::sort(rangesInOrder.begin(), rangesInOrder.end());
for (size_t r=0; r<rangesInOrder.size(); r++) {
SelectionRange current = rangesInOrder[r];
for (int i = current.Start().Position();
}
}
text[size] = '\0';
- ss->Set(text, size + 1, pdoc->dbcsCodePage,
+ ss->Set(text, static_cast<int>(size + 1), pdoc->dbcsCodePage,
vs.styles[STYLE_DEFAULT].characterSet, sel.IsRectangular(), sel.selType == Selection::selLines);
}
}
}
bool Editor::PointInSelection(Point pt) {
- SelectionPosition pos = SPositionFromLocation(pt);
- int xPos = XFromPosition(pos);
+ SelectionPosition pos = SPositionFromLocation(pt, false, true);
+ Point ptPos = LocationFromPosition(pos);
for (size_t r=0; r<sel.Count(); r++) {
SelectionRange range = sel.Range(r);
if (range.Contains(pos)) {
bool hit = true;
if (pos == range.Start()) {
// see if just before selection
- if (pt.x < xPos) {
+ if (pt.x < ptPos.x) {
hit = false;
}
}
if (pos == range.End()) {
// see if just after selection
- if (pt.x > xPos) {
+ if (pt.x > ptPos.x) {
hit = false;
}
}
}
}
-void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
- if (lineAnchor_ < lineCurrent_) {
- SetSelection(pdoc->LineStart(lineCurrent_ + 1),
- pdoc->LineStart(lineAnchor_));
- } else if (lineAnchor_ > lineCurrent_) {
- SetSelection(pdoc->LineStart(lineCurrent_),
- pdoc->LineStart(lineAnchor_ + 1));
- } else { // Same line, select it
- SetSelection(pdoc->LineStart(lineAnchor_ + 1),
- pdoc->LineStart(lineAnchor_));
+Window::Cursor Editor::GetMarginCursor(Point pt) {
+ int x = 0;
+ for (int margin = 0; margin < ViewStyle::margins; margin++) {
+ if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
+ return static_cast<Window::Cursor>(vs.ms[margin].cursor);
+ x += vs.ms[margin].width;
+ }
+ return Window::cursorReverseArrow;
+}
+
+void Editor::TrimAndSetSelection(int currentPos_, int anchor_) {
+ sel.TrimSelection(SelectionRange(currentPos_, anchor_));
+ SetSelection(currentPos_, anchor_);
+}
+
+void Editor::LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine) {
+ int selCurrentPos, selAnchorPos;
+ if (wholeLine) {
+ int lineCurrent_ = pdoc->LineFromPosition(lineCurrentPos_);
+ int lineAnchor_ = pdoc->LineFromPosition(lineAnchorPos_);
+ if (lineAnchorPos_ < lineCurrentPos_) {
+ selCurrentPos = pdoc->LineStart(lineCurrent_ + 1);
+ selAnchorPos = pdoc->LineStart(lineAnchor_);
+ } else if (lineAnchorPos_ > lineCurrentPos_) {
+ selCurrentPos = pdoc->LineStart(lineCurrent_);
+ selAnchorPos = pdoc->LineStart(lineAnchor_ + 1);
+ } else { // Same line, select it
+ selCurrentPos = pdoc->LineStart(lineAnchor_ + 1);
+ selAnchorPos = pdoc->LineStart(lineAnchor_);
+ }
+ } else {
+ if (lineAnchorPos_ < lineCurrentPos_) {
+ selCurrentPos = StartEndDisplayLine(lineCurrentPos_, false) + 1;
+ selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1);
+ selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true);
+ } else if (lineAnchorPos_ > lineCurrentPos_) {
+ selCurrentPos = StartEndDisplayLine(lineCurrentPos_, true);
+ selAnchorPos = StartEndDisplayLine(lineAnchorPos_, false) + 1;
+ selAnchorPos = pdoc->MovePositionOutsideChar(selAnchorPos, 1);
+ } else { // Same line, select it
+ selCurrentPos = StartEndDisplayLine(lineAnchorPos_, false) + 1;
+ selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1);
+ selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true);
+ }
+ }
+ TrimAndSetSelection(selCurrentPos, selAnchorPos);
+}
+
+void Editor::WordSelection(int pos) {
+ if (pos < wordSelectAnchorStartPos) {
+ // Extend backward to the word containing pos.
+ // Skip ExtendWordSelect if the line is empty or if pos is after the last character.
+ // This ensures that a series of empty lines isn't counted as a single "word".
+ if (!pdoc->IsLineEndPosition(pos))
+ pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1);
+ TrimAndSetSelection(pos, wordSelectAnchorEndPos);
+ } else if (pos > wordSelectAnchorEndPos) {
+ // Extend forward to the word containing the character to the left of pos.
+ // Skip ExtendWordSelect if the line is empty or if pos is the first position on the line.
+ // This ensures that a series of empty lines isn't counted as a single "word".
+ if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos)))
+ pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1);
+ TrimAndSetSelection(pos, wordSelectAnchorStartPos);
+ } else {
+ // Select only the anchored word
+ if (pos >= originalAnchorPos)
+ TrimAndSetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos);
+ else
+ TrimAndSetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos);
}
}
}
}
-static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) {
- return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)
+void Editor::MouseLeave() {
+ SetHotSpotRange(NULL);
+ if (!HaveMouseCapture()) {
+ ptMouseLast = Point(-1,-1);
+ DwellEnd(true);
+ }
+}
+
+static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) {
+ return (!rectangular && ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0))
|| (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0));
}
inDragDrop = ddNone;
sel.SetMoveExtends(false);
- bool processed = NotifyMarginClick(pt, shift, ctrl, alt);
- if (processed)
+ if (NotifyMarginClick(pt, shift, ctrl, alt))
return;
NotifyIndicatorClick(true, newPos.Position(), shift, ctrl, alt);
bool inSelMargin = PointInSelMargin(pt);
- if (shift & !inSelMargin) {
- SetSelection(newPos.Position());
+ // In margin ctrl+(double)click should always select everything
+ if (ctrl && inSelMargin) {
+ SelectAll();
+ lastClickTime = curTime;
+ lastClick = pt;
+ return;
+ }
+ if (shift && !inSelMargin) {
+ SetSelection(newPos);
}
if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick)) {
//Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime);
SetMouseCapture(true);
- SetEmptySelection(newPos.Position());
+ if (!ctrl || !multipleSelection || (selectionType != selChar && selectionType != selWord))
+ SetEmptySelection(newPos.Position());
bool doubleClick = false;
// Stop mouse button bounce changing selection type
if (!Platform::MouseButtonBounce() || curTime != lastClickTime) {
- if (selectionType == selChar) {
- selectionType = selWord;
- doubleClick = true;
- } else if (selectionType == selWord) {
- selectionType = selLine;
+ if (inSelMargin) {
+ // Inside margin selection type should be either selSubLine or selWholeLine.
+ if (selectionType == selSubLine) {
+ // If it is selSubLine, we're inside a *double* click and word wrap is enabled,
+ // so we switch to selWholeLine in order to select whole line.
+ selectionType = selWholeLine;
+ } else if (selectionType != selSubLine && selectionType != selWholeLine) {
+ // If it is neither, reset selection type to line selection.
+ selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine;
+ }
} else {
- selectionType = selChar;
- originalAnchorPos = sel.MainCaret();
+ if (selectionType == selChar) {
+ selectionType = selWord;
+ doubleClick = true;
+ } else if (selectionType == selWord) {
+ // Since we ended up here, we're inside a *triple* click, which should always select
+ // whole line irregardless of word wrap being enabled or not.
+ selectionType = selWholeLine;
+ } else {
+ selectionType = selChar;
+ originalAnchorPos = sel.MainCaret();
+ }
}
}
if (selectionType == selWord) {
- if (sel.MainCaret() >= originalAnchorPos) { // Moved forward
- SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
- pdoc->ExtendWordSelect(originalAnchorPos, -1));
- } else { // Moved backward
- SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
- pdoc->ExtendWordSelect(originalAnchorPos, 1));
- }
- } else if (selectionType == selLine) {
- lineAnchor = LineFromLocation(pt);
- SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
+ int charPos = originalAnchorPos;
+ if (sel.MainCaret() == originalAnchorPos) {
+ charPos = PositionFromLocation(pt, false, true);
+ charPos = MovePositionOutsideChar(charPos, -1);
+ }
+
+ int startWord, endWord;
+ if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) {
+ startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1);
+ endWord = pdoc->ExtendWordSelect(charPos, 1);
+ } else {
+ // Selecting backwards, or anchor beyond last character on line. In these cases,
+ // we select the word containing the character to the *left* of the anchor.
+ if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) {
+ startWord = pdoc->ExtendWordSelect(charPos, -1);
+ endWord = pdoc->ExtendWordSelect(startWord, 1);
+ } else {
+ // Anchor at start of line; select nothing to begin with.
+ startWord = charPos;
+ endWord = charPos;
+ }
+ }
+
+ wordSelectAnchorStartPos = startWord;
+ wordSelectAnchorEndPos = endWord;
+ wordSelectInitialCaretPos = sel.MainCaret();
+ WordSelection(wordSelectInitialCaretPos);
+ } else if (selectionType == selSubLine || selectionType == selWholeLine) {
+ lineAnchorPos = newPos.Position();
+ LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine);
//Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
} else {
SetEmptySelection(sel.MainCaret());
} else { // Single click
if (inSelMargin) {
sel.selType = Selection::selStream;
- if (ctrl) {
- SelectAll();
- lastClickTime = curTime;
- return;
- }
if (!shift) {
- lineAnchor = LineFromLocation(pt);
- // Single click in margin: select whole line
- LineSelection(lineAnchor, lineAnchor);
- SetSelection(pdoc->LineStart(lineAnchor + 1),
- pdoc->LineStart(lineAnchor));
+ // Single click in margin: select whole line or only subline if word wrap is enabled
+ lineAnchorPos = newPos.Position();
+ selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine;
+ LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine);
} else {
// Single shift+click in margin: select from line anchor to clicked line
if (sel.MainAnchor() > sel.MainCaret())
- lineAnchor = pdoc->LineFromPosition(sel.MainAnchor() - 1);
+ lineAnchorPos = sel.MainAnchor() - 1;
else
- lineAnchor = pdoc->LineFromPosition(sel.MainAnchor());
- int lineStart = LineFromLocation(pt);
- LineSelection(lineStart, lineAnchor);
- //lineAnchor = lineStart; // Keep the same anchor for ButtonMove
+ lineAnchorPos = sel.MainAnchor();
+ // Reset selection type if there is an empty selection.
+ // This ensures that we don't end up stuck in previous selection mode, which is no longer valid.
+ // Otherwise, if there's a non empty selection, reset selection type only if it differs from selSubLine and selWholeLine.
+ // This ensures that we continue selecting in the same selection mode.
+ if (sel.Empty() || (selectionType != selSubLine && selectionType != selWholeLine))
+ selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine;
+ LineSelection(newPos.Position(), lineAnchorPos, selectionType == selWholeLine);
}
SetDragPosition(SelectionPosition(invalidPosition));
SetMouseCapture(true);
- selectionType = selLine;
} else {
if (PointIsHotspot(pt)) {
NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt);
+ hotSpotClickPos = PositionFromLocation(pt,true,false);
}
if (!shift) {
if (PointInSelection(pt) && !SelectionEmpty())
InvalidateSelection(SelectionRange(newPos), true);
if (sel.Count() > 1)
Redraw();
- sel.Clear();
+ if ((sel.Count() > 1) || (sel.selType != Selection::selStream))
+ sel.Clear();
sel.selType = alt ? Selection::selRectangle : Selection::selStream;
SetSelection(newPos, newPos);
}
}
}
lastClickTime = curTime;
- lastXChosen = pt.x;
+ lastClick = pt;
+ lastXChosen = pt.x + xOffset;
ShowCaretAtCurrentPosition();
}
}
}
-void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) {
+void Editor::GetHotSpotRange(int &hsStart_, int &hsEnd_) {
hsStart_ = hsStart;
hsEnd_ = hsEnd;
}
}
} else if (selectionType == selWord) {
// Continue selecting by word
- if (movePos.Position() == originalAnchorPos) { // Didn't move
+ if (movePos.Position() == wordSelectInitialCaretPos) { // Didn't move
// No need to do anything. Previously this case was lumped
// in with "Moved forward", but that can be harmful in this
// case: a handler for the NotifyDoubleClick re-adjusts
// the ButtonMove() called via Tick() for auto-scrolling
// could result in the fancier word selection adjustment
// being unmade.
- } else if (movePos.Position() > originalAnchorPos) { // Moved forward
- SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
- pdoc->ExtendWordSelect(originalAnchorPos, -1));
- } else { // Moved backward
- SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
- pdoc->ExtendWordSelect(originalAnchorPos, 1));
+ } else {
+ wordSelectInitialCaretPos = -1;
+ WordSelection(movePos.Position());
}
} else {
// Continue selecting by line
- int lineMove = LineFromLocation(pt);
- LineSelection(lineMove, lineAnchor);
+ LineSelection(movePos.Position(), lineAnchorPos, selectionType == selWholeLine);
}
}
// Autoscroll
PRectangle rcClient = GetClientRectangle();
+ int lineMove = DisplayFromPosition(movePos.Position());
if (pt.y > rcClient.bottom) {
- int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
- if (lineMove < 0) {
- lineMove = cs.DisplayFromDoc(pdoc->LinesTotal() - 1);
- }
ScrollTo(lineMove - LinesOnScreen() + 1);
Redraw();
} else if (pt.y < rcClient.top) {
- int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
- ScrollTo(lineMove - 1);
+ ScrollTo(lineMove);
Redraw();
}
EnsureCaretVisible(false, false, true);
if (hsStart != -1 && !PositionIsHotspot(movePos.Position()))
SetHotSpotRange(NULL);
+ if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) {
+ if (inDragDrop == ddNone) {
+ DisplayCursor(Window::cursorText);
+ }
+ hotSpotClickPos = INVALID_POSITION;
+ }
+
} else {
if (vs.fixedColumnWidth > 0) { // There is a margin
if (PointInSelMargin(pt)) {
- DisplayCursor(Window::cursorReverseArrow);
+ DisplayCursor(GetMarginCursor(pt));
+ SetHotSpotRange(NULL);
return; // No need to test for selection
}
}
newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position());
if (inDragDrop == ddInitial) {
inDragDrop = ddNone;
- SetEmptySelection(newPos.Position());
+ SetEmptySelection(newPos);
+ selectionType = selChar;
+ originalAnchorPos = sel.MainCaret();
+ }
+ if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
+ hotSpotClickPos = INVALID_POSITION;
+ NotifyHotSpotReleaseClick(newPos.Position(), false, ctrl, false);
}
if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) {
- DisplayCursor(Window::cursorReverseArrow);
+ DisplayCursor(GetMarginCursor(pt));
} else {
DisplayCursor(Window::cursorText);
SetHotSpotRange(NULL);
SetRectangularRange();
lastClickTime = curTime;
lastClick = pt;
- lastXChosen = pt.x;
+ lastXChosen = pt.x + xOffset;
if (sel.selType == Selection::selStream) {
SetLastXChosen();
}
}
if ((dwellDelay < SC_TIME_FOREVER) &&
(ticksToDwell > 0) &&
- (!HaveMouseCapture())) {
+ (!HaveMouseCapture()) &&
+ (ptMouseLast.y >= 0)) {
ticksToDwell -= timer.tickSize;
if (ticksToDwell <= 0) {
dwelling = true;
}
}
+int Editor::PositionAfterArea(PRectangle rcArea) {
+ // The start of the document line after the display line after the area
+ // This often means that the line after a modification is restyled which helps
+ // detect multiline comment additions and heals single line comments
+ int lineAfter = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1;
+ if (lineAfter < cs.LinesDisplayed())
+ return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1);
+ else
+ return pdoc->Length();
+}
+
+// Style to a position within the view. If this causes a change at end of last line then
+// affects later lines so style all the viewed text.
+void Editor::StyleToPositionInView(Position pos) {
+ int endWindow = PositionAfterArea(GetClientRectangle());
+ if (pos > endWindow)
+ pos = endWindow;
+ int styleAtEnd = pdoc->StyleAt(pos-1);
+ pdoc->EnsureStyledTo(pos);
+ if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) {
+ // Style at end of line changed so is multi-line change like starting a comment
+ // so require rest of window to be styled.
+ pdoc->EnsureStyledTo(endWindow);
+ }
+}
+
+void Editor::IdleStyling() {
+ // Style the line after the modification as this allows modifications that change just the
+ // line of the modification to heal instead of propagating to the rest of the window.
+ StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(styleNeeded.upTo) + 2));
+
+ if (needUpdateUI) {
+ NotifyUpdateUI();
+ needUpdateUI = 0;
+ }
+ styleNeeded.Reset();
+}
+
+void Editor::QueueStyling(int upTo) {
+ styleNeeded.NeedUpTo(upTo);
+}
+
bool Editor::PaintContains(PRectangle rc) {
if (rc.Empty()) {
return true;
void Editor::SetAnnotationHeights(int start, int end) {
if (vs.annotationVisible) {
- for (int line=start; line<end; line++) {
- cs.SetHeight(line, pdoc->AnnotationLines(line) + 1);
+ bool changedHeight = false;
+ for (int line=start; line<end && line<pdoc->LinesTotal(); line++) {
+ int linesWrapped = 1;
+ if (wrapState != eWrapNone) {
+ AutoSurface surface(this);
+ AutoLineLayout ll(llc, RetrieveLineLayout(line));
+ if (surface && ll) {
+ LayoutLine(line, surface, vs, ll, wrapWidth);
+ linesWrapped = ll->lines;
+ }
+ }
+ if (cs.SetHeight(line, pdoc->AnnotationLines(line) + linesWrapped))
+ changedHeight = true;
+ }
+ if (changedHeight) {
+ Redraw();
}
}
}
}
}
}
+ Redraw();
}
}
if (cs.GetExpanded(line)) {
int lineMaxSubord = pdoc->GetLastChild(line);
- cs.SetExpanded(line, 0);
if (lineMaxSubord > line) {
+ cs.SetExpanded(line, 0);
cs.SetVisible(line + 1, lineMaxSubord, false);
int lineCurrent = pdoc->LineFromPosition(sel.MainCaret());
}
}
+int Editor::ContractedFoldNext(int lineStart) {
+ for (int line = lineStart; line<pdoc->LinesTotal();) {
+ if (!cs.GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG))
+ return line;
+ line = cs.ContractedNext(line+1);
+ if (line < 0)
+ return -1;
+ }
+
+ return -1;
+}
+
/**
* Recurse up from this line to find any folds that prevent this line from being visible
* and unfold them all.
void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
// In case in need of wrapping to ensure DisplayFromDoc works.
- WrapLines(true, -1);
+ if (lineDoc >= wrapStart)
+ WrapLines(true, -1);
if (!cs.GetVisible(lineDoc)) {
- int lineParent = pdoc->GetFoldParent(lineDoc);
+ int lookLine = lineDoc;
+ int lookLineLevel = pdoc->GetLevel(lookLine);
+ while ((lookLine > 0) && (lookLineLevel & SC_FOLDLEVELWHITEFLAG)) {
+ lookLineLevel = pdoc->GetLevel(--lookLine);
+ }
+ int lineParent = pdoc->GetFoldParent(lookLine);
if (lineParent >= 0) {
if (lineDoc != lineParent)
EnsureLineVisible(lineParent, enforcePolicy);
}
}
+int Editor::GetTag(char *tagValue, int tagNumber) {
+ const char *text = 0;
+ int length = 0;
+ if ((tagNumber >= 1) && (tagNumber <= 9)) {
+ char name[3] = "\\?";
+ name[1] = static_cast<char>(tagNumber + '0');
+ length = 2;
+ text = pdoc->SubstituteByPosition(name, &length);
+ }
+ if (tagValue) {
+ if (text)
+ memcpy(tagValue, text, length + 1);
+ else
+ *tagValue = '\0';
+ }
+ return length;
+}
+
int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
UndoGroup ug(pdoc);
if (length == -1)
void Editor::AddStyledText(char *buffer, int appendLength) {
// The buffer consists of alternating character bytes and style bytes
- size_t textLength = appendLength / 2;
+ int textLength = appendLength / 2;
char *text = new char[textLength];
- size_t i;
- for (i = 0;i < textLength;i++) {
+ int i;
+ for (i = 0; i < textLength; i++) {
text[i] = buffer[i*2];
}
pdoc->InsertString(CurrentPosition(), text, textLength);
- for (i = 0;i < textLength;i++) {
+ for (i = 0; i < textLength; i++) {
text[i] = buffer[i*2+1];
}
pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
vs.EnsureStyle(wParam);
switch (iMessage) {
case SCI_STYLESETFORE:
- vs.styles[wParam].fore.desired = ColourDesired(lParam);
+ vs.styles[wParam].fore = ColourDesired(lParam);
break;
case SCI_STYLESETBACK:
- vs.styles[wParam].back.desired = ColourDesired(lParam);
+ vs.styles[wParam].back = ColourDesired(lParam);
break;
case SCI_STYLESETBOLD:
- vs.styles[wParam].bold = lParam != 0;
+ vs.styles[wParam].weight = lParam != 0 ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL;
+ break;
+ case SCI_STYLESETWEIGHT:
+ vs.styles[wParam].weight = lParam;
break;
case SCI_STYLESETITALIC:
vs.styles[wParam].italic = lParam != 0;
vs.styles[wParam].eolFilled = lParam != 0;
break;
case SCI_STYLESETSIZE:
+ vs.styles[wParam].size = lParam * SC_FONT_SIZE_MULTIPLIER;
+ break;
+ case SCI_STYLESETSIZEFRACTIONAL:
vs.styles[wParam].size = lParam;
break;
case SCI_STYLESETFONT:
vs.EnsureStyle(wParam);
switch (iMessage) {
case SCI_STYLEGETFORE:
- return vs.styles[wParam].fore.desired.AsLong();
+ return vs.styles[wParam].fore.AsLong();
case SCI_STYLEGETBACK:
- return vs.styles[wParam].back.desired.AsLong();
+ return vs.styles[wParam].back.AsLong();
case SCI_STYLEGETBOLD:
- return vs.styles[wParam].bold ? 1 : 0;
+ return vs.styles[wParam].weight > SC_WEIGHT_NORMAL;
+ case SCI_STYLEGETWEIGHT:
+ return vs.styles[wParam].weight;
case SCI_STYLEGETITALIC:
return vs.styles[wParam].italic ? 1 : 0;
case SCI_STYLEGETEOLFILLED:
return vs.styles[wParam].eolFilled ? 1 : 0;
case SCI_STYLEGETSIZE:
+ return vs.styles[wParam].size / SC_FONT_SIZE_MULTIPLIER;
+ case SCI_STYLEGETSIZEFRACTIONAL:
return vs.styles[wParam].size;
case SCI_STYLEGETFONT:
if (!vs.styles[wParam].fontName)
}
sptr_t Editor::StringResult(sptr_t lParam, const char *val) {
- const int n = strlen(val);
+ const size_t n = strlen(val);
if (lParam != 0) {
char *ptr = reinterpret_cast<char *>(lParam);
strcpy(ptr, val);
CopyAllowLine();
break;
+ case SCI_VERTICALCENTRECARET:
+ VerticalCentreCaret();
+ break;
+
+ case SCI_MOVESELECTEDLINESUP:
+ MoveSelectedLinesUp();
+ break;
+
+ case SCI_MOVESELECTEDLINESDOWN:
+ MoveSelectedLinesDown();
+ break;
+
case SCI_COPYRANGE:
CopyRangeToClipboard(wParam, lParam);
break;
case SCI_PASTE:
Paste();
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
case SCI_GETSEARCHFLAGS:
return searchFlags;
+ case SCI_GETTAG:
+ return GetTag(CharPtrFromSPtr(lParam), wParam);
+
case SCI_POSITIONBEFORE:
return pdoc->MovePositionOutsideChar(wParam - 1, -1, true);
case SCI_SETXOFFSET:
xOffset = wParam;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
SetHorizontalScrollPos();
Redraw();
break;
ClearAll();
return 0;
+ case SCI_DELETERANGE:
+ pdoc->DeleteChars(wParam, lParam);
+ return 0;
+
case SCI_CLEARDOCUMENTSTYLE:
ClearDocumentStyle();
return 0;
caret.period = wParam;
break;
+ case SCI_GETWORDCHARS:
+ return pdoc->GetCharsOfClass(CharClassify::ccWord, reinterpret_cast<unsigned char *>(lParam));
+
case SCI_SETWORDCHARS: {
pdoc->SetDefaultCharClasses(false);
if (lParam == 0)
}
break;
+ case SCI_GETWHITESPACECHARS:
+ return pdoc->GetCharsOfClass(CharClassify::ccSpace, reinterpret_cast<unsigned char *>(lParam));
+
case SCI_SETWHITESPACECHARS: {
if (lParam == 0)
return 0;
}
break;
+ case SCI_GETPUNCTUATIONCHARS:
+ return pdoc->GetCharsOfClass(CharClassify::ccPunctuation, reinterpret_cast<unsigned char *>(lParam));
+
+ case SCI_SETPUNCTUATIONCHARS: {
+ if (lParam == 0)
+ return 0;
+ pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), CharClassify::ccPunctuation);
+ }
+ break;
+
case SCI_SETCHARSDEFAULT:
pdoc->SetDefaultCharClasses(true);
break;
break;
case SCI_GETSELECTIONSTART:
- return Platform::Minimum(sel.MainAnchor(), sel.MainCaret());
+ return sel.LimitsForRectangularElseMain().start.Position();
case SCI_SETSELECTIONEND:
SetSelection(wParam, Platform::Minimum(sel.MainAnchor(), wParam));
break;
case SCI_GETSELECTIONEND:
- return Platform::Maximum(sel.MainAnchor(), sel.MainCaret());
+ return sel.LimitsForRectangularElseMain().end.Position();
+
+ case SCI_SETEMPTYSELECTION:
+ SetEmptySelection(wParam);
+ break;
case SCI_SETPRINTMAGNIFICATION:
printMagnification = wParam;
case SCI_GOTOPOS:
SetEmptySelection(wParam);
EnsureCaretVisible();
- Redraw();
break;
case SCI_GETCURLINE: {
break;
}
xOffset = 0;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
InvalidateStyleRedraw();
ReconfigureScrollBars();
break;
return wrapState;
case SCI_SETWRAPVISUALFLAGS:
- wrapVisualFlags = wParam;
- InvalidateStyleRedraw();
- ReconfigureScrollBars();
+ if (wrapVisualFlags != static_cast<int>(wParam)) {
+ wrapVisualFlags = wParam;
+ InvalidateStyleRedraw();
+ ReconfigureScrollBars();
+ }
break;
case SCI_GETWRAPVISUALFLAGS:
return wrapVisualFlagsLocation;
case SCI_SETWRAPSTARTINDENT:
- wrapVisualStartIndent = wParam;
- InvalidateStyleRedraw();
- ReconfigureScrollBars();
+ if (wrapVisualStartIndent != static_cast<int>(wParam)) {
+ wrapVisualStartIndent = wParam;
+ InvalidateStyleRedraw();
+ ReconfigureScrollBars();
+ }
break;
case SCI_GETWRAPSTARTINDENT:
return wrapVisualStartIndent;
case SCI_SETWRAPINDENTMODE:
- wrapIndentMode = wParam;
- InvalidateStyleRedraw();
- ReconfigureScrollBars();
+ if (wrapIndentMode != static_cast<int>(wParam)) {
+ wrapIndentMode = wParam;
+ InvalidateStyleRedraw();
+ ReconfigureScrollBars();
+ }
break;
case SCI_GETWRAPINDENTMODE:
return endAtLastLine;
case SCI_SETCARETSTICKY:
- PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
- if (caretSticky != (wParam != 0)) {
- caretSticky = wParam != 0;
+ PLATFORM_ASSERT(wParam <= SC_CARETSTICKY_WHITESPACE);
+ if (wParam <= SC_CARETSTICKY_WHITESPACE) {
+ caretSticky = wParam;
}
break;
case SCI_GETCODEPAGE:
return pdoc->dbcsCodePage;
+#ifdef INCLUDE_DEPRECATED_FEATURES
case SCI_SETUSEPALETTE:
- palette.allowRealization = wParam != 0;
InvalidateStyleRedraw();
break;
case SCI_GETUSEPALETTE:
- return palette.allowRealization;
+ return 0;
+#endif
// Marker definition and setting
case SCI_MARKERDEFINE:
- if (wParam <= MARKER_MAX)
+ if (wParam <= MARKER_MAX) {
vs.markers[wParam].markType = lParam;
+ vs.CalcLargestMarkerHeight();
+ }
InvalidateStyleData();
RedrawSelMargin();
break;
case SCI_MARKERSETFORE:
if (wParam <= MARKER_MAX)
- vs.markers[wParam].fore.desired = ColourDesired(lParam);
+ vs.markers[wParam].fore = ColourDesired(lParam);
+ InvalidateStyleData();
+ RedrawSelMargin();
+ break;
+ case SCI_MARKERSETBACKSELECTED:
+ if (wParam <= MARKER_MAX)
+ vs.markers[wParam].backSelected = ColourDesired(lParam);
InvalidateStyleData();
RedrawSelMargin();
break;
+ case SCI_MARKERENABLEHIGHLIGHT:
+ highlightDelimiter.isEnabled = wParam == 1;
+ RedrawSelMargin();
+ break;
case SCI_MARKERSETBACK:
if (wParam <= MARKER_MAX)
- vs.markers[wParam].back.desired = ColourDesired(lParam);
+ vs.markers[wParam].back = ColourDesired(lParam);
InvalidateStyleData();
RedrawSelMargin();
break;
case SCI_MARKERGET:
return pdoc->GetMark(wParam);
- case SCI_MARKERNEXT: {
- int lt = pdoc->LinesTotal();
- for (int iLine = wParam; iLine < lt; iLine++) {
- if ((pdoc->GetMark(iLine) & lParam) != 0)
- return iLine;
- }
- }
- return -1;
+ case SCI_MARKERNEXT:
+ return pdoc->MarkerNext(wParam, lParam);
case SCI_MARKERPREVIOUS: {
for (int iLine = wParam; iLine >= 0; iLine--) {
case SCI_MARKERDEFINEPIXMAP:
if (wParam <= MARKER_MAX) {
vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam));
+ vs.CalcLargestMarkerHeight();
+ };
+ InvalidateStyleData();
+ RedrawSelMargin();
+ break;
+
+ case SCI_RGBAIMAGESETWIDTH:
+ sizeRGBAImage.x = wParam;
+ break;
+
+ case SCI_RGBAIMAGESETHEIGHT:
+ sizeRGBAImage.y = wParam;
+ break;
+
+ case SCI_MARKERDEFINERGBAIMAGE:
+ if (wParam <= MARKER_MAX) {
+ vs.markers[wParam].SetRGBAImage(sizeRGBAImage, reinterpret_cast<unsigned char *>(lParam));
+ vs.CalcLargestMarkerHeight();
};
InvalidateStyleData();
RedrawSelMargin();
else
return 0;
+ case SCI_SETMARGINCURSORN:
+ if (ValidMargin(wParam))
+ vs.ms[wParam].cursor = lParam;
+ break;
+
+ case SCI_GETMARGINCURSORN:
+ if (ValidMargin(wParam))
+ return vs.ms[wParam].cursor;
+ else
+ return 0;
+
case SCI_STYLECLEARALL:
vs.ClearStyles();
InvalidateStyleRedraw();
case SCI_STYLESETFORE:
case SCI_STYLESETBACK:
case SCI_STYLESETBOLD:
+ case SCI_STYLESETWEIGHT:
case SCI_STYLESETITALIC:
case SCI_STYLESETEOLFILLED:
case SCI_STYLESETSIZE:
+ case SCI_STYLESETSIZEFRACTIONAL:
case SCI_STYLESETFONT:
case SCI_STYLESETUNDERLINE:
case SCI_STYLESETCASE:
case SCI_STYLEGETFORE:
case SCI_STYLEGETBACK:
case SCI_STYLEGETBOLD:
+ case SCI_STYLEGETWEIGHT:
case SCI_STYLEGETITALIC:
case SCI_STYLEGETEOLFILLED:
case SCI_STYLEGETSIZE:
+ case SCI_STYLEGETSIZEFRACTIONAL:
case SCI_STYLEGETFONT:
case SCI_STYLEGETUNDERLINE:
case SCI_STYLEGETCASE:
InvalidateStyleRedraw();
break;
case SCI_GETCARETLINEBACK:
- return vs.caretLineBackground.desired.AsLong();
+ return vs.caretLineBackground.AsLong();
case SCI_SETCARETLINEBACK:
- vs.caretLineBackground.desired = wParam;
+ vs.caretLineBackground = wParam;
InvalidateStyleRedraw();
break;
case SCI_GETCARETLINEBACKALPHA:
case SCI_GETLINEVISIBLE:
return cs.GetVisible(wParam);
+ case SCI_GETALLLINESVISIBLE:
+ return cs.HiddenLines() ? 0 : 1;
+
case SCI_SETFOLDEXPANDED:
if (cs.SetExpanded(wParam, lParam != 0)) {
RedrawSelMargin();
ToggleContraction(wParam);
break;
+ case SCI_CONTRACTEDFOLDNEXT:
+ return ContractedFoldNext(wParam);
+
case SCI_ENSUREVISIBLE:
EnsureLineVisible(wParam, false);
break;
case SCI_SETSELFORE:
vs.selforeset = wParam != 0;
- vs.selforeground.desired = ColourDesired(lParam);
- vs.selAdditionalForeground.desired = ColourDesired(lParam);
+ vs.selforeground = ColourDesired(lParam);
+ vs.selAdditionalForeground = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_SETSELBACK:
vs.selbackset = wParam != 0;
- vs.selbackground.desired = ColourDesired(lParam);
- vs.selAdditionalBackground.desired = ColourDesired(lParam);
+ vs.selbackground = ColourDesired(lParam);
+ vs.selAdditionalBackground = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_SETWHITESPACEFORE:
vs.whitespaceForegroundSet = wParam != 0;
- vs.whitespaceForeground.desired = ColourDesired(lParam);
+ vs.whitespaceForeground = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_SETWHITESPACEBACK:
vs.whitespaceBackgroundSet = wParam != 0;
- vs.whitespaceBackground.desired = ColourDesired(lParam);
+ vs.whitespaceBackground = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_SETCARETFORE:
- vs.caretcolour.desired = ColourDesired(wParam);
+ vs.caretcolour = ColourDesired(wParam);
InvalidateStyleRedraw();
break;
case SCI_GETCARETFORE:
- return vs.caretcolour.desired.AsLong();
+ return vs.caretcolour.AsLong();
case SCI_SETCARETSTYLE:
- if (wParam >= CARETSTYLE_INVISIBLE && wParam <= CARETSTYLE_BLOCK)
+ if (wParam <= CARETSTYLE_BLOCK)
vs.caretStyle = wParam;
else
/* Default to the line caret */
return vs.caretStyle;
case SCI_SETCARETWIDTH:
- if (wParam <= 0)
+ if (static_cast<int>(wParam) <= 0)
vs.caretWidth = 0;
else if (wParam >= 3)
vs.caretWidth = 3;
case SCI_INDICSETFORE:
if (wParam <= INDIC_MAX) {
- vs.indicators[wParam].fore.desired = ColourDesired(lParam);
+ vs.indicators[wParam].fore = ColourDesired(lParam);
InvalidateStyleRedraw();
}
break;
case SCI_INDICGETFORE:
- return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fore.desired.AsLong() : 0;
+ return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fore.AsLong() : 0;
case SCI_INDICSETUNDER:
if (wParam <= INDIC_MAX) {
return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0;
case SCI_INDICSETALPHA:
- if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 100) {
+ if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
vs.indicators[wParam].fillAlpha = lParam;
InvalidateStyleRedraw();
}
case SCI_INDICGETALPHA:
return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
+ case SCI_INDICSETOUTLINEALPHA:
+ if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
+ vs.indicators[wParam].outlineAlpha = lParam;
+ InvalidateStyleRedraw();
+ }
+ break;
+
+ case SCI_INDICGETOUTLINEALPHA:
+ return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0;
+
case SCI_SETINDICATORCURRENT:
pdoc->decorations.SetCurrentIndicator(wParam);
break;
case SCI_DOCUMENTSTARTEXTEND:
case SCI_DOCUMENTEND:
case SCI_DOCUMENTENDEXTEND:
+ case SCI_SCROLLTOSTART:
+ case SCI_SCROLLTOEND:
case SCI_STUTTEREDPAGEUP:
case SCI_STUTTEREDPAGEUPEXTEND:
SetBraceHighlight(static_cast<int>(wParam), lParam, STYLE_BRACELIGHT);
break;
+ case SCI_BRACEHIGHLIGHTINDICATOR:
+ if (lParam >= 0 && lParam <= INDIC_MAX) {
+ vs.braceHighlightIndicatorSet = wParam != 0;
+ vs.braceHighlightIndicator = lParam;
+ }
+ break;
+
case SCI_BRACEBADLIGHT:
SetBraceHighlight(static_cast<int>(wParam), -1, STYLE_BRACEBAD);
break;
+ case SCI_BRACEBADLIGHTINDICATOR:
+ if (lParam >= 0 && lParam <= INDIC_MAX) {
+ vs.braceBadLightIndicatorSet = wParam != 0;
+ vs.braceBadLightIndicator = lParam;
+ }
+ break;
+
case SCI_BRACEMATCH:
// wParam is position of char to find brace for,
// lParam is maximum amount of text to restyle to find it
break;
case SCI_GETEDGECOLOUR:
- return vs.edgecolour.desired.AsLong();
+ return vs.edgecolour.AsLong();
case SCI_SETEDGECOLOUR:
- vs.edgecolour.desired = ColourDesired(wParam);
+ vs.edgecolour = ColourDesired(wParam);
InvalidateStyleRedraw();
break;
(reinterpret_cast<Document *>(lParam))->Release();
break;
+ case SCI_CREATELOADER: {
+ Document *doc = new Document();
+ if (doc) {
+ doc->AddRef();
+ doc->Allocate(wParam);
+ doc->SetUndoCollection(false);
+ }
+ return reinterpret_cast<sptr_t>(static_cast<ILoader *>(doc));
+ }
+
case SCI_SETMODEVENTMASK:
modEventMask = wParam;
return 0;
case SCI_SETFOLDMARGINCOLOUR:
vs.foldmarginColourSet = wParam != 0;
- vs.foldmarginColour.desired = ColourDesired(lParam);
+ vs.foldmarginColour = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_SETFOLDMARGINHICOLOUR:
vs.foldmarginHighlightColourSet = wParam != 0;
- vs.foldmarginHighlightColour.desired = ColourDesired(lParam);
+ vs.foldmarginHighlightColour = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_SETHOTSPOTACTIVEFORE:
vs.hotspotForegroundSet = wParam != 0;
- vs.hotspotForeground.desired = ColourDesired(lParam);
+ vs.hotspotForeground = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_GETHOTSPOTACTIVEFORE:
- return vs.hotspotForeground.desired.AsLong();
+ return vs.hotspotForeground.AsLong();
case SCI_SETHOTSPOTACTIVEBACK:
vs.hotspotBackgroundSet = wParam != 0;
- vs.hotspotBackground.desired = ColourDesired(lParam);
+ vs.hotspotBackground = ColourDesired(lParam);
InvalidateStyleRedraw();
break;
case SCI_GETHOTSPOTACTIVEBACK:
- return vs.hotspotBackground.desired.AsLong();
+ return vs.hotspotBackground.AsLong();
case SCI_SETHOTSPOTACTIVEUNDERLINE:
vs.hotspotUnderline = wParam != 0;
case SCI_GETCHARACTERPOINTER:
return reinterpret_cast<sptr_t>(pdoc->BufferPointer());
+ case SCI_GETRANGEPOINTER:
+ return reinterpret_cast<sptr_t>(pdoc->RangePointer(wParam, lParam));
+
+ case SCI_GETGAPPOSITION:
+ return pdoc->GapPosition();
+
case SCI_SETEXTRAASCENT:
vs.extraAscent = wParam;
InvalidateStyleRedraw();
case SCI_MARGINGETSTYLEOFFSET:
return vs.marginStyleOffset;
+ case SCI_SETMARGINOPTIONS:
+ marginOptions = wParam;
+ break;
+
+ case SCI_GETMARGINOPTIONS:
+ return marginOptions;
+
case SCI_MARGINSETTEXT:
pdoc->MarginSetText(wParam, CharPtrFromSPtr(lParam));
break;
case SCI_GETADDITIONALSELECTIONTYPING:
return additionalSelectionTyping;
+ case SCI_SETMULTIPASTE:
+ multiPasteMode = wParam;
+ break;
+
+ case SCI_GETMULTIPASTE:
+ return multiPasteMode;
+
case SCI_SETADDITIONALCARETSBLINK:
additionalCaretsBlink = wParam != 0;
InvalidateCaret();
return virtualSpaceOptions;
case SCI_SETADDITIONALSELFORE:
- vs.selAdditionalForeground.desired = ColourDesired(wParam);
+ vs.selAdditionalForeground = ColourDesired(wParam);
InvalidateStyleRedraw();
break;
case SCI_SETADDITIONALSELBACK:
- vs.selAdditionalBackground.desired = ColourDesired(wParam);
+ vs.selAdditionalBackground = ColourDesired(wParam);
InvalidateStyleRedraw();
break;
return vs.selAdditionalAlpha;
case SCI_SETADDITIONALCARETFORE:
- vs.additionalCaretColour.desired = ColourDesired(wParam);
+ vs.additionalCaretColour = ColourDesired(wParam);
InvalidateStyleRedraw();
break;
case SCI_GETADDITIONALCARETFORE:
- return vs.additionalCaretColour.desired.AsLong();
+ return vs.additionalCaretColour.AsLong();
case SCI_ROTATESELECTION:
sel.RotateMain();
sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret);
break;
+ case SCI_CHANGELEXERSTATE:
+ pdoc->ChangeLexerState(wParam, lParam);
+ break;
+
+ case SCI_SETIDENTIFIER:
+ SetCtrlID(wParam);
+ break;
+
+ case SCI_GETIDENTIFIER:
+ return GetCtrlID();
+
+ case SCI_SETTECHNOLOGY:
+ // No action by default
+ break;
+
+ case SCI_GETTECHNOLOGY:
+ return technology;
+
+ case SCI_COUNTCHARACTERS:
+ return pdoc->CountCharacters(wParam, lParam);
+
default:
return DefWndProc(iMessage, wParam, lParam);
}
/** @file Editor.h
** Defines the main editor class.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
Idler();
};
+/**
+ * When platform has a way to generate an event before painting,
+ * accumulate needed styling range in StyleNeeded to avoid unnecessary work.
+ */
+class StyleNeeded {
+public:
+ bool active;
+ Position upTo;
+
+ StyleNeeded() : active(false), upTo(0) {}
+ void Reset() {
+ active = false;
+ upTo = 0;
+ }
+ void NeedUpTo(Position pos) {
+ if (upTo < pos)
+ upTo = pos;
+ }
+};
+
/**
* Hold a piece of text selected for copying or dragging.
* The text is expected to hold a terminating '\0' and this is counted in len.
* When a style attribute is changed, this cache is flushed. */
bool stylesValid;
ViewStyle vs;
- Palette palette;
+ int technology;
+ Point sizeRGBAImage;
int printMagnification;
int printColourMode;
int cursorMode;
int controlCharSymbol;
+ // Highlight current folding block
+ HighlightDelimiter highlightDelimiter;
+
bool hasFocus;
bool hideSelection;
bool inOverstrike;
int lineWidthMaxSeen;
bool verticalScrollBarVisible;
bool endAtLastLine;
- bool caretSticky;
+ int caretSticky;
+ int marginOptions;
bool multipleSelection;
bool additionalSelectionTyping;
+ int multiPasteMode;
bool additionalCaretsBlink;
bool additionalCaretsVisible;
int dwellDelay;
int ticksToDwell;
bool dwelling;
- enum { selChar, selWord, selLine } selectionType;
+ enum { selChar, selWord, selSubLine, selWholeLine } selectionType;
Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
SelectionPosition posDrag;
SelectionPosition posDrop;
+ int hotSpotClickPos;
int lastXChosen;
- int lineAnchor;
+ int lineAnchorPos;
int originalAnchorPos;
+ int wordSelectAnchorStartPos;
+ int wordSelectAnchorEndPos;
+ int wordSelectInitialCaretPos;
int targetStart;
int targetEnd;
int searchFlags;
int posTopLine;
int lengthForEncode;
- bool needUpdateUI;
+ int needUpdateUI;
Position braces[2];
int bracesMatchStyle;
int highlightGuideColumn;
enum { notPainting, painting, paintAbandoned } paintState;
PRectangle rcPaint;
bool paintingAllText;
+ bool willRedrawAll;
+ StyleNeeded styleNeeded;
int modEventMask;
int wrapVisualFlags;
int wrapVisualFlagsLocation;
int wrapVisualStartIndent;
- int wrapAddIndent; // This will be added to initial indent of line
int wrapIndentMode; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
bool convertPastes;
void InvalidateStyleData();
void InvalidateStyleRedraw();
- virtual void RefreshColourPalette(Palette &pal, bool want);
void RefreshStyleData();
- void DropGraphics();
+ void DropGraphics(bool freeObjects);
+ void AllocateGraphics();
virtual PRectangle GetClientRectangle();
PRectangle GetTextRectangle();
bool AbandonPaint();
void RedrawRect(PRectangle rc);
void Redraw();
- void RedrawSelMargin(int line=-1);
+ void RedrawSelMargin(int line=-1, bool allAfter=false);
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
void ScrollTo(int line, bool moveThumb=true);
virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos);
+ void VerticalCentreCaret();
+ void MoveSelectedLines(int lineDelta);
+ void MoveSelectedLinesUp();
+ void MoveSelectedLinesDown();
void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos);
+
+ struct XYScrollPosition {
+ int xOffset;
+ int topLine;
+ XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {}
+ };
+ XYScrollPosition XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz);
+ void SetXYScroll(XYScrollPosition newXY);
void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
void ShowCaretAtCurrentPosition();
void DropCaret();
LineLayout *RetrieveLineLayout(int lineNumber);
void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
int width=LineLayout::wrapWidthInfinite);
- ColourAllocated SelectionBackground(ViewStyle &vsDraw, bool main);
- ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
+ ColourDesired SelectionBackground(ViewStyle &vsDraw, bool main);
+ ColourDesired TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourDesired background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
- void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour);
+ void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour);
void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
- int line, int lineEnd, int xStart, int subLine, int subLineStart,
- bool overrideBackground, ColourAllocated background,
- bool drawWrapMark, ColourAllocated wrapColour);
+ int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart,
+ bool overrideBackground, ColourDesired background,
+ bool drawWrapMark, ColourDesired wrapColour);
+ void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
+ int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
- void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
- int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour);
+ void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
+ int xStart, int offset, int posCaret, PRectangle rcCaret, ColourDesired caretColour);
void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void RefreshPixMaps(Surface *surfaceWindow);
int InsertSpace(int position, unsigned int spaces);
void AddChar(char ch);
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
- void ClearSelection();
+ void InsertPaste(SelectionPosition selStart, const char *text, int len);
+ void ClearSelection(bool retainMultipleSelections=false);
void ClearAll();
void ClearDocumentStyle();
void Cut();
virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus);
+ virtual void SetCtrlID(int identifier);
virtual int GetCtrlID() { return ctrlID; }
virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleToNeeded(int endStyleNeeded);
virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
+ void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt);
void NotifyUpdateUI();
void NotifyPainted();
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
void NotifyModified(Document *document, DocModification mh, void *userData);
void NotifyDeleted(Document *document, void *userData);
void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
+ void NotifyLexerChanged(Document *doc, void *userData);
+ void NotifyErrorOccurred(Document *doc, void *userData, int status);
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+ void ContainerNeedsUpdate(int flags);
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
- void ChangeCaseOfSelection(bool makeUpperCase);
+ enum { cmSame, cmUpper, cmLower } caseMap;
+ virtual std::string CaseMapString(const std::string &s, int caseMapping);
+ void ChangeCaseOfSelection(int caseMapping);
void LineTranspose();
void Duplicate(bool forLine);
virtual void CancelModes();
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
+ int KeyDownWithModifiers(int key, int modifiers, bool *consumed);
int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
- int GetWhitespaceVisible();
- void SetWhitespaceVisible(int view);
-
void Indent(bool forwards);
+ virtual CaseFolder *CaseFolderForEncoding();
long FindText(uptr_t wParam, sptr_t lParam);
void SearchAnchor();
long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
char *CopyRange(int start, int end);
+ std::string RangeText(int start, int end) const;
void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
void CopyRangeToClipboard(int start, int end);
void CopyText(int length, const char *text);
bool PositionInSelection(int pos);
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
- void LineSelection(int lineCurrent_, int lineAnchor_);
+ Window::Cursor GetMarginCursor(Point pt);
+ void TrimAndSetSelection(int currentPos_, int anchor_);
+ void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine);
+ void WordSelection(int pos);
void DwellEnd(bool mouseMoved);
+ void MouseLeave();
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
void ButtonMove(Point pt);
void ButtonUp(Point pt, unsigned int curTime, bool ctrl);
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
+ int PositionAfterArea(PRectangle rcArea);
+ void StyleToPositionInView(Position pos);
+ void IdleStyling();
+ virtual void QueueStyling(int upTo);
+
virtual bool PaintContains(PRectangle rc);
bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
void SetAnnotationHeights(int start, int end);
void SetDocPointer(Document *document);
-
+
void SetAnnotationVisible(int visible);
void Expand(int &line, bool doExpand);
void ToggleContraction(int line);
+ int ContractedFoldNext(int lineStart);
void EnsureLineVisible(int lineDoc, bool enforcePolicy);
+ int GetTag(char *tagValue, int tagNumber);
int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
bool PositionIsHotspot(int position);
bool PointIsHotspot(Point pt);
void SetHotSpotRange(Point *pt);
- void GetHotSpotRange(int& hsStart, int& hsEnd);
+ void GetHotSpotRange(int &hsStart, int &hsEnd);
int CodePage() const;
virtual bool ValidCodePage(int /* codePage */) const { return true; }
private:
Surface *surf;
public:
- AutoSurface(Editor *ed) : surf(0) {
+ AutoSurface(Editor *ed, int technology = -1) : surf(0) {
if (ed->wMain.GetID()) {
- surf = Surface::Allocate();
+ surf = Surface::Allocate(technology != -1 ? technology : ed->technology);
if (surf) {
surf->Init(ed->wMain.GetID());
surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
}
}
}
- AutoSurface(SurfaceID sid, Editor *ed) : surf(0) {
+ AutoSurface(SurfaceID sid, Editor *ed, int technology = -1) : surf(0) {
if (ed->wMain.GetID()) {
- surf = Surface::Allocate();
+ surf = Surface::Allocate(technology != -1 ? technology : ed->technology);
if (surf) {
surf->Init(sid, ed->wMain.GetID());
surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
-
#include "SciLexer.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
#include "ExternalLexer.h"
#ifdef SCI_NAMESPACE
//
//------------------------------------------
-char **WordListsToStrings(WordList *val[]) {
- int dim = 0;
- while (val[dim])
- dim++;
- char **wls = new char * [dim + 1];
- for (int i = 0;i < dim;i++) {
- std::string words;
- words = "";
- for (int n = 0; n < val[i]->len; n++) {
- words += val[i]->words[n];
- if (n != val[i]->len - 1)
- words += " ";
- }
- wls[i] = new char[words.length() + 1];
- strcpy(wls[i], words.c_str());
- }
- wls[dim] = 0;
- return wls;
-}
-
-void DeleteWLStrings(char *strs[]) {
- int dim = 0;
- while (strs[dim]) {
- delete strs[dim];
- dim++;
- }
- delete [] strs;
-}
-
-void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (!fneLexer)
- return ;
-
- char **kwds = WordListsToStrings(keywordlists);
- char *ps = styler.GetProperties();
-
- // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
- // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
- DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
- WindowID wID = da.GetWindow();
-
- fneLexer(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
- delete ps;
- DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (!fneFolder)
- return ;
-
- char **kwds = WordListsToStrings(keywordlists);
- char *ps = styler.GetProperties();
-
- // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
- // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
- DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
- WindowID wID = da.GetWindow();
-
- fneFolder(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
- delete ps;
- DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
- fneLexer = fLexer;
- fneFolder = fFolder;
- externalLanguage = index;
+void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
+ fneFactory = fFactory;
+ fnFactory = fFactory(index);
}
//------------------------------------------
//
//------------------------------------------
-LexerLibrary::LexerLibrary(const char* ModuleName) {
+LexerLibrary::LexerLibrary(const char *ModuleName) {
// Initialise some members...
first = NULL;
last = NULL;
// Find functions in the DLL
GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
- ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
- ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
+ GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
// Assign a buffer for the lexer name.
char lexname[100];
for (int i = 0; i < nl; i++) {
GetLexerName(i, lexname, 100);
lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
+ Catalogue::AddLexerModule(lex);
// Create a LexerMinder so we don't leak the ExternalLexerModule...
lm = new LexerMinder;
}
// The external lexer needs to know how to call into its DLL to
- // do its lexing and folding, we tell it here. Folder may be null.
- lex->SetExternal(Lexer, Folder, i);
+ // do its lexing and folding, we tell it here.
+ lex->SetExternal(fnFactory, i);
}
}
}
}
void LexerLibrary::Release() {
- //TODO maintain a list of lexers created, and delete them!
LexerMinder *lm;
LexerMinder *lmNext;
lm = first;
/// Return the single LexerManager instance...
LexerManager *LexerManager::GetInstance() {
- if(!theInstance)
+ if (!theInstance)
theInstance = new LexerManager;
return theInstance;
}
/// Delete any LexerManager instance...
-void LexerManager::DeleteInstance()
-{
- if(theInstance) {
- delete theInstance;
- theInstance = NULL;
- }
+void LexerManager::DeleteInstance() {
+ delete theInstance;
+ theInstance = NULL;
}
/// protected constructor - this is a singleton...
Clear();
}
-void LexerManager::Load(const char* path)
-{
+void LexerManager::Load(const char *path) {
LoadLexerLibrary(path);
}
-void LexerManager::LoadLexerLibrary(const char* module)
-{
+void LexerManager::LoadLexerLibrary(const char *module) {
+ for (LexerLibrary *ll = first; ll; ll= ll->next) {
+ if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
+ return;
+ }
LexerLibrary *lib = new LexerLibrary(module);
if (NULL != first) {
last->next = lib;
}
}
-void LexerManager::Clear()
-{
+void LexerManager::Clear() {
if (NULL != first) {
LexerLibrary *cur = first;
LexerLibrary *next;
//
//------------------------------------------
-LMMinder::~LMMinder()
-{
+LMMinder::~LMMinder() {
LexerManager::DeleteInstance();
}
namespace Scintilla {
#endif
-// External Lexer function definitions...
-typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props);
-typedef void (EXT_LEXER_DECL *ExtFoldFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props);
-typedef void* (EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
+typedef void*(EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
typedef int (EXT_LEXER_DECL *GetLexerCountFn)();
typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);
-
-//class DynamicLibrary;
+typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index);
/// Sub-class of LexerModule to use an external lexer.
-class ExternalLexerModule : protected LexerModule {
+class ExternalLexerModule : public LexerModule {
protected:
- ExtLexerFunction fneLexer;
- ExtFoldFunction fneFolder;
- int externalLanguage;
+ GetLexerFactoryFunction fneFactory;
char name[100];
public:
- ExternalLexerModule(int language_, LexerFunction fnLexer_,
- const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){
+ ExternalLexerModule(int language_, LexerFunction fnLexer_,
+ const char *languageName_=0, LexerFunction fnFolder_=0) :
+ LexerModule(language_, fnLexer_, 0, fnFolder_),
+ fneFactory(0) {
strncpy(name, languageName_, sizeof(name));
name[sizeof(name)-1] = '\0';
languageName = name;
- };
- virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index);
+ }
+ virtual void SetExternal(GetLexerFactoryFunction fFactory, int index);
};
/// LexerMinder points to an ExternalLexerModule - so we don't leak them.
LexerMinder *last;
public:
- LexerLibrary(const char* ModuleName);
+ LexerLibrary(const char *ModuleName);
~LexerLibrary();
void Release();
-
+
LexerLibrary *next;
std::string m_sModuleName;
};
class LexerManager {
public:
~LexerManager();
-
+
static LexerManager *GetInstance();
static void DeleteInstance();
-
- void Load(const char* path);
+
+ void Load(const char *path);
void Clear();
private:
LexerManager();
static LexerManager *theInstance;
- void LoadLexerLibrary(const char* module);
+ void LoadLexerLibrary(const char *module);
LexerLibrary *first;
LexerLibrary *last;
};
#define SC_EFF_QUALITY_NON_ANTIALIASED 1
#define SC_EFF_QUALITY_ANTIALIASED 2
#define SC_EFF_QUALITY_LCD_OPTIMIZED 3
+
+#define SCWIN_TECH_GDI 0
+#define SCWIN_TECH_DIRECTWRITE 1
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "Scintilla.h"
+#include "XPM.h"
#include "Indicator.h"
#ifdef SCI_NAMESPACE
#endif
void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) {
- surface->PenColour(fore.allocated);
+ surface->PenColour(fore);
int ymid = (rc.bottom + rc.top) / 2;
if (style == INDIC_SQUIGGLE) {
surface->MoveTo(rc.left, rc.top);
y = 2 - y;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
+ } else if (style == INDIC_SQUIGGLELOW) {
+ surface->MoveTo(rc.left, rc.top);
+ int x = rc.left + 3;
+ int y = 0;
+ while (x < rc.right) {
+ surface->LineTo(x-1, rc.top + y);
+ y = 1 - y;
+ surface->LineTo(x, rc.top + y);
+ x += 3;
+ }
+ surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid);
int x = rc.left + 5;
surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1);
- } else if (style == INDIC_ROUNDBOX) {
+ } else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
- surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
+ surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore, fillAlpha, fore, outlineAlpha, 0);
+ } else if (style == INDIC_DOTBOX) {
+ PRectangle rcBox = rcLine;
+ rcBox.top = rcLine.top + 1;
+ rcBox.left = rc.left;
+ rcBox.right = rc.right;
+ // Cap width at 4000 to avoid large allocations when mistakes made
+ int width = Platform::Minimum(rcBox.Width(), 4000);
+ RGBAImage image(width, rcBox.Height(), 0);
+ // Draw horizontal lines top and bottom
+ for (int x=0; x<width; x++) {
+ for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
+ image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha);
+ }
+ }
+ // Draw vertical lines left and right
+ for (int y=1; y<rcBox.Height(); y++) {
+ for (int x=0; x<width; x += width-1) {
+ image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha);
+ }
+ }
+ surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels());
+ } else if (style == INDIC_DASH) {
+ int x = rc.left;
+ while (x < rc.right) {
+ surface->MoveTo(x, ymid);
+ surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
+ x += 7;
+ }
+ } else if (style == INDIC_DOTS) {
+ int x = rc.left;
+ while (x < rc.right) {
+ PRectangle rcDot(x, ymid, x+1, ymid+1);
+ surface->FillRectangle(rcDot, fore);
+ x += 2;
+ }
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid);
public:
int style;
bool under;
- ColourPair fore;
+ ColourDesired fore;
int fillAlpha;
- Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
+ int outlineAlpha;
+ Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
}
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};
return 0;
}
+#if PLAT_GTK_MACOSX
+#define OS_X_KEYS 1
+#else
+#define OS_X_KEYS 0
+#endif
+
+// Define a modifier that is exactly Ctrl key on all platforms
+// Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META
+#if OS_X_KEYS
+#define SCI_CTRL_META SCI_META
+#define SCI_SCTRL_META (SCI_META | SCI_SHIFT)
+#else
+#define SCI_CTRL_META SCI_CTRL
+#define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT)
+#endif
+
const KeyToCommand KeyMap::MapDefault[] = {
+
+#if OS_X_KEYS
+ {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND},
+ {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
+ {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART},
+ {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
+ {SCK_LEFT, SCI_CTRL, SCI_VCHOME},
+ {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND},
+ {SCK_RIGHT, SCI_CTRL, SCI_LINEEND},
+ {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND},
+#endif
+
{SCK_DOWN, SCI_NORM, SCI_LINEDOWN},
{SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
- {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN},
+ {SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND},
{SCK_UP, SCI_NORM, SCI_LINEUP},
{SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
- {SCK_UP, SCI_CTRL, SCI_LINESCROLLUP},
+ {SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP},
{SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND},
{'[', SCI_CTRL, SCI_PARAUP},
{'[', SCI_CSHIFT, SCI_PARAUPEXTEND},
{']', SCI_CSHIFT, SCI_PARADOWNEXTEND},
{SCK_LEFT, SCI_NORM, SCI_CHARLEFT},
{SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
- {SCK_LEFT, SCI_CTRL, SCI_WORDLEFT},
- {SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND},
+ {SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT},
+ {SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND},
{SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
{SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
- {SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT},
- {SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND},
+ {SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT},
+ {SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND},
{'/', SCI_CTRL, SCI_WORDPARTLEFT},
{'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND},
{SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY},
-// {SCK_HOME, SCI_ASHIFT, SCI_HOMEDISPLAYEXTEND},
{SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND},
{SCK_END, SCI_NORM, SCI_LINEEND},
{SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
{SCK_END, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_END, SCI_ALT, SCI_LINEENDDISPLAY},
-// {SCK_END, SCI_ASHIFT, SCI_LINEENDDISPLAYEXTEND},
{SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND},
{SCK_PRIOR, SCI_NORM, SCI_PAGEUP},
{SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
{SCK_BACK, SCI_ALT, SCI_UNDO},
{SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT},
{'Z', SCI_CTRL, SCI_UNDO},
+#if OS_X_KEYS
+ {'Z', SCI_CSHIFT, SCI_REDO},
+#else
{'Y', SCI_CTRL, SCI_REDO},
+#endif
{'X', SCI_CTRL, SCI_CUT},
{'C', SCI_CTRL, SCI_COPY},
{'V', SCI_CTRL, SCI_PASTE},
{SCK_ADD, SCI_CTRL, SCI_ZOOMIN},
{SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
{SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM},
- //'L', SCI_CTRL, SCI_FORMFEED,
{'L', SCI_CTRL, SCI_LINECUT},
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},
#define SCI_SHIFT SCMOD_SHIFT
#define SCI_CTRL SCMOD_CTRL
#define SCI_ALT SCMOD_ALT
+#define SCI_META SCMOD_META
#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT)
#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT)
+++ /dev/null
-// Scintilla source code edit control
-/** @file KeyWords.cxx
- ** Colourise for particular languages.
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-/**
- * Creates an array that points into each word in the string and puts \0 terminators
- * after each word.
- */
-static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
- int prev = '\n';
- int words = 0;
- // For rapid determination of whether a character is a separator, build
- // a look up table.
- bool wordSeparator[256];
- for (int i=0;i<256; i++) {
- wordSeparator[i] = false;
- }
- wordSeparator['\r'] = true;
- wordSeparator['\n'] = true;
- if (!onlyLineEnds) {
- wordSeparator[' '] = true;
- wordSeparator['\t'] = true;
- }
- for (int j = 0; wordlist[j]; j++) {
- int curr = static_cast<unsigned char>(wordlist[j]);
- if (!wordSeparator[curr] && wordSeparator[prev])
- words++;
- prev = curr;
- }
- char **keywords = new char *[words + 1];
- if (keywords) {
- words = 0;
- prev = '\0';
- size_t slen = strlen(wordlist);
- for (size_t k = 0; k < slen; k++) {
- if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
- if (!prev) {
- keywords[words] = &wordlist[k];
- words++;
- }
- } else {
- wordlist[k] = '\0';
- }
- prev = wordlist[k];
- }
- keywords[words] = &wordlist[slen];
- *len = words;
- } else {
- *len = 0;
- }
- return keywords;
-}
-
-void WordList::Clear() {
- if (words) {
- delete []list;
- delete []words;
- }
- words = 0;
- list = 0;
- len = 0;
- sorted = false;
-}
-
-void WordList::Set(const char *s) {
- list = new char[strlen(s) + 1];
- strcpy(list, s);
- sorted = false;
- words = ArrayFromWordList(list, &len, onlyLineEnds);
-}
-
-extern "C" int cmpString(const void *a1, const void *a2) {
- // Can't work out the correct incantation to use modern casts here
- return strcmp(*(char**)(a1), *(char**)(a2));
-}
-
-static void SortWordList(char **words, unsigned int len) {
- qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
- cmpString);
-}
-
-bool WordList::InList(const char *s) {
- if (0 == words)
- return false;
- if (!sorted) {
- sorted = true;
- SortWordList(words, len);
- for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
- starts[k] = -1;
- for (int l = len - 1; l >= 0; l--) {
- unsigned char indexChar = words[l][0];
- starts[indexChar] = l;
- }
- }
- unsigned char firstChar = s[0];
- int j = starts[firstChar];
- if (j >= 0) {
- while ((unsigned char)words[j][0] == firstChar) {
- if (s[1] == words[j][1]) {
- const char *a = words[j] + 1;
- const char *b = s + 1;
- while (*a && *a == *b) {
- a++;
- b++;
- }
- if (!*a && !*b)
- return true;
- }
- j++;
- }
- }
- j = starts['^'];
- if (j >= 0) {
- while (words[j][0] == '^') {
- const char *a = words[j] + 1;
- const char *b = s;
- while (*a && *a == *b) {
- a++;
- b++;
- }
- if (!*a)
- return true;
- j++;
- }
- }
- return false;
-}
-
-/** similar to InList, but word s can be a substring of keyword.
- * eg. the keyword define is defined as def~ine. This means the word must start
- * with def to be a keyword, but also defi, defin and define are valid.
- * The marker is ~ in this case.
- */
-bool WordList::InListAbbreviated(const char *s, const char marker) {
- if (0 == words)
- return false;
- if (!sorted) {
- sorted = true;
- SortWordList(words, len);
- for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
- starts[k] = -1;
- for (int l = len - 1; l >= 0; l--) {
- unsigned char indexChar = words[l][0];
- starts[indexChar] = l;
- }
- }
- unsigned char firstChar = s[0];
- int j = starts[firstChar];
- if (j >= 0) {
- while (words[j][0] == firstChar) {
- bool isSubword = false;
- int start = 1;
- if (words[j][1] == marker) {
- isSubword = true;
- start++;
- }
- if (s[1] == words[j][start]) {
- const char *a = words[j] + start;
- const char *b = s + 1;
- while (*a && *a == *b) {
- a++;
- if (*a == marker) {
- isSubword = true;
- a++;
- }
- b++;
- }
- if ((!*a || isSubword) && !*b)
- return true;
- }
- j++;
- }
- }
- j = starts['^'];
- if (j >= 0) {
- while (words[j][0] == '^') {
- const char *a = words[j] + 1;
- const char *b = s;
- while (*a && *a == *b) {
- a++;
- b++;
- }
- if (!*a)
- return true;
- j++;
- }
- }
- return false;
-}
-
-const LexerModule *LexerModule::base = 0;
-int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
-
-LexerModule::LexerModule(int language_,
- LexerFunction fnLexer_,
- const char *languageName_,
- LexerFunction fnFolder_,
- const char * const wordListDescriptions_[],
- int styleBits_) :
- language(language_),
- fnLexer(fnLexer_),
- fnFolder(fnFolder_),
- wordListDescriptions(wordListDescriptions_),
- styleBits(styleBits_),
- languageName(languageName_) {
- next = base;
- base = this;
- if (language == SCLEX_AUTOMATIC) {
- language = nextLanguage;
- nextLanguage++;
- }
-}
-
-int LexerModule::GetNumWordLists() const {
- if (wordListDescriptions == NULL) {
- return -1;
- } else {
- int numWordLists = 0;
-
- while (wordListDescriptions[numWordLists]) {
- ++numWordLists;
- }
-
- return numWordLists;
- }
-}
-
-const char *LexerModule::GetWordListDescription(int index) const {
- static const char *emptyStr = "";
-
- PLATFORM_ASSERT(index < GetNumWordLists());
- if (index >= GetNumWordLists()) {
- return emptyStr;
- } else {
- return wordListDescriptions[index];
- }
-}
-
-int LexerModule::GetStyleBitsNeeded() const {
- return styleBits;
-}
-
-const LexerModule *LexerModule::Find(int language) {
- const LexerModule *lm = base;
- while (lm) {
- if (lm->language == language) {
- return lm;
- }
- lm = lm->next;
- }
- return 0;
-}
-
-const LexerModule *LexerModule::Find(const char *languageName) {
- if (languageName) {
- const LexerModule *lm = base;
- while (lm) {
- if (lm->languageName && 0 == strcmp(lm->languageName, languageName)) {
- return lm;
- }
- lm = lm->next;
- }
- }
- return 0;
-}
-
-void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (fnLexer)
- fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
-}
-
-void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (fnFolder) {
- int lineCurrent = styler.GetLine(startPos);
- // Move back one line in case deletion wrecked current line fold state
- if (lineCurrent > 0) {
- lineCurrent--;
- int newStartPos = styler.LineStart(lineCurrent);
- lengthDoc += startPos - newStartPos;
- startPos = newStartPos;
- initStyle = 0;
- if (startPos > 0) {
- initStyle = styler.StyleAt(startPos - 1);
- }
- }
- fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
- }
-}
-
-// Alternative historical name for Scintilla_LinkLexers
-int wxForceScintillaLexers(void) {
- return Scintilla_LinkLexers();
-}
-
-// To add or remove a lexer, add or remove its file and run LexGen.py.
-
-// Force a reference to all of the Scintilla lexers so that the linker will
-// not remove the code of the lexers.
-int Scintilla_LinkLexers() {
- static int forcer = 0;
-
-// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
-#define LINK_LEXER(lexer) extern LexerModule lexer; forcer += lexer.GetLanguage();
-
-//++Autogenerated -- run src/LexGen.py to regenerate
-//**\(\tLINK_LEXER(\*);\n\)
- LINK_LEXER(lmAbaqus);
- LINK_LEXER(lmAda);
- LINK_LEXER(lmAns1);
- LINK_LEXER(lmAPDL);
- LINK_LEXER(lmAsm);
- LINK_LEXER(lmASY);
- LINK_LEXER(lmAU3);
- LINK_LEXER(lmAVE);
- LINK_LEXER(lmBaan);
- LINK_LEXER(lmBash);
- LINK_LEXER(lmBatch);
- LINK_LEXER(lmBlitzBasic);
- LINK_LEXER(lmBullant);
- LINK_LEXER(lmCaml);
- LINK_LEXER(lmClw);
- LINK_LEXER(lmClwNoCase);
- LINK_LEXER(lmCmake);
- LINK_LEXER(lmCOBOL);
- LINK_LEXER(lmConf);
- LINK_LEXER(lmCPP);
- LINK_LEXER(lmCPPNoCase);
- LINK_LEXER(lmCsound);
- LINK_LEXER(lmCss);
- LINK_LEXER(lmD);
- LINK_LEXER(lmDiff);
- LINK_LEXER(lmEiffel);
- LINK_LEXER(lmEiffelkw);
- LINK_LEXER(lmErlang);
- LINK_LEXER(lmErrorList);
- LINK_LEXER(lmESCRIPT);
- LINK_LEXER(lmF77);
- LINK_LEXER(lmFlagShip);
- LINK_LEXER(lmForth);
- LINK_LEXER(lmFortran);
- LINK_LEXER(lmFreeBasic);
- LINK_LEXER(lmGAP);
- LINK_LEXER(lmGui4Cli);
- LINK_LEXER(lmHaskell);
- LINK_LEXER(lmHTML);
- LINK_LEXER(lmInno);
- LINK_LEXER(lmKix);
- LINK_LEXER(lmLatex);
- LINK_LEXER(lmLISP);
- LINK_LEXER(lmLot);
- LINK_LEXER(lmLout);
- LINK_LEXER(lmLua);
- LINK_LEXER(lmMagikSF);
- LINK_LEXER(lmMake);
- LINK_LEXER(lmMarkdown);
- LINK_LEXER(lmMatlab);
- LINK_LEXER(lmMETAPOST);
- LINK_LEXER(lmMMIXAL);
- LINK_LEXER(lmMSSQL);
- LINK_LEXER(lmMySQL);
- LINK_LEXER(lmNimrod);
- LINK_LEXER(lmNncrontab);
- LINK_LEXER(lmNsis);
- LINK_LEXER(lmNull);
- LINK_LEXER(lmOctave);
- LINK_LEXER(lmOpal);
- LINK_LEXER(lmPascal);
- LINK_LEXER(lmPB);
- LINK_LEXER(lmPerl);
- LINK_LEXER(lmPHPSCRIPT);
- LINK_LEXER(lmPLM);
- LINK_LEXER(lmPo);
- LINK_LEXER(lmPOV);
- LINK_LEXER(lmPowerPro);
- LINK_LEXER(lmPowerShell);
- LINK_LEXER(lmProgress);
- LINK_LEXER(lmProps);
- LINK_LEXER(lmPS);
- LINK_LEXER(lmPureBasic);
- LINK_LEXER(lmPython);
- LINK_LEXER(lmR);
- LINK_LEXER(lmREBOL);
- LINK_LEXER(lmRuby);
- LINK_LEXER(lmScriptol);
- LINK_LEXER(lmSmalltalk);
- LINK_LEXER(lmSML);
- LINK_LEXER(lmSorc);
- LINK_LEXER(lmSpecman);
- LINK_LEXER(lmSpice);
- LINK_LEXER(lmSQL);
- LINK_LEXER(lmTACL);
- LINK_LEXER(lmTADS3);
- LINK_LEXER(lmTAL);
- LINK_LEXER(lmTCL);
- LINK_LEXER(lmTeX);
- LINK_LEXER(lmVB);
- LINK_LEXER(lmVBScript);
- LINK_LEXER(lmVerilog);
- LINK_LEXER(lmVHDL);
- LINK_LEXER(lmXML);
- LINK_LEXER(lmYAML);
-
-//--Autogenerated -- end of automatically generated section
-
- return 1;
-}
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexAPDL.cxx
- ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
- ** By Hadar Raz.
- **/
-// Copyright 1998-2003 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80 && (isalnum(ch) || ch == '_'));
-}
-
-static inline bool IsAnOperator(char ch) {
- // '.' left out as it is used to make up numbers
- if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
- ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
- ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
- ch == '$' || ch == ':' || ch == '%')
- return true;
- return false;
-}
-
-static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- int stringStart = ' ';
-
- WordList &processors = *keywordlists[0];
- WordList &commands = *keywordlists[1];
- WordList &slashcommands = *keywordlists[2];
- WordList &starcommands = *keywordlists[3];
- WordList &arguments = *keywordlists[4];
- WordList &functions = *keywordlists[5];
-
- // Do not leak onto next line
- initStyle = SCE_APDL_DEFAULT;
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
- // Determine if the current state should terminate.
- if (sc.state == SCE_APDL_NUMBER) {
- if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
- ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
- sc.SetState(SCE_APDL_DEFAULT);
- }
- } else if (sc.state == SCE_APDL_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_APDL_DEFAULT);
- }
- } else if (sc.state == SCE_APDL_COMMENTBLOCK) {
- if (sc.atLineEnd) {
- if (sc.ch == '\r') {
- sc.Forward();
- }
- sc.ForwardSetState(SCE_APDL_DEFAULT);
- }
- } else if (sc.state == SCE_APDL_STRING) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_APDL_DEFAULT);
- } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
- sc.ForwardSetState(SCE_APDL_DEFAULT);
- }
- } else if (sc.state == SCE_APDL_WORD) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (processors.InList(s)) {
- sc.ChangeState(SCE_APDL_PROCESSOR);
- } else if (slashcommands.InList(s)) {
- sc.ChangeState(SCE_APDL_SLASHCOMMAND);
- } else if (starcommands.InList(s)) {
- sc.ChangeState(SCE_APDL_STARCOMMAND);
- } else if (commands.InList(s)) {
- sc.ChangeState(SCE_APDL_COMMAND);
- } else if (arguments.InList(s)) {
- sc.ChangeState(SCE_APDL_ARGUMENT);
- } else if (functions.InList(s)) {
- sc.ChangeState(SCE_APDL_FUNCTION);
- }
- sc.SetState(SCE_APDL_DEFAULT);
- }
- } else if (sc.state == SCE_APDL_OPERATOR) {
- if (!IsAnOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_APDL_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_APDL_DEFAULT) {
- if (sc.ch == '!' && sc.chNext == '!') {
- sc.SetState(SCE_APDL_COMMENTBLOCK);
- } else if (sc.ch == '!') {
- sc.SetState(SCE_APDL_COMMENT);
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_APDL_NUMBER);
- } else if (sc.ch == '\'' || sc.ch == '\"') {
- sc.SetState(SCE_APDL_STRING);
- stringStart = sc.ch;
- } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
- sc.SetState(SCE_APDL_WORD);
- } else if (IsAnOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_APDL_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-//------------------------------------------------------------------------------
-// 06-27-07 Sergio Lucato
-// - Included code folding for Ansys APDL lexer
-// - Copyied from LexBasic.cxx and modified for APDL
-//------------------------------------------------------------------------------
-
-/* Bits:
- * 1 - whitespace
- * 2 - operator
- * 4 - identifier
- * 8 - decimal digit
- * 16 - hex digit
- * 32 - bin digit
- */
-static int character_classification[128] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
- 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
- 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
- 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
-};
-
-static bool IsSpace(int c) {
- return c < 128 && (character_classification[c] & 1);
-}
-
-static bool IsIdentifier(int c) {
- return c < 128 && (character_classification[c] & 4);
-}
-
-static int LowerCase(int c)
-{
- if (c >= 'A' && c <= 'Z')
- return 'a' + c - 'A';
- return c;
-}
-
-static int CheckAPDLFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "*if") ||
- !strcmp(token, "*do") ||
- !strcmp(token, "*dowhile") ) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "*endif") ||
- !strcmp(token, "*enddo") ) {
- return -1;
- }
- return 0;
-}
-
-static void FoldAPDLDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
-
- int line = styler.GetLine(startPos);
- int level = styler.LevelAt(line);
- int go = 0, done = 0;
- int endPos = startPos + length;
- char word[256];
- int wordlen = 0;
- int i;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- // Scan for tokens at the start of the line (they may include
- // whitespace, for tokens like "End Function"
- for (i = startPos; i < endPos; i++) {
- int c = styler.SafeGetCharAt(i);
- if (!done && !go) {
- if (wordlen) { // are we scanning a token already?
- word[wordlen] = static_cast<char>(LowerCase(c));
- if (!IsIdentifier(c)) { // done with token
- word[wordlen] = '\0';
- go = CheckAPDLFoldPoint(word, level);
- if (!go) {
- // Treat any whitespace as single blank, for
- // things like "End Function".
- if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
- word[wordlen] = ' ';
- if (wordlen < 255)
- wordlen++;
- }
- else // done with this line
- done = 1;
- }
- } else if (wordlen < 255) {
- wordlen++;
- }
- } else { // start scanning at first non-whitespace character
- if (!IsSpace(c)) {
- if (IsIdentifier(c)) {
- word[0] = static_cast<char>(LowerCase(c));
- wordlen = 1;
- } else // done with this line
- done = 1;
- }
- }
- }
- if (c == '\n') { // line end
- if (!done && wordlen == 0 && foldCompact) // line was only space
- level |= SC_FOLDLEVELWHITEFLAG;
- if (level != styler.LevelAt(line))
- styler.SetLevel(line, level);
- level += go;
- line++;
- // reset state
- wordlen = 0;
- level &= ~SC_FOLDLEVELHEADERFLAG;
- level &= ~SC_FOLDLEVELWHITEFLAG;
- go = 0;
- done = 0;
- }
- }
-}
-
-static const char * const apdlWordListDesc[] = {
- "processors",
- "commands",
- "slashommands",
- "starcommands",
- "arguments",
- "functions",
- 0
-};
-
-LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-//Author: instanton (email: soft_share<at>126<dot>com)
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
-
- CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
-
- int visibleChars = 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart) {
- if (sc.state == SCE_ASY_STRING) {
- sc.SetState(SCE_ASY_STRING);
- }
- visibleChars = 0;
- }
-
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
-// continuationLine = true;
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_ASY_OPERATOR:
- sc.SetState(SCE_ASY_DEFAULT);
- break;
- case SCE_ASY_NUMBER:
- if (!setWord.Contains(sc.ch)) {
- sc.SetState(SCE_ASY_DEFAULT);
- }
- break;
- case SCE_ASY_IDENTIFIER:
- if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
- char s[1000];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_ASY_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_ASY_WORD2);
- }
- sc.SetState(SCE_ASY_DEFAULT);
- }
- break;
- case SCE_ASY_COMMENT:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_ASY_DEFAULT);
- }
- break;
- case SCE_ASY_COMMENTLINE:
- if (sc.atLineStart) {
- sc.SetState(SCE_ASY_DEFAULT);
- }
- break;
- case SCE_ASY_STRING:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_ASY_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_ASY_DEFAULT);
- }
- break;
- case SCE_ASY_CHARACTER:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_ASY_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_ASY_DEFAULT);
- }
- break;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_ASY_DEFAULT) {
- if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
- sc.SetState(SCE_ASY_IDENTIFIER);
- } else if (sc.Match('/', '*')) {
- sc.SetState(SCE_ASY_COMMENT);
- sc.Forward(); //
- } else if (sc.Match('/', '/')) {
- sc.SetState(SCE_ASY_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_ASY_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_ASY_CHARACTER);
- } else if (sc.ch == '#' && visibleChars == 0) {
- do {
- sc.Forward();
- } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.atLineEnd) {
- sc.SetState(SCE_ASY_DEFAULT);
- }
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_ASY_OPERATOR);
- }
- }
-
- }
- sc.Complete();
-}
-
-static bool IsAsyCommentStyle(int style) {
- return style == SCE_ASY_COMMENT;
-}
-
-
-static inline bool isASYidentifier(int ch) {
- return
- ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ;
-}
-
-static int ParseASYWord(unsigned int pos, Accessor &styler, char *word)
-{
- int length=0;
- char ch=styler.SafeGetCharAt(pos);
- *word=0;
-
- while(isASYidentifier(ch) && length<100){
- word[length]=ch;
- length++;
- ch=styler.SafeGetCharAt(pos+length);
- }
- word[length]=0;
- return length;
-}
-
-static bool IsASYDrawingLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
-
- int startpos = pos;
- char buffer[100]="";
-
- while (startpos<eol_pos){
- char ch = styler[startpos];
- ParseASYWord(startpos,styler,buffer);
- bool drawcommands = strncmp(buffer,"draw",4)==0||
- strncmp(buffer,"pair",4)==0||strncmp(buffer,"label",5)==0;
- if (!drawcommands && ch!=' ') return false;
- else if (drawcommands) return true;
- startpos++;
- }
- return false;
-}
-
-static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsAsyCommentStyle(style)) {
- if (!IsAsyCommentStyle(stylePrev) && (stylePrev != SCE_ASY_COMMENTLINEDOC)) {
- levelNext++;
- } else if (!IsAsyCommentStyle(styleNext) && (styleNext != SCE_ASY_COMMENTLINEDOC) && !atEOL) {
- levelNext--;
- }
- }
- if (style == SCE_ASY_OPERATOR) {
- if (ch == '{') {
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
-
- if (atEOL && IsASYDrawingLine(lineCurrent, styler)){
- if (lineCurrent==0 && IsASYDrawingLine(lineCurrent + 1, styler))
- levelNext++;
- else if (lineCurrent!=0 && !IsASYDrawingLine(lineCurrent - 1, styler)
- && IsASYDrawingLine(lineCurrent + 1, styler)
- )
- levelNext++;
- else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&
- !IsASYDrawingLine(lineCurrent+1, styler))
- levelNext--;
- }
-
- if (atEOL) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!IsASpace(ch))
- visibleChars++;
- }
-}
-
-static const char * const asyWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- 0,
- };
-
-LexerModule lmASY(SCLEX_ASYMPTOTE, ColouriseAsyDoc, "asy", FoldAsyDoc, asyWordLists);
+++ /dev/null
-// Scintilla source code edit control
-// @file LexAU3.cxx
-// Lexer for AutoIt3 http://www.hiddensoft.com/autoit3
-// by Jos van der Zande, jvdzande@yahoo.com
-//
-// Changes:
-// March 28, 2004 - Added the standard Folding code
-// April 21, 2004 - Added Preprosessor Table + Syntax Highlighting
-// Fixed Number highlighting
-// Changed default isoperator to IsAOperator to have a better match to AutoIt3
-// Fixed "#comments_start" -> "#comments-start"
-// Fixed "#comments_end" -> "#comments-end"
-// Fixed Sendkeys in Strings when not terminated with }
-// Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
-// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
-// Added logic for #include <xyz.au3> to treat the <> as string
-// Added underscore to IsAOperator.
-// May 17, 2004 - Changed the folding logic from indent to keyword folding.
-// Added Folding logic for blocks of single-commentlines or commentblock.
-// triggered by: fold.comment=1
-// Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1
-// Added Special for #region - #endregion syntax highlight and folding.
-// May 30, 2004 - Fixed issue with continuation lines on If statements.
-// June 5, 2004 - Added comma to Operators for better readability.
-// Added fold.compact support set with fold.compact=1
-// Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
-// it will now only happen when fold.comment=2.
-// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
-// Typed Characters now show as "default" till they match any table.
-// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
-// Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
-// Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
-// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
-// Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator.
-// Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account
-// - Added folding support for With...EndWith
-// - Added support for a DOT in variable names
-// - Fixed Underscore in CommentBlock
-// May 23, 2005 - Fixed the SentKey lexing in case of a missing }
-// Aug 11, 2005 - Fixed possible bug with s_save length > 100.
-// Aug 23, 2005 - Added Switch/endswitch support to the folding logic.
-// Sep 27, 2005 - Fixed the SentKey lexing logic in case of multiple sentkeys.
-// Mar 12, 2006 - Fixed issue with <> coloring as String in stead of Operator in rare occasions.
-// Apr 8, 2006 - Added support for AutoIt3 Standard UDF library (SCE_AU3_UDF)
-// Mar 9, 2007 - Fixed bug with + following a String getting the wrong Color.
-// Jun 20, 2007 - Fixed Commentblock issue when LF's are used as EOL.
-// Jul 26, 2007 - Fixed #endregion undetected bug.
-//
-// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-// Scintilla source code edit control
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsTypeCharacter(const int ch)
-{
- return ch == '$';
-}
-static inline bool IsAWordChar(const int ch)
-{
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(const int ch)
-{
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
-}
-
-static inline bool IsAOperator(char ch) {
- if (isascii(ch) && isalnum(ch))
- return false;
- if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
- ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' ||
- ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' )
- return true;
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// GetSendKey() filters the portion before and after a/multiple space(s)
-// and return the first portion to be looked-up in the table
-// also check if the second portion is valid... (up,down.on.off,toggle or a number)
-///////////////////////////////////////////////////////////////////////////////
-
-static int GetSendKey(const char *szLine, char *szKey)
-{
- int nFlag = 0;
- int nStartFound = 0;
- int nKeyPos = 0;
- int nSpecPos= 0;
- int nSpecNum= 1;
- int nPos = 0;
- char cTemp;
- char szSpecial[100];
-
- // split the portion of the sendkey in the part before and after the spaces
- while ( ( (cTemp = szLine[nPos]) != '\0'))
- {
- // skip leading Ctrl/Shift/Alt state
- if (cTemp == '{') {
- nStartFound = 1;
- }
- //
- if (nStartFound == 1) {
- if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
- {
- nFlag = 1;
- // Add } to the end of the first bit for table lookup later.
- szKey[nKeyPos++] = '}';
- }
- else if (cTemp == ' ')
- {
- // skip other spaces
- }
- else if (nFlag == 0)
- {
- // save first portion into var till space or } is hit
- szKey[nKeyPos++] = cTemp;
- }
- else if ((nFlag == 1) && (cTemp != '}'))
- {
- // Save second portion into var...
- szSpecial[nSpecPos++] = cTemp;
- // check if Second portion is all numbers for repeat fuction
- if (isdigit(cTemp) == false) {nSpecNum = 0;}
- }
- }
- nPos++; // skip to next char
-
- } // End While
-
-
- // Check if the second portion is either a number or one of these keywords
- szKey[nKeyPos] = '\0';
- szSpecial[nSpecPos] = '\0';
- if (strcmp(szSpecial,"down")== 0 || strcmp(szSpecial,"up")== 0 ||
- strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 ||
- strcmp(szSpecial,"toggle")== 0 || nSpecNum == 1 )
- {
- nFlag = 0;
- }
- else
- {
- nFlag = 1;
- }
- return nFlag; // 1 is bad, 0 is good
-
-} // GetSendKey()
-
-//
-// Routine to check the last "none comment" character on a line to see if its a continuation
-//
-static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
-{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine+1) - 2;
- //int stylech = styler.StyleAt(nsPos);
- while (nsPos < nePos)
- {
- //stylech = styler.StyleAt(nePos);
- int stylech = styler.StyleAt(nsPos);
- if (!(stylech == SCE_AU3_COMMENT)) {
- char ch = styler.SafeGetCharAt(nePos);
- if (!isspacechar(ch)) {
- if (ch == '_')
- return true;
- else
- return false;
- }
- }
- nePos--; // skip to next char
- } // End While
- return false;
-} // IsContinuationLine()
-
-//
-// syntax highlighting logic
-static void ColouriseAU3Doc(unsigned int startPos,
- int length, int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
- WordList &keywords8 = *keywordlists[7];
- // find the first previous line without continuation character at the end
- int lineCurrent = styler.GetLine(startPos);
- int s_startPos = startPos;
- // When not inside a Block comment: find First line without _
- if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
- while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
- (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent); // get start position
- initStyle = 0; // reset the start style to 0
- }
- }
- // Set the new length to include it from the start and set the start position
- length = length + s_startPos - startPos; // correct the total length to process
- styler.StartAt(startPos);
-
- StyleContext sc(startPos, length, initStyle, styler);
- char si; // string indicator "=1 '=2
- char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
- char ci; // comment indicator 0=not linecomment(;)
- char s_save[100];
- si=0;
- ni=0;
- ci=0;
- //$$$
- for (; sc.More(); sc.Forward()) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- // **********************************************
- // save the total current word for eof processing
- if (IsAWordChar(sc.ch) || sc.ch == '}')
- {
- strcpy(s_save,s);
- int tp = strlen(s_save);
- if (tp < 99) {
- s_save[tp] = static_cast<char>(tolower(sc.ch));
- s_save[tp+1] = '\0';
- }
- }
- // **********************************************
- //
- switch (sc.state)
- {
- case SCE_AU3_COMMENTBLOCK:
- {
- //Reset at line end
- if (sc.atLineEnd) {
- ci=0;
- if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
- if (sc.atLineEnd)
- sc.SetState(SCE_AU3_DEFAULT);
- else
- sc.SetState(SCE_AU3_COMMENTBLOCK);
- }
- break;
- }
- //skip rest of line when a ; is encountered
- if (sc.chPrev == ';') {
- ci=2;
- sc.SetState(SCE_AU3_COMMENTBLOCK);
- }
- // skip rest of the line
- if (ci==2)
- break;
- // check when first character is detected on the line
- if (ci==0) {
- if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
- ci=1;
- sc.SetState(SCE_AU3_COMMENTBLOCK);
- }
- break;
- }
- if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
- if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
- sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line
- else
- ci=2; // line doesn't begin with #CE so skip the rest of the line
- }
- break;
- }
- case SCE_AU3_COMMENT:
- {
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
- break;
- }
- case SCE_AU3_OPERATOR:
- {
- // check if its a COMobject
- if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
- sc.SetState(SCE_AU3_COMOBJ);
- }
- else {
- sc.SetState(SCE_AU3_DEFAULT);
- }
- break;
- }
- case SCE_AU3_SPECIAL:
- {
- if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
- break;
- }
- case SCE_AU3_KEYWORD:
- {
- if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0))))
- {
- if (!IsTypeCharacter(sc.ch))
- {
- if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 )
- {
- sc.ChangeState(SCE_AU3_COMMENTBLOCK);
- sc.SetState(SCE_AU3_COMMENTBLOCK);
- break;
- }
- else if (keywords.InList(s)) {
- sc.ChangeState(SCE_AU3_KEYWORD);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_AU3_FUNCTION);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_AU3_MACRO);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_AU3_PREPROCESSOR);
- sc.SetState(SCE_AU3_DEFAULT);
- if (strcmp(s, "#include")== 0)
- {
- si = 3; // use to determine string start for #inlude <>
- }
- }
- else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_AU3_SPECIAL);
- sc.SetState(SCE_AU3_SPECIAL);
- }
- else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
- sc.ChangeState(SCE_AU3_EXPAND);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- else if (keywords8.InList(s)) {
- sc.ChangeState(SCE_AU3_UDF);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- else if (strcmp(s, "_") == 0) {
- sc.ChangeState(SCE_AU3_OPERATOR);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- else if (!IsAWordChar(sc.ch)) {
- sc.ChangeState(SCE_AU3_DEFAULT);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- }
- }
- if (sc.atLineEnd) {
- sc.SetState(SCE_AU3_DEFAULT);}
- break;
- }
- case SCE_AU3_NUMBER:
- {
- // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
- //
- // test for Hex notation
- if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
- {
- ni = 2;
- break;
- }
- // test for E notation
- if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
- {
- ni = 3;
- break;
- }
- // Allow Hex characters inside hex numeric strings
- if ((ni == 2) &&
- (sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
- sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
- {
- break;
- }
- // test for 1 dec point only
- if (sc.ch == '.')
- {
- if (ni==0)
- {
- ni=1;
- }
- else
- {
- ni=9;
- }
- break;
- }
- // end of numeric string ?
- if (!(IsADigit(sc.ch)))
- {
- if (ni==9)
- {
- sc.ChangeState(SCE_AU3_DEFAULT);
- }
- sc.SetState(SCE_AU3_DEFAULT);
- }
- break;
- }
- case SCE_AU3_VARIABLE:
- {
- // Check if its a COMObject
- if (sc.ch == '.' && !IsADigit(sc.chNext)) {
- sc.SetState(SCE_AU3_OPERATOR);
- }
- else if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_AU3_DEFAULT);
- }
- break;
- }
- case SCE_AU3_COMOBJ:
- {
- if (!(IsAWordChar(sc.ch))) {
- sc.SetState(SCE_AU3_DEFAULT);
- }
- break;
- }
- case SCE_AU3_STRING:
- {
- // check for " to end a double qouted string or
- // check for ' to end a single qouted string
- if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
- {
- sc.ForwardSetState(SCE_AU3_DEFAULT);
- si=0;
- break;
- }
- if (sc.atLineEnd)
- {
- si=0;
- // at line end and not found a continuation char then reset to default
- int lineCurrent = styler.GetLine(sc.currentPos);
- if (!IsContinuationLine(lineCurrent,styler))
- {
- sc.SetState(SCE_AU3_DEFAULT);
- break;
- }
- }
- // find Sendkeys in a STRING
- if (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) {
- sc.SetState(SCE_AU3_SENT);}
- break;
- }
-
- case SCE_AU3_SENT:
- {
- // Send key string ended
- if (sc.chPrev == '}' && sc.ch != '}')
- {
- // set color to SENDKEY when valid sendkey .. else set back to regular string
- char sk[100];
- // split {111 222} and return {111} and check if 222 is valid.
- // if return code = 1 then invalid 222 so must be string
- if (GetSendKey(s,sk))
- {
- sc.ChangeState(SCE_AU3_STRING);
- }
- // if single char between {?} then its ok as sendkey for a single character
- else if (strlen(sk) == 3)
- {
- sc.ChangeState(SCE_AU3_SENT);
- }
- // if sendkey {111} is in table then ok as sendkey
- else if (keywords4.InList(sk))
- {
- sc.ChangeState(SCE_AU3_SENT);
- }
- else
- {
- sc.ChangeState(SCE_AU3_STRING);
- }
- sc.SetState(SCE_AU3_STRING);
- }
- else
- {
- // check if the start is a valid SendKey start
- int nPos = 0;
- int nState = 1;
- char cTemp;
- while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
- {
- if (cTemp == '{' && nState == 1)
- {
- nState = 2;
- }
- if (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' ))
- {
- nState = 0;
- }
- nPos++;
- }
- //Verify characters infront of { ... if not assume regular string
- if (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) {
- sc.ChangeState(SCE_AU3_STRING);
- sc.SetState(SCE_AU3_STRING);
- }
- // If invalid character found then assume its a regular string
- if (nState == 0) {
- sc.ChangeState(SCE_AU3_STRING);
- sc.SetState(SCE_AU3_STRING);
- }
- }
- // check if next portion is again a sendkey
- if (sc.atLineEnd)
- {
- sc.ChangeState(SCE_AU3_STRING);
- sc.SetState(SCE_AU3_DEFAULT);
- si = 0; // reset string indicator
- }
- //* check in next characters following a sentkey are again a sent key
- // Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{}
- if (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) {
- sc.SetState(SCE_AU3_SENT);}
- // check to see if the string ended...
- // Sendkey string isn't complete but the string ended....
- if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\''))
- {
- sc.ChangeState(SCE_AU3_STRING);
- sc.ForwardSetState(SCE_AU3_DEFAULT);
- }
- break;
- }
- } //switch (sc.state)
-
- // Determine if a new state should be entered:
-
- if (sc.state == SCE_AU3_DEFAULT)
- {
- if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
- else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
- else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
- else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
- else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
- //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
- else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
- else if (sc.ch == '\"') {
- sc.SetState(SCE_AU3_STRING);
- si = 1; }
- else if (sc.ch == '\'') {
- sc.SetState(SCE_AU3_STRING);
- si = 2; }
- else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
- {
- sc.SetState(SCE_AU3_NUMBER);
- ni = 0;
- }
- else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
- else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
- else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
- }
- } //for (; sc.More(); sc.Forward())
-
- //*************************************
- // Colourize the last word correctly
- //*************************************
- if (sc.state == SCE_AU3_KEYWORD)
- {
- if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
- {
- sc.ChangeState(SCE_AU3_COMMENTBLOCK);
- sc.SetState(SCE_AU3_COMMENTBLOCK);
- }
- else if (keywords.InList(s_save)) {
- sc.ChangeState(SCE_AU3_KEYWORD);
- sc.SetState(SCE_AU3_KEYWORD);
- }
- else if (keywords2.InList(s_save)) {
- sc.ChangeState(SCE_AU3_FUNCTION);
- sc.SetState(SCE_AU3_FUNCTION);
- }
- else if (keywords3.InList(s_save)) {
- sc.ChangeState(SCE_AU3_MACRO);
- sc.SetState(SCE_AU3_MACRO);
- }
- else if (keywords5.InList(s_save)) {
- sc.ChangeState(SCE_AU3_PREPROCESSOR);
- sc.SetState(SCE_AU3_PREPROCESSOR);
- }
- else if (keywords6.InList(s_save)) {
- sc.ChangeState(SCE_AU3_SPECIAL);
- sc.SetState(SCE_AU3_SPECIAL);
- }
- else if (keywords7.InList(s_save) && sc.atLineEnd) {
- sc.ChangeState(SCE_AU3_EXPAND);
- sc.SetState(SCE_AU3_EXPAND);
- }
- else if (keywords8.InList(s_save)) {
- sc.ChangeState(SCE_AU3_UDF);
- sc.SetState(SCE_AU3_UDF);
- }
- else {
- sc.ChangeState(SCE_AU3_DEFAULT);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- }
- if (sc.state == SCE_AU3_SENT)
- {
- // Send key string ended
- if (sc.chPrev == '}' && sc.ch != '}')
- {
- // set color to SENDKEY when valid sendkey .. else set back to regular string
- char sk[100];
- // split {111 222} and return {111} and check if 222 is valid.
- // if return code = 1 then invalid 222 so must be string
- if (GetSendKey(s_save,sk))
- {
- sc.ChangeState(SCE_AU3_STRING);
- }
- // if single char between {?} then its ok as sendkey for a single character
- else if (strlen(sk) == 3)
- {
- sc.ChangeState(SCE_AU3_SENT);
- }
- // if sendkey {111} is in table then ok as sendkey
- else if (keywords4.InList(sk))
- {
- sc.ChangeState(SCE_AU3_SENT);
- }
- else
- {
- sc.ChangeState(SCE_AU3_STRING);
- }
- sc.SetState(SCE_AU3_STRING);
- }
- // check if next portion is again a sendkey
- if (sc.atLineEnd)
- {
- sc.ChangeState(SCE_AU3_STRING);
- sc.SetState(SCE_AU3_DEFAULT);
- }
- }
- //*************************************
- sc.Complete();
-}
-
-//
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK;
-}
-
-//
-// Routine to find first none space on the current line and return its Style
-// needed for comment lines not starting on pos 1
-static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
-{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine+1) - 1;
- while (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)
- {
- nsPos++; // skip to next char
-
- } // End While
- return styler.StyleAt(nsPos);
-
-} // GetStyleFirstWord()
-
-
-//
-static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
-{
- int endPos = startPos + length;
- // get settings from the config files for folding comments and preprocessor lines
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
- // Backtrack to previous line in case need to fix its fold status
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- // vars for style of previous/current/next lines
- int style = GetStyleFirstWord(lineCurrent,styler);
- int stylePrev = 0;
- // find the first previous line without continuation character at the end
- while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
- (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- if (lineCurrent > 0) {
- stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
- }
- // vars for getting first word to check for keywords
- bool FirstWordStart = false;
- bool FirstWordEnd = false;
- char szKeyword[11]="";
- int szKeywordlen = 0;
- char szThen[5]="";
- int szThenlen = 0;
- bool ThenFoundLast = false;
- // var for indentlevel
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelNext = levelCurrent;
- //
- int visibleChars = 0;
- char chNext = styler.SafeGetCharAt(startPos);
- char chPrev = ' ';
- //
- for (int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- if (IsAWordChar(ch)) {
- visibleChars++;
- }
- // get the syle for the current character neede to check in comment
- int stylech = styler.StyleAt(i);
- // get first word for the line for indent check max 9 characters
- if (FirstWordStart && (!(FirstWordEnd))) {
- if (!IsAWordChar(ch)) {
- FirstWordEnd = true;
- szKeyword[szKeywordlen] = '\0';
- }
- else {
- if (szKeywordlen < 10) {
- szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
- }
- }
- }
- // start the capture of the first word
- if (!(FirstWordStart)) {
- if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
- FirstWordStart = true;
- szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
- }
- }
- // only process this logic when not in comment section
- if (!(stylech == SCE_AU3_COMMENT)) {
- if (ThenFoundLast) {
- if (IsAWordChar(ch)) {
- ThenFoundLast = false;
- }
- }
- // find out if the word "then" is the last on a "if" line
- if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
- if (szThenlen == 4) {
- szThen[0] = szThen[1];
- szThen[1] = szThen[2];
- szThen[2] = szThen[3];
- szThen[3] = static_cast<char>(tolower(ch));
- if (strcmp(szThen,"then") == 0 ) {
- ThenFoundLast = true;
- }
- }
- else {
- szThen[szThenlen++] = static_cast<char>(tolower(ch));
- if (szThenlen == 5) {
- szThen[4] = '\0';
- }
- }
- }
- }
- // End of Line found so process the information
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
- // **************************
- // Folding logic for Keywords
- // **************************
- // if a keyword is found on the current line and the line doesn't end with _ (continuation)
- // and we are not inside a commentblock.
- if (szKeywordlen > 0 && (!(chPrev == '_')) &&
- ((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
- szKeyword[szKeywordlen] = '\0';
- // only fold "if" last keyword is "then" (else its a one line if)
- if (strcmp(szKeyword,"if") == 0 && ThenFoundLast) {
- levelNext++;
- }
- // create new fold for these words
- if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
- strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
- strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
- levelNext++;
- }
- // create double Fold for select&switch because Case will subtract one of the current level
- if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
- levelNext++;
- levelNext++;
- }
- // end the fold for these words before the current line
- if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
- strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
- strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
- levelNext--;
- levelCurrent--;
- }
- // end the fold for these words before the current line and Start new fold
- if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 ||
- strcmp(szKeyword,"elseif") == 0 ) {
- levelCurrent--;
- }
- // end the double fold for this word before the current line
- if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
- levelNext--;
- levelNext--;
- levelCurrent--;
- levelCurrent--;
- }
- // end the fold for these words on the current line
- if (strcmp(szKeyword,"#endregion") == 0 ) {
- levelNext--;
- }
- }
- // Preprocessor and Comment folding
- int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
- // *************************************
- // Folding logic for preprocessor blocks
- // *************************************
- // process preprosessor line
- if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {
- if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {
- levelNext++;
- }
- // fold till the last line for normal comment lines
- else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {
- levelNext--;
- }
- }
- // *********************************
- // Folding logic for Comment blocks
- // *********************************
- if (foldComment && IsStreamCommentStyle(style)) {
- // Start of a comment block
- if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
- levelNext++;
- }
- // fold till the last line for normal comment lines
- else if (IsStreamCommentStyle(stylePrev)
- && !(styleNext == SCE_AU3_COMMENT)
- && stylePrev == SCE_AU3_COMMENT
- && style == SCE_AU3_COMMENT) {
- levelNext--;
- }
- // fold till the one but last line for Blockcomment lines
- else if (IsStreamCommentStyle(stylePrev)
- && !(styleNext == SCE_AU3_COMMENTBLOCK)
- && style == SCE_AU3_COMMENTBLOCK) {
- levelNext--;
- levelCurrent--;
- }
- }
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- // reset values for the next line
- lineCurrent++;
- stylePrev = style;
- style = styleNext;
- levelCurrent = levelNext;
- visibleChars = 0;
- // if the last character is an Underscore then don't reset since the line continues on the next line.
- if (!(chPrev == '_')) {
- szKeywordlen = 0;
- szThenlen = 0;
- FirstWordStart = false;
- FirstWordEnd = false;
- ThenFoundLast = false;
- }
- }
- // save the last processed character
- if (!isspacechar(ch)) {
- chPrev = ch;
- visibleChars++;
- }
- }
-}
-
-
-//
-
-static const char * const AU3WordLists[] = {
- "#autoit keywords",
- "#autoit functions",
- "#autoit macros",
- "#autoit Sent keys",
- "#autoit Pre-processors",
- "#autoit Special",
- "#autoit Expand",
- "#autoit UDF",
- 0
-};
-LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
+++ /dev/null
-// SciTE - Scintilla based Text Editor
-/** @file LexAVE.cxx
- ** Lexer for Avenue.
- **
- ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-static inline bool IsEnumChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch)|| ch == '_');
-}
-static inline bool IsANumberChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' );
-}
-
-inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-inline bool isAveOperator(char ch) {
- if (isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' ||
- ch == '{' || ch == '}' ||
- ch == '[' || ch == ']' || ch == ';' ||
- ch == '<' || ch == '>' || ch == ',' ||
- ch == '.' )
- return true;
- return false;
-}
-
-static void ColouriseAveDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
-
- // Do not leak onto next line
- if (initStyle == SCE_AVE_STRINGEOL) {
- initStyle = SCE_AVE_DEFAULT;
- }
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
- if (sc.atLineEnd) {
- // Update the line state, so it can be seen by next line
- int currentLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(currentLine, 0);
- }
- if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
- // Prevent SCE_AVE_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_AVE_STRING);
- }
-
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_AVE_OPERATOR) {
- sc.SetState(SCE_AVE_DEFAULT);
- } else if (sc.state == SCE_AVE_NUMBER) {
- if (!IsANumberChar(sc.ch)) {
- sc.SetState(SCE_AVE_DEFAULT);
- }
- } else if (sc.state == SCE_AVE_ENUM) {
- if (!IsEnumChar(sc.ch)) {
- sc.SetState(SCE_AVE_DEFAULT);
- }
- } else if (sc.state == SCE_AVE_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- //sc.GetCurrent(s, sizeof(s));
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_AVE_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_AVE_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_AVE_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_AVE_WORD4);
- } else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_AVE_WORD5);
- } else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_AVE_WORD6);
- }
- sc.SetState(SCE_AVE_DEFAULT);
- }
- } else if (sc.state == SCE_AVE_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_AVE_DEFAULT);
- }
- } else if (sc.state == SCE_AVE_STRING) {
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_AVE_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_AVE_STRINGEOL);
- sc.ForwardSetState(SCE_AVE_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_AVE_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_AVE_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_AVE_IDENTIFIER);
- } else if (sc.Match('\"')) {
- sc.SetState(SCE_AVE_STRING);
- } else if (sc.Match('\'')) {
- sc.SetState(SCE_AVE_COMMENT);
- sc.Forward();
- } else if (isAveOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_AVE_OPERATOR);
- } else if (sc.Match('#')) {
- sc.SetState(SCE_AVE_ENUM);
- sc.Forward();
- }
- }
- }
- sc.Complete();
-}
-
-static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
- Accessor &styler) {
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = static_cast<char>(tolower(styler[startPos]));
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- int styleNext = styler.StyleAt(startPos);
- char s[10];
-
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = static_cast<char>(tolower(chNext));
- chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_AVE_WORD) {
- if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
- for (unsigned int j = 0; j < 6; j++) {
- if (!iswordchar(styler[i + j])) {
- break;
- }
- s[j] = static_cast<char>(tolower(styler[i + j]));
- s[j + 1] = '\0';
- }
-
- if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
- levelCurrent++;
- }
- if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
- // Normally "elseif" and "then" will be on the same line and will cancel
- // each other out. // As implemented, this does not support fold.at.else.
- levelCurrent--;
- }
- }
- } else if (style == SCE_AVE_OPERATOR) {
- if (ch == '{' || ch == '(') {
- levelCurrent++;
- } else if (ch == '}' || ch == ')') {
- levelCurrent--;
- }
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact) {
- lev |= SC_FOLDLEVELWHITEFLAG;
- }
- if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch)) {
- visibleChars++;
- }
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
-
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexABAQUS.cxx
- ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
- ** By Sergio Lucato.
- ** Sort of completely rewritten by Gertjan Kloosterman
- **/
-// The License.txt file describes the conditions under which this software may be distributed.
-
-// Code folding copyied and modified from LexBasic.cxx
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80 && (isalnum(ch) || (ch == '_')));
-}
-
-static inline bool IsAKeywordChar(const int ch) {
- return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
-}
-
-static inline bool IsASetChar(const int ch) {
- return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
-}
-
-static inline bool IsAnOperator(char ch) {
- // '.' left out as it is used to make up numbers
- if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
- ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
- ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
- ch == '$' || ch == ':' || ch == '%')
- return true;
- return false;
-}
-
-static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */,
- Accessor &styler) {
- enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
- DAT_LINE_VAL, DAT_LINE_COMMA,\
- COMMENT_LINE,\
- ST_ERROR, LINE_END } state ;
-
- // Do not leak onto next line
- state = LINE_END ;
- initStyle = SCE_ABAQUS_DEFAULT;
- StyleContext sc(startPos, length, initStyle, styler);
-
- // Things are actually quite simple
- // we have commentlines
- // keywordlines and datalines
- // On a data line there will only be colouring of numbers
- // a keyword line is constructed as
- // *word,[ paramname[=paramvalue]]*
- // if the line ends with a , the keyword line continues onto the new line
-
- for (; sc.More(); sc.Forward()) {
- switch ( state ) {
- case KW_LINE_KW :
- if ( sc.atLineEnd ) {
- // finished the line in keyword state, switch to LINE_END
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- } else if ( IsAKeywordChar(sc.ch) ) {
- // nothing changes
- state = KW_LINE_KW ;
- } else if ( sc.ch == ',' ) {
- // Well well we say a comma, arguments *MUST* follow
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = KW_LINE_COMMA ;
- } else {
- // Flag an error
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- // Done with processing
- break ;
- case KW_LINE_COMMA :
- // acomma on a keywordline was seen
- if ( IsAKeywordChar(sc.ch)) {
- sc.SetState(SCE_ABAQUS_ARGUMENT) ;
- state = KW_LINE_PAR ;
- } else if ( sc.atLineEnd || (sc.ch == ',') ) {
- // we remain in keyword mode
- state = KW_LINE_COMMA ;
- } else if ( sc.ch == ' ' ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = KW_LINE_COMMA ;
- } else {
- // Anything else constitutes an error
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- break ;
- case KW_LINE_PAR :
- if ( sc.atLineEnd ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
- // remain in this state
- state = KW_LINE_PAR ;
- } else if ( sc.ch == ',' ) {
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = KW_LINE_COMMA ;
- } else if ( sc.ch == '=' ) {
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = KW_LINE_EQ ;
- } else {
- // Anything else constitutes an error
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- break ;
- case KW_LINE_EQ :
- if ( sc.ch == ' ' ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- // remain in this state
- state = KW_LINE_EQ ;
- } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
- sc.SetState(SCE_ABAQUS_NUMBER) ;
- state = KW_LINE_VAL ;
- } else if ( IsAKeywordChar(sc.ch) ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = KW_LINE_VAL ;
- } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
- sc.SetState(SCE_ABAQUS_STRING) ;
- state = KW_LINE_VAL ;
- } else {
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- break ;
- case KW_LINE_VAL :
- if ( sc.atLineEnd ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
- // nothing changes
- state = KW_LINE_VAL ;
- } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
- ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
- (sc.state == SCE_ABAQUS_NUMBER)) {
- // remain in number mode
- state = KW_LINE_VAL ;
- } else if (sc.state == SCE_ABAQUS_STRING) {
- // accept everything until a closing quote
- if ( sc.ch == '\'' || sc.ch == '\"' ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = KW_LINE_VAL ;
- }
- } else if ( sc.ch == ',' ) {
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = KW_LINE_COMMA ;
- } else {
- // anything else is an error
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- break ;
- case DAT_LINE_VAL :
- if ( sc.atLineEnd ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
- // nothing changes
- state = DAT_LINE_VAL ;
- } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
- ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
- (sc.state == SCE_ABAQUS_NUMBER)) {
- // remain in number mode
- state = DAT_LINE_VAL ;
- } else if (sc.state == SCE_ABAQUS_STRING) {
- // accept everything until a closing quote
- if ( sc.ch == '\'' || sc.ch == '\"' ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = DAT_LINE_VAL ;
- }
- } else if ( sc.ch == ',' ) {
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = DAT_LINE_COMMA ;
- } else {
- // anything else is an error
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- break ;
- case DAT_LINE_COMMA :
- // a comma on a data line was seen
- if ( sc.atLineEnd ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- } else if ( sc.ch == ' ' ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = DAT_LINE_COMMA ;
- } else if (sc.ch == ',') {
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = DAT_LINE_COMMA ;
- } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
- sc.SetState(SCE_ABAQUS_NUMBER) ;
- state = DAT_LINE_VAL ;
- } else if ( IsAKeywordChar(sc.ch) ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = DAT_LINE_VAL ;
- } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
- sc.SetState(SCE_ABAQUS_STRING) ;
- state = DAT_LINE_VAL ;
- } else {
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- break ;
- case COMMENT_LINE :
- if ( sc.atLineEnd ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- }
- break ;
- case ST_ERROR :
- if ( sc.atLineEnd ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = LINE_END ;
- }
- break ;
- case LINE_END :
- if ( sc.atLineEnd || sc.ch == ' ' ) {
- // nothing changes
- state = LINE_END ;
- } else if ( sc.ch == '*' ) {
- if ( sc.chNext == '*' ) {
- state = COMMENT_LINE ;
- sc.SetState(SCE_ABAQUS_COMMENT) ;
- } else {
- state = KW_LINE_KW ;
- sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
- }
- } else {
- // it must be a data line, things are as if we are in DAT_LINE_COMMA
- if ( sc.ch == ',' ) {
- sc.SetState(SCE_ABAQUS_OPERATOR) ;
- state = DAT_LINE_COMMA ;
- } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
- sc.SetState(SCE_ABAQUS_NUMBER) ;
- state = DAT_LINE_VAL ;
- } else if ( IsAKeywordChar(sc.ch) ) {
- sc.SetState(SCE_ABAQUS_DEFAULT) ;
- state = DAT_LINE_VAL ;
- } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
- sc.SetState(SCE_ABAQUS_STRING) ;
- state = DAT_LINE_VAL ;
- } else {
- sc.SetState(SCE_ABAQUS_PROCESSOR) ;
- state = ST_ERROR ;
- }
- }
- break ;
- }
- }
- sc.Complete();
-}
-
-//------------------------------------------------------------------------------
-// This copyied and modified from LexBasic.cxx
-//------------------------------------------------------------------------------
-
-/* Bits:
- * 1 - whitespace
- * 2 - operator
- * 4 - identifier
- * 8 - decimal digit
- * 16 - hex digit
- * 32 - bin digit
- */
-static int character_classification[128] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
- 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
- 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
- 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
-};
-
-static bool IsSpace(int c) {
- return c < 128 && (character_classification[c] & 1);
-}
-
-static bool IsIdentifier(int c) {
- return c < 128 && (character_classification[c] & 4);
-}
-
-static int LowerCase(int c)
-{
- if (c >= 'A' && c <= 'Z')
- return 'a' + c - 'A';
- return c;
-}
-
-static int LineEnd(int line, Accessor &styler)
-{
- const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
- int eol_pos ;
- // if the line is the last line, the eol_pos is styler.Length()
- // eol will contain a new line, or a virtual new line
- if ( docLines == line )
- eol_pos = styler.Length() ;
- else
- eol_pos = styler.LineStart(line + 1) - 1;
- return eol_pos ;
-}
-
-static int LineStart(int line, Accessor &styler)
-{
- return styler.LineStart(line) ;
-}
-
-// LineType
-//
-// bits determines the line type
-// 1 : data line
-// 2 : only whitespace
-// 3 : data line with only whitespace
-// 4 : keyword line
-// 5 : block open keyword line
-// 6 : block close keyword line
-// 7 : keyword line in error
-// 8 : comment line
-static int LineType(int line, Accessor &styler) {
- int pos = LineStart(line, styler) ;
- int eol_pos = LineEnd(line, styler) ;
-
- int c ;
- char ch = ' ';
-
- int i = pos ;
- while ( i < eol_pos ) {
- c = styler.SafeGetCharAt(i);
- ch = static_cast<char>(LowerCase(c));
- // We can say something as soon as no whitespace
- // was encountered
- if ( !IsSpace(c) )
- break ;
- i++ ;
- }
-
- if ( i >= eol_pos ) {
- // This is a whitespace line, currently
- // classifies as data line
- return 3 ;
- }
-
- if ( ch != '*' ) {
- // This is a data line
- return 1 ;
- }
-
- if ( i == eol_pos - 1 ) {
- // Only a single *, error but make keyword line
- return 4+3 ;
- }
-
- // This means we can have a second character
- // if that is also a * this means a comment
- // otherwise it is a keyword.
- c = styler.SafeGetCharAt(i+1);
- ch = static_cast<char>(LowerCase(c));
- if ( ch == '*' ) {
- return 8 ;
- }
-
- // At this point we know this is a keyword line
- // the character at position i is a *
- // it is not a comment line
- char word[256] ;
- int wlen = 0;
-
- word[wlen] = '*' ;
- wlen++ ;
-
- i++ ;
- while ( (i < eol_pos) && (wlen < 255) ) {
- c = styler.SafeGetCharAt(i);
- ch = static_cast<char>(LowerCase(c));
-
- if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
- break ;
-
- if ( IsIdentifier(c) ) {
- word[wlen] = ch ;
- wlen++ ;
- }
-
- i++ ;
- }
-
- word[wlen] = 0 ;
-
- // Make a comparison
- if ( !strcmp(word, "*step") ||
- !strcmp(word, "*part") ||
- !strcmp(word, "*instance") ||
- !strcmp(word, "*assembly")) {
- return 4+1 ;
- }
-
- if ( !strcmp(word, "*endstep") ||
- !strcmp(word, "*endpart") ||
- !strcmp(word, "*endinstance") ||
- !strcmp(word, "*endassembly")) {
- return 4+2 ;
- }
-
- return 4 ;
-}
-
-static void SafeSetLevel(int line, int level, Accessor &styler)
-{
- if ( line < 0 )
- return ;
-
- int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
-
- if ( (level & mask) < 0 )
- return ;
-
- if ( styler.LevelAt(line) != level )
- styler.SetLevel(line, level) ;
-}
-
-static void FoldABAQUSDoc(unsigned int startPos, int length, int,
-WordList *[], Accessor &styler) {
- int startLine = styler.GetLine(startPos) ;
- int endLine = styler.GetLine(startPos+length-1) ;
-
- // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- // We want to deal with all the cases
- // To know the correct indentlevel, we need to look back to the
- // previous command line indentation level
- // order of formatting keyline datalines commentlines
- int beginData = -1 ;
- int beginComment = -1 ;
- int prvKeyLine = startLine ;
- int prvKeyLineTp = 0 ;
-
- // Scan until we find the previous keyword line
- // this will give us the level reference that we need
- while ( prvKeyLine > 0 ) {
- prvKeyLine-- ;
- prvKeyLineTp = LineType(prvKeyLine, styler) ;
- if ( prvKeyLineTp & 4 )
- break ;
- }
-
- // Determine the base line level of all lines following
- // the previous keyword
- // new keyword lines are placed on this level
- //if ( prvKeyLineTp & 4 ) {
- int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
- //}
-
- // uncomment line below if weird behaviour continues
- prvKeyLine = -1 ;
-
- // Now start scanning over the lines.
- for ( int line = startLine; line <= endLine; line++ ) {
- int lineType = LineType(line, styler) ;
-
- // Check for comment line
- if ( lineType == 8 ) {
- if ( beginComment < 0 ) {
- beginComment = line ;
- }
- }
-
- // Check for data line
- if ( (lineType == 1) || (lineType == 3) ) {
- if ( beginData < 0 ) {
- if ( beginComment >= 0 ) {
- beginData = beginComment ;
- } else {
- beginData = line ;
- }
- }
- beginComment = -1 ;
- }
-
- // Check for keywordline.
- // As soon as a keyword line is encountered, we can set the
- // levels of everything from the previous keyword line to this one
- if ( lineType & 4 ) {
- // this is a keyword, we can now place the previous keyword
- // all its data lines and the remainder
-
- // Write comments and data line
- if ( beginComment < 0 ) {
- beginComment = line ;
- }
-
- if ( beginData < 0 ) {
- beginData = beginComment ;
- if ( prvKeyLineTp != 5 )
- SafeSetLevel(prvKeyLine, level, styler) ;
- else
- SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
- } else {
- SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
- }
-
- int datLevel = level + 1 ;
- if ( !(prvKeyLineTp & 4) ) {
- datLevel = level ;
- }
-
- for ( int ll = beginData; ll < beginComment; ll++ )
- SafeSetLevel(ll, datLevel, styler) ;
-
- // The keyword we just found is going to be written at another level
- // if we have a type 5 and type 6
- if ( prvKeyLineTp == 5 ) {
- level += 1 ;
- }
-
- if ( prvKeyLineTp == 6 ) {
- level -= 1 ;
- if ( level < 0 ) {
- level = 0 ;
- }
- }
-
- for ( int lll = beginComment; lll < line; lll++ )
- SafeSetLevel(lll, level, styler) ;
-
- // wrap and reset
- beginComment = -1 ;
- beginData = -1 ;
- prvKeyLine = line ;
- prvKeyLineTp = lineType ;
- }
-
- }
-
- if ( beginComment < 0 ) {
- beginComment = endLine + 1 ;
- } else {
- // We need to find out whether this comment block is followed by
- // a data line or a keyword line
- const int docLines = styler.GetLine(styler.Length() - 1);
-
- for ( int line = endLine + 1; line <= docLines; line++ ) {
- int lineType = LineType(line, styler) ;
-
- if ( lineType != 8 ) {
- if ( !(lineType & 4) ) {
- beginComment = endLine + 1 ;
- }
- break ;
- }
- }
- }
-
- if ( beginData < 0 ) {
- beginData = beginComment ;
- if ( prvKeyLineTp != 5 )
- SafeSetLevel(prvKeyLine, level, styler) ;
- else
- SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
- } else {
- SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
- }
-
- int datLevel = level + 1 ;
- if ( !(prvKeyLineTp & 4) ) {
- datLevel = level ;
- }
-
- for ( int ll = beginData; ll < beginComment; ll++ )
- SafeSetLevel(ll, datLevel, styler) ;
-
- if ( prvKeyLineTp == 5 ) {
- level += 1 ;
- }
-
- if ( prvKeyLineTp == 6 ) {
- level -= 1 ;
- }
- for ( int m = beginComment; m <= endLine; m++ )
- SafeSetLevel(m, level, styler) ;
-}
-
-static const char * const abaqusWordListDesc[] = {
- "processors",
- "commands",
- "slashommands",
- "starcommands",
- "arguments",
- "functions",
- 0
-};
-
-LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexAda.cxx
- ** Lexer for Ada 95
- **/
-// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <string>
-
-#include "Platform.h"
-
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "PropSet.h"
-#include "KeyWords.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-/*
- * Interface
- */
-
-static void ColouriseDocument(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler);
-
-static const char * const adaWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
-
-/*
- * Implementation
- */
-
-// Functions that have apostropheStartsAttribute as a parameter set it according to whether
-// an apostrophe encountered after processing the current token will start an attribute or
-// a character literal.
-static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
-static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
-static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
-
-static inline bool IsDelimiterCharacter(int ch);
-static inline bool IsNumberStartCharacter(int ch);
-static inline bool IsNumberCharacter(int ch);
-static inline bool IsSeparatorOrDelimiterCharacter(int ch);
-static bool IsValidIdentifier(const std::string& identifier);
-static bool IsValidNumber(const std::string& number);
-static inline bool IsWordStartCharacter(int ch);
-static inline bool IsWordCharacter(int ch);
-
-static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = true;
-
- sc.SetState(SCE_ADA_CHARACTER);
-
- // Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
- // is handled correctly)
- sc.Forward();
- sc.Forward();
-
- ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
-}
-
-static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
- while (!sc.atLineEnd && !sc.Match(chEnd)) {
- sc.Forward();
- }
-
- if (!sc.atLineEnd) {
- sc.ForwardSetState(SCE_ADA_DEFAULT);
- } else {
- sc.ChangeState(stateEOL);
- }
-}
-
-static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
- // Apostrophe meaning is not changed, but the parameter is present for uniformity
-
- sc.SetState(SCE_ADA_COMMENTLINE);
-
- while (!sc.atLineEnd) {
- sc.Forward();
- }
-}
-
-static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = sc.Match (')');
- sc.SetState(SCE_ADA_DELIMITER);
- sc.ForwardSetState(SCE_ADA_DEFAULT);
-}
-
-static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = false;
-
- sc.SetState(SCE_ADA_LABEL);
-
- // Skip "<<"
- sc.Forward();
- sc.Forward();
-
- std::string identifier;
-
- while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
- identifier += static_cast<char>(tolower(sc.ch));
- sc.Forward();
- }
-
- // Skip ">>"
- if (sc.Match('>', '>')) {
- sc.Forward();
- sc.Forward();
- } else {
- sc.ChangeState(SCE_ADA_ILLEGAL);
- }
-
- // If the name is an invalid identifier or a keyword, then make it invalid label
- if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
- sc.ChangeState(SCE_ADA_ILLEGAL);
- }
-
- sc.SetState(SCE_ADA_DEFAULT);
-
-}
-
-static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = true;
-
- std::string number;
- sc.SetState(SCE_ADA_NUMBER);
-
- // Get all characters up to a delimiter or a separator, including points, but excluding
- // double points (ranges).
- while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
- number += static_cast<char>(sc.ch);
- sc.Forward();
- }
-
- // Special case: exponent with sign
- if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
- (sc.ch == '+' || sc.ch == '-')) {
- number += static_cast<char>(sc.ch);
- sc.Forward ();
-
- while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
- number += static_cast<char>(sc.ch);
- sc.Forward();
- }
- }
-
- if (!IsValidNumber(number)) {
- sc.ChangeState(SCE_ADA_ILLEGAL);
- }
-
- sc.SetState(SCE_ADA_DEFAULT);
-}
-
-static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = true;
-
- sc.SetState(SCE_ADA_STRING);
- sc.Forward();
-
- ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
-}
-
-static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
- // Apostrophe meaning is not changed, but the parameter is present for uniformity
- sc.SetState(SCE_ADA_DEFAULT);
- sc.ForwardSetState(SCE_ADA_DEFAULT);
-}
-
-static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = true;
- sc.SetState(SCE_ADA_IDENTIFIER);
-
- std::string word;
-
- while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
- word += static_cast<char>(tolower(sc.ch));
- sc.Forward();
- }
-
- if (!IsValidIdentifier(word)) {
- sc.ChangeState(SCE_ADA_ILLEGAL);
-
- } else if (keywords.InList(word.c_str())) {
- sc.ChangeState(SCE_ADA_WORD);
-
- if (word != "all") {
- apostropheStartsAttribute = false;
- }
- }
-
- sc.SetState(SCE_ADA_DEFAULT);
-}
-
-//
-// ColouriseDocument
-//
-
-static void ColouriseDocument(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
- WordList &keywords = *keywordlists[0];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- int lineCurrent = styler.GetLine(startPos);
- bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
-
- while (sc.More()) {
- if (sc.atLineEnd) {
- // Go to the next line
- sc.Forward();
- lineCurrent++;
-
- // Remember the line state for future incremental lexing
- styler.SetLineState(lineCurrent, apostropheStartsAttribute);
-
- // Don't continue any styles on the next line
- sc.SetState(SCE_ADA_DEFAULT);
- }
-
- // Comments
- if (sc.Match('-', '-')) {
- ColouriseComment(sc, apostropheStartsAttribute);
-
- // Strings
- } else if (sc.Match('"')) {
- ColouriseString(sc, apostropheStartsAttribute);
-
- // Characters
- } else if (sc.Match('\'') && !apostropheStartsAttribute) {
- ColouriseCharacter(sc, apostropheStartsAttribute);
-
- // Labels
- } else if (sc.Match('<', '<')) {
- ColouriseLabel(sc, keywords, apostropheStartsAttribute);
-
- // Whitespace
- } else if (IsASpace(sc.ch)) {
- ColouriseWhiteSpace(sc, apostropheStartsAttribute);
-
- // Delimiters
- } else if (IsDelimiterCharacter(sc.ch)) {
- ColouriseDelimiter(sc, apostropheStartsAttribute);
-
- // Numbers
- } else if (IsADigit(sc.ch) || sc.ch == '#') {
- ColouriseNumber(sc, apostropheStartsAttribute);
-
- // Keywords or identifiers
- } else {
- ColouriseWord(sc, keywords, apostropheStartsAttribute);
- }
- }
-
- sc.Complete();
-}
-
-static inline bool IsDelimiterCharacter(int ch) {
- switch (ch) {
- case '&':
- case '\'':
- case '(':
- case ')':
- case '*':
- case '+':
- case ',':
- case '-':
- case '.':
- case '/':
- case ':':
- case ';':
- case '<':
- case '=':
- case '>':
- case '|':
- return true;
- default:
- return false;
- }
-}
-
-static inline bool IsNumberCharacter(int ch) {
- return IsNumberStartCharacter(ch) ||
- ch == '_' ||
- ch == '.' ||
- ch == '#' ||
- (ch >= 'a' && ch <= 'f') ||
- (ch >= 'A' && ch <= 'F');
-}
-
-static inline bool IsNumberStartCharacter(int ch) {
- return IsADigit(ch);
-}
-
-static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
- return IsASpace(ch) || IsDelimiterCharacter(ch);
-}
-
-static bool IsValidIdentifier(const std::string& identifier) {
- // First character can't be '_', so initialize the flag to true
- bool lastWasUnderscore = true;
-
- size_t length = identifier.length();
-
- // Zero-length identifiers are not valid (these can occur inside labels)
- if (length == 0) {
- return false;
- }
-
- // Check for valid character at the start
- if (!IsWordStartCharacter(identifier[0])) {
- return false;
- }
-
- // Check for only valid characters and no double underscores
- for (size_t i = 0; i < length; i++) {
- if (!IsWordCharacter(identifier[i]) ||
- (identifier[i] == '_' && lastWasUnderscore)) {
- return false;
- }
- lastWasUnderscore = identifier[i] == '_';
- }
-
- // Check for underscore at the end
- if (lastWasUnderscore == true) {
- return false;
- }
-
- // All checks passed
- return true;
-}
-
-static bool IsValidNumber(const std::string& number) {
- size_t hashPos = number.find("#");
- bool seenDot = false;
-
- size_t i = 0;
- size_t length = number.length();
-
- if (length == 0)
- return false; // Just in case
-
- // Decimal number
- if (hashPos == std::string::npos) {
- bool canBeSpecial = false;
-
- for (; i < length; i++) {
- if (number[i] == '_') {
- if (!canBeSpecial) {
- return false;
- }
- canBeSpecial = false;
- } else if (number[i] == '.') {
- if (!canBeSpecial || seenDot) {
- return false;
- }
- canBeSpecial = false;
- seenDot = true;
- } else if (IsADigit(number[i])) {
- canBeSpecial = true;
- } else {
- break;
- }
- }
-
- if (!canBeSpecial)
- return false;
- } else {
- // Based number
- bool canBeSpecial = false;
- int base = 0;
-
- // Parse base
- for (; i < length; i++) {
- int ch = number[i];
- if (ch == '_') {
- if (!canBeSpecial)
- return false;
- canBeSpecial = false;
- } else if (IsADigit(ch)) {
- base = base * 10 + (ch - '0');
- if (base > 16)
- return false;
- canBeSpecial = true;
- } else if (ch == '#' && canBeSpecial) {
- break;
- } else {
- return false;
- }
- }
-
- if (base < 2)
- return false;
- if (i == length)
- return false;
-
- i++; // Skip over '#'
-
- // Parse number
- canBeSpecial = false;
-
- for (; i < length; i++) {
- int ch = tolower(number[i]);
-
- if (ch == '_') {
- if (!canBeSpecial) {
- return false;
- }
- canBeSpecial = false;
-
- } else if (ch == '.') {
- if (!canBeSpecial || seenDot) {
- return false;
- }
- canBeSpecial = false;
- seenDot = true;
-
- } else if (IsADigit(ch)) {
- if (ch - '0' >= base) {
- return false;
- }
- canBeSpecial = true;
-
- } else if (ch >= 'a' && ch <= 'f') {
- if (ch - 'a' + 10 >= base) {
- return false;
- }
- canBeSpecial = true;
-
- } else if (ch == '#' && canBeSpecial) {
- break;
-
- } else {
- return false;
- }
- }
-
- if (i == length) {
- return false;
- }
-
- i++;
- }
-
- // Exponent (optional)
- if (i < length) {
- if (number[i] != 'e' && number[i] != 'E')
- return false;
-
- i++; // Move past 'E'
-
- if (i == length) {
- return false;
- }
-
- if (number[i] == '+')
- i++;
- else if (number[i] == '-') {
- if (seenDot) {
- i++;
- } else {
- return false; // Integer literals should not have negative exponents
- }
- }
-
- if (i == length) {
- return false;
- }
-
- bool canBeSpecial = false;
-
- for (; i < length; i++) {
- if (number[i] == '_') {
- if (!canBeSpecial) {
- return false;
- }
- canBeSpecial = false;
- } else if (IsADigit(number[i])) {
- canBeSpecial = true;
- } else {
- return false;
- }
- }
-
- if (!canBeSpecial)
- return false;
- }
-
- // if i == length, number was parsed successfully.
- return i == length;
-}
-
-static inline bool IsWordCharacter(int ch) {
- return IsWordStartCharacter(ch) || IsADigit(ch);
-}
-
-static inline bool IsWordStartCharacter(int ch) {
- return (isascii(ch) && isalpha(ch)) || ch == '_';
-}
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexAsm.cxx
- ** Lexer for Assembler, just for the MASM syntax
- ** Written by The Black Horus
- ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
- ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
- **/
-// Copyright 1998-2003 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
- ch == '_' || ch == '?');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
- ch == '%' || ch == '@' || ch == '$' || ch == '?');
-}
-
-static inline bool IsAsmOperator(const int ch) {
- if ((ch < 0x80) && (isalnum(ch)))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
- ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
- ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
- ch == '%' || ch == ':')
- return true;
- return false;
-}
-
-static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &cpuInstruction = *keywordlists[0];
- WordList &mathInstruction = *keywordlists[1];
- WordList ®isters = *keywordlists[2];
- WordList &directive = *keywordlists[3];
- WordList &directiveOperand = *keywordlists[4];
- WordList &extInstruction = *keywordlists[5];
-
- // Do not leak onto next line
- if (initStyle == SCE_ASM_STRINGEOL)
- initStyle = SCE_ASM_DEFAULT;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
-
- // Prevent SCE_ASM_STRINGEOL from leaking back to previous line
- if (sc.atLineStart && (sc.state == SCE_ASM_STRING)) {
- sc.SetState(SCE_ASM_STRING);
- } else if (sc.atLineStart && (sc.state == SCE_ASM_CHARACTER)) {
- sc.SetState(SCE_ASM_CHARACTER);
- }
-
- // Handle line continuation generically.
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_ASM_OPERATOR) {
- if (!IsAsmOperator(sc.ch)) {
- sc.SetState(SCE_ASM_DEFAULT);
- }
- }else if (sc.state == SCE_ASM_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_ASM_DEFAULT);
- }
- } else if (sc.state == SCE_ASM_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) ) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
-
- if (cpuInstruction.InList(s)) {
- sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
- } else if (mathInstruction.InList(s)) {
- sc.ChangeState(SCE_ASM_MATHINSTRUCTION);
- } else if (registers.InList(s)) {
- sc.ChangeState(SCE_ASM_REGISTER);
- } else if (directive.InList(s)) {
- sc.ChangeState(SCE_ASM_DIRECTIVE);
- } else if (directiveOperand.InList(s)) {
- sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
- } else if (extInstruction.InList(s)) {
- sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
- }
- sc.SetState(SCE_ASM_DEFAULT);
- }
- }
- else if (sc.state == SCE_ASM_COMMENT ) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_ASM_DEFAULT);
- }
- } else if (sc.state == SCE_ASM_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_ASM_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_ASM_STRINGEOL);
- sc.ForwardSetState(SCE_ASM_DEFAULT);
- }
- } else if (sc.state == SCE_ASM_CHARACTER) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_ASM_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_ASM_STRINGEOL);
- sc.ForwardSetState(SCE_ASM_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_ASM_DEFAULT) {
- if (sc.ch == ';'){
- sc.SetState(SCE_ASM_COMMENT);
- } else if (isascii(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && isascii(sc.chNext) && isdigit(sc.chNext)))) {
- sc.SetState(SCE_ASM_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_ASM_IDENTIFIER);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_ASM_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_ASM_CHARACTER);
- } else if (IsAsmOperator(sc.ch)) {
- sc.SetState(SCE_ASM_OPERATOR);
- }
- }
-
- }
- sc.Complete();
-}
-
-static const char * const asmWordListDesc[] = {
- "CPU instructions",
- "FPU instructions",
- "Registers",
- "Directives",
- "Directive operands",
- "Extended instructions",
- 0
-};
-
-LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexAsn1.cxx
- ** Lexer for ASN.1
- **/
-// Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de
-// Last Updated: 20/07/2004
-// The License.txt file describes the conditions under which this software may be distributed.
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-// Some char test functions
-static bool isAsn1Number(int ch)
-{
- return (ch >= '0' && ch <= '9');
-}
-
-static bool isAsn1Letter(int ch)
-{
- return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-}
-
-static bool isAsn1Char(int ch)
-{
- return (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch);
-}
-
-//
-// Function determining the color of a given code portion
-// Based on a "state"
-//
-static void ColouriseAsn1Doc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[], Accessor &styler)
-{
- // The keywords
- WordList &Keywords = *keywordLists[0];
- WordList &Attributes = *keywordLists[1];
- WordList &Descriptors = *keywordLists[2];
- WordList &Types = *keywordLists[3];
-
- // Parse the whole buffer character by character using StyleContext
- StyleContext sc(startPos, length, initStyle, styler);
- for (; sc.More(); sc.Forward())
- {
- // The state engine
- switch (sc.state)
- {
- case SCE_ASN1_DEFAULT: // Plain characters
-asn1_default:
- if (sc.ch == '-' && sc.chNext == '-')
- // A comment begins here
- sc.SetState(SCE_ASN1_COMMENT);
- else if (sc.ch == '"')
- // A string begins here
- sc.SetState(SCE_ASN1_STRING);
- else if (isAsn1Number (sc.ch))
- // A number starts here (identifier should start with a letter in ASN.1)
- sc.SetState(SCE_ASN1_SCALAR);
- else if (isAsn1Char (sc.ch))
- // An identifier starts here (identifier always start with a letter)
- sc.SetState(SCE_ASN1_IDENTIFIER);
- else if (sc.ch == ':')
- // A ::= operator starts here
- sc.SetState(SCE_ASN1_OPERATOR);
- break;
- case SCE_ASN1_COMMENT: // A comment
- if (sc.ch == '\r' || sc.ch == '\n')
- // A comment ends here
- sc.SetState(SCE_ASN1_DEFAULT);
- break;
- case SCE_ASN1_IDENTIFIER: // An identifier (keyword, attribute, descriptor or type)
- if (!isAsn1Char (sc.ch))
- {
- // The end of identifier is here: we can look for it in lists by now and change its state
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (Keywords.InList(s))
- // It's a keyword, change its state
- sc.ChangeState(SCE_ASN1_KEYWORD);
- else if (Attributes.InList(s))
- // It's an attribute, change its state
- sc.ChangeState(SCE_ASN1_ATTRIBUTE);
- else if (Descriptors.InList(s))
- // It's a descriptor, change its state
- sc.ChangeState(SCE_ASN1_DESCRIPTOR);
- else if (Types.InList(s))
- // It's a type, change its state
- sc.ChangeState(SCE_ASN1_TYPE);
-
- // Set to default now
- sc.SetState(SCE_ASN1_DEFAULT);
- }
- break;
- case SCE_ASN1_STRING: // A string delimited by ""
- if (sc.ch == '"')
- {
- // A string ends here
- sc.ForwardSetState(SCE_ASN1_DEFAULT);
-
- // To correctly manage a char sticking to the string quote
- goto asn1_default;
- }
- break;
- case SCE_ASN1_SCALAR: // A plain number
- if (!isAsn1Number (sc.ch))
- // A number ends here
- sc.SetState(SCE_ASN1_DEFAULT);
- break;
- case SCE_ASN1_OPERATOR: // The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap)
- if (sc.ch == '{')
- {
- // An OID definition starts here: enter the sub loop
- for (; sc.More(); sc.Forward())
- {
- if (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev)))
- // The OID number is highlighted
- sc.SetState(SCE_ASN1_OID);
- else if (isAsn1Char (sc.ch))
- // The OID parent identifier is plain
- sc.SetState(SCE_ASN1_IDENTIFIER);
- else
- sc.SetState(SCE_ASN1_DEFAULT);
-
- if (sc.ch == '}')
- // Here ends the OID and the operator sub loop: go back to main loop
- break;
- }
- }
- else if (isAsn1Number (sc.ch))
- {
- // A trap number definition starts here: enter the sub loop
- for (; sc.More(); sc.Forward())
- {
- if (isAsn1Number (sc.ch))
- // The trap number is highlighted
- sc.SetState(SCE_ASN1_OID);
- else
- {
- // The number ends here: go back to main loop
- sc.SetState(SCE_ASN1_DEFAULT);
- break;
- }
- }
- }
- else if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ')
- // The operator doesn't imply an OID definition nor a trap, back to main loop
- goto asn1_default; // To be sure to handle actually the state change
- break;
- }
- }
- sc.Complete();
-}
-
-static void FoldAsn1Doc(unsigned int, int, int, WordList *[], Accessor &styler)
-{
- // No folding enabled, no reason to continue...
- if( styler.GetPropertyInt("fold") == 0 )
- return;
-
- // No folding implemented: doesn't make sense for ASN.1
-}
-
-static const char * const asn1WordLists[] = {
- "Keywords",
- "Attributes",
- "Descriptors",
- "Types",
- 0, };
-
-
-LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexBaan.cxx
- ** Lexer for Baan.
- ** Based heavily on LexCPP.cxx
- **/
-// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$' || ch == ':');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static void ColouriseBaanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
-
- if (initStyle == SCE_BAAN_STRINGEOL) // Does not leak onto next line
- initStyle = SCE_BAAN_DEFAULT;
-
- int visibleChars = 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_BAAN_OPERATOR) {
- sc.SetState(SCE_BAAN_DEFAULT);
- } else if (sc.state == SCE_BAAN_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- } else if (sc.state == SCE_BAAN_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_BAAN_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_BAAN_WORD2);
- }
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- } else if (sc.state == SCE_BAAN_PREPROCESSOR) {
- if (stylingWithinPreprocessor) {
- if (IsASpace(sc.ch)) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- } else {
- if (sc.atLineEnd && (sc.chNext != '^')) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- }
- } else if (sc.state == SCE_BAAN_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- } else if (sc.state == SCE_BAAN_COMMENTDOC) {
- if (sc.MatchIgnoreCase("enddllusage")) {
- for (unsigned int i = 0; i < 10; i++){
- sc.Forward();
- }
- sc.ForwardSetState(SCE_BAAN_DEFAULT);
- }
- } else if (sc.state == SCE_BAAN_STRING) {
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_BAAN_DEFAULT);
- } else if ((sc.atLineEnd) && (sc.chNext != '^')) {
- sc.ChangeState(SCE_BAAN_STRINGEOL);
- sc.ForwardSetState(SCE_C_DEFAULT);
- visibleChars = 0;
- }
- }
-
- if (sc.state == SCE_BAAN_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_BAAN_NUMBER);
- } else if (sc.MatchIgnoreCase("dllusage")){
- sc.SetState(SCE_BAAN_COMMENTDOC);
- do {
- sc.Forward();
- } while ((!sc.atLineEnd) && sc.More());
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_BAAN_IDENTIFIER);
- } else if (sc.Match('|')){
- sc.SetState(SCE_BAAN_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_BAAN_STRING);
- } else if (sc.ch == '#' && visibleChars == 0) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_BAAN_PREPROCESSOR);
- // Skip whitespace between # and preprocessor word
- do {
- sc.Forward();
- } while (IsASpace(sc.ch) && sc.More());
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_BAAN_OPERATOR);
- }
- }
- if (sc.atLineEnd) {
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- visibleChars = 0;
- }
- if (!IsASpace(sc.ch)) {
- visibleChars++;
- }
- }
- sc.Complete();
-}
-
-static void FoldBaanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment &&
- (style == SCE_BAAN_COMMENT || style == SCE_BAAN_COMMENTDOC)) {
- if (style != stylePrev) {
- levelCurrent++;
- } else if ((style != styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelCurrent--;
- }
- }
- if (style == SCE_BAAN_OPERATOR) {
- if (ch == '{') {
- levelCurrent++;
- } else if (ch == '}') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-LexerModule lmBaan(SCLEX_BAAN, ColouriseBaanDoc, "baan", FoldBaanDoc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexBash.cxx
- ** Lexer for Bash.
- **/
-// Copyright 2004-2008 by Neil Hodgson <neilh@scintilla.org>
-// Adapted from LexPerl by Kein-Hong Man 2004
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#define HERE_DELIM_MAX 256
-
-// define this if you want 'invalid octals' to be marked as errors
-// usually, this is not a good idea, permissive lexing is better
-#undef PEDANTIC_OCTAL
-
-#define BASH_BASE_ERROR 65
-#define BASH_BASE_DECIMAL 66
-#define BASH_BASE_HEX 67
-#ifdef PEDANTIC_OCTAL
-#define BASH_BASE_OCTAL 68
-#define BASH_BASE_OCTAL_ERROR 69
-#endif
-
-static inline int translateBashDigit(int ch) {
- if (ch >= '0' && ch <= '9') {
- return ch - '0';
- } else if (ch >= 'a' && ch <= 'z') {
- return ch - 'a' + 10;
- } else if (ch >= 'A' && ch <= 'Z') {
- return ch - 'A' + 36;
- } else if (ch == '@') {
- return 62;
- } else if (ch == '_') {
- return 63;
- }
- return BASH_BASE_ERROR;
-}
-
-static inline int getBashNumberBase(char *s) {
- int i = 0;
- int base = 0;
- while (*s) {
- base = base * 10 + (*s++ - '0');
- i++;
- }
- if (base > 64 || i > 2) {
- return BASH_BASE_ERROR;
- }
- return base;
-}
-
-static int opposite(int ch) {
- if (ch == '(') return ')';
- if (ch == '[') return ']';
- if (ch == '{') return '}';
- if (ch == '<') return '>';
- return ch;
-}
-
-static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
-
- CharacterSet setWordStart(CharacterSet::setAlpha, "_");
- // note that [+-] are often parts of identifiers in shell scripts
- CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
- CharacterSet setBashOperator(CharacterSet::setNone, "^&\\%()-+=|{}[]:;>,*/<?!.~@");
- CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
- CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
- CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
- CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!");
- CharacterSet setLeftShift(CharacterSet::setDigits, "=$");
-
- class HereDocCls { // Class to manage HERE document elements
- public:
- int State; // 0: '<<' encountered
- // 1: collect the delimiter
- // 2: here doc text (lines after the delimiter)
- int Quote; // the char after '<<'
- bool Quoted; // true if Quote in ('\'','"','`')
- bool Indent; // indented delimiter (for <<-)
- int DelimiterLength; // strlen(Delimiter)
- char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
- HereDocCls() {
- State = 0;
- Quote = 0;
- Quoted = false;
- Indent = 0;
- DelimiterLength = 0;
- Delimiter = new char[HERE_DELIM_MAX];
- Delimiter[0] = '\0';
- }
- void Append(int ch) {
- Delimiter[DelimiterLength++] = static_cast<char>(ch);
- Delimiter[DelimiterLength] = '\0';
- }
- ~HereDocCls() {
- delete []Delimiter;
- }
- };
- HereDocCls HereDoc;
-
- class QuoteCls { // Class to manage quote pairs (simplified vs LexPerl)
- public:
- int Count;
- int Up, Down;
- QuoteCls() {
- Count = 0;
- Up = '\0';
- Down = '\0';
- }
- void Open(int u) {
- Count++;
- Up = u;
- Down = opposite(Up);
- }
- void Start(int u) {
- Count = 0;
- Open(u);
- }
- };
- QuoteCls Quote;
-
- int numBase = 0;
- int digit;
- unsigned int endPos = startPos + length;
-
- // Backtrack to beginning of style if required...
- // If in a long distance lexical state, backtrack to find quote characters
- if (initStyle == SCE_SH_HERE_Q) {
- while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_SH_HERE_DELIM)) {
- startPos--;
- }
- startPos = styler.LineStart(styler.GetLine(startPos));
- initStyle = styler.StyleAt(startPos - 1);
- }
- // Bash strings can be multi-line with embedded newlines, so backtrack.
- // Bash numbers have additional state during lexing, so backtrack too.
- if (initStyle == SCE_SH_STRING
- || initStyle == SCE_SH_BACKTICKS
- || initStyle == SCE_SH_CHARACTER
- || initStyle == SCE_SH_NUMBER
- || initStyle == SCE_SH_IDENTIFIER
- || initStyle == SCE_SH_COMMENTLINE) {
- while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
- startPos--;
- }
- initStyle = SCE_SH_DEFAULT;
- }
-
- StyleContext sc(startPos, endPos - startPos, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_SH_OPERATOR:
- sc.SetState(SCE_SH_DEFAULT);
- break;
- case SCE_SH_WORD:
- // "." never used in Bash variable names but used in file names
- if (!setWord.Contains(sc.ch)) {
- char s[1000];
- sc.GetCurrent(s, sizeof(s));
- if (s[0] != '-' && // for file operators
- !keywords.InList(s)) {
- sc.ChangeState(SCE_SH_IDENTIFIER);
- }
- sc.SetState(SCE_SH_DEFAULT);
- }
- break;
- case SCE_SH_IDENTIFIER:
- if (sc.chPrev == '\\') { // for escaped chars
- sc.ForwardSetState(SCE_SH_DEFAULT);
- } else if (!setWord.Contains(sc.ch)) {
- sc.SetState(SCE_SH_DEFAULT);
- }
- break;
- case SCE_SH_NUMBER:
- digit = translateBashDigit(sc.ch);
- if (numBase == BASH_BASE_DECIMAL) {
- if (sc.ch == '#') {
- char s[10];
- sc.GetCurrent(s, sizeof(s));
- numBase = getBashNumberBase(s);
- if (numBase != BASH_BASE_ERROR)
- break;
- } else if (IsADigit(sc.ch))
- break;
- } else if (numBase == BASH_BASE_HEX) {
- if (IsADigit(sc.ch, 16))
- break;
-#ifdef PEDANTIC_OCTAL
- } else if (numBase == BASH_BASE_OCTAL ||
- numBase == BASH_BASE_OCTAL_ERROR) {
- if (digit <= 7)
- break;
- if (digit <= 9) {
- numBase = BASH_BASE_OCTAL_ERROR;
- break;
- }
-#endif
- } else if (numBase == BASH_BASE_ERROR) {
- if (digit <= 9)
- break;
- } else { // DD#DDDD number style handling
- if (digit != BASH_BASE_ERROR) {
- if (numBase <= 36) {
- // case-insensitive if base<=36
- if (digit >= 36) digit -= 26;
- }
- if (digit < numBase)
- break;
- if (digit <= 9) {
- numBase = BASH_BASE_ERROR;
- break;
- }
- }
- }
- // fallthrough when number is at an end or error
- if (numBase == BASH_BASE_ERROR
-#ifdef PEDANTIC_OCTAL
- || numBase == BASH_BASE_OCTAL_ERROR
-#endif
- ) {
- sc.ChangeState(SCE_SH_ERROR);
- }
- sc.SetState(SCE_SH_DEFAULT);
- break;
- case SCE_SH_COMMENTLINE:
- if (sc.ch == '\\' && (sc.chNext == '\r' || sc.chNext == '\n')) {
- // comment continuation
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_SH_DEFAULT);
- }
- break;
- case SCE_SH_HERE_DELIM:
- // From Bash info:
- // ---------------
- // Specifier format is: <<[-]WORD
- // Optional '-' is for removal of leading tabs from here-doc.
- // Whitespace acceptable after <<[-] operator
- //
- if (HereDoc.State == 0) { // '<<' encountered
- HereDoc.Quote = sc.chNext;
- HereDoc.Quoted = false;
- HereDoc.DelimiterLength = 0;
- HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- if (sc.chNext == '\'' || sc.chNext == '\"') { // a quoted here-doc delimiter (' or ")
- sc.Forward();
- HereDoc.Quoted = true;
- HereDoc.State = 1;
- } else if (!HereDoc.Indent && sc.chNext == '-') { // <<- indent case
- HereDoc.Indent = true;
- } else if (setHereDoc.Contains(sc.chNext)) {
- // an unquoted here-doc delimiter, no special handling
- // TODO check what exactly bash considers part of the delim
- HereDoc.State = 1;
- } else if (sc.chNext == '<') { // HERE string <<<
- sc.Forward();
- sc.ForwardSetState(SCE_SH_DEFAULT);
- } else if (IsASpace(sc.chNext)) {
- // eat whitespace
- } else if (setLeftShift.Contains(sc.chNext)) {
- // left shift << or <<= operator cases
- sc.ChangeState(SCE_SH_OPERATOR);
- sc.ForwardSetState(SCE_SH_DEFAULT);
- } else {
- // symbols terminates; deprecated zero-length delimiter
- HereDoc.State = 1;
- }
- } else if (HereDoc.State == 1) { // collect the delimiter
- if (HereDoc.Quoted) { // a quoted here-doc delimiter
- if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
- sc.ForwardSetState(SCE_SH_DEFAULT);
- } else {
- if (sc.ch == '\\' && sc.chNext == HereDoc.Quote) { // escaped quote
- sc.Forward();
- }
- HereDoc.Append(sc.ch);
- }
- } else { // an unquoted here-doc delimiter
- if (setHereDoc2.Contains(sc.ch)) {
- HereDoc.Append(sc.ch);
- } else if (sc.ch == '\\') {
- // skip escape prefix
- } else {
- sc.SetState(SCE_SH_DEFAULT);
- }
- }
- if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup
- sc.SetState(SCE_SH_ERROR);
- HereDoc.State = 0;
- }
- }
- break;
- case SCE_SH_HERE_Q:
- // HereDoc.State == 2
- if (sc.atLineStart) {
- sc.SetState(SCE_SH_HERE_Q);
- int prefixws = 0;
- while (IsASpace(sc.ch) && !sc.atLineEnd) { // whitespace prefix
- sc.Forward();
- prefixws++;
- }
- if (prefixws > 0)
- sc.SetState(SCE_SH_HERE_Q);
- while (!sc.atLineEnd) {
- sc.Forward();
- }
- char s[HERE_DELIM_MAX];
- sc.GetCurrent(s, sizeof(s));
- if (sc.LengthCurrent() == 0)
- break;
- if (s[strlen(s) - 1] == '\r')
- s[strlen(s) - 1] = '\0';
- if (strcmp(HereDoc.Delimiter, s) == 0) {
- if ((prefixws > 0 && HereDoc.Indent) || // indentation rule
- (prefixws == 0 && !HereDoc.Indent)) {
- sc.SetState(SCE_SH_DEFAULT);
- break;
- }
- }
- }
- break;
- case SCE_SH_SCALAR: // variable names
- if (!setParam.Contains(sc.ch)) {
- if (sc.LengthCurrent() == 1) {
- // Special variable: $(, $_ etc.
- sc.ForwardSetState(SCE_SH_DEFAULT);
- } else {
- sc.SetState(SCE_SH_DEFAULT);
- }
- }
- break;
- case SCE_SH_STRING: // delimited styles
- case SCE_SH_CHARACTER:
- case SCE_SH_BACKTICKS:
- case SCE_SH_PARAM:
- if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0) {
- sc.ForwardSetState(SCE_SH_DEFAULT);
- }
- } else if (sc.ch == Quote.Up) {
- Quote.Count++;
- }
- break;
- }
-
- // Must check end of HereDoc state 1 before default state is handled
- if (HereDoc.State == 1 && sc.atLineEnd) {
- // Begin of here-doc (the line after the here-doc delimiter):
- // Lexically, the here-doc starts from the next line after the >>, but the
- // first line of here-doc seem to follow the style of the last EOL sequence
- HereDoc.State = 2;
- if (HereDoc.Quoted) {
- if (sc.state == SCE_SH_HERE_DELIM) {
- // Missing quote at end of string! We are stricter than bash.
- // Colour here-doc anyway while marking this bit as an error.
- sc.ChangeState(SCE_SH_ERROR);
- }
- // HereDoc.Quote always == '\''
- }
- sc.SetState(SCE_SH_HERE_Q);
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_SH_DEFAULT) {
- if (sc.ch == '\\') { // escaped character
- sc.SetState(SCE_SH_IDENTIFIER);
- } else if (IsADigit(sc.ch)) {
- sc.SetState(SCE_SH_NUMBER);
- numBase = BASH_BASE_DECIMAL;
- if (sc.ch == '0') { // hex,octal
- if (sc.chNext == 'x' || sc.chNext == 'X') {
- numBase = BASH_BASE_HEX;
- sc.Forward();
- } else if (IsADigit(sc.chNext)) {
-#ifdef PEDANTIC_OCTAL
- numBase = BASH_BASE_OCTAL;
-#else
- numBase = BASH_BASE_HEX;
-#endif
- }
- }
- } else if (setWordStart.Contains(sc.ch)) {
- sc.SetState(SCE_SH_WORD);
- } else if (sc.ch == '#') {
- sc.SetState(SCE_SH_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_SH_STRING);
- Quote.Start(sc.ch);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_SH_CHARACTER);
- Quote.Start(sc.ch);
- } else if (sc.ch == '`') {
- sc.SetState(SCE_SH_BACKTICKS);
- Quote.Start(sc.ch);
- } else if (sc.ch == '$') {
- sc.SetState(SCE_SH_SCALAR);
- sc.Forward();
- if (sc.ch == '{') {
- sc.ChangeState(SCE_SH_PARAM);
- } else if (sc.ch == '\'') {
- sc.ChangeState(SCE_SH_CHARACTER);
- } else if (sc.ch == '"') {
- sc.ChangeState(SCE_SH_STRING);
- } else if (sc.ch == '(' || sc.ch == '`') {
- sc.ChangeState(SCE_SH_BACKTICKS);
- if (sc.chNext == '(') { // $(( is lexed as operator
- sc.ChangeState(SCE_SH_OPERATOR);
- }
- } else {
- continue; // scalar has no delimiter pair
- }
- // fallthrough, open delim for $[{'"(`]
- Quote.Start(sc.ch);
- } else if (sc.Match('<', '<')) {
- sc.SetState(SCE_SH_HERE_DELIM);
- HereDoc.State = 0;
- HereDoc.Indent = false;
- } else if (sc.ch == '-' && // one-char file test operators
- setSingleCharOp.Contains(sc.chNext) &&
- !setWord.Contains(sc.GetRelative(2)) &&
- IsASpace(sc.chPrev)) {
- sc.SetState(SCE_SH_WORD);
- sc.Forward();
- } else if (setBashOperator.Contains(sc.ch)) {
- sc.SetState(SCE_SH_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eol_pos; i++) {
- char ch = styler[i];
- if (ch == '#')
- return true;
- else if (ch != ' ' && ch != '\t')
- return false;
- }
- return false;
-}
-
-static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- // Comment folding
- if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
- {
- if (!IsCommentLine(lineCurrent - 1, styler)
- && IsCommentLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsCommentLine(lineCurrent - 1, styler)
- && !IsCommentLine(lineCurrent + 1, styler))
- levelCurrent--;
- }
- if (style == SCE_SH_OPERATOR) {
- if (ch == '{') {
- levelCurrent++;
- } else if (ch == '}') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const bashWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmBash(SCLEX_BASH, ColouriseBashDoc, "bash", FoldBashDoc, bashWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexBasic.cxx
- ** Lexer for BlitzBasic and PureBasic.
- **/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics
-// and derivatives. Once they diverge enough, might want to split it into multiple
-// lexers for more code clearity.
-//
-// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.
-
-// Folding only works for simple things like functions or types.
-
-// You may want to have a look at my ctags lexer as well, if you additionally to coloring
-// and folding need to extract things like label tags in your editor.
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-#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
-
-/* Bits:
- * 1 - whitespace
- * 2 - operator
- * 4 - identifier
- * 8 - decimal digit
- * 16 - hex digit
- * 32 - bin digit
- */
-static int character_classification[128] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
- 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
- 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
- 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
-};
-
-static bool IsSpace(int c) {
- return c < 128 && (character_classification[c] & 1);
-}
-
-static bool IsOperator(int c) {
- return c < 128 && (character_classification[c] & 2);
-}
-
-static bool IsIdentifier(int c) {
- return c < 128 && (character_classification[c] & 4);
-}
-
-static bool IsDigit(int c) {
- return c < 128 && (character_classification[c] & 8);
-}
-
-static bool IsHexDigit(int c) {
- return c < 128 && (character_classification[c] & 16);
-}
-
-static bool IsBinDigit(int c) {
- return c < 128 && (character_classification[c] & 32);
-}
-
-static int LowerCase(int c)
-{
- if (c >= 'A' && c <= 'Z')
- return 'a' + c - 'A';
- return c;
-}
-
-static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler, char comment_char) {
- bool wasfirst = true, isfirst = true; // true if first token in a line
- styler.StartAt(startPos);
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- // Can't use sc.More() here else we miss the last character
- for (; ; sc.Forward()) {
- if (sc.state == SCE_B_IDENTIFIER) {
- if (!IsIdentifier(sc.ch)) {
- // Labels
- if (wasfirst && sc.Match(':')) {
- sc.ChangeState(SCE_B_LABEL);
- sc.ForwardSetState(SCE_B_DEFAULT);
- } else {
- char s[100];
- int kstates[4] = {
- SCE_B_KEYWORD,
- SCE_B_KEYWORD2,
- SCE_B_KEYWORD3,
- SCE_B_KEYWORD4,
- };
- sc.GetCurrentLowered(s, sizeof(s));
- for (int i = 0; i < 4; i++) {
- if (keywordlists[i]->InList(s)) {
- sc.ChangeState(kstates[i]);
- }
- }
- // Types, must set them as operator else they will be
- // matched as number/constant
- if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||
- sc.Match('#')) {
- sc.SetState(SCE_B_OPERATOR);
- } else {
- sc.SetState(SCE_B_DEFAULT);
- }
- }
- }
- } else if (sc.state == SCE_B_OPERATOR) {
- if (!IsOperator(sc.ch) || sc.Match('#'))
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_LABEL) {
- if (!IsIdentifier(sc.ch))
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_CONSTANT) {
- if (!IsIdentifier(sc.ch))
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_NUMBER) {
- if (!IsDigit(sc.ch))
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_HEXNUMBER) {
- if (!IsHexDigit(sc.ch))
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_BINNUMBER) {
- if (!IsBinDigit(sc.ch))
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_STRING) {
- if (sc.ch == '"') {
- sc.ForwardSetState(SCE_B_DEFAULT);
- }
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_B_ERROR);
- sc.SetState(SCE_B_DEFAULT);
- }
- } else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_B_DEFAULT);
- }
- }
-
- if (sc.atLineStart)
- isfirst = true;
-
- if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
- if (isfirst && sc.Match('.')) {
- sc.SetState(SCE_B_LABEL);
- } else if (isfirst && sc.Match('#')) {
- wasfirst = isfirst;
- sc.SetState(SCE_B_IDENTIFIER);
- } else if (sc.Match(comment_char)) {
- // Hack to make deprecated QBASIC '$Include show
- // up in freebasic with SCE_B_PREPROCESSOR.
- if (comment_char == '\'' && sc.Match(comment_char, '$'))
- sc.SetState(SCE_B_PREPROCESSOR);
- else
- sc.SetState(SCE_B_COMMENT);
- } else if (sc.Match('"')) {
- sc.SetState(SCE_B_STRING);
- } else if (IsDigit(sc.ch)) {
- sc.SetState(SCE_B_NUMBER);
- } else if (sc.Match('$')) {
- sc.SetState(SCE_B_HEXNUMBER);
- } else if (sc.Match('%')) {
- sc.SetState(SCE_B_BINNUMBER);
- } else if (sc.Match('#')) {
- sc.SetState(SCE_B_CONSTANT);
- } else if (IsOperator(sc.ch)) {
- sc.SetState(SCE_B_OPERATOR);
- } else if (IsIdentifier(sc.ch)) {
- wasfirst = isfirst;
- sc.SetState(SCE_B_IDENTIFIER);
- } else if (!IsSpace(sc.ch)) {
- sc.SetState(SCE_B_ERROR);
- }
- }
-
- if (!IsSpace(sc.ch))
- isfirst = false;
-
- if (!sc.More())
- break;
- }
- sc.Complete();
-}
-
-static int CheckBlitzFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "function") ||
- !strcmp(token, "type")) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "end function") ||
- !strcmp(token, "end type")) {
- return -1;
- }
- return 0;
-}
-
-static int CheckPureFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "procedure") ||
- !strcmp(token, "enumeration") ||
- !strcmp(token, "interface") ||
- !strcmp(token, "structure")) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "endprocedure") ||
- !strcmp(token, "endenumeration") ||
- !strcmp(token, "endinterface") ||
- !strcmp(token, "endstructure")) {
- return -1;
- }
- return 0;
-}
-
-static int CheckFreeFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "function") ||
- !strcmp(token, "sub") ||
- !strcmp(token, "type")) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "end function") ||
- !strcmp(token, "end sub") ||
- !strcmp(token, "end type")) {
- return -1;
- }
- return 0;
-}
-
-static void FoldBasicDoc(unsigned int startPos, int length,
- Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
- int line = styler.GetLine(startPos);
- int level = styler.LevelAt(line);
- int go = 0, done = 0;
- int endPos = startPos + length;
- char word[256];
- int wordlen = 0;
- int i;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- // Scan for tokens at the start of the line (they may include
- // whitespace, for tokens like "End Function"
- for (i = startPos; i < endPos; i++) {
- int c = styler.SafeGetCharAt(i);
- if (!done && !go) {
- if (wordlen) { // are we scanning a token already?
- word[wordlen] = static_cast<char>(LowerCase(c));
- if (!IsIdentifier(c)) { // done with token
- word[wordlen] = '\0';
- go = CheckFoldPoint(word, level);
- if (!go) {
- // Treat any whitespace as single blank, for
- // things like "End Function".
- if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
- word[wordlen] = ' ';
- if (wordlen < 255)
- wordlen++;
- }
- else // done with this line
- done = 1;
- }
- } else if (wordlen < 255) {
- wordlen++;
- }
- } else { // start scanning at first non-whitespace character
- if (!IsSpace(c)) {
- if (IsIdentifier(c)) {
- word[0] = static_cast<char>(LowerCase(c));
- wordlen = 1;
- } else // done with this line
- done = 1;
- }
- }
- }
- if (c == '\n') { // line end
- if (!done && wordlen == 0 && foldCompact) // line was only space
- level |= SC_FOLDLEVELWHITEFLAG;
- if (level != styler.LevelAt(line))
- styler.SetLevel(line, level);
- level += go;
- line++;
- // reset state
- wordlen = 0;
- level &= ~SC_FOLDLEVELHEADERFLAG;
- level &= ~SC_FOLDLEVELWHITEFLAG;
- go = 0;
- done = 0;
- }
- }
-}
-
-static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
-}
-
-static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
-}
-
-static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
-}
-
-static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
-}
-
-static void FoldPureBasicDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
-}
-
-static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
-}
-
-static const char * const blitzbasicWordListDesc[] = {
- "BlitzBasic Keywords",
- "user1",
- "user2",
- "user3",
- 0
-};
-
-static const char * const purebasicWordListDesc[] = {
- "PureBasic Keywords",
- "PureBasic PreProcessor Keywords",
- "user defined 1",
- "user defined 2",
- 0
-};
-
-static const char * const freebasicWordListDesc[] = {
- "FreeBasic Keywords",
- "FreeBasic PreProcessor Keywords",
- "user defined 1",
- "user defined 2",
- 0
-};
-
-LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
- FoldBlitzBasicDoc, blitzbasicWordListDesc);
-
-LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
- FoldPureBasicDoc, purebasicWordListDesc);
-
-LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
- FoldFreeBasicDoc, freebasicWordListDesc);
-
+++ /dev/null
-// SciTE - Scintilla based Text Editor
-// LexBullant.cxx - lexer for Bullant
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
- char s[100];
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- s[i + 1] = '\0';
- }
- int lev= 0;
- char chAttr = SCE_C_IDENTIFIER;
- if (isdigit(s[0]) || (s[0] == '.')){
- chAttr = SCE_C_NUMBER;
- }
- else {
- if (keywords.InList(s)) {
- chAttr = SCE_C_WORD;
- if (strcmp(s, "end") == 0)
- lev = -1;
- else if (strcmp(s, "method") == 0 ||
- strcmp(s, "case") == 0 ||
- strcmp(s, "class") == 0 ||
- strcmp(s, "debug") == 0 ||
- strcmp(s, "test") == 0 ||
- strcmp(s, "if") == 0 ||
- strcmp(s, "lock") == 0 ||
- strcmp(s, "transaction") == 0 ||
- strcmp(s, "trap") == 0 ||
- strcmp(s, "until") == 0 ||
- strcmp(s, "while") == 0)
- lev = 1;
- }
- }
- styler.ColourTo(end, chAttr);
- return lev;
-}
-
-static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- WordList &keywords = *keywordlists[0];
-
- styler.StartAt(startPos);
-
- bool fold = styler.GetPropertyInt("fold") != 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
-
- int state = initStyle;
- if (state == SCE_C_STRINGEOL) // Does not leak onto next line
- state = SCE_C_DEFAULT;
- char chPrev = ' ';
- char chNext = styler[startPos];
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- styler.StartSegment(startPos);
- int endFoundThisLine = 0;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
- // Avoid triggering two times on Dos/Win
- // End of line
- endFoundThisLine = 0;
- if (state == SCE_C_STRINGEOL) {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- }
- if (fold) {
- int lev = levelPrev;
- if (visibleChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- levelPrev = levelCurrent;
- }
- visibleChars = 0;
-
-/* int indentBlock = GetLineIndentation(lineCurrent);
- if (blockChange==1){
- lineCurrent++;
- int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);
- } else if (blockChange==-1) {
- indentBlock -= indentSize;
- if (indentBlock < 0)
- indentBlock = 0;
- SetLineIndentation(lineCurrent, indentBlock);
- lineCurrent++;
- }
- blockChange=0;
-*/ }
- if (!isspace(ch))
- visibleChars++;
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_C_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourTo(i-1, state);
- state = SCE_C_IDENTIFIER;
- } else if (ch == '@' && chNext == 'o') {
- if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {
- styler.ColourTo(i-1, state);
- state = SCE_C_COMMENT;
- }
- } else if (ch == '#') {
- styler.ColourTo(i-1, state);
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\"') {
- styler.ColourTo(i-1, state);
- state = SCE_C_STRING;
- } else if (ch == '\'') {
- styler.ColourTo(i-1, state);
- state = SCE_C_CHARACTER;
- } else if (isoperator(ch)) {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i, SCE_C_OPERATOR);
- }
- } else if (state == SCE_C_IDENTIFIER) {
- if (!iswordchar(ch)) {
- int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);
- state = SCE_C_DEFAULT;
- chNext = styler.SafeGetCharAt(i + 1);
- if (ch == '#') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_C_STRING;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_C_OPERATOR);
- }
- if (endFoundThisLine == 0)
- levelCurrent+=levelChange;
- if (levelChange == -1)
- endFoundThisLine=1;
- }
- } else if (state == SCE_C_COMMENT) {
- if (ch == '@' && chNext == 'o') {
- if (styler.SafeGetCharAt(i+2) == 'n') {
- styler.ColourTo(i+2, state);
- state = SCE_C_DEFAULT;
- i+=2;
- }
- }
- } else if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- endFoundThisLine = 0;
- styler.ColourTo(i-1, state);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_STRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- } else if (chNext == '\r' || chNext == '\n') {
- endFoundThisLine = 0;
- styler.ColourTo(i-1, SCE_C_STRINGEOL);
- state = SCE_C_STRINGEOL;
- }
- } else if (state == SCE_C_CHARACTER) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- endFoundThisLine = 0;
- styler.ColourTo(i-1, SCE_C_STRINGEOL);
- state = SCE_C_STRINGEOL;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- }
- }
- chPrev = ch;
- }
- styler.ColourTo(lengthDoc - 1, state);
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- if (fold) {
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- //styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-
- }
-}
-
-static const char * const bullantWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexClw.cxx
- ** Lexer for Clarion.
- ** 2004/12/17 Updated Lexer
- **/
-// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
-// 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 <ctype.h>
-
-#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
-
-// Is an end of line character
-inline bool IsEOL(const int ch) {
-
- return(ch == '\n');
-}
-
-// Convert character to uppercase
-static char CharacterUpper(char chChar) {
-
- if (chChar < 'a' || chChar > 'z') {
- return(chChar);
- }
- else {
- return(static_cast<char>(chChar - 'a' + 'A'));
- }
-}
-
-// Convert string to uppercase
-static void StringUpper(char *szString) {
-
- while (*szString) {
- *szString = CharacterUpper(*szString);
- szString++;
- }
-}
-
-// Is a label start character
-inline bool IsALabelStart(const int iChar) {
-
- return(isalpha(iChar) || iChar == '_');
-}
-
-// Is a label character
-inline bool IsALabelCharacter(const int iChar) {
-
- return(isalnum(iChar) || iChar == '_' || iChar == ':');
-}
-
-// Is the character is a ! and the the next character is not a !
-inline bool IsACommentStart(const int iChar) {
-
- return(iChar == '!');
-}
-
-// Is the character a Clarion hex character (ABCDEF)
-inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
-
- // Case insensitive.
- if (!bCaseSensitive) {
- if (strchr("ABCDEFabcdef", iChar) != NULL) {
- return(true);
- }
- }
- // Case sensitive
- else {
- if (strchr("ABCDEF", iChar) != NULL) {
- return(true);
- }
- }
- return(false);
-}
-
-// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
-inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
-
- // Case insensitive.
- if (!bCaseSensitive) {
- // If character is a numeric base character
- if (strchr("BOHboh", iChar) != NULL) {
- return(true);
- }
- }
- // Case sensitive
- else {
- // If character is a numeric base character
- if (strchr("BOH", iChar) != NULL) {
- return(true);
- }
- }
- return(false);
-}
-
-// Set the correct numeric constant state
-inline bool SetNumericConstantState(StyleContext &scDoc) {
-
- int iPoints = 0; // Point counter
- char cNumericString[512]; // Numeric string buffer
-
- // Buffer the current numberic string
- scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
- // Loop through the string until end of string (NULL termination)
- for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) {
- // Depending on the character
- switch (cNumericString[iIndex]) {
- // Is a . (point)
- case '.' :
- // Increment point counter
- iPoints++;
- break;
- default :
- break;
- }
- }
- // If points found (can be more than one for improper formatted number
- if (iPoints > 0) {
- return(true);
- }
- // Else no points found
- else {
- return(false);
- }
-}
-
-// Get the next word in uppercase from the current position (keyword lookahead)
-inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
-
- unsigned int iIndex = 0; // Buffer Index
-
- // Loop through the remaining string from the current position
- for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
- // Get the character from the buffer using the offset
- char cCharacter = styler[iOffset];
- if (IsEOL(cCharacter)) {
- break;
- }
- // If the character is alphabet character
- if (isalpha(cCharacter)) {
- // Add UPPERCASE character to the word buffer
- cWord[iIndex++] = CharacterUpper(cCharacter);
- }
- }
- // Add null termination
- cWord[iIndex] = '\0';
- // If no word was found
- if (iIndex == 0) {
- // Return failure
- return(false);
- }
- // Else word was found
- else {
- // Return success
- return(true);
- }
-}
-
-// Clarion Language Colouring Procedure
-static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
-
- int iParenthesesLevel = 0; // Parenthese Level
- int iColumn1Label = false; // Label starts in Column 1
-
- WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
- WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
- WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
- WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
- WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
- WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
- WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
- WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
- WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
-
- const char wlProcReservedKeywordList[] =
- "PROCEDURE FUNCTION";
- WordList wlProcReservedKeywords;
- wlProcReservedKeywords.Set(wlProcReservedKeywordList);
-
- const char wlCompilerKeywordList[] =
- "COMPILE OMIT";
- WordList wlCompilerKeywords;
- wlCompilerKeywords.Set(wlCompilerKeywordList);
-
- const char wlLegacyStatementsList[] =
- "BOF EOF FUNCTION POINTER SHARE";
- WordList wlLegacyStatements;
- wlLegacyStatements.Set(wlLegacyStatementsList);
-
- StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
-
- // lex source code
- for (; scDoc.More(); scDoc.Forward())
- {
- //
- // Determine if the current state should terminate.
- //
-
- // Label State Handling
- if (scDoc.state == SCE_CLW_LABEL) {
- // If the character is not a valid label
- if (!IsALabelCharacter(scDoc.ch)) {
- // If the character is a . (dot syntax)
- if (scDoc.ch == '.') {
- // Turn off column 1 label flag as label now cannot be reserved work
- iColumn1Label = false;
- // Uncolour the . (dot) to default state, move forward one character,
- // and change back to the label state.
- scDoc.SetState(SCE_CLW_DEFAULT);
- scDoc.Forward();
- scDoc.SetState(SCE_CLW_LABEL);
- }
- // Else check label
- else {
- char cLabel[512]; // Label buffer
- // Buffer the current label string
- scDoc.GetCurrent(cLabel,sizeof(cLabel));
- // If case insensitive, convert string to UPPERCASE to match passed keywords.
- if (!bCaseSensitive) {
- StringUpper(cLabel);
- }
- // Else if UPPERCASE label string is in the Clarion compiler keyword list
- if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
- // change the label to error state
- scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
- }
- // Else if UPPERCASE label string is in the Clarion reserved keyword list
- else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
- // change the label to error state
- scDoc.ChangeState(SCE_CLW_ERROR);
- }
- // Else if UPPERCASE label string is
- else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
- char cWord[512]; // Word buffer
- // Get the next word from the current position
- if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
- // If the next word is a procedure reserved word
- if (wlProcReservedKeywords.InList(cWord)) {
- // Change the label to error state
- scDoc.ChangeState(SCE_CLW_ERROR);
- }
- }
- }
- // Else if label string is in the compiler directive keyword list
- else if (wlCompilerDirectives.InList(cLabel)) {
- // change the state to compiler directive state
- scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
- }
- // Terminate the label state and set to default state
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- }
- }
- // Keyword State Handling
- else if (scDoc.state == SCE_CLW_KEYWORD) {
- // If character is : (colon)
- if (scDoc.ch == ':') {
- char cEquate[512]; // Equate buffer
- // Move forward to include : (colon) in buffer
- scDoc.Forward();
- // Buffer the equate string
- scDoc.GetCurrent(cEquate,sizeof(cEquate));
- // If case insensitive, convert string to UPPERCASE to match passed keywords.
- if (!bCaseSensitive) {
- StringUpper(cEquate);
- }
- // If statement string is in the equate list
- if (wlStandardEquates.InList(cEquate)) {
- // Change to equate state
- scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
- }
- }
- // If the character is not a valid label character
- else if (!IsALabelCharacter(scDoc.ch)) {
- char cStatement[512]; // Statement buffer
- // Buffer the statement string
- scDoc.GetCurrent(cStatement,sizeof(cStatement));
- // If case insensitive, convert string to UPPERCASE to match passed keywords.
- if (!bCaseSensitive) {
- StringUpper(cStatement);
- }
- // If statement string is in the Clarion keyword list
- if (wlClarionKeywords.InList(cStatement)) {
- // Change the statement string to the Clarion keyword state
- scDoc.ChangeState(SCE_CLW_KEYWORD);
- }
- // Else if statement string is in the compiler directive keyword list
- else if (wlCompilerDirectives.InList(cStatement)) {
- // Change the statement string to the compiler directive state
- scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
- }
- // Else if statement string is in the runtime expressions keyword list
- else if (wlRuntimeExpressions.InList(cStatement)) {
- // Change the statement string to the runtime expressions state
- scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
- }
- // Else if statement string is in the builtin procedures and functions keyword list
- else if (wlBuiltInProcsFuncs.InList(cStatement)) {
- // Change the statement string to the builtin procedures and functions state
- scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
- }
- // Else if statement string is in the tructures and data types keyword list
- else if (wlStructsDataTypes.InList(cStatement)) {
- // Change the statement string to the structures and data types state
- scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
- }
- // Else if statement string is in the procedure attribute keyword list
- else if (wlAttributes.InList(cStatement)) {
- // Change the statement string to the procedure attribute state
- scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
- }
- // Else if statement string is in the standard equate keyword list
- else if (wlStandardEquates.InList(cStatement)) {
- // Change the statement string to the standard equate state
- scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
- }
- // Else if statement string is in the deprecated or legacy keyword list
- else if (wlLegacyStatements.InList(cStatement)) {
- // Change the statement string to the standard equate state
- scDoc.ChangeState(SCE_CLW_DEPRECATED);
- }
- // Else the statement string doesn't match any work list
- else {
- // Change the statement string to the default state
- scDoc.ChangeState(SCE_CLW_DEFAULT);
- }
- // Terminate the keyword state and set to default state
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- }
- // String State Handling
- else if (scDoc.state == SCE_CLW_STRING) {
- // If the character is an ' (single quote)
- if (scDoc.ch == '\'') {
- // Set the state to default and move forward colouring
- // the ' (single quote) as default state
- // terminating the string state
- scDoc.SetState(SCE_CLW_DEFAULT);
- scDoc.Forward();
- }
- // If the next character is an ' (single quote)
- if (scDoc.chNext == '\'') {
- // Move forward one character and set to default state
- // colouring the next ' (single quote) as default state
- // terminating the string state
- scDoc.ForwardSetState(SCE_CLW_DEFAULT);
- scDoc.Forward();
- }
- }
- // Picture String State Handling
- else if (scDoc.state == SCE_CLW_PICTURE_STRING) {
- // If the character is an ( (open parenthese)
- if (scDoc.ch == '(') {
- // Increment the parenthese level
- iParenthesesLevel++;
- }
- // Else if the character is a ) (close parenthese)
- else if (scDoc.ch == ')') {
- // If the parenthese level is set to zero
- // parentheses matched
- if (!iParenthesesLevel) {
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- // Else parenthese level is greater than zero
- // still looking for matching parentheses
- else {
- // Decrement the parenthese level
- iParenthesesLevel--;
- }
- }
- }
- // Standard Equate State Handling
- else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {
- if (!isalnum(scDoc.ch)) {
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- }
- // Integer Constant State Handling
- else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {
- // If the character is not a digit (0-9)
- // or character is not a hexidecimal character (A-F)
- // or character is not a . (point)
- // or character is not a numberic base character (B,O,H)
- if (!(isdigit(scDoc.ch)
- || IsAHexCharacter(scDoc.ch, bCaseSensitive)
- || scDoc.ch == '.'
- || IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
- // If the number was a real
- if (SetNumericConstantState(scDoc)) {
- // Colour the matched string to the real constant state
- scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
- }
- // Else the number was an integer
- else {
- // Colour the matched string to an integer constant state
- scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);
- }
- // Terminate the integer constant state and set to default state
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- }
-
- //
- // Determine if a new state should be entered.
- //
-
- // Beginning of Line Handling
- if (scDoc.atLineStart) {
- // Reset the column 1 label flag
- iColumn1Label = false;
- // If column 1 character is a label start character
- if (IsALabelStart(scDoc.ch)) {
- // Label character is found in column 1
- // so set column 1 label flag and clear last column 1 label
- iColumn1Label = true;
- // Set the state to label
- scDoc.SetState(SCE_CLW_LABEL);
- }
- // else if character is a space or tab
- else if (IsASpace(scDoc.ch)){
- // Set to default state
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- // else if comment start (!) or is an * (asterisk)
- else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
- // then set the state to comment.
- scDoc.SetState(SCE_CLW_COMMENT);
- }
- // else the character is a ? (question mark)
- else if (scDoc.ch == '?') {
- // Change to the compiler directive state, move forward,
- // colouring the ? (question mark), change back to default state.
- scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
- scDoc.Forward();
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- // else an invalid character in column 1
- else {
- // Set to error state
- scDoc.SetState(SCE_CLW_ERROR);
- }
- }
- // End of Line Handling
- else if (scDoc.atLineEnd) {
- // Reset to the default state at the end of each line.
- scDoc.SetState(SCE_CLW_DEFAULT);
- }
- // Default Handling
- else {
- // If in default state
- if (scDoc.state == SCE_CLW_DEFAULT) {
- // If is a letter could be a possible statement
- if (isalpha(scDoc.ch)) {
- // Set the state to Clarion Keyword and verify later
- scDoc.SetState(SCE_CLW_KEYWORD);
- }
- // else is a number
- else if (isdigit(scDoc.ch)) {
- // Set the state to Integer Constant and verify later
- scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
- }
- // else if the start of a comment or a | (line continuation)
- else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
- // then set the state to comment.
- scDoc.SetState(SCE_CLW_COMMENT);
- }
- // else if the character is a ' (single quote)
- else if (scDoc.ch == '\'') {
- // If the character is also a ' (single quote)
- // Embedded Apostrophe
- if (scDoc.chNext == '\'') {
- // Move forward colouring it as default state
- scDoc.ForwardSetState(SCE_CLW_DEFAULT);
- }
- else {
- // move to the next character and then set the state to comment.
- scDoc.ForwardSetState(SCE_CLW_STRING);
- }
- }
- // else the character is an @ (ampersand)
- else if (scDoc.ch == '@') {
- // Case insensitive.
- if (!bCaseSensitive) {
- // If character is a valid picture token character
- if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) {
- // Set to the picture string state
- scDoc.SetState(SCE_CLW_PICTURE_STRING);
- }
- }
- // Case sensitive
- else {
- // If character is a valid picture token character
- if (strchr("DEKNPST", scDoc.chNext) != NULL) {
- // Set the picture string state
- scDoc.SetState(SCE_CLW_PICTURE_STRING);
- }
- }
- }
- }
- }
- }
- // lexing complete
- scDoc.Complete();
-}
-
-// Clarion Language Case Sensitive Colouring Procedure
-static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
-
- ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
-}
-
-// Clarion Language Case Insensitive Colouring Procedure
-static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
-
- ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
-}
-
-// Fill Buffer
-
-static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
-
- unsigned int uiPos = 0;
-
- while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
- szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
- uiPos++;
- }
- szBuffer[uiPos] = '\0';
-}
-
-// Classify Clarion Fold Point
-
-static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
-
- if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
- if (strcmp(szString, "PROCEDURE") == 0) {
- // iLevel = SC_FOLDLEVELBASE + 1;
- }
- else if (strcmp(szString, "MAP") == 0 ||
- strcmp(szString,"ACCEPT") == 0 ||
- strcmp(szString,"BEGIN") == 0 ||
- strcmp(szString,"CASE") == 0 ||
- strcmp(szString,"EXECUTE") == 0 ||
- strcmp(szString,"IF") == 0 ||
- strcmp(szString,"ITEMIZE") == 0 ||
- strcmp(szString,"INTERFACE") == 0 ||
- strcmp(szString,"JOIN") == 0 ||
- strcmp(szString,"LOOP") == 0 ||
- strcmp(szString,"MODULE") == 0 ||
- strcmp(szString,"RECORD") == 0) {
- iLevel++;
- }
- else if (strcmp(szString, "APPLICATION") == 0 ||
- strcmp(szString, "CLASS") == 0 ||
- strcmp(szString, "DETAIL") == 0 ||
- strcmp(szString, "FILE") == 0 ||
- strcmp(szString, "FOOTER") == 0 ||
- strcmp(szString, "FORM") == 0 ||
- strcmp(szString, "GROUP") == 0 ||
- strcmp(szString, "HEADER") == 0 ||
- strcmp(szString, "INTERFACE") == 0 ||
- strcmp(szString, "MENU") == 0 ||
- strcmp(szString, "MENUBAR") == 0 ||
- strcmp(szString, "OLE") == 0 ||
- strcmp(szString, "OPTION") == 0 ||
- strcmp(szString, "QUEUE") == 0 ||
- strcmp(szString, "REPORT") == 0 ||
- strcmp(szString, "SHEET") == 0 ||
- strcmp(szString, "TAB") == 0 ||
- strcmp(szString, "TOOLBAR") == 0 ||
- strcmp(szString, "VIEW") == 0 ||
- strcmp(szString, "WINDOW") == 0) {
- iLevel++;
- }
- else if (strcmp(szString, "END") == 0 ||
- strcmp(szString, "UNTIL") == 0 ||
- strcmp(szString, "WHILE") == 0) {
- iLevel--;
- }
- }
- return(iLevel);
-}
-
-// Clarion Language Folding Procedure
-static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
-
- unsigned int uiEndPos = uiStartPos + iLength;
- int iLineCurrent = accStyler.GetLine(uiStartPos);
- int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int iLevelCurrent = iLevelPrev;
- char chNext = accStyler[uiStartPos];
- int iStyle = iInitStyle;
- int iStyleNext = accStyler.StyleAt(uiStartPos);
- int iVisibleChars = 0;
- int iLastStart = 0;
-
- for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
-
- char chChar = chNext;
- chNext = accStyler.SafeGetCharAt(uiPos + 1);
- int iStylePrev = iStyle;
- iStyle = iStyleNext;
- iStyleNext = accStyler.StyleAt(uiPos + 1);
- bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
-
- if (iStylePrev == SCE_CLW_DEFAULT) {
- if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
- // Store last word start point.
- iLastStart = uiPos;
- }
- }
-
- if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
- if(iswordchar(chChar) && !iswordchar(chNext)) {
- char chBuffer[100];
- FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
- iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
- // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
- // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
- // iLevelPrev = SC_FOLDLEVELBASE;
- // }
- }
- }
-
- if (bEOL) {
- int iLevel = iLevelPrev;
- if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
- iLevel |= SC_FOLDLEVELHEADERFLAG;
- if (iLevel != accStyler.LevelAt(iLineCurrent)) {
- accStyler.SetLevel(iLineCurrent,iLevel);
- }
- iLineCurrent++;
- iLevelPrev = iLevelCurrent;
- iVisibleChars = 0;
- }
-
- if (!isspacechar(chChar))
- iVisibleChars++;
- }
-
- // Fill in the real level of the next line, keeping the current flags
- // as they will be filled in later.
- int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
-}
-
-// Word List Descriptions
-static const char * const rgWordListDescriptions[] = {
- "Clarion Keywords",
- "Compiler Directives",
- "Built-in Procedures and Functions",
- "Runtime Expressions",
- "Structure and Data Types",
- "Attributes",
- "Standard Equates",
- "Reserved Words (Labels)",
- "Reserved Words (Procedure Labels)",
- 0,
-};
-
-// Case Sensitive Clarion Language Lexer
-LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
-
-// Case Insensitive Clarion Language Lexer
-LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCOBOL.cxx
- ** Lexer for COBOL
- ** Based on LexPascal.cxx
- ** Written by Laurent le Tynevez
- ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
- ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
- ** Updated by Rod Falck, Aug 2006 Converted to COBOL
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#define IN_DIVISION 0x01
-#define IN_DECLARATIVES 0x02
-#define IN_SECTION 0x04
-#define IN_PARAGRAPH 0x08
-#define IN_FLAGS 0xF
-#define NOT_HEADER 0x10
-
-inline bool isCOBOLoperator(char ch)
- {
- return isoperator(ch);
- }
-
-inline bool isCOBOLwordchar(char ch)
- {
- return isascii(ch) && (isalnum(ch) || ch == '-');
-
- }
-
-inline bool isCOBOLwordstart(char ch)
- {
- return isascii(ch) && isalnum(ch);
- }
-
-static int CountBits(int nBits)
- {
- int count = 0;
- for (int i = 0; i < 32; ++i)
- {
- count += nBits & 1;
- nBits >>= 1;
- }
- return count;
- }
-
-static void getRange(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- i++;
- }
- s[i] = '\0';
-}
-
-static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr) {
- styler.ColourTo(end, attr);
-}
-
-
-static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
- int ret = 0;
-
- WordList& a_keywords = *keywordlists[0];
- WordList& b_keywords = *keywordlists[1];
- WordList& c_keywords = *keywordlists[2];
-
- char s[100];
- getRange(start, end, styler, s, sizeof(s));
-
- char chAttr = SCE_C_IDENTIFIER;
- if (isdigit(s[0]) || (s[0] == '.')) {
- chAttr = SCE_C_NUMBER;
- char *p = s + 1;
- while (*p) {
- if (!isdigit(*p) && isCOBOLwordchar(*p)) {
- chAttr = SCE_C_IDENTIFIER;
- break;
- }
- ++p;
- }
- }
- else {
- if (a_keywords.InList(s)) {
- chAttr = SCE_C_WORD;
- }
- else if (b_keywords.InList(s)) {
- chAttr = SCE_C_WORD2;
- }
- else if (c_keywords.InList(s)) {
- chAttr = SCE_C_UUID;
- }
- }
- if (*bAarea) {
- if (strcmp(s, "division") == 0) {
- ret = IN_DIVISION;
- // we've determined the containment, anything else is just ignored for those purposes
- *bAarea = false;
- } else if (strcmp(s, "declaratives") == 0) {
- ret = IN_DIVISION | IN_DECLARATIVES;
- if (nContainment & IN_DECLARATIVES)
- ret |= NOT_HEADER | IN_SECTION;
- // we've determined the containment, anything else is just ignored for those purposes
- *bAarea = false;
- } else if (strcmp(s, "section") == 0) {
- ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;
- // we've determined the containment, anything else is just ignored for those purposes
- *bAarea = false;
- } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) {
- ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;
- } else {
- ret = nContainment | IN_PARAGRAPH;
- }
- }
- ColourTo(styler, end, chAttr);
- return ret;
-}
-
-static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- styler.StartAt(startPos);
-
- int state = initStyle;
- if (state == SCE_C_CHARACTER) // Does not leak onto next line
- state = SCE_C_DEFAULT;
- char chPrev = ' ';
- char chNext = styler[startPos];
- unsigned int lengthDoc = startPos + length;
-
- int nContainment;
-
- int currentLine = styler.GetLine(startPos);
- if (currentLine > 0) {
- styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
- nContainment = styler.GetLineState(currentLine);
- nContainment &= ~NOT_HEADER;
- } else {
- styler.SetLineState(currentLine, 0);
- nContainment = 0;
- }
-
- styler.StartSegment(startPos);
- bool bNewLine = true;
- bool bAarea = !isspacechar(chNext);
- int column = 0;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
-
- chNext = styler.SafeGetCharAt(i + 1);
-
- ++column;
-
- if (bNewLine) {
- column = 0;
- }
- if (column <= 1 && !bAarea) {
- bAarea = !isspacechar(ch);
- }
- bool bSetNewLine = false;
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
- // Avoid triggering two times on Dos/Win
- // End of line
- if (state == SCE_C_CHARACTER) {
- ColourTo(styler, i, state);
- state = SCE_C_DEFAULT;
- }
- styler.SetLineState(currentLine, nContainment);
- currentLine++;
- bSetNewLine = true;
- if (nContainment & NOT_HEADER)
- nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);
- }
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_C_DEFAULT) {
- if (isCOBOLwordstart(ch) || (ch == '$' && isalpha(chNext))) {
- ColourTo(styler, i-1, state);
- state = SCE_C_IDENTIFIER;
- } else if (column == 0 && ch == '*' && chNext != '*') {
- ColourTo(styler, i-1, state);
- state = SCE_C_COMMENTLINE;
- } else if (column == 0 && ch == '/' && chNext != '*') {
- ColourTo(styler, i-1, state);
- state = SCE_C_COMMENTLINE;
- } else if (column == 0 && ch == '*' && chNext == '*') {
- ColourTo(styler, i-1, state);
- state = SCE_C_COMMENTDOC;
- } else if (column == 0 && ch == '/' && chNext == '*') {
- ColourTo(styler, i-1, state);
- state = SCE_C_COMMENTDOC;
- } else if (ch == '"') {
- ColourTo(styler, i-1, state);
- state = SCE_C_STRING;
- } else if (ch == '\'') {
- ColourTo(styler, i-1, state);
- state = SCE_C_CHARACTER;
- } else if (ch == '?' && column == 0) {
- ColourTo(styler, i-1, state);
- state = SCE_C_PREPROCESSOR;
- } else if (isCOBOLoperator(ch)) {
- ColourTo(styler, i-1, state);
- ColourTo(styler, i, SCE_C_OPERATOR);
- }
- } else if (state == SCE_C_IDENTIFIER) {
- if (!isCOBOLwordchar(ch)) {
- int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
-
- if(lStateChange != 0) {
- styler.SetLineState(currentLine, lStateChange);
- nContainment = lStateChange;
- }
-
- state = SCE_C_DEFAULT;
- chNext = styler.SafeGetCharAt(i + 1);
- if (ch == '"') {
- state = SCE_C_STRING;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (isCOBOLoperator(ch)) {
- ColourTo(styler, i, SCE_C_OPERATOR);
- }
- }
- } else {
- if (state == SCE_C_PREPROCESSOR) {
- if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
- ColourTo(styler, i-1, state);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_COMMENT) {
- if (ch == '\r' || ch == '\n') {
- ColourTo(styler, i, state);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_COMMENTDOC) {
- if (ch == '\r' || ch == '\n') {
- if (((i > styler.GetStartSegment() + 2) || (
- (initStyle == SCE_C_COMMENTDOC) &&
- (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
- ColourTo(styler, i, state);
- state = SCE_C_DEFAULT;
- }
- }
- } else if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- ColourTo(styler, i-1, state);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_STRING) {
- if (ch == '"') {
- ColourTo(styler, i, state);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_CHARACTER) {
- if (ch == '\'') {
- ColourTo(styler, i, state);
- state = SCE_C_DEFAULT;
- }
- }
- }
- chPrev = ch;
- bNewLine = bSetNewLine;
- if (bNewLine)
- {
- bAarea = false;
- }
- }
- ColourTo(styler, lengthDoc - 1, state);
-}
-
-static void FoldCOBOLDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;
- char chNext = styler[startPos];
-
- bool bNewLine = true;
- bool bAarea = !isspacechar(chNext);
- int column = 0;
- bool bComment = false;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- ++column;
-
- if (bNewLine) {
- column = 0;
- bComment = (ch == '*' || ch == '/' || ch == '?');
- }
- if (column <= 1 && !bAarea) {
- bAarea = !isspacechar(ch);
- }
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (atEOL) {
- int nContainment = styler.GetLineState(lineCurrent);
- int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;
- if (bAarea && !bComment)
- --lev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {
- // this level is at the same level or less than the previous line
- // therefore these is nothing for the previous header to collapse, so remove the header
- styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
- }
- levelPrev = lev;
- visibleChars = 0;
- bAarea = false;
- bNewLine = true;
- lineCurrent++;
- } else {
- bNewLine = false;
- }
-
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const COBOLWordListDesc[] = {
- "A Keywords",
- "B Keywords",
- "Extended Keywords",
- 0
-};
-
-LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCPP.cxx
- ** Lexer for C++, C, Java, and JavaScript.
- **/
-// Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static bool IsSpaceEquiv(int state) {
- return (state <= SCE_C_COMMENTDOC) ||
- // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
- (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
- (state == SCE_C_COMMENTDOCKEYWORDERROR);
-}
-
-// Preconditions: sc.currentPos points to a character after '+' or '-'.
-// The test for pos reaching 0 should be redundant,
-// and is in only for safety measures.
-// Limitation: this code will give the incorrect answer for code like
-// a = b+++/ptn/...
-// Putting a space between the '++' post-inc operator and the '+' binary op
-// fixes this, and is highly recommended for readability anyway.
-static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
- int pos = (int) sc.currentPos;
- while (--pos > 0) {
- char ch = styler[pos];
- if (ch == '+' || ch == '-') {
- return styler[pos - 1] == ch;
- }
- }
- return false;
-}
-
-static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler, bool caseSensitive) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- // property styling.within.preprocessor
- // For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default)
- // or only from the initial # to the end of the command word(1).
- bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
-
- CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
- CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
-
- CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
-
- CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
-
- // property lexer.cpp.allow.dollars
- // Set to 0 to disallow the '$' character in identifiers with the cpp lexer.
- if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
- setWordStart.Add('$');
- setWord.Add('$');
- }
-
- int chPrevNonWhite = ' ';
- int visibleChars = 0;
- bool lastWordWasUUID = false;
- int styleBeforeDCKeyword = SCE_C_DEFAULT;
- bool continuationLine = false;
- bool isIncludePreprocessor = false;
-
- if (initStyle == SCE_C_PREPROCESSOR) {
- // Set continuationLine if last character of previous line is '\'
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0) {
- int chBack = styler.SafeGetCharAt(startPos-1, 0);
- int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
- int lineEndChar = '!';
- if (chBack2 == '\r' && chBack == '\n') {
- lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
- } else if (chBack == '\n' || chBack == '\r') {
- lineEndChar = chBack2;
- }
- continuationLine = lineEndChar == '\\';
- }
- }
-
- // look back to set chPrevNonWhite properly for better regex colouring
- if (startPos > 0) {
- int back = startPos;
- while (--back && IsSpaceEquiv(styler.StyleAt(back)))
- ;
- if (styler.StyleAt(back) == SCE_C_OPERATOR) {
- chPrevNonWhite = styler.SafeGetCharAt(back);
- }
- }
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart) {
- if (sc.state == SCE_C_STRING) {
- // Prevent SCE_C_STRINGEOL from leaking back to previous line which
- // ends with a line continuation by locking in the state upto this position.
- sc.SetState(SCE_C_STRING);
- }
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- visibleChars = 0;
- lastWordWasUUID = false;
- isIncludePreprocessor = false;
- }
-
- // Handle line continuation generically.
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continuationLine = true;
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_C_OPERATOR:
- sc.SetState(SCE_C_DEFAULT);
- break;
- case SCE_C_NUMBER:
- // We accept almost anything because of hex. and number suffixes
- if (!setWord.Contains(sc.ch)) {
- sc.SetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_IDENTIFIER:
- if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
- char s[1000];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (keywords.InList(s)) {
- lastWordWasUUID = strcmp(s, "uuid") == 0;
- sc.ChangeState(SCE_C_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_C_WORD2);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_C_GLOBALCLASS);
- }
- sc.SetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_PREPROCESSOR:
- if (sc.atLineStart && !continuationLine) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (stylingWithinPreprocessor) {
- if (IsASpace(sc.ch)) {
- sc.SetState(SCE_C_DEFAULT);
- }
- } else {
- if (sc.Match('/', '*') || sc.Match('/', '/')) {
- sc.SetState(SCE_C_DEFAULT);
- }
- }
- break;
- case SCE_C_COMMENT:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_COMMENTDOC:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
- // Verify that we have the conditions to mark a comment-doc-keyword
- if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
- styleBeforeDCKeyword = SCE_C_COMMENTDOC;
- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
- }
- }
- break;
- case SCE_C_COMMENTLINE:
- if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_COMMENTLINEDOC:
- if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
- // Verify that we have the conditions to mark a comment-doc-keyword
- if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
- styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;
- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
- }
- }
- break;
- case SCE_C_COMMENTDOCKEYWORD:
- if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (!setDoxygen.Contains(sc.ch)) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
- }
- sc.SetState(styleBeforeDCKeyword);
- }
- break;
- case SCE_C_STRING:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
- } else if (isIncludePreprocessor) {
- if (sc.ch == '>') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- isIncludePreprocessor = false;
- }
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_CHARACTER:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_REGEX:
- if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.ch == '/') {
- sc.Forward();
- while ((sc.ch < 0x80) && islower(sc.ch))
- sc.Forward(); // gobble regex flags
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.ch == '\\') {
- // Gobble up the quoted character
- if (sc.chNext == '\\' || sc.chNext == '/') {
- sc.Forward();
- }
- }
- break;
- case SCE_C_STRINGEOL:
- if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
- }
- break;
- case SCE_C_VERBATIM:
- if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- }
- break;
- case SCE_C_UUID:
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
- sc.SetState(SCE_C_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_C_DEFAULT) {
- if (sc.Match('@', '\"')) {
- sc.SetState(SCE_C_VERBATIM);
- sc.Forward();
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- if (lastWordWasUUID) {
- sc.SetState(SCE_C_UUID);
- lastWordWasUUID = false;
- } else {
- sc.SetState(SCE_C_NUMBER);
- }
- } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
- if (lastWordWasUUID) {
- sc.SetState(SCE_C_UUID);
- lastWordWasUUID = false;
- } else {
- sc.SetState(SCE_C_IDENTIFIER);
- }
- } else if (sc.Match('/', '*')) {
- if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
- sc.SetState(SCE_C_COMMENTDOC);
- } else {
- sc.SetState(SCE_C_COMMENT);
- }
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
- // Support of Qt/Doxygen doc. style
- sc.SetState(SCE_C_COMMENTLINEDOC);
- else
- sc.SetState(SCE_C_COMMENTLINE);
- } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite) &&
- (!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) {
- sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_C_STRING);
- isIncludePreprocessor = false; // ensure that '>' won't end the string
- } else if (isIncludePreprocessor && sc.ch == '<') {
- sc.SetState(SCE_C_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_C_CHARACTER);
- } else if (sc.ch == '#' && visibleChars == 0) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_C_PREPROCESSOR);
- // Skip whitespace between # and preprocessor word
- do {
- sc.Forward();
- } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.atLineEnd) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.Match("include")) {
- isIncludePreprocessor = true;
- }
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_C_OPERATOR);
- }
- }
-
- if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
- chPrevNonWhite = sc.ch;
- visibleChars++;
- }
- continuationLine = false;
- }
- sc.Complete();
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_C_COMMENT ||
- style == SCE_C_COMMENTDOC ||
- style == SCE_C_COMMENTDOCKEYWORD ||
- style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
-
- // property fold.comment
- // This option enables folding multi-line comments and explicit fold points when using the C++ lexer.
- // Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //}
- // at the end of a section that should fold.
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-
- // property fold.preprocessor
- // This option enables folding preprocessor directives when using the C++ lexer.
- // Includes C#'s explicit #region and #endregion folding directives.
- bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
-
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- // property fold.at.else
- // This option enables C++ folding on a "} else {" line of an if statement.
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
- levelNext++;
- } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- }
- if (foldComment && (style == SCE_C_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelNext++;
- } else if (chNext2 == '}') {
- levelNext--;
- }
- }
- }
- if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
- if (ch == '#') {
- unsigned int j = i + 1;
- while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- if (styler.Match(j, "region") || styler.Match(j, "if")) {
- levelNext++;
- } else if (styler.Match(j, "end")) {
- levelNext--;
- }
- }
- }
- if (style == SCE_C_OPERATOR) {
- if (ch == '{') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- if (!IsASpace(ch))
- visibleChars++;
- if (atEOL || (i == endPos-1)) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
- // There is an empty line at end of file so give it same level and empty
- styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
- }
- visibleChars = 0;
- }
- }
-}
-
-static const char * const cppWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- "Unused",
- "Global classes and typedefs",
- 0,
- };
-
-static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
-}
-
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCSS.cxx
- ** Lexer for Cascading Style Sheets
- ** Written by Jakub Vrána
- ** Improved by Philippe Lhoste (CSS2)
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const unsigned int ch) {
- /* FIXME:
- * The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars.
- * Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee
- * that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher
- */
- return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
-}
-
-inline bool IsCssOperator(const int ch) {
- if (!((ch < 0x80) && isalnum(ch)) &&
- (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' ||
- ch == '.' || ch == '#' || ch == '!' || ch == '@' ||
- /* CSS2 */
- ch == '*' || ch == '>' || ch == '+' || ch == '=' || ch == '~' || ch == '|' ||
- ch == '[' || ch == ']' || ch == '(' || ch == ')')) {
- return true;
- }
- return false;
-}
-
-static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
- WordList &css1Props = *keywordlists[0];
- WordList &pseudoClasses = *keywordlists[1];
- WordList &css2Props = *keywordlists[2];
- WordList &css3Props = *keywordlists[3];
- WordList &pseudoElements = *keywordlists[4];
- WordList &exProps = *keywordlists[5];
- WordList &exPseudoClasses = *keywordlists[6];
- WordList &exPseudoElements = *keywordlists[7];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- int lastState = -1; // before operator
- int lastStateC = -1; // before comment
- int op = ' '; // last operator
- int opPrev = ' '; // last operator
-
- for (; sc.More(); sc.Forward()) {
- if (sc.state == SCE_CSS_COMMENT && sc.Match('*', '/')) {
- if (lastStateC == -1) {
- // backtrack to get last state:
- // comments are like whitespace, so we must return to the previous state
- unsigned int i = startPos;
- for (; i > 0; i--) {
- if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
- if (lastStateC == SCE_CSS_OPERATOR) {
- op = styler.SafeGetCharAt(i-1);
- opPrev = styler.SafeGetCharAt(i-2);
- while (--i) {
- lastState = styler.StyleAt(i-1);
- if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
- break;
- }
- if (i == 0)
- lastState = SCE_CSS_DEFAULT;
- }
- break;
- }
- }
- if (i == 0)
- lastStateC = SCE_CSS_DEFAULT;
- }
- sc.Forward();
- sc.ForwardSetState(lastStateC);
- }
-
- if (sc.state == SCE_CSS_COMMENT)
- continue;
-
- if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {
- if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
- continue;
- unsigned int i = sc.currentPos;
- while (i && styler[i-1] == '\\')
- i--;
- if ((sc.currentPos - i) % 2 == 1)
- continue;
- sc.ForwardSetState(SCE_CSS_VALUE);
- }
-
- if (sc.state == SCE_CSS_OPERATOR) {
- if (op == ' ') {
- unsigned int i = startPos;
- op = styler.SafeGetCharAt(i-1);
- opPrev = styler.SafeGetCharAt(i-2);
- while (--i) {
- lastState = styler.StyleAt(i-1);
- if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
- break;
- }
- }
- switch (op) {
- case '@':
- if (lastState == SCE_CSS_DEFAULT)
- sc.SetState(SCE_CSS_DIRECTIVE);
- break;
- case '>':
- case '+':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
- lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
- sc.SetState(SCE_CSS_DEFAULT);
- break;
- case '[':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
- lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
- sc.SetState(SCE_CSS_ATTRIBUTE);
- break;
- case ']':
- if (lastState == SCE_CSS_ATTRIBUTE)
- sc.SetState(SCE_CSS_TAG);
- break;
- case '{':
- if (lastState == SCE_CSS_DIRECTIVE)
- sc.SetState(SCE_CSS_DEFAULT);
- else if (lastState == SCE_CSS_TAG)
- sc.SetState(SCE_CSS_IDENTIFIER);
- break;
- case '}':
- if (lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT ||
- lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 || lastState == SCE_CSS_IDENTIFIER3)
- sc.SetState(SCE_CSS_DEFAULT);
- break;
- case '(':
- if (lastState == SCE_CSS_PSEUDOCLASS)
- sc.SetState(SCE_CSS_TAG);
- else if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)
- sc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS);
- break;
- case ')':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
- lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
- lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
- sc.SetState(SCE_CSS_TAG);
- break;
- case ':':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
- lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
- lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
- sc.SetState(SCE_CSS_PSEUDOCLASS);
- else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 ||
- lastState == SCE_CSS_IDENTIFIER3 || lastState == SCE_CSS_EXTENDED_IDENTIFIER ||
- lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
- sc.SetState(SCE_CSS_VALUE);
- break;
- case '.':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
- lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
- sc.SetState(SCE_CSS_CLASS);
- break;
- case '#':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
- lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
- sc.SetState(SCE_CSS_ID);
- break;
- case ',':
- case '|':
- case '~':
- if (lastState == SCE_CSS_TAG)
- sc.SetState(SCE_CSS_DEFAULT);
- break;
- case ';':
- if (lastState == SCE_CSS_DIRECTIVE)
- sc.SetState(SCE_CSS_DEFAULT);
- else if (lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT)
- sc.SetState(SCE_CSS_IDENTIFIER);
- break;
- case '!':
- if (lastState == SCE_CSS_VALUE)
- sc.SetState(SCE_CSS_IMPORTANT);
- break;
- }
- }
-
- if (IsAWordChar(sc.ch)) {
- if (sc.state == SCE_CSS_DEFAULT)
- sc.SetState(SCE_CSS_TAG);
- continue;
- }
-
- if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
- sc.SetState(SCE_CSS_TAG);
- continue;
- }
-
- if (IsAWordChar(sc.chPrev) && (
- sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 ||
- sc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER ||
- sc.state == SCE_CSS_UNKNOWN_IDENTIFIER ||
- sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
- sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
- sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
- sc.state == SCE_CSS_IMPORTANT
- )) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- char *s2 = s;
- while (*s2 && !IsAWordChar(*s2))
- s2++;
- switch (sc.state) {
- case SCE_CSS_IDENTIFIER:
- case SCE_CSS_IDENTIFIER2:
- case SCE_CSS_IDENTIFIER3:
- case SCE_CSS_EXTENDED_IDENTIFIER:
- case SCE_CSS_UNKNOWN_IDENTIFIER:
- if (css1Props.InList(s2))
- sc.ChangeState(SCE_CSS_IDENTIFIER);
- else if (css2Props.InList(s2))
- sc.ChangeState(SCE_CSS_IDENTIFIER2);
- else if (css3Props.InList(s2))
- sc.ChangeState(SCE_CSS_IDENTIFIER3);
- else if (exProps.InList(s2))
- sc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER);
- else
- sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
- break;
- case SCE_CSS_PSEUDOCLASS:
- case SCE_CSS_PSEUDOELEMENT:
- case SCE_CSS_EXTENDED_PSEUDOCLASS:
- case SCE_CSS_EXTENDED_PSEUDOELEMENT:
- case SCE_CSS_UNKNOWN_PSEUDOCLASS:
- if (op == ':' && opPrev != ':' && pseudoClasses.InList(s2))
- sc.ChangeState(SCE_CSS_PSEUDOCLASS);
- else if (opPrev == ':' && pseudoElements.InList(s2))
- sc.ChangeState(SCE_CSS_PSEUDOELEMENT);
- else if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2))
- sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS);
- else if (opPrev == ':' && exPseudoElements.InList(s2))
- sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT);
- else
- sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
- break;
- case SCE_CSS_IMPORTANT:
- if (strcmp(s2, "important") != 0)
- sc.ChangeState(SCE_CSS_VALUE);
- break;
- }
- }
-
- if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (
- sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID ||
- (sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */
- sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
- sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
- sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
- ))
- ))
- sc.SetState(SCE_CSS_TAG);
-
- if (sc.Match('/', '*')) {
- lastStateC = sc.state;
- sc.SetState(SCE_CSS_COMMENT);
- sc.Forward();
- } else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
- sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
- } else if (IsCssOperator(sc.ch)
- && (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
- && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
- && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
- ) {
- if (sc.state != SCE_CSS_OPERATOR)
- lastState = sc.state;
- sc.SetState(SCE_CSS_OPERATOR);
- op = sc.ch;
- opPrev = sc.chPrev;
- }
- }
-
- sc.Complete();
-}
-
-static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styler.StyleAt(i);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment) {
- if (!inComment && (style == SCE_CSS_COMMENT))
- levelCurrent++;
- else if (inComment && (style != SCE_CSS_COMMENT))
- levelCurrent--;
- inComment = (style == SCE_CSS_COMMENT);
- }
- if (style == SCE_CSS_OPERATOR) {
- if (ch == '{') {
- levelCurrent++;
- } else if (ch == '}') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const cssWordListDesc[] = {
- "CSS1 Properties",
- "Pseudo-classes",
- "CSS2 Properties",
- "CSS3 Properties",
- "Pseudo-elements",
- "Browser-Specific CSS Properties",
- "Browser-Specific Pseudo-classes",
- "Browser-Specific Pseudo-elements",
- 0
-};
-
-LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCaml.cxx
- ** Lexer for Objective Caml.
- **/
-// Copyright 2005-2009 by Robert Roessler <robertr@rftp.com>
-// The License.txt file describes the conditions under which this software may be distributed.
-/* Release History
- 20050204 Initial release.
- 20050205 Quick compiler standards/"cleanliness" adjustment.
- 20050206 Added cast for IsLeadByte().
- 20050209 Changes to "external" build support.
- 20050306 Fix for 1st-char-in-doc "corner" case.
- 20050502 Fix for [harmless] one-past-the-end coloring.
- 20050515 Refined numeric token recognition logic.
- 20051125 Added 2nd "optional" keywords class.
- 20051129 Support "magic" (read-only) comments for RCaml.
- 20051204 Swtich to using StyleContext infrastructure.
- 20090629 Add full Standard ML '97 support.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "PropSetSimple.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-// Since the Microsoft __iscsym[f] funcs are not ANSI...
-inline int iscaml(int c) {return isalnum(c) || c == '_';}
-inline int iscamlf(int c) {return isalpha(c) || c == '_';}
-
-static const int baseT[24] = {
- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A - L */
- 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
-};
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#ifdef BUILD_AS_EXTERNAL_LEXER
-/*
- (actually seems to work!)
-*/
-#include "WindowAccessor.h"
-#include "ExternalLexer.h"
-
-#if PLAT_WIN
-#include <windows.h>
-#endif
-
-static void ColouriseCamlDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler);
-
-static void FoldCamlDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler);
-
-static void InternalLexOrFold(int lexOrFold, unsigned int startPos, int length,
- int initStyle, char *words[], WindowID window, char *props);
-
-static const char* LexerName = "caml";
-
-#ifdef TRACE
-void Platform::DebugPrintf(const char *format, ...) {
- char buffer[2000];
- va_list pArguments;
- va_start(pArguments, format);
- vsprintf(buffer,format,pArguments);
- va_end(pArguments);
- Platform::DebugDisplay(buffer);
-}
-#else
-void Platform::DebugPrintf(const char *, ...) {
-}
-#endif
-
-bool Platform::IsDBCSLeadByte(int codePage, char ch) {
- return ::IsDBCSLeadByteEx(codePage, ch) != 0;
-}
-
-long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
- return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam);
-}
-
-long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) {
- return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam,
- reinterpret_cast<LPARAM>(lParam));
-}
-
-void EXT_LEXER_DECL Fold(unsigned int lexer, unsigned int startPos, int length,
- int initStyle, char *words[], WindowID window, char *props)
-{
- // below useless evaluation(s) to supress "not used" warnings
- lexer;
- // build expected data structures and do the Fold
- InternalLexOrFold(1, startPos, length, initStyle, words, window, props);
-
-}
-
-int EXT_LEXER_DECL GetLexerCount()
-{
- return 1; // just us [Objective] Caml lexers here!
-}
-
-void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
-{
- // below useless evaluation(s) to supress "not used" warnings
- Index;
- // return as much of our lexer name as will fit (what's up with Index?)
- if (buflength > 0) {
- buflength--;
- int n = strlen(LexerName);
- if (n > buflength)
- n = buflength;
- memcpy(name, LexerName, n), name[n] = '\0';
- }
-}
-
-void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length,
- int initStyle, char *words[], WindowID window, char *props)
-{
- // below useless evaluation(s) to supress "not used" warnings
- lexer;
- // build expected data structures and do the Lex
- InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
-}
-
-static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
- int initStyle, char *words[], WindowID window, char *props)
-{
- // create and initialize a WindowAccessor (including contained PropSet)
- PropSetSimple ps;
- ps.SetMultiple(props);
- WindowAccessor wa(window, ps);
- // create and initialize WordList(s)
- int nWL = 0;
- for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed
- WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs
- int i = 0;
- for (; i < nWL; i++) {
- wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION)
- wl[i]->Set(words[i]);
- }
- wl[i] = 0;
- // call our "internal" folder/lexer (... then do Flush!)
- if (foldOrLex)
- FoldCamlDoc(startPos, length, initStyle, wl, wa);
- else
- ColouriseCamlDoc(startPos, length, initStyle, wl, wa);
- wa.Flush();
- // clean up before leaving
- for (i = nWL - 1; i >= 0; i--)
- delete wl[i];
- delete [] wl;
-}
-
-static
-#endif /* BUILD_AS_EXTERNAL_LEXER */
-
-void ColouriseCamlDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
-{
- // initialize styler
- StyleContext sc(startPos, length, initStyle, styler);
-
- int chBase = 0, chToken = 0, chLit = 0;
- WordList& keywords = *keywordlists[0];
- WordList& keywords2 = *keywordlists[1];
- WordList& keywords3 = *keywordlists[2];
- const bool isSML = keywords.InList("andalso");
- const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
-
- // set up [initial] state info (terminating states that shouldn't "bleed")
- const int state_ = sc.state & 0x0f;
- if (state_ <= SCE_CAML_CHAR
- || (isSML && state_ == SCE_CAML_STRING))
- sc.state = SCE_CAML_DEFAULT;
- int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;
-
- // foreach char in range...
- while (sc.More()) {
- // set up [per-char] state info
- int state2 = -1; // (ASSUME no state change)
- int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
- bool advance = true; // (ASSUME scanner "eats" 1 char)
-
- // step state machine
- switch (sc.state & 0x0f) {
- case SCE_CAML_DEFAULT:
- chToken = sc.currentPos; // save [possible] token start (JIC)
- // it's wide open; what do we have?
- if (iscamlf(sc.ch))
- state2 = SCE_CAML_IDENTIFIER;
- else if (!isSML && sc.Match('`') && iscamlf(sc.chNext))
- state2 = SCE_CAML_TAGNAME;
- else if (!isSML && sc.Match('#') && isdigit(sc.chNext))
- state2 = SCE_CAML_LINENUM;
- else if (isdigit(sc.ch)) {
- // it's a number, assume base 10
- state2 = SCE_CAML_NUMBER, chBase = 10;
- if (sc.Match('0')) {
- // there MAY be a base specified...
- const char* baseC = "bBoOxX";
- if (isSML) {
- if (sc.chNext == 'w')
- sc.Forward(); // (consume SML "word" indicator)
- baseC = "x";
- }
- // ... change to specified base AS REQUIRED
- if (strchr(baseC, sc.chNext))
- chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
- }
- } else if (!isSML && sc.Match('\'')) // (Caml char literal?)
- state2 = SCE_CAML_CHAR, chLit = 0;
- else if (isSML && sc.Match('#', '"')) // (SML char literal?)
- state2 = SCE_CAML_CHAR, sc.Forward();
- else if (sc.Match('"'))
- state2 = SCE_CAML_STRING;
- else if (sc.Match('(', '*'))
- state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...
- else if (strchr("!?~" /* Caml "prefix-symbol" */
- "=<>@^|&+-*/$%" /* Caml "infix-symbol" */
- "()[]{};,:.#", sc.ch) // Caml "bracket" or ;,:.#
- // SML "extra" ident chars
- || (isSML && (sc.Match('\\') || sc.Match('`'))))
- state2 = SCE_CAML_OPERATOR;
- break;
-
- case SCE_CAML_IDENTIFIER:
- // [try to] interpret as [additional] identifier char
- if (!(iscaml(sc.ch) || sc.Match('\''))) {
- const int n = sc.currentPos - chToken;
- if (n < 24) {
- // length is believable as keyword, [re-]construct token
- char t[24];
- for (int i = -n; i < 0; i++)
- t[n + i] = static_cast<char>(sc.GetRelative(i));
- t[n] = '\0';
- // special-case "_" token as KEYWORD
- if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
- sc.ChangeState(SCE_CAML_KEYWORD);
- else if (keywords2.InList(t))
- sc.ChangeState(SCE_CAML_KEYWORD2);
- else if (keywords3.InList(t))
- sc.ChangeState(SCE_CAML_KEYWORD3);
- }
- state2 = SCE_CAML_DEFAULT, advance = false;
- }
- break;
-
- case SCE_CAML_TAGNAME:
- // [try to] interpret as [additional] tagname char
- if (!(iscaml(sc.ch) || sc.Match('\'')))
- state2 = SCE_CAML_DEFAULT, advance = false;
- break;
-
- /*case SCE_CAML_KEYWORD:
- case SCE_CAML_KEYWORD2:
- case SCE_CAML_KEYWORD3:
- // [try to] interpret as [additional] keyword char
- if (!iscaml(ch))
- state2 = SCE_CAML_DEFAULT, advance = false;
- break;*/
-
- case SCE_CAML_LINENUM:
- // [try to] interpret as [additional] linenum directive char
- if (!isdigit(sc.ch))
- state2 = SCE_CAML_DEFAULT, advance = false;
- break;
-
- case SCE_CAML_OPERATOR: {
- // [try to] interpret as [additional] operator char
- const char* o = 0;
- if (iscaml(sc.ch) || isspace(sc.ch) // ident or whitespace
- || (o = strchr(")]};,\'\"#", sc.ch),o) // "termination" chars
- || (!isSML && sc.Match('`')) // Caml extra term char
- || (!strchr("!$%&*+-./:<=>?@^|~", sc.ch)// "operator" chars
- // SML extra ident chars
- && !(isSML && (sc.Match('\\') || sc.Match('`'))))) {
- // check for INCLUSIVE termination
- if (o && strchr(")]};,", sc.ch)) {
- if ((sc.Match(')') && sc.chPrev == '(')
- || (sc.Match(']') && sc.chPrev == '['))
- // special-case "()" and "[]" tokens as KEYWORDS
- sc.ChangeState(SCE_CAML_KEYWORD);
- chColor++;
- } else
- advance = false;
- state2 = SCE_CAML_DEFAULT;
- }
- break;
- }
-
- case SCE_CAML_NUMBER:
- // [try to] interpret as [additional] numeric literal char
- if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))
- break;
- // how about an integer suffix?
- if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))
- && (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))
- break;
- // or a floating-point literal?
- if (chBase == 10) {
- // with a decimal point?
- if (sc.Match('.')
- && ((!isSML && sc.chPrev == '_')
- || IsADigit(sc.chPrev, chBase)))
- break;
- // with an exponent? (I)
- if ((sc.Match('e') || sc.Match('E'))
- && ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))
- || IsADigit(sc.chPrev, chBase)))
- break;
- // with an exponent? (II)
- if (((!isSML && (sc.Match('+') || sc.Match('-')))
- || (isSML && sc.Match('~')))
- && (sc.chPrev == 'e' || sc.chPrev == 'E'))
- break;
- }
- // it looks like we have run out of number
- state2 = SCE_CAML_DEFAULT, advance = false;
- break;
-
- case SCE_CAML_CHAR:
- if (!isSML) {
- // [try to] interpret as [additional] char literal char
- if (sc.Match('\\')) {
- chLit = 1; // (definitely IS a char literal)
- if (sc.chPrev == '\\')
- sc.ch = ' '; // (...\\')
- // should we be terminating - one way or another?
- } else if ((sc.Match('\'') && sc.chPrev != '\\')
- || sc.atLineEnd) {
- state2 = SCE_CAML_DEFAULT;
- if (sc.Match('\''))
- chColor++;
- else
- sc.ChangeState(SCE_CAML_IDENTIFIER);
- // ... maybe a char literal, maybe not
- } else if (chLit < 1 && sc.currentPos - chToken >= 2)
- sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
- break;
- }/* else
- // fall through for SML char literal (handle like string) */
-
- case SCE_CAML_STRING:
- // [try to] interpret as [additional] [SML char/] string literal char
- if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext))
- state2 = SCE_CAML_WHITE;
- else if (sc.Match('\\') && sc.chPrev == '\\')
- sc.ch = ' '; // (...\\")
- // should we be terminating - one way or another?
- else if ((sc.Match('"') && sc.chPrev != '\\')
- || (isSML && sc.atLineEnd)) {
- state2 = SCE_CAML_DEFAULT;
- if (sc.Match('"'))
- chColor++;
- }
- break;
-
- case SCE_CAML_WHITE:
- // [try to] interpret as [additional] SML embedded whitespace char
- if (sc.Match('\\')) {
- // style this puppy NOW...
- state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++,
- styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();
- // ... then backtrack to determine original SML literal type
- int p = chColor - 2;
- for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;
- if (p >= 0)
- state2 = static_cast<int>(styler.StyleAt(p));
- // take care of state change NOW
- sc.ChangeState(state2), state2 = -1;
- }
- break;
-
- case SCE_CAML_COMMENT:
- case SCE_CAML_COMMENT1:
- case SCE_CAML_COMMENT2:
- case SCE_CAML_COMMENT3:
- // we're IN a comment - does this start a NESTED comment?
- if (sc.Match('(', '*'))
- state2 = sc.state + 1, chToken = sc.currentPos,
- sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;
- // [try to] interpret as [additional] comment char
- else if (sc.Match(')') && sc.chPrev == '*') {
- if (nesting)
- state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
- else
- state2 = SCE_CAML_DEFAULT;
- chColor++;
- // enable "magic" (read-only) comment AS REQUIRED
- } else if (useMagic && sc.currentPos - chToken == 4
- && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
- sc.state |= 0x10; // (switch to read-only comment style)
- break;
- }
-
- // handle state change and char coloring AS REQUIRED
- if (state2 >= 0)
- styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
- // move to next char UNLESS re-scanning current char
- if (advance)
- sc.Forward();
- }
-
- // do any required terminal char coloring (JIC)
- sc.Complete();
-}
-
-#ifdef BUILD_AS_EXTERNAL_LEXER
-static
-#endif /* BUILD_AS_EXTERNAL_LEXER */
-void FoldCamlDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
-{
- // below useless evaluation(s) to supress "not used" warnings
- startPos || length || initStyle || keywordlists[0] || styler.Length();
-}
-
-static const char * const camlWordListDesc[] = {
- "Keywords", // primary Objective Caml keywords
- "Keywords2", // "optional" keywords (typically from Pervasives)
- "Keywords3", // "optional" keywords (typically typenames)
- 0
-};
-
-#ifndef BUILD_AS_EXTERNAL_LEXER
-LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc);
-#endif /* BUILD_AS_EXTERNAL_LEXER */
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCmake.cxx
- ** Lexer for Cmake
- **/
-// Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
-// based on the NSIS lexer
-// The License.txt file describes the conditions under which this software may be distributed.
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static bool isCmakeNumber(char ch)
-{
- return(ch >= '0' && ch <= '9');
-}
-
-static bool isCmakeChar(char ch)
-{
- return(ch == '.' ) || (ch == '_' ) || isCmakeNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-}
-
-static bool isCmakeLetter(char ch)
-{
- return(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-}
-
-static bool CmakeNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
-{
- int nNextLine = -1;
- for ( unsigned int i = start; i < end; i++ ) {
- char cNext = styler.SafeGetCharAt( i );
- if ( cNext == '\n' ) {
- nNextLine = i+1;
- break;
- }
- }
-
- if ( nNextLine == -1 ) // We never foudn the next line...
- return false;
-
- for ( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ ) {
- char cNext = styler.SafeGetCharAt( firstChar );
- if ( cNext == ' ' )
- continue;
- if ( cNext == '\t' )
- continue;
- if ( styler.Match(firstChar, "ELSE") || styler.Match(firstChar, "else"))
- return true;
- break;
- }
-
- return false;
-}
-
-static int calculateFoldCmake(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse)
-{
- // If the word is too long, it is not what we are looking for
- if ( end - start > 20 )
- return foldlevel;
-
- int newFoldlevel = foldlevel;
-
- char s[20]; // The key word we are looking for has atmost 13 characters
- for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) {
- s[i] = static_cast<char>( styler[ start + i ] );
- s[i + 1] = '\0';
- }
-
- if ( CompareCaseInsensitive(s, "IF") == 0 || CompareCaseInsensitive(s, "WHILE") == 0
- || CompareCaseInsensitive(s, "MACRO") == 0 || CompareCaseInsensitive(s, "FOREACH") == 0
- || CompareCaseInsensitive(s, "ELSEIF") == 0 )
- newFoldlevel++;
- else if ( CompareCaseInsensitive(s, "ENDIF") == 0 || CompareCaseInsensitive(s, "ENDWHILE") == 0
- || CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0)
- newFoldlevel--;
- else if ( bElse && CompareCaseInsensitive(s, "ELSEIF") == 0 )
- newFoldlevel++;
- else if ( bElse && CompareCaseInsensitive(s, "ELSE") == 0 )
- newFoldlevel++;
-
- return newFoldlevel;
-}
-
-static int classifyWordCmake(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
-{
- char word[100] = {0};
- char lowercaseWord[100] = {0};
-
- WordList &Commands = *keywordLists[0];
- WordList &Parameters = *keywordLists[1];
- WordList &UserDefined = *keywordLists[2];
-
- for (unsigned int i = 0; i < end - start + 1 && i < 99; i++) {
- word[i] = static_cast<char>( styler[ start + i ] );
- lowercaseWord[i] = static_cast<char>(tolower(word[i]));
- }
-
- // Check for special words...
- if ( CompareCaseInsensitive(word, "MACRO") == 0 || CompareCaseInsensitive(word, "ENDMACRO") == 0 )
- return SCE_CMAKE_MACRODEF;
-
- if ( CompareCaseInsensitive(word, "IF") == 0 || CompareCaseInsensitive(word, "ENDIF") == 0 )
- return SCE_CMAKE_IFDEFINEDEF;
-
- if ( CompareCaseInsensitive(word, "ELSEIF") == 0 || CompareCaseInsensitive(word, "ELSE") == 0 )
- return SCE_CMAKE_IFDEFINEDEF;
-
- if ( CompareCaseInsensitive(word, "WHILE") == 0 || CompareCaseInsensitive(word, "ENDWHILE") == 0)
- return SCE_CMAKE_WHILEDEF;
-
- if ( CompareCaseInsensitive(word, "FOREACH") == 0 || CompareCaseInsensitive(word, "ENDFOREACH") == 0)
- return SCE_CMAKE_FOREACHDEF;
-
- if ( Commands.InList(lowercaseWord) )
- return SCE_CMAKE_COMMANDS;
-
- if ( Parameters.InList(word) )
- return SCE_CMAKE_PARAMETERS;
-
-
- if ( UserDefined.InList(word) )
- return SCE_CMAKE_USERDEFINED;
-
- if ( strlen(word) > 3 ) {
- if ( word[1] == '{' && word[strlen(word)-1] == '}' )
- return SCE_CMAKE_VARIABLE;
- }
-
- // To check for numbers
- if ( isCmakeNumber( word[0] ) ) {
- bool bHasSimpleCmakeNumber = true;
- for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) {
- if ( !isCmakeNumber( word[j] ) ) {
- bHasSimpleCmakeNumber = false;
- break;
- }
- }
-
- if ( bHasSimpleCmakeNumber )
- return SCE_CMAKE_NUMBER;
- }
-
- return SCE_CMAKE_DEFAULT;
-}
-
-static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
-{
- int state = SCE_CMAKE_DEFAULT;
- if ( startPos > 0 )
- state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
-
- styler.StartAt( startPos );
- styler.GetLine( startPos );
-
- unsigned int nLengthDoc = startPos + length;
- styler.StartSegment( startPos );
-
- char cCurrChar;
- bool bVarInString = false;
- bool bClassicVarInString = false;
-
- unsigned int i;
- for ( i = startPos; i < nLengthDoc; i++ ) {
- cCurrChar = styler.SafeGetCharAt( i );
- char cNextChar = styler.SafeGetCharAt(i+1);
-
- switch (state) {
- case SCE_CMAKE_DEFAULT:
- if ( cCurrChar == '#' ) { // we have a comment line
- styler.ColourTo(i-1, state );
- state = SCE_CMAKE_COMMENT;
- break;
- }
- if ( cCurrChar == '"' ) {
- styler.ColourTo(i-1, state );
- state = SCE_CMAKE_STRINGDQ;
- bVarInString = false;
- bClassicVarInString = false;
- break;
- }
- if ( cCurrChar == '\'' ) {
- styler.ColourTo(i-1, state );
- state = SCE_CMAKE_STRINGRQ;
- bVarInString = false;
- bClassicVarInString = false;
- break;
- }
- if ( cCurrChar == '`' ) {
- styler.ColourTo(i-1, state );
- state = SCE_CMAKE_STRINGLQ;
- bVarInString = false;
- bClassicVarInString = false;
- break;
- }
-
- // CMake Variable
- if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) {
- styler.ColourTo(i-1,state);
- state = SCE_CMAKE_VARIABLE;
-
- // If it is a number, we must check and set style here first...
- if ( isCmakeNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
- styler.ColourTo( i, SCE_CMAKE_NUMBER);
-
- break;
- }
-
- break;
- case SCE_CMAKE_COMMENT:
- if ( cNextChar == '\n' || cNextChar == '\r' ) {
- // Special case:
- if ( cCurrChar == '\\' ) {
- styler.ColourTo(i-2,state);
- styler.ColourTo(i,SCE_CMAKE_DEFAULT);
- }
- else {
- styler.ColourTo(i,state);
- state = SCE_CMAKE_DEFAULT;
- }
- }
- break;
- case SCE_CMAKE_STRINGDQ:
- case SCE_CMAKE_STRINGLQ:
- case SCE_CMAKE_STRINGRQ:
-
- if ( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
- break; // Ignore the next character, even if it is a quote of some sort
-
- if ( cCurrChar == '"' && state == SCE_CMAKE_STRINGDQ ) {
- styler.ColourTo(i,state);
- state = SCE_CMAKE_DEFAULT;
- break;
- }
-
- if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) {
- styler.ColourTo(i,state);
- state = SCE_CMAKE_DEFAULT;
- break;
- }
-
- if ( cCurrChar == '\'' && state == SCE_CMAKE_STRINGRQ ) {
- styler.ColourTo(i,state);
- state = SCE_CMAKE_DEFAULT;
- break;
- }
-
- if ( cNextChar == '\r' || cNextChar == '\n' ) {
- int nCurLine = styler.GetLine(i+1);
- int nBack = i;
- // We need to check if the previous line has a \ in it...
- bool bNextLine = false;
-
- while ( nBack > 0 ) {
- if ( styler.GetLine(nBack) != nCurLine )
- break;
-
- char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
-
- if ( cTemp == '\\' ) {
- bNextLine = true;
- break;
- }
- if ( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
- break;
-
- nBack--;
- }
-
- if ( bNextLine ) {
- styler.ColourTo(i+1,state);
- }
- if ( bNextLine == false ) {
- styler.ColourTo(i,state);
- state = SCE_CMAKE_DEFAULT;
- }
- }
- break;
-
- case SCE_CMAKE_VARIABLE:
-
- // CMake Variable:
- if ( cCurrChar == '$' )
- state = SCE_CMAKE_DEFAULT;
- else if ( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
- state = SCE_CMAKE_DEFAULT;
- else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) {
- state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler );
- styler.ColourTo( i, state);
- state = SCE_CMAKE_DEFAULT;
- }
- else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) {
- if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER )
- styler.ColourTo( i-1, SCE_CMAKE_NUMBER );
-
- state = SCE_CMAKE_DEFAULT;
-
- if ( cCurrChar == '"' ) {
- state = SCE_CMAKE_STRINGDQ;
- bVarInString = false;
- bClassicVarInString = false;
- }
- else if ( cCurrChar == '`' ) {
- state = SCE_CMAKE_STRINGLQ;
- bVarInString = false;
- bClassicVarInString = false;
- }
- else if ( cCurrChar == '\'' ) {
- state = SCE_CMAKE_STRINGRQ;
- bVarInString = false;
- bClassicVarInString = false;
- }
- else if ( cCurrChar == '#' ) {
- state = SCE_CMAKE_COMMENT;
- }
- }
- break;
- }
-
- if ( state == SCE_CMAKE_COMMENT) {
- styler.ColourTo(i,state);
- }
- else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {
- bool bIngoreNextDollarSign = false;
-
- if ( bVarInString && cCurrChar == '$' ) {
- bVarInString = false;
- bIngoreNextDollarSign = true;
- }
- else if ( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) {
- styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
- bVarInString = false;
- bIngoreNextDollarSign = false;
- }
-
- else if ( bVarInString && !isCmakeChar(cNextChar) ) {
- int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler);
- if ( nWordState == SCE_CMAKE_VARIABLE )
- styler.ColourTo( i, SCE_CMAKE_STRINGVAR);
- bVarInString = false;
- }
- // Covers "${TEST}..."
- else if ( bClassicVarInString && cNextChar == '}' ) {
- styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
- bClassicVarInString = false;
- }
-
- // Start of var in string
- if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) {
- styler.ColourTo( i-1, state);
- bClassicVarInString = true;
- bVarInString = false;
- }
- else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) {
- styler.ColourTo( i-1, state);
- bVarInString = true;
- bClassicVarInString = false;
- }
- }
- }
-
- // Colourise remaining document
- styler.ColourTo(nLengthDoc-1,state);
-}
-
-static void FoldCmakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
-{
- // No folding enabled, no reason to continue...
- if ( styler.GetPropertyInt("fold") == 0 )
- return;
-
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
-
- int lineCurrent = styler.GetLine(startPos);
- unsigned int safeStartPos = styler.LineStart( lineCurrent );
-
- bool bArg1 = true;
- int nWordStart = -1;
-
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelNext = levelCurrent;
-
- for (unsigned int i = safeStartPos; i < startPos + length; i++) {
- char chCurr = styler.SafeGetCharAt(i);
-
- if ( bArg1 ) {
- if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) {
- nWordStart = i;
- }
- else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) {
- int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse);
-
- if ( newLevel == levelNext ) {
- if ( foldAtElse ) {
- if ( CmakeNextLineHasElse(i, startPos + length, styler) )
- levelNext--;
- }
- }
- else
- levelNext = newLevel;
- bArg1 = false;
- }
- }
-
- if ( chCurr == '\n' ) {
- if ( bArg1 && foldAtElse) {
- if ( CmakeNextLineHasElse(i, startPos + length, styler) )
- levelNext--;
- }
-
- // If we are on a new line...
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext )
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
-
- lineCurrent++;
- levelCurrent = levelNext;
- bArg1 = true; // New line, lets look at first argument again
- nWordStart = -1;
- }
- }
-
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
-}
-
-static const char * const cmakeWordLists[] = {
- "Commands",
- "Parameters",
- "UserDefined",
- 0,
- 0,};
-
-LexerModule lmCmake(SCLEX_CMAKE, ColouriseCmakeDoc, "cmake", FoldCmakeDoc, cmakeWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexConf.cxx
- ** Lexer for Apache Configuration Files.
- **
- ** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
- ** i created this lexer because i needed something pretty when dealing
- ** when Apache Configuration 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
-{
- int state = SCE_CONF_DEFAULT;
- char chNext = styler[startPos];
- int lengthDoc = startPos + length;
- // create a buffer large enough to take the largest chunk...
- char *buffer = new char[length];
- int bufferCount = 0;
-
- // this assumes that we have 2 keyword list in conf.properties
- WordList &directives = *keywordLists[0];
- WordList ¶ms = *keywordLists[1];
-
- // go through all provided text segment
- // using the hand-written state machine shown below
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- i++;
- continue;
- }
- switch(state) {
- case SCE_CONF_DEFAULT:
- if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
- // whitespace is simply ignored here...
- styler.ColourTo(i,SCE_CONF_DEFAULT);
- break;
- } else if( ch == '#' ) {
- // signals the start of a comment...
- state = SCE_CONF_COMMENT;
- styler.ColourTo(i,SCE_CONF_COMMENT);
- } else if( ch == '.' /*|| ch == '/'*/) {
- // signals the start of a file...
- state = SCE_CONF_EXTENSION;
- styler.ColourTo(i,SCE_CONF_EXTENSION);
- } else if( ch == '"') {
- state = SCE_CONF_STRING;
- styler.ColourTo(i,SCE_CONF_STRING);
- } else if( ispunct(ch) ) {
- // signals an operator...
- // no state jump necessary for this
- // simple case...
- styler.ColourTo(i,SCE_CONF_OPERATOR);
- } else if( isalpha(ch) ) {
- // signals the start of an identifier
- bufferCount = 0;
- buffer[bufferCount++] = static_cast<char>(tolower(ch));
- state = SCE_CONF_IDENTIFIER;
- } else if( isdigit(ch) ) {
- // signals the start of a number
- bufferCount = 0;
- buffer[bufferCount++] = ch;
- //styler.ColourTo(i,SCE_CONF_NUMBER);
- state = SCE_CONF_NUMBER;
- } else {
- // style it the default style..
- styler.ColourTo(i,SCE_CONF_DEFAULT);
- }
- break;
-
- case SCE_CONF_COMMENT:
- // if we find a newline here,
- // we simply go to default state
- // else continue to work on it...
- if( ch == '\n' || ch == '\r' ) {
- state = SCE_CONF_DEFAULT;
- } else {
- styler.ColourTo(i,SCE_CONF_COMMENT);
- }
- break;
-
- case SCE_CONF_EXTENSION:
- // if we find a non-alphanumeric char,
- // we simply go to default state
- // else we're still dealing with an extension...
- if( isalnum(ch) || (ch == '_') ||
- (ch == '-') || (ch == '$') ||
- (ch == '/') || (ch == '.') || (ch == '*') )
- {
- styler.ColourTo(i,SCE_CONF_EXTENSION);
- } else {
- state = SCE_CONF_DEFAULT;
- chNext = styler[i--];
- }
- break;
-
- case SCE_CONF_STRING:
- // if we find the end of a string char, we simply go to default state
- // else we're still dealing with an string...
- if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
- state = SCE_CONF_DEFAULT;
- }
- styler.ColourTo(i,SCE_CONF_STRING);
- break;
-
- case SCE_CONF_IDENTIFIER:
- // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
- if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
- buffer[bufferCount++] = static_cast<char>(tolower(ch));
- } else {
- state = SCE_CONF_DEFAULT;
- buffer[bufferCount] = '\0';
-
- // check if the buffer contains a keyword, and highlight it if it is a keyword...
- if(directives.InList(buffer)) {
- styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
- } else if(params.InList(buffer)) {
- styler.ColourTo(i-1,SCE_CONF_PARAMETER );
- } else if(strchr(buffer,'/') || strchr(buffer,'.')) {
- styler.ColourTo(i-1,SCE_CONF_EXTENSION);
- } else {
- styler.ColourTo(i-1,SCE_CONF_DEFAULT);
- }
-
- // push back the faulty character
- chNext = styler[i--];
-
- }
- break;
-
- case SCE_CONF_NUMBER:
- // stay in CONF_NUMBER state until we find a non-numeric
- if( isdigit(ch) || ch == '.') {
- buffer[bufferCount++] = ch;
- } else {
- state = SCE_CONF_DEFAULT;
- buffer[bufferCount] = '\0';
-
- // Colourize here...
- if( strchr(buffer,'.') ) {
- // it is an IP address...
- styler.ColourTo(i-1,SCE_CONF_IP);
- } else {
- // normal number
- styler.ColourTo(i-1,SCE_CONF_NUMBER);
- }
-
- // push back a character
- chNext = styler[i--];
- }
- break;
-
- }
- }
- delete []buffer;
-}
-
-static const char * const confWordListDesc[] = {
- "Directives",
- "Parameters",
- 0
-};
-
-LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCrontab.cxx
- ** Lexer to use with extended crontab files used by a powerful
- ** Windows scheduler/event monitor/automation manager nnCron.
- ** (http://nemtsev.eserv.ru/)
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordList
-*keywordLists[], Accessor &styler)
-{
- int state = SCE_NNCRONTAB_DEFAULT;
- char chNext = styler[startPos];
- int lengthDoc = startPos + length;
- // create a buffer large enough to take the largest chunk...
- char *buffer = new char[length];
- int bufferCount = 0;
- // used when highliting environment variables inside quoted string:
- bool insideString = false;
-
- // this assumes that we have 3 keyword list in conf.properties
- WordList §ion = *keywordLists[0];
- WordList &keyword = *keywordLists[1];
- WordList &modifier = *keywordLists[2];
-
- // go through all provided text segment
- // using the hand-written state machine shown below
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- i++;
- continue;
- }
- switch(state) {
- case SCE_NNCRONTAB_DEFAULT:
- if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
- // whitespace is simply ignored here...
- styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
- break;
- } else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') {
- // signals the start of a task...
- state = SCE_NNCRONTAB_TASK;
- styler.ColourTo(i,SCE_NNCRONTAB_TASK);
- }
- else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
- styler.SafeGetCharAt(i+1) == '\t')) {
- // signals the start of an extended comment...
- state = SCE_NNCRONTAB_COMMENT;
- styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
- } else if( ch == '#' ) {
- // signals the start of a plain comment...
- state = SCE_NNCRONTAB_COMMENT;
- styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
- } else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') {
- // signals the end of a task...
- state = SCE_NNCRONTAB_TASK;
- styler.ColourTo(i,SCE_NNCRONTAB_TASK);
- } else if( ch == '"') {
- state = SCE_NNCRONTAB_STRING;
- styler.ColourTo(i,SCE_NNCRONTAB_STRING);
- } else if( ch == '%') {
- // signals environment variables
- state = SCE_NNCRONTAB_ENVIRONMENT;
- styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
- } else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') {
- // signals environment variables
- state = SCE_NNCRONTAB_ENVIRONMENT;
- styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
- } else if( ch == '*' ) {
- // signals an asterisk
- // no state jump necessary for this simple case...
- styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
- } else if( isalpha(ch) || ch == '<' ) {
- // signals the start of an identifier
- bufferCount = 0;
- buffer[bufferCount++] = ch;
- state = SCE_NNCRONTAB_IDENTIFIER;
- } else if( isdigit(ch) ) {
- // signals the start of a number
- bufferCount = 0;
- buffer[bufferCount++] = ch;
- state = SCE_NNCRONTAB_NUMBER;
- } else {
- // style it the default style..
- styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
- }
- break;
-
- case SCE_NNCRONTAB_COMMENT:
- // if we find a newline here,
- // we simply go to default state
- // else continue to work on it...
- if( ch == '\n' || ch == '\r' ) {
- state = SCE_NNCRONTAB_DEFAULT;
- } else {
- styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
- }
- break;
-
- case SCE_NNCRONTAB_TASK:
- // if we find a newline here,
- // we simply go to default state
- // else continue to work on it...
- if( ch == '\n' || ch == '\r' ) {
- state = SCE_NNCRONTAB_DEFAULT;
- } else {
- styler.ColourTo(i,SCE_NNCRONTAB_TASK);
- }
- break;
-
- case SCE_NNCRONTAB_STRING:
- if( ch == '%' ) {
- state = SCE_NNCRONTAB_ENVIRONMENT;
- insideString = true;
- styler.ColourTo(i-1,SCE_NNCRONTAB_STRING);
- break;
- }
- // if we find the end of a string char, we simply go to default state
- // else we're still dealing with an string...
- if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') ||
- (ch == '\n') || (ch == '\r') ) {
- state = SCE_NNCRONTAB_DEFAULT;
- }
- styler.ColourTo(i,SCE_NNCRONTAB_STRING);
- break;
-
- case SCE_NNCRONTAB_ENVIRONMENT:
- // if we find the end of a string char, we simply go to default state
- // else we're still dealing with an string...
- if( ch == '%' && insideString ) {
- state = SCE_NNCRONTAB_STRING;
- insideString = false;
- break;
- }
- if( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\')
- || (ch == '\n') || (ch == '\r') || (ch == '>') ) {
- state = SCE_NNCRONTAB_DEFAULT;
- styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
- break;
- }
- styler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT);
- break;
-
- case SCE_NNCRONTAB_IDENTIFIER:
- // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
- if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') ||
- (ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
- (ch == '@') ) {
- buffer[bufferCount++] = ch;
- } else {
- state = SCE_NNCRONTAB_DEFAULT;
- buffer[bufferCount] = '\0';
-
- // check if the buffer contains a keyword,
- // and highlight it if it is a keyword...
- if(section.InList(buffer)) {
- styler.ColourTo(i,SCE_NNCRONTAB_SECTION );
- } else if(keyword.InList(buffer)) {
- styler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD );
- } // else if(strchr(buffer,'/') || strchr(buffer,'.')) {
- // styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);
- // }
- else if(modifier.InList(buffer)) {
- styler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER );
- } else {
- styler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT);
- }
- // push back the faulty character
- chNext = styler[i--];
- }
- break;
-
- case SCE_NNCRONTAB_NUMBER:
- // stay in CONF_NUMBER state until we find a non-numeric
- if( isdigit(ch) /* || ch == '.' */ ) {
- buffer[bufferCount++] = ch;
- } else {
- state = SCE_NNCRONTAB_DEFAULT;
- buffer[bufferCount] = '\0';
- // Colourize here... (normal number)
- styler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER);
- // push back a character
- chNext = styler[i--];
- }
- break;
- }
- }
- delete []buffer;
-}
-
-static const char * const cronWordListDesc[] = {
- "Section keywords and Forth words",
- "nnCrontab keywords",
- "Modifiers",
- 0
-};
-
-LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexCsound.cxx
- ** Lexer for Csound (Orchestra & Score)
- ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
- **/
-// Copyright 1998-2003 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
- ch == '_' || ch == '?');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
- ch == '%' || ch == '@' || ch == '$' || ch == '?');
-}
-
-static inline bool IsCsoundOperator(char ch) {
- if (isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
- ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
- ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
- ch == '%' || ch == ':')
- return true;
- return false;
-}
-
-static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &opcode = *keywordlists[0];
- WordList &headerStmt = *keywordlists[1];
- WordList &otherKeyword = *keywordlists[2];
-
- // Do not leak onto next line
- if (initStyle == SCE_CSOUND_STRINGEOL)
- initStyle = SCE_CSOUND_DEFAULT;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
- // Handle line continuation generically.
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_CSOUND_OPERATOR) {
- if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_CSOUND_DEFAULT);
- }
- }else if (sc.state == SCE_CSOUND_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_CSOUND_DEFAULT);
- }
- } else if (sc.state == SCE_CSOUND_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) ) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
-
- if (opcode.InList(s)) {
- sc.ChangeState(SCE_CSOUND_OPCODE);
- } else if (headerStmt.InList(s)) {
- sc.ChangeState(SCE_CSOUND_HEADERSTMT);
- } else if (otherKeyword.InList(s)) {
- sc.ChangeState(SCE_CSOUND_USERKEYWORD);
- } else if (s[0] == 'p') {
- sc.ChangeState(SCE_CSOUND_PARAM);
- } else if (s[0] == 'a') {
- sc.ChangeState(SCE_CSOUND_ARATE_VAR);
- } else if (s[0] == 'k') {
- sc.ChangeState(SCE_CSOUND_KRATE_VAR);
- } else if (s[0] == 'i') { // covers both i-rate variables and i-statements
- sc.ChangeState(SCE_CSOUND_IRATE_VAR);
- } else if (s[0] == 'g') {
- sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
- }
- sc.SetState(SCE_CSOUND_DEFAULT);
- }
- }
- else if (sc.state == SCE_CSOUND_COMMENT ) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_CSOUND_DEFAULT);
- }
- }
- else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
- (sc.state == SCE_CSOUND_KRATE_VAR) ||
- (sc.state == SCE_CSOUND_IRATE_VAR)) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_CSOUND_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_CSOUND_DEFAULT) {
- if (sc.ch == ';'){
- sc.SetState(SCE_CSOUND_COMMENT);
- } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
- sc.SetState(SCE_CSOUND_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_CSOUND_IDENTIFIER);
- } else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_CSOUND_OPERATOR);
- } else if (sc.ch == 'p') {
- sc.SetState(SCE_CSOUND_PARAM);
- } else if (sc.ch == 'a') {
- sc.SetState(SCE_CSOUND_ARATE_VAR);
- } else if (sc.ch == 'k') {
- sc.SetState(SCE_CSOUND_KRATE_VAR);
- } else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
- sc.SetState(SCE_CSOUND_IRATE_VAR);
- } else if (sc.ch == 'g') {
- sc.SetState(SCE_CSOUND_GLOBAL_VAR);
- }
- }
- }
- sc.Complete();
-}
-
-static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
- Accessor &styler) {
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int stylePrev = 0;
- int styleNext = styler.StyleAt(startPos);
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
- char s[20];
- unsigned int j = 0;
- while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
- s[j] = styler[i + j];
- j++;
- }
- s[j] = '\0';
-
- if (strcmp(s, "instr") == 0)
- levelCurrent++;
- if (strcmp(s, "endin") == 0)
- levelCurrent--;
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- stylePrev = style;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-
-static const char * const csoundWordListDesc[] = {
- "Opcodes",
- "Header Statements",
- "User keywords",
- 0
-};
-
-LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);
+++ /dev/null
-/** @file LexD.cxx
- ** Lexer for D.
- **
- ** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com>
- **/
-// Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-/* Nested comments require keeping the value of the nesting level for every
- position in the document. But since scintilla always styles line by line,
- we only need to store one value per line. The non-negative number indicates
- nesting level at the end of the line.
-*/
-
-// Underscore, letter, digit and universal alphas from C99 Appendix D.
-
-static bool IsWordStart(int ch) {
- return (isascii(ch) && (isalpha(ch) || ch == '_')) || !isascii(ch);
-}
-
-static bool IsWord(int ch) {
- return (isascii(ch) && (isalnum(ch) || ch == '_')) || !isascii(ch);
-}
-
-static bool IsDoxygen(int ch) {
- if (isascii(ch) && islower(ch))
- return true;
- if (ch == '$' || ch == '@' || ch == '\\' ||
- ch == '&' || ch == '#' || ch == '<' || ch == '>' ||
- ch == '{' || ch == '}' || ch == '[' || ch == ']')
- return true;
- return false;
-}
-
-static bool IsStringSuffix(int ch) {
- return ch == 'c' || ch == 'w' || ch == 'd';
-}
-
-
-static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2]; //doxygen
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
-
- int styleBeforeDCKeyword = SCE_D_DEFAULT;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- int curLine = styler.GetLine(startPos);
- int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
- bool numFloat = false; // Float literals have '+' and '-' signs
- bool numHex = false;
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart) {
- curLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(curLine, curNcLevel);
- }
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_D_OPERATOR:
- sc.SetState(SCE_D_DEFAULT);
- break;
- case SCE_D_NUMBER:
- // We accept almost anything because of hex. and number suffixes
- if (isascii(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {
- continue;
- } else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {
- // Don't parse 0..2 as number.
- numFloat=true;
- continue;
- } else if ( ( sc.ch == '-' || sc.ch == '+' ) && ( /*sign and*/
- ( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/
- ( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) { /*hex*/
- // Parse exponent sign in float literals: 2e+10 0x2e+10
- continue;
- } else {
- sc.SetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_IDENTIFIER:
- if (!IsWord(sc.ch)) {
- char s[1000];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_D_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_D_WORD2);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_D_TYPEDEF);
- } else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_D_WORD5);
- } else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_D_WORD6);
- } else if (keywords7.InList(s)) {
- sc.ChangeState(SCE_D_WORD7);
- }
- sc.SetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_COMMENT:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_COMMENTDOC:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_D_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
- // Verify that we have the conditions to mark a comment-doc-keyword
- if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
- styleBeforeDCKeyword = SCE_D_COMMENTDOC;
- sc.SetState(SCE_D_COMMENTDOCKEYWORD);
- }
- }
- break;
- case SCE_D_COMMENTLINE:
- if (sc.atLineStart) {
- sc.SetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_COMMENTLINEDOC:
- if (sc.atLineStart) {
- sc.SetState(SCE_D_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
- // Verify that we have the conditions to mark a comment-doc-keyword
- if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
- styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
- sc.SetState(SCE_D_COMMENTDOCKEYWORD);
- }
- }
- break;
- case SCE_D_COMMENTDOCKEYWORD:
- if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
- sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
- sc.Forward();
- sc.ForwardSetState(SCE_D_DEFAULT);
- } else if (!IsDoxygen(sc.ch)) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
- sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
- }
- sc.SetState(styleBeforeDCKeyword);
- }
- break;
- case SCE_D_COMMENTNESTED:
- if (sc.Match('+', '/')) {
- if (curNcLevel > 0)
- curNcLevel -= 1;
- curLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(curLine, curNcLevel);
- sc.Forward();
- if (curNcLevel == 0) {
- sc.ForwardSetState(SCE_D_DEFAULT);
- }
- } else if (sc.Match('/','+')) {
- curNcLevel += 1;
- curLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(curLine, curNcLevel);
- sc.Forward();
- }
- break;
- case SCE_D_STRING:
- if (sc.ch == '\\') {
- if (sc.chNext == '"' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '"') {
- if(IsStringSuffix(sc.chNext))
- sc.Forward();
- sc.ForwardSetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_CHARACTER:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_D_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- // Char has no suffixes
- sc.ForwardSetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_STRINGEOL:
- if (sc.atLineStart) {
- sc.SetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_STRINGB:
- if (sc.ch == '`') {
- if(IsStringSuffix(sc.chNext))
- sc.Forward();
- sc.ForwardSetState(SCE_D_DEFAULT);
- }
- break;
- case SCE_D_STRINGR:
- if (sc.ch == '"') {
- if(IsStringSuffix(sc.chNext))
- sc.Forward();
- sc.ForwardSetState(SCE_D_DEFAULT);
- }
- break;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_D_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_D_NUMBER);
- numFloat = sc.ch == '.';
- // Remember hex literal
- numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );
- } else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')
- && sc.chNext == '"' ) {
- // Limited support for hex and delimited strings: parse as r""
- sc.SetState(SCE_D_STRINGR);
- sc.Forward();
- } else if (IsWordStart(sc.ch) || sc.ch == '$') {
- sc.SetState(SCE_D_IDENTIFIER);
- } else if (sc.Match('/','+')) {
- curNcLevel += 1;
- curLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(curLine, curNcLevel);
- sc.SetState(SCE_D_COMMENTNESTED);
- sc.Forward();
- } else if (sc.Match('/', '*')) {
- if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
- sc.SetState(SCE_D_COMMENTDOC);
- } else {
- sc.SetState(SCE_D_COMMENT);
- }
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
- // Support of Qt/Doxygen doc. style
- sc.SetState(SCE_D_COMMENTLINEDOC);
- else
- sc.SetState(SCE_D_COMMENTLINE);
- } else if (sc.ch == '"') {
- sc.SetState(SCE_D_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_D_CHARACTER);
- } else if (sc.ch == '`') {
- sc.SetState(SCE_D_STRINGB);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_D_OPERATOR);
- if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator
- }
- }
- }
- sc.Complete();
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_D_COMMENT ||
- style == SCE_D_COMMENTDOC ||
- style == SCE_D_COMMENTDOCKEYWORD ||
- style == SCE_D_COMMENTDOCKEYWORDERROR;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- // property lexer.d.fold.at.else
- // This option enables D folding on a "} else {" line of an if statement.
- bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
- styler.GetPropertyInt("fold.at.else", 0)) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelNext++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- }
- if (style == SCE_D_OPERATOR) {
- if (ch == '{') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- if (atEOL) {
- if (foldComment) { // Handle nested comments
- int nc;
- nc = styler.GetLineState(lineCurrent);
- nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
- levelNext += nc;
- }
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!IsASpace(ch))
- visibleChars++;
- }
-}
-
-static void FoldDDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- FoldDoc(startPos, length, initStyle, styler);
-}
-
-static const char * const dWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- "Type definitions and aliases",
- "Keywords 5",
- "Keywords 6",
- "Keywords 7",
- 0,
- };
-
-static void ColouriseDDoc(unsigned int startPos, int length,
- int initStyle, WordList *keywordlists[], Accessor &styler) {
- ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexESCRIPT.cxx
- ** Lexer for ESCRIPT
- **/
-// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-
-
-static void ColouriseESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
-
- // Do not leak onto next line
- /*if (initStyle == SCE_ESCRIPT_STRINGEOL)
- initStyle = SCE_ESCRIPT_DEFAULT;*/
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- bool caseSensitive = styler.GetPropertyInt("escript.case.sensitive", 0) != 0;
-
- for (; sc.More(); sc.Forward()) {
-
- /*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) {
- // Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_ESCRIPT_STRING);
- }*/
-
- // Handle line continuation generically.
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) {
- sc.SetState(SCE_ESCRIPT_DEFAULT);
- } else if (sc.state == SCE_ESCRIPT_NUMBER) {
- if (!IsADigit(sc.ch) || sc.ch != '.') {
- sc.SetState(SCE_ESCRIPT_DEFAULT);
- }
- } else if (sc.state == SCE_ESCRIPT_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
-
-// sc.GetCurrentLowered(s, sizeof(s));
-
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_ESCRIPT_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_ESCRIPT_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_ESCRIPT_WORD3);
- // sc.state = SCE_ESCRIPT_IDENTIFIER;
- }
- sc.SetState(SCE_ESCRIPT_DEFAULT);
- }
- } else if (sc.state == SCE_ESCRIPT_COMMENT) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
- }
- } else if (sc.state == SCE_ESCRIPT_COMMENTDOC) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
- }
- } else if (sc.state == SCE_ESCRIPT_COMMENTLINE) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_ESCRIPT_DEFAULT);
- }
- } else if (sc.state == SCE_ESCRIPT_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_ESCRIPT_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_ESCRIPT_NUMBER);
- } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
- sc.SetState(SCE_ESCRIPT_IDENTIFIER);
- } else if (sc.Match('/', '*')) {
- sc.SetState(SCE_ESCRIPT_COMMENT);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- sc.SetState(SCE_ESCRIPT_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_ESCRIPT_STRING);
- //} else if (isoperator(static_cast<char>(sc.ch))) {
- } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
- sc.SetState(SCE_ESCRIPT_OPERATOR);
- } else if (sc.ch == '{' || sc.ch == '}') {
- sc.SetState(SCE_ESCRIPT_BRACE);
- }
- }
-
- }
- sc.Complete();
-}
-
-
-static int classifyFoldPointESCRIPT(const char* s, const char* prevWord) {
- int lev = 0;
- if (strcmp(prevWord, "end") == 0) return lev;
- if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
- return -1;
-
- if (strcmp(s, "for") == 0 || strcmp(s, "foreach") == 0
- || strcmp(s, "program") == 0 || strcmp(s, "function") == 0
- || strcmp(s, "while") == 0 || strcmp(s, "case") == 0
- || strcmp(s, "if") == 0 ) {
- lev = 1;
- } else if ( strcmp(s, "endfor") == 0 || strcmp(s, "endforeach") == 0
- || strcmp(s, "endprogram") == 0 || strcmp(s, "endfunction") == 0
- || strcmp(s, "endwhile") == 0 || strcmp(s, "endcase") == 0
- || strcmp(s, "endif") == 0 ) {
- lev = -1;
- }
-
- return lev;
-}
-
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_ESCRIPT_COMMENT ||
- style == SCE_ESCRIPT_COMMENTDOC ||
- style == SCE_ESCRIPT_COMMENTLINE;
-}
-
-static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
- //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- // Do not know how to fold the comment at the moment.
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldComment = true;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
-
- int lastStart = 0;
- char prevWord[32] = "";
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
-
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelCurrent++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelCurrent--;
- }
- }
-
- if (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
-
- if (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3)
- {
- // Store last word start point.
- lastStart = i;
- }
-
- if (style == SCE_ESCRIPT_WORD3) {
- if(iswordchar(ch) && !iswordchar(chNext)) {
- char s[32];
- unsigned int j;
- for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
- s[j] = static_cast<char>(tolower(styler[lastStart + j]));
- }
- s[j] = '\0';
- levelCurrent += classifyFoldPointESCRIPT(s, prevWord);
- strcpy(prevWord, s);
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- strcpy(prevWord, "");
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-
-
-static const char * const ESCRIPTWordLists[] = {
- "Primary keywords and identifiers",
- "Intrinsic functions",
- "Extended and user defined functions",
- 0,
-};
-
-LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, "escript", FoldESCRIPTDoc, ESCRIPTWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexEiffel.cxx
- ** Lexer for Eiffel.
- **/
-// 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 <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#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 inline bool isEiffelOperator(unsigned int ch) {
- // '.' left out as it is used to make up numbers
- return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' ||
- ch == '{' || ch == '}' || ch == '~' ||
- ch == '[' || ch == ']' || ch == ';' ||
- ch == '<' || ch == '>' || ch == ',' ||
- ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
- ch == '!' || ch == '@' || ch == '?';
-}
-
-static inline bool IsAWordChar(unsigned int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(unsigned int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static void ColouriseEiffelDoc(unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_EIFFEL_STRINGEOL) {
- if (sc.ch != '\r' && sc.ch != '\n') {
- sc.SetState(SCE_EIFFEL_DEFAULT);
- }
- } else if (sc.state == SCE_EIFFEL_OPERATOR) {
- sc.SetState(SCE_EIFFEL_DEFAULT);
- } else if (sc.state == SCE_EIFFEL_WORD) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (!keywords.InList(s)) {
- sc.ChangeState(SCE_EIFFEL_IDENTIFIER);
- }
- sc.SetState(SCE_EIFFEL_DEFAULT);
- }
- } else if (sc.state == SCE_EIFFEL_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_EIFFEL_DEFAULT);
- }
- } else if (sc.state == SCE_EIFFEL_COMMENTLINE) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_EIFFEL_DEFAULT);
- }
- } else if (sc.state == SCE_EIFFEL_STRING) {
- if (sc.ch == '%') {
- sc.Forward();
- } else if (sc.ch == '\"') {
- sc.Forward();
- sc.SetState(SCE_EIFFEL_DEFAULT);
- }
- } else if (sc.state == SCE_EIFFEL_CHARACTER) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_EIFFEL_STRINGEOL);
- } else if (sc.ch == '%') {
- sc.Forward();
- } else if (sc.ch == '\'') {
- sc.Forward();
- sc.SetState(SCE_EIFFEL_DEFAULT);
- }
- }
-
- if (sc.state == SCE_EIFFEL_DEFAULT) {
- if (sc.ch == '-' && sc.chNext == '-') {
- sc.SetState(SCE_EIFFEL_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_EIFFEL_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_EIFFEL_CHARACTER);
- } else if (IsADigit(sc.ch) || (sc.ch == '.')) {
- sc.SetState(SCE_EIFFEL_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_EIFFEL_WORD);
- } else if (isEiffelOperator(sc.ch)) {
- sc.SetState(SCE_EIFFEL_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-static bool IsEiffelComment(Accessor &styler, int pos, int len) {
- return len>1 && styler[pos]=='-' && styler[pos+1]=='-';
-}
-
-static void FoldEiffelDocIndent(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- int lengthDoc = startPos + length;
-
- // Backtrack to previous line in case need to fix its fold status
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);
- char chNext = styler[startPos];
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- }
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- }
- }
-}
-
-static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* initStyle */, WordList *[],
- Accessor &styler) {
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int stylePrev = 0;
- int styleNext = styler.StyleAt(startPos);
- // lastDeferred should be determined by looking back to last keyword in case
- // the "deferred" is on a line before "class"
- bool lastDeferred = false;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {
- char s[20];
- unsigned int j = 0;
- while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
- s[j] = styler[i + j];
- j++;
- }
- s[j] = '\0';
-
- if (
- (strcmp(s, "check") == 0) ||
- (strcmp(s, "debug") == 0) ||
- (strcmp(s, "deferred") == 0) ||
- (strcmp(s, "do") == 0) ||
- (strcmp(s, "from") == 0) ||
- (strcmp(s, "if") == 0) ||
- (strcmp(s, "inspect") == 0) ||
- (strcmp(s, "once") == 0)
- )
- levelCurrent++;
- if (!lastDeferred && (strcmp(s, "class") == 0))
- levelCurrent++;
- if (strcmp(s, "end") == 0)
- levelCurrent--;
- lastDeferred = strcmp(s, "deferred") == 0;
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- stylePrev = style;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const eiffelWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc);
-LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-/** @file LexErlang.cxx
- ** Lexer for Erlang.
- ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
- ** Originally wrote by Peter-Henry Mander,
- ** based on Matlab lexer by José Fonseca.
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 int is_radix(int radix, int ch) {
- int digit;
-
- if (36 < radix || 2 > radix)
- return 0;
-
- if (isdigit(ch)) {
- digit = ch - '0';
- } else if (isalnum(ch)) {
- digit = toupper(ch) - 'A' + 10;
- } else {
- return 0;
- }
-
- return (digit < radix);
-}
-
-typedef enum {
- STATE_NULL,
- COMMENT,
- COMMENT_FUNCTION,
- COMMENT_MODULE,
- COMMENT_DOC,
- COMMENT_DOC_MACRO,
- ATOM_UNQUOTED,
- ATOM_QUOTED,
- NODE_NAME_UNQUOTED,
- NODE_NAME_QUOTED,
- MACRO_START,
- MACRO_UNQUOTED,
- MACRO_QUOTED,
- RECORD_START,
- RECORD_UNQUOTED,
- RECORD_QUOTED,
- NUMERAL_START,
- NUMERAL_BASE_VALUE,
- NUMERAL_FLOAT,
- NUMERAL_EXPONENT,
- PREPROCESSOR
-} atom_parse_state_t;
-
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');
-}
-
-static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- StyleContext sc(startPos, length, initStyle, styler);
- WordList &reservedWords = *keywordlists[0];
- WordList &erlangBIFs = *keywordlists[1];
- WordList &erlangPreproc = *keywordlists[2];
- WordList &erlangModulesAtt = *keywordlists[3];
- WordList &erlangDoc = *keywordlists[4];
- WordList &erlangDocMacro = *keywordlists[5];
- int radix_digits = 0;
- int exponent_digits = 0;
- atom_parse_state_t parse_state = STATE_NULL;
- atom_parse_state_t old_parse_state = STATE_NULL;
- bool to_late_to_comment = false;
- char cur[100];
- int old_style = SCE_ERLANG_DEFAULT;
-
- styler.StartAt(startPos);
-
- for (; sc.More(); sc.Forward()) {
- int style = SCE_ERLANG_DEFAULT;
- if (STATE_NULL != parse_state) {
-
- switch (parse_state) {
-
- case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;
-
- /* COMMENTS ------------------------------------------------------*/
- case COMMENT : {
- if (sc.ch != '%') {
- to_late_to_comment = true;
- } else if (!to_late_to_comment && sc.ch == '%') {
- // Switch to comment level 2 (Function)
- sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
- old_style = SCE_ERLANG_COMMENT_FUNCTION;
- parse_state = COMMENT_FUNCTION;
- sc.Forward();
- }
- }
- // V--- Falling through!
- case COMMENT_FUNCTION : {
- if (sc.ch != '%') {
- to_late_to_comment = true;
- } else if (!to_late_to_comment && sc.ch == '%') {
- // Switch to comment level 3 (Module)
- sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
- old_style = SCE_ERLANG_COMMENT_MODULE;
- parse_state = COMMENT_MODULE;
- sc.Forward();
- }
- }
- // V--- Falling through!
- case COMMENT_MODULE : {
- if (parse_state != COMMENT) {
- // Search for comment documentation
- if (sc.chNext == '@') {
- old_parse_state = parse_state;
- parse_state = ('{' == sc.ch)
- ? COMMENT_DOC_MACRO
- : COMMENT_DOC;
- sc.ForwardSetState(sc.state);
- }
- }
-
- // All comments types fall here.
- if (sc.atLineEnd) {
- to_late_to_comment = false;
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- case COMMENT_DOC :
- // V--- Falling through!
- case COMMENT_DOC_MACRO : {
-
- if (!isalnum(sc.ch)) {
- // Try to match documentation comment
- sc.GetCurrent(cur, sizeof(cur));
-
- if (parse_state == COMMENT_DOC_MACRO
- && erlangDocMacro.InList(cur)) {
- sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
- while (sc.ch != '}' && !sc.atLineEnd)
- sc.Forward();
- } else if (erlangDoc.InList(cur)) {
- sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
- } else {
- sc.ChangeState(old_style);
- }
-
- // Switch back to old state
- sc.SetState(old_style);
- parse_state = old_parse_state;
- }
-
- if (sc.atLineEnd) {
- to_late_to_comment = false;
- sc.ChangeState(old_style);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* -------------------------------------------------------------- */
- /* Atoms ---------------------------------------------------------*/
- case ATOM_UNQUOTED : {
- if ('@' == sc.ch){
- parse_state = NODE_NAME_UNQUOTED;
- } else if (sc.ch == ':') {
- // Searching for module name
- if (sc.chNext == ' ') {
- // error
- sc.ChangeState(SCE_ERLANG_UNKNOWN);
- parse_state = STATE_NULL;
- } else {
- sc.Forward();
- if (isalnum(sc.ch)) {
- sc.GetCurrent(cur, sizeof(cur));
- sc.ChangeState(SCE_ERLANG_MODULES);
- sc.SetState(SCE_ERLANG_MODULES);
- }
- }
- } else if (!IsAWordChar(sc.ch)) {
-
- sc.GetCurrent(cur, sizeof(cur));
- if (reservedWords.InList(cur)) {
- style = SCE_ERLANG_KEYWORD;
- } else if (erlangBIFs.InList(cur)
- && strcmp(cur,"erlang:")){
- style = SCE_ERLANG_BIFS;
- } else if (sc.ch == '(' || '/' == sc.ch){
- style = SCE_ERLANG_FUNCTION_NAME;
- } else {
- style = SCE_ERLANG_ATOM;
- }
-
- sc.ChangeState(style);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
-
- } break;
-
- case ATOM_QUOTED : {
- if ( '@' == sc.ch ){
- parse_state = NODE_NAME_QUOTED;
- } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
- sc.ChangeState(SCE_ERLANG_ATOM);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* -------------------------------------------------------------- */
- /* Node names ----------------------------------------------------*/
- case NODE_NAME_UNQUOTED : {
- if ('@' == sc.ch) {
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else if (!IsAWordChar(sc.ch)) {
- sc.ChangeState(SCE_ERLANG_NODE_NAME);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- case NODE_NAME_QUOTED : {
- if ('@' == sc.ch) {
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
- sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* -------------------------------------------------------------- */
- /* Records -------------------------------------------------------*/
- case RECORD_START : {
- if ('\'' == sc.ch) {
- parse_state = RECORD_QUOTED;
- } else if (isalpha(sc.ch) && islower(sc.ch)) {
- parse_state = RECORD_UNQUOTED;
- } else { // error
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- case RECORD_UNQUOTED : {
- if (!IsAWordChar(sc.ch)) {
- sc.ChangeState(SCE_ERLANG_RECORD);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- case RECORD_QUOTED : {
- if ('\'' == sc.ch && '\\' != sc.chPrev) {
- sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* -------------------------------------------------------------- */
- /* Macros --------------------------------------------------------*/
- case MACRO_START : {
- if ('\'' == sc.ch) {
- parse_state = MACRO_QUOTED;
- } else if (isalpha(sc.ch)) {
- parse_state = MACRO_UNQUOTED;
- } else { // error
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- case MACRO_UNQUOTED : {
- if (!IsAWordChar(sc.ch)) {
- sc.ChangeState(SCE_ERLANG_MACRO);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- case MACRO_QUOTED : {
- if ('\'' == sc.ch && '\\' != sc.chPrev) {
- sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* -------------------------------------------------------------- */
- /* Numerics ------------------------------------------------------*/
- /* Simple integer */
- case NUMERAL_START : {
- if (isdigit(sc.ch)) {
- radix_digits *= 10;
- radix_digits += sc.ch - '0'; // Assuming ASCII here!
- } else if ('#' == sc.ch) {
- if (2 > radix_digits || 36 < radix_digits) {
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- parse_state = NUMERAL_BASE_VALUE;
- }
- } else if ('.' == sc.ch && isdigit(sc.chNext)) {
- radix_digits = 0;
- parse_state = NUMERAL_FLOAT;
- } else if ('e' == sc.ch || 'E' == sc.ch) {
- exponent_digits = 0;
- parse_state = NUMERAL_EXPONENT;
- } else {
- radix_digits = 0;
- sc.ChangeState(SCE_ERLANG_NUMBER);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* Integer in other base than 10 (x#yyy) */
- case NUMERAL_BASE_VALUE : {
- if (!is_radix(radix_digits,sc.ch)) {
- radix_digits = 0;
-
- if (!isalnum(sc.ch))
- sc.ChangeState(SCE_ERLANG_NUMBER);
-
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* Float (x.yyy) */
- case NUMERAL_FLOAT : {
- if ('e' == sc.ch || 'E' == sc.ch) {
- exponent_digits = 0;
- parse_state = NUMERAL_EXPONENT;
- } else if (!isdigit(sc.ch)) {
- sc.ChangeState(SCE_ERLANG_NUMBER);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- /* Exponent, either integer or float (xEyy, x.yyEzzz) */
- case NUMERAL_EXPONENT : {
- if (('-' == sc.ch || '+' == sc.ch)
- && (isdigit(sc.chNext))) {
- sc.Forward();
- } else if (!isdigit(sc.ch)) {
- if (0 < exponent_digits)
- sc.ChangeState(SCE_ERLANG_NUMBER);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- } else {
- ++exponent_digits;
- }
- } break;
-
- /* -------------------------------------------------------------- */
- /* Preprocessor --------------------------------------------------*/
- case PREPROCESSOR : {
- if (!IsAWordChar(sc.ch)) {
-
- sc.GetCurrent(cur, sizeof(cur));
- if (erlangPreproc.InList(cur)) {
- style = SCE_ERLANG_PREPROC;
- } else if (erlangModulesAtt.InList(cur)) {
- style = SCE_ERLANG_MODULES_ATT;
- }
-
- sc.ChangeState(style);
- sc.SetState(SCE_ERLANG_DEFAULT);
- parse_state = STATE_NULL;
- }
- } break;
-
- }
-
- } /* End of : STATE_NULL != parse_state */
- else
- {
- switch (sc.state) {
- case SCE_ERLANG_VARIABLE : {
- if (!IsAWordChar(sc.ch))
- sc.SetState(SCE_ERLANG_DEFAULT);
- } break;
- case SCE_ERLANG_STRING : {
- if (sc.ch == '\"' && sc.chPrev != '\\')
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } break;
- case SCE_ERLANG_COMMENT : {
- if (sc.atLineEnd)
- sc.SetState(SCE_ERLANG_DEFAULT);
- } break;
- case SCE_ERLANG_CHARACTER : {
- if (sc.chPrev == '\\') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } else if (sc.ch != '\\') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- }
- } break;
- case SCE_ERLANG_OPERATOR : {
- if (sc.chPrev == '.') {
- if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
- || sc.ch == '^') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_ERLANG_DEFAULT);
- } else {
- sc.SetState(SCE_ERLANG_DEFAULT);
- }
- } else {
- sc.SetState(SCE_ERLANG_DEFAULT);
- }
- } break;
- }
- }
-
- if (sc.state == SCE_ERLANG_DEFAULT) {
- bool no_new_state = false;
-
- switch (sc.ch) {
- case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
- case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
- case '%' : {
- parse_state = COMMENT;
- sc.SetState(SCE_ERLANG_COMMENT);
- } break;
- case '#' : {
- parse_state = RECORD_START;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } break;
- case '?' : {
- parse_state = MACRO_START;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } break;
- case '\'' : {
- parse_state = ATOM_QUOTED;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } break;
- case '+' :
- case '-' : {
- if (IsADigit(sc.chNext)) {
- parse_state = NUMERAL_START;
- radix_digits = 0;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (sc.ch != '+') {
- parse_state = PREPROCESSOR;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- }
- } break;
- default : no_new_state = true;
- }
-
- if (no_new_state) {
- if (isdigit(sc.ch)) {
- parse_state = NUMERAL_START;
- radix_digits = sc.ch - '0';
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (isupper(sc.ch) || '_' == sc.ch) {
- sc.SetState(SCE_ERLANG_VARIABLE);
- } else if (isalpha(sc.ch)) {
- parse_state = ATOM_UNQUOTED;
- sc.SetState(SCE_ERLANG_UNKNOWN);
- } else if (isoperator(static_cast<char>(sc.ch))
- || sc.ch == '\\') {
- sc.SetState(SCE_ERLANG_OPERATOR);
- }
- }
- }
-
- }
- sc.Complete();
-}
-
-static int ClassifyErlangFoldPoint(
- Accessor &styler,
- int styleNext,
- int keyword_start
-) {
- int lev = 0;
- if (styler.Match(keyword_start,"case")
- || (
- styler.Match(keyword_start,"fun")
- && (SCE_ERLANG_FUNCTION_NAME != styleNext)
- )
- || styler.Match(keyword_start,"if")
- || styler.Match(keyword_start,"query")
- || styler.Match(keyword_start,"receive")
- ) {
- ++lev;
- } else if (styler.Match(keyword_start,"end")) {
- --lev;
- }
-
- return lev;
-}
-
-static void FoldErlangDoc(
- unsigned int startPos, int length, int initStyle,
- WordList** /*keywordlists*/, Accessor &styler
-) {
- unsigned int endPos = startPos + length;
- int currentLine = styler.GetLine(startPos);
- int lev;
- int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
- int currentLevel = previousLevel;
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- int stylePrev;
- int keyword_start = 0;
- char ch;
- char chNext = styler.SafeGetCharAt(startPos);
- bool atEOL;
-
- for (unsigned int i = startPos; i < endPos; i++) {
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- // Get styles
- stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');
-
- if (stylePrev != SCE_ERLANG_KEYWORD
- && style == SCE_ERLANG_KEYWORD) {
- keyword_start = i;
- }
-
- // Fold on keywords
- if (stylePrev == SCE_ERLANG_KEYWORD
- && style != SCE_ERLANG_KEYWORD
- && style != SCE_ERLANG_ATOM
- ) {
- currentLevel += ClassifyErlangFoldPoint(styler,
- styleNext,
- keyword_start);
- }
-
- // Fold on comments
- if (style == SCE_ERLANG_COMMENT
- || style == SCE_ERLANG_COMMENT_MODULE
- || style == SCE_ERLANG_COMMENT_FUNCTION) {
-
- if (ch == '%' && chNext == '{') {
- currentLevel++;
- } else if (ch == '%' && chNext == '}') {
- currentLevel--;
- }
- }
-
- // Fold on braces
- if (style == SCE_ERLANG_OPERATOR) {
- if (ch == '{' || ch == '(' || ch == '[') {
- currentLevel++;
- } else if (ch == '}' || ch == ')' || ch == ']') {
- currentLevel--;
- }
- }
-
-
- if (atEOL) {
- lev = previousLevel;
-
- if (currentLevel > previousLevel)
- lev |= SC_FOLDLEVELHEADERFLAG;
-
- if (lev != styler.LevelAt(currentLine))
- styler.SetLevel(currentLine, lev);
-
- currentLine++;
- previousLevel = currentLevel;
- }
-
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- styler.SetLevel(currentLine,
- previousLevel
- | (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
-}
-
-static const char * const erlangWordListDesc[] = {
- "Erlang Reserved words",
- "Erlang BIFs",
- "Erlang Preprocessor",
- "Erlang Module Attributes",
- "Erlang Documentation",
- "Erlang Documentation Macro",
- 0
-};
-
-LexerModule lmErlang(
- SCLEX_ERLANG,
- ColouriseErlangDoc,
- "erlang",
- FoldErlangDoc,
- erlangWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexFlagShip.cxx
- ** Lexer for FlagShip
- ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
- **/
-// Copyright 2005 by Randy Butler
-// Copyright 1998-2003 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 bool IsFlagShipComment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]=='\'';
-}
-
-static inline bool IsTypeCharacter(int ch) {
- return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
-}
-
-// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
- return ch >= 0x80 ||
- (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return ch >= 0x80 ||
- (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsADateCharacter(const int ch) {
- return (ch < 0x80) &&
- (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
-}
-
-
-static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- //bool FSScriptSyntax = true;
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- styler.StartAt(startPos);
-
- int visibleChars = 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_FS_OPERATOR) {
- sc.SetState(SCE_FS_DEFAULT);
- } else if (sc.state == SCE_FS_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD4);
- }// Else, it is really an identifier...
- sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_STRING) {
- // VB doubles quotes to preserve them, so just end this string
- // state now as a following quote will start again
- if (sc.ch == '\"') {
- if (tolower(sc.chNext) == 'c') {
- sc.Forward();
- }
- sc.ForwardSetState(SCE_FS_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_FS_STRINGEOL);
- sc.ForwardSetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_COMMENT) {
- if (sc.Match('*', '/')) { // new code
- sc.Forward();
- sc.ForwardSetState(SCE_FS_DEFAULT);
- //if (sc.atLineEnd) { // old code
- // sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_COMMENTLINE) { //new code
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_FS_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_FS_PREPROCESSOR) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_DATE) {
- if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
- sc.ForwardSetState(SCE_FS_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_FS_DEFAULT) {
- if (sc.Match('/', '*')) { // New code
- sc.SetState(SCE_FS_COMMENT);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- //if (sc.ch == '\'') { // Old code
- // sc.SetState(SCE_FS_COMMENT); // old code
- } else if (sc.Match('/', '/')) { // New code
- sc.SetState(SCE_FS_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_FS_STRING);
- } else if (sc.ch == '#' && visibleChars == 0) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_FS_PREPROCESSOR);
- } else if (sc.ch == '#') {
- int n = 1;
- int chSeek = ' ';
- while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
- chSeek = sc.GetRelative(n);
- n++;
- }
- if (IsADigit(chSeek)) {
- sc.SetState(SCE_FS_DATE);
- } else {
- sc.SetState(SCE_FS_OPERATOR);
- }
- } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
- sc.SetState(SCE_FS_NUMBER);
- } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
- sc.SetState(SCE_FS_NUMBER);
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_FS_NUMBER);
- } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
- sc.SetState(SCE_FS_IDENTIFIER);
- } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
- sc.SetState(SCE_FS_OPERATOR);
- }
- }
-
- if (sc.atLineEnd) {
- visibleChars = 0;
- }
- if (!IsASpace(sc.ch)) {
- visibleChars++;
- }
- }
- sc.Complete();
-}
-
-static void FoldFlagShipDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
-
- int endPos = startPos + length;
-
- // Backtrack to previous line in case need to fix its fold status
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsFlagShipComment);
- char chNext = styler[startPos];
- for (int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsFlagShipComment);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsFlagShipComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- }
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- }
- }
-}
-
-
-static const char * const FSWordListDesc[] = {
- "Keywords",
- "functions",
- "user2",
- "user3",
- 0
-};
-
-LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
-
-
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexForth.cxx
- ** Lexer for FORTH
- **/
-// Copyright 1998-2003 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
- ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
- ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
- ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
- ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
- ch == ')' );
-}
-
-static inline bool IsAWordStart(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
-}
-
-static inline bool IsANumChar(int ch) {
- return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
-}
-
-static inline bool IsASpaceChar(int ch) {
- return (ch < 0x80) && isspace(ch);
-}
-
-static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
- Accessor &styler) {
-
- WordList &control = *keywordLists[0];
- WordList &keyword = *keywordLists[1];
- WordList &defword = *keywordLists[2];
- WordList &preword1 = *keywordLists[3];
- WordList &preword2 = *keywordLists[4];
- WordList &strings = *keywordLists[5];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
- // Determine if the current state should terminate.
- if (sc.state == SCE_FORTH_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_FORTH_DEFAULT);
- }
- }else if (sc.state == SCE_FORTH_COMMENT_ML) {
- if (sc.ch == ')') {
- sc.ForwardSetState(SCE_FORTH_DEFAULT);
- }
- }else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
- // handle numbers here too, because what we thought was a number might
- // turn out to be a keyword e.g. 2DUP
- if (IsASpaceChar(sc.ch) ) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
- if (control.InList(s)) {
- sc.ChangeState(SCE_FORTH_CONTROL);
- } else if (keyword.InList(s)) {
- sc.ChangeState(SCE_FORTH_KEYWORD);
- } else if (defword.InList(s)) {
- sc.ChangeState(SCE_FORTH_DEFWORD);
- } else if (preword1.InList(s)) {
- sc.ChangeState(SCE_FORTH_PREWORD1);
- } else if (preword2.InList(s)) {
- sc.ChangeState(SCE_FORTH_PREWORD2);
- } else if (strings.InList(s)) {
- sc.ChangeState(SCE_FORTH_STRING);
- newState = SCE_FORTH_STRING;
- }
- sc.SetState(newState);
- }
- if (sc.state == SCE_FORTH_NUMBER) {
- if (IsASpaceChar(sc.ch)) {
- sc.SetState(SCE_FORTH_DEFAULT);
- } else if (!IsANumChar(sc.ch)) {
- sc.ChangeState(SCE_FORTH_IDENTIFIER);
- }
- }
- }else if (sc.state == SCE_FORTH_STRING) {
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_FORTH_DEFAULT);
- }
- }else if (sc.state == SCE_FORTH_LOCALE) {
- if (sc.ch == '}') {
- sc.ForwardSetState(SCE_FORTH_DEFAULT);
- }
- }else if (sc.state == SCE_FORTH_DEFWORD) {
- if (IsASpaceChar(sc.ch)) {
- sc.SetState(SCE_FORTH_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_FORTH_DEFAULT) {
- if (sc.ch == '\\'){
- sc.SetState(SCE_FORTH_COMMENT);
- } else if (sc.ch == '(' &&
- (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
- (sc.atLineEnd || IsASpaceChar(sc.chNext))) {
- sc.SetState(SCE_FORTH_COMMENT_ML);
- } else if ( (sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
- // number starting with $ is a hex number
- sc.SetState(SCE_FORTH_NUMBER);
- while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
- sc.Forward();
- } else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
- // number starting with % is binary
- sc.SetState(SCE_FORTH_NUMBER);
- while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
- sc.Forward();
- } else if ( isascii(sc.ch) &&
- (isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
- ){
- sc.SetState(SCE_FORTH_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_FORTH_IDENTIFIER);
- } else if (sc.ch == '{') {
- sc.SetState(SCE_FORTH_LOCALE);
- } else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
- // highlight word definitions e.g. : GCD ( n n -- n ) ..... ;
- // ^ ^^^
- sc.SetState(SCE_FORTH_DEFWORD);
- while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
- sc.Forward();
- } else if (sc.ch == ';' &&
- (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
- (sc.atLineEnd || IsASpaceChar(sc.chNext)) ) {
- // mark the ';' that ends a word
- sc.SetState(SCE_FORTH_DEFWORD);
- sc.ForwardSetState(SCE_FORTH_DEFAULT);
- }
- }
-
- }
- sc.Complete();
-}
-
-static void FoldForthDoc(unsigned int, int, int, WordList *[],
- Accessor &) {
-}
-
-static const char * const forthWordLists[] = {
- "control keywords",
- "keywords",
- "definition words",
- "prewords with one argument",
- "prewords with two arguments",
- "string definition keywords",
- 0,
- };
-
-LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
-
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexFortran.cxx
- ** Lexer for Fortran.
- ** Writen by Chuan-jian Shen, Last changed Sep. 2003
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-/***************************************/
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
-}
-/**********************************************/
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch));
-}
-/***************************************/
-inline bool IsABlank(unsigned int ch) {
- return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
-}
-/***************************************/
-inline bool IsALineEnd(char ch) {
- return ((ch == '\n') || (ch == '\r')) ;
-}
-/***************************************/
-unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) {
- while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;
- if (styler.SafeGetCharAt(pos) == '\n') pos++;
- while (IsABlank(styler.SafeGetCharAt(pos++))) continue;
- char chCur = styler.SafeGetCharAt(pos);
- if (chCur == '&') {
- while (IsABlank(styler.SafeGetCharAt(++pos))) continue;
- return pos;
- } else {
- return pos;
- }
-}
-/***************************************/
-static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler, bool isFixFormat) {
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- /***************************************/
- int posLineStart = 0, numNonBlank = 0, prevState = 0;
- int endPos = startPos + length;
- /***************************************/
- // backtrack to the nearest keyword
- while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
- startPos--;
- }
- startPos = styler.LineStart(styler.GetLine(startPos));
- initStyle = styler.StyleAt(startPos - 1);
- StyleContext sc(startPos, endPos-startPos, initStyle, styler);
- /***************************************/
- for (; sc.More(); sc.Forward()) {
- // remember the start position of the line
- if (sc.atLineStart) {
- posLineStart = sc.currentPos;
- numNonBlank = 0;
- sc.SetState(SCE_F_DEFAULT);
- }
- if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
- /***********************************************/
- // Handle the fix format generically
- int toLineStart = sc.currentPos - posLineStart;
- if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
- if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
- if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
- sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
- sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") ||
- sc.chNext == '$') {
- sc.SetState(SCE_F_PREPROCESSOR);
- } else {
- sc.SetState(SCE_F_COMMENT);
- }
-
- while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
- } else if (toLineStart > 72) {
- sc.SetState(SCE_F_COMMENT);
- while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
- } else if (toLineStart < 5) {
- if (IsADigit(sc.ch))
- sc.SetState(SCE_F_LABEL);
- else
- sc.SetState(SCE_F_DEFAULT);
- } else if (toLineStart == 5) {
- if (!IsASpace(sc.ch) && sc.ch != '0') {
- sc.SetState(SCE_F_CONTINUATION);
- sc.ForwardSetState(prevState);
- } else
- sc.SetState(SCE_F_DEFAULT);
- }
- continue;
- }
- /***************************************/
- // Handle line continuation generically.
- if (!isFixFormat && sc.ch == '&') {
- char chTemp = ' ';
- int j = 1;
- while (IsABlank(chTemp) && j<132) {
- chTemp = static_cast<char>(sc.GetRelative(j));
- j++;
- }
- if (chTemp == '!') {
- sc.SetState(SCE_F_CONTINUATION);
- if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
- } else if (chTemp == '\r' || chTemp == '\n') {
- int currentState = sc.state;
- sc.SetState(SCE_F_CONTINUATION);
- sc.ForwardSetState(SCE_F_DEFAULT);
- while (IsASpace(sc.ch) && sc.More()) sc.Forward();
- if (sc.ch == '&') {
- sc.SetState(SCE_F_CONTINUATION);
- sc.Forward();
- }
- sc.SetState(currentState);
- }
- }
- /***************************************/
- // Determine if the current state should terminate.
- if (sc.state == SCE_F_OPERATOR) {
- sc.SetState(SCE_F_DEFAULT);
- } else if (sc.state == SCE_F_NUMBER) {
- if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) {
- sc.SetState(SCE_F_DEFAULT);
- }
- } else if (sc.state == SCE_F_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_F_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_F_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_F_WORD3);
- }
- sc.SetState(SCE_F_DEFAULT);
- }
- } else if (sc.state == SCE_F_COMMENT || sc.state == SCE_F_PREPROCESSOR) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_F_DEFAULT);
- }
- } else if (sc.state == SCE_F_STRING1) {
- prevState = sc.state;
- if (sc.ch == '\'') {
- if (sc.chNext == '\'') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_F_DEFAULT);
- prevState = SCE_F_DEFAULT;
- }
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_F_STRINGEOL);
- sc.ForwardSetState(SCE_F_DEFAULT);
- }
- } else if (sc.state == SCE_F_STRING2) {
- prevState = sc.state;
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_F_STRINGEOL);
- sc.ForwardSetState(SCE_F_DEFAULT);
- } else if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_F_DEFAULT);
- prevState = SCE_F_DEFAULT;
- }
- }
- } else if (sc.state == SCE_F_OPERATOR2) {
- if (sc.ch == '.') {
- sc.ForwardSetState(SCE_F_DEFAULT);
- }
- } else if (sc.state == SCE_F_CONTINUATION) {
- sc.SetState(SCE_F_DEFAULT);
- } else if (sc.state == SCE_F_LABEL) {
- if (!IsADigit(sc.ch)) {
- sc.SetState(SCE_F_DEFAULT);
- } else {
- if (isFixFormat && sc.currentPos-posLineStart > 4)
- sc.SetState(SCE_F_DEFAULT);
- else if (numNonBlank > 5)
- sc.SetState(SCE_F_DEFAULT);
- }
- }
- /***************************************/
- // Determine if a new state should be entered.
- if (sc.state == SCE_F_DEFAULT) {
- if (sc.ch == '!') {
- if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
- sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
- sc.SetState(SCE_F_PREPROCESSOR);
- } else {
- sc.SetState(SCE_F_COMMENT);
- }
- } else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) {
- sc.SetState(SCE_F_LABEL);
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_F_NUMBER);
- } else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
- tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
- sc.SetState(SCE_F_NUMBER);
- sc.Forward();
- } else if (sc.ch == '.' && isalpha(sc.chNext)) {
- sc.SetState(SCE_F_OPERATOR2);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_F_IDENTIFIER);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_F_STRING2);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_F_STRING1);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_F_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-/***************************************/
-// To determine the folding level depending on keywords
-static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
- int lev = 0;
- if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
- return -1;
- if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
- || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
- || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
- || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
- || strcmp(s, "module") == 0 || strcmp(s, "program") == 0
- || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
- || (strcmp(s, "type") == 0 && chNextNonBlank != '(') ){
- if (strcmp(prevWord, "end") == 0)
- lev = 0;
- else
- lev = 1;
- } else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
- || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
- || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
- || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
- || strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0
- || strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
- || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
- || strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
- || strcmp(s, "endwhere") == 0
- || strcmp(s, "procedure") == 0 ) { // Take care of the module procedure statement
- lev = -1;
- } else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
- lev = 0;
- }
- return lev;
-}
-// Folding the code
-static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
- Accessor &styler, bool isFixFormat) {
- //
- // bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- // Do not know how to fold the comment at the moment.
- //
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- char chNextNonBlank;
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- /***************************************/
- int lastStart = 0;
- char prevWord[32] = "";
- char Label[6] = "";
- // Variables for do label folding.
- static int doLabels[100];
- static int posLabel=-1;
- /***************************************/
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- chNextNonBlank = chNext;
- unsigned int j=i+1;
- while(IsABlank(chNextNonBlank) && j<endPos) {
- j ++ ;
- chNextNonBlank = styler.SafeGetCharAt(j);
- }
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- //
- if (stylePrev == SCE_F_DEFAULT && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
- // Store last word and label start point.
- lastStart = i;
- }
- /***************************************/
- if (style == SCE_F_WORD) {
- if(iswordchar(ch) && !iswordchar(chNext)) {
- char s[32];
- unsigned int k;
- for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
- s[k] = static_cast<char>(tolower(styler[lastStart+k]));
- }
- s[k] = '\0';
- // Handle the forall and where statement and structure.
- if (strcmp(s, "forall") == 0 || strcmp(s, "where") == 0) {
- if (strcmp(prevWord, "end") != 0) {
- j = i + 1;
- char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j);
- // Find the position of the first (
- while (ch1 != chBrace && j<endPos) {
- j++;
- ch1 = styler.SafeGetCharAt(j);
- }
- char styBrace = styler.StyleAt(j);
- int depth = 1;
- char chAtPos;
- char styAtPos;
- while (j<endPos) {
- j++;
- chAtPos = styler.SafeGetCharAt(j);
- styAtPos = styler.StyleAt(j);
- if (styAtPos == styBrace) {
- if (chAtPos == chBrace) depth++;
- if (chAtPos == chSeek) depth--;
- if (depth == 0) break;
- }
- }
- while (j<endPos) {
- j++;
- chAtPos = styler.SafeGetCharAt(j);
- styAtPos = styler.StyleAt(j);
- if (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos)) continue;
- if (isFixFormat) {
- if (!IsALineEnd(chAtPos)) {
- break;
- } else {
- if (lineCurrent < styler.GetLine(styler.Length()-1)) {
- j = styler.LineStart(lineCurrent+1);
- if (styler.StyleAt(j+5) == SCE_F_CONTINUATION) {
- j += 5;
- continue;
- } else {
- levelCurrent++;
- break;
- }
- }
- }
- } else {
- if (chAtPos == '&' && styler.StyleAt(j) == SCE_F_CONTINUATION) {
- j = GetContinuedPos(j+1, styler);
- continue;
- } else if (IsALineEnd(chAtPos)) {
- levelCurrent ++;
- break;
- } else {
- break;
- }
- }
- }
- }
- } else {
- levelCurrent += classifyFoldPointFortran(s, prevWord, chNextNonBlank);
- // Store the do Labels into array
- if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) {
- unsigned int k = 0;
- for (i=j; (i<j+5 && i<endPos); i++) {
- ch = styler.SafeGetCharAt(i);
- if (IsADigit(ch))
- Label[k++] = ch;
- else
- break;
- }
- Label[k] = '\0';
- posLabel ++;
- doLabels[posLabel] = atoi(Label);
- }
- }
- strcpy(prevWord, s);
- }
- } else if (style == SCE_F_LABEL) {
- if(IsADigit(ch) && !IsADigit(chNext)) {
- for(j = 0; ( j < 5 ) && ( j < i-lastStart+1 ); j++) {
- ch = styler.SafeGetCharAt(lastStart + j);
- if (IsADigit(ch) && styler.StyleAt(lastStart+j) == SCE_F_LABEL)
- Label[j] = ch;
- else
- break;
- }
- Label[j] = '\0';
- while (doLabels[posLabel] == atoi(Label) && posLabel > -1) {
- levelCurrent--;
- posLabel--;
- }
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- strcpy(prevWord, "");
- }
- /***************************************/
- if (!isspacechar(ch)) visibleChars++;
- }
- /***************************************/
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-/***************************************/
-static const char * const FortranWordLists[] = {
- "Primary keywords and identifiers",
- "Intrinsic functions",
- "Extended and user defined functions",
- 0,
-};
-/***************************************/
-static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
-}
-/***************************************/
-static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-/***************************************/
-static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- FoldFortranDoc(startPos, length, initStyle,styler, false);
-}
-/***************************************/
-static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- FoldFortranDoc(startPos, length, initStyle,styler, true);
-}
-/***************************************/
-LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists);
-LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexGAP.cxx
- ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
- ** http://www.gap-system.org
- **/
-// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsGAPOperator(char ch) {
- if (isalnum(ch)) return false;
- if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
- ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
- ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
- ch == ')' || ch == ';' || ch == '[' || ch == ']' ||
- ch == '{' || ch == '}' || ch == ':' )
- return true;
- return false;
-}
-
-static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(styler[start + i]);
- i++;
- }
- s[i] = '\0';
-}
-
-static void ColouriseGAPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords1 = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- // Do not leak onto next line
- if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- // Prevent SCE_GAP_STRINGEOL from leaking back to previous line
- if ( sc.atLineStart ) {
- if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);
- if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);
- }
-
- // Handle line continuation generically
- if (sc.ch == '\\' ) {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate
- switch (sc.state) {
- case SCE_GAP_OPERATOR :
- sc.SetState(SCE_GAP_DEFAULT);
- break;
-
- case SCE_GAP_NUMBER :
- if (!IsADigit(sc.ch)) {
- if (sc.ch == '\\') {
- if (!sc.atLineEnd) {
- if (!IsADigit(sc.chNext)) {
- sc.Forward();
- sc.ChangeState(SCE_GAP_IDENTIFIER);
- }
- }
- } else if (isalpha(sc.ch) || sc.ch == '_') {
- sc.ChangeState(SCE_GAP_IDENTIFIER);
- }
- else sc.SetState(SCE_GAP_DEFAULT);
- }
- break;
-
- case SCE_GAP_IDENTIFIER :
- if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {
- if (sc.ch == '\\') sc.Forward();
- else {
- char s[1000];
- sc.GetCurrent(s, sizeof(s));
- if (keywords1.InList(s)) {
- sc.ChangeState(SCE_GAP_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_GAP_KEYWORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_GAP_KEYWORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_GAP_KEYWORD4);
- }
- sc.SetState(SCE_GAP_DEFAULT);
- }
- }
- break;
-
- case SCE_GAP_COMMENT :
- if (sc.atLineEnd) {
- sc.SetState(SCE_GAP_DEFAULT);
- }
- break;
-
- case SCE_GAP_STRING:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_GAP_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_GAP_DEFAULT);
- }
- break;
-
- case SCE_GAP_CHAR:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_GAP_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_GAP_DEFAULT);
- }
- break;
-
- case SCE_GAP_STRINGEOL:
- if (sc.atLineStart) {
- sc.SetState(SCE_GAP_DEFAULT);
- }
- break;
- }
-
- // Determine if a new state should be entered
- if (sc.state == SCE_GAP_DEFAULT) {
- if (IsGAPOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_GAP_OPERATOR);
- }
- else if (IsADigit(sc.ch)) {
- sc.SetState(SCE_GAP_NUMBER);
- } else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') {
- sc.SetState(SCE_GAP_IDENTIFIER);
- if (sc.ch == '\\') sc.Forward();
- } else if (sc.ch == '#') {
- sc.SetState(SCE_GAP_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_GAP_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_GAP_CHAR);
- }
- }
-
- }
- sc.Complete();
-}
-
-static int ClassifyFoldPointGAP(const char* s) {
- int level = 0;
- if (strcmp(s, "function") == 0 ||
- strcmp(s, "do") == 0 ||
- strcmp(s, "if") == 0 ||
- strcmp(s, "repeat") == 0 ) {
- level = 1;
- } else if (strcmp(s, "end") == 0 ||
- strcmp(s, "od") == 0 ||
- strcmp(s, "fi") == 0 ||
- strcmp(s, "until") == 0 ) {
- level = -1;
- }
- return level;
-}
-
-static void FoldGAPDoc( unsigned int startPos, int length, int initStyle, WordList** , Accessor &styler) {
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
-
- int lastStart = 0;
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) {
- // Store last word start point.
- lastStart = i;
- }
-
- if (stylePrev == SCE_GAP_KEYWORD) {
- if(iswordchar(ch) && !iswordchar(chNext)) {
- char s[100];
- GetRange(lastStart, i, styler, s, sizeof(s));
- levelCurrent += ClassifyFoldPointGAP(s);
- }
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const GAPWordListDesc[] = {
- "Keywords 1",
- "Keywords 2",
- "Keywords 3 (unused)",
- "Keywords 4 (unused)",
- 0
-};
-
-LexerModule lmGAP(
- SCLEX_GAP,
- ColouriseGAPDoc,
- "gap",
- FoldGAPDoc,
- GAPWordListDesc);
+#!/usr/bin/env python
# LexGen.py - implemented 2002 by Neil Hodgson neilh@scintilla.org
# Released to the public domain.
modules.append(l.split()[1])
return modules
+# Properties that start with lexer. or fold. are automatically found but there are some
+# older properties that don't follow this pattern so must be explicitly listed.
knownIrregularProperties = [
"fold",
"styling.within.preprocessor",
properties = {}
f = open(lexFile)
for l in f.readlines():
- if "GetProperty" in l:
+ if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l:
l = l.strip()
if not l.startswith("//"): # Drop comments
propertyName = l.split("\"")[1]
# Only allow lower case property names
name = propertyName
documents[name] = ""
+ elif "DefineProperty" in l and "\"" in l:
+ propertyName = l.split("\"")[1]
+ if propertyName.lower() == propertyName:
+ # Only allow lower case property names
+ name = propertyName
+ documents[name] = ""
elif name:
if l.startswith("//"):
if documents[name]:
documents[name] += " "
documents[name] += l[2:].strip()
+ elif l.startswith("\""):
+ l = l[1:].strip()
+ if l.endswith(";"):
+ l = l[:-1].strip()
+ if l.endswith(")"):
+ l = l[:-1].strip()
+ if l.endswith("\""):
+ l = l[:-1]
+ # Fix escaped double quotes
+ l = l.replace("\\\"", "\"")
+ documents[name] += l
else:
name = ""
+ for name in list(documents.keys()):
+ if documents[name] == "":
+ del documents[name]
return documents
def ciCompare(a,b):
def ciKey(a):
return a.lower()
-
+
def sortListInsensitive(l):
try: # Try key function
l.sort(key=ciKey)
except TypeError: # Earlier version of Python, so use comparison function
l.sort(ciCompare)
+def UpdateLineInFile(path, linePrefix, lineReplace):
+ lines = []
+ with open(path, "r") as f:
+ for l in f.readlines():
+ l = l.rstrip()
+ if l.startswith(linePrefix):
+ lines.append(lineReplace)
+ else:
+ lines.append(l)
+ contents = NATIVE.join(lines) + NATIVE
+ UpdateFile(path, contents)
+
+def UpdateVersionNumbers(root):
+ with open(root + "scintilla/version.txt") as f:
+ version = f.read()
+ versionDotted = version[0] + '.' + version[1] + '.' + version[2]
+ versionCommad = version[0] + ', ' + version[1] + ', ' + version[2] + ', 0'
+
+ UpdateLineInFile(root + "scintilla/win32/ScintRes.rc", "#define VERSION_SCINTILLA",
+ "#define VERSION_SCINTILLA \"" + versionDotted + "\"")
+ UpdateLineInFile(root + "scintilla/win32/ScintRes.rc", "#define VERSION_WORDS",
+ "#define VERSION_WORDS " + versionCommad)
+ UpdateLineInFile(root + "scintilla/qt/ScintillaEditBase/ScintillaEditBase.pro",
+ "VERSION =",
+ "VERSION = " + versionDotted)
+ UpdateLineInFile(root + "scintilla/qt/ScintillaEdit/ScintillaEdit.pro",
+ "VERSION =",
+ "VERSION = " + versionDotted)
+ UpdateLineInFile(root + "scintilla/doc/ScintillaDownload.html", " Release",
+ " Release " + versionDotted)
+ UpdateLineInFile(root + "scintilla/doc/index.html",
+ ' <font color="#FFCC99" size="3"> Release version',
+ ' <font color="#FFCC99" size="3"> Release version ' + versionDotted + '<br />')
+
+ if os.path.exists(root + "scite"):
+ UpdateLineInFile(root + "scite/src/SciTE.h", "#define VERSION_SCITE",
+ "#define VERSION_SCITE \"" + versionDotted + "\"")
+ UpdateLineInFile(root + "scite/src/SciTE.h", "#define VERSION_WORDS",
+ "#define VERSION_WORDS " + versionCommad)
+ UpdateLineInFile(root + "scite/doc/SciTEDownload.html", " Release",
+ " Release " + versionDotted)
+ UpdateLineInFile(root + "scite/doc/SciTE.html",
+ ' <font color="#FFCC99" size="3"> Release version',
+ ' <font color="#FFCC99" size="3"> Release version ' + versionDotted + '<br />')
+
def RegenerateAll():
root="../../"
# Find all the lexer source code files
- lexFilePaths = glob.glob(root + "scintilla/src/Lex*.cxx")
+ lexFilePaths = glob.glob(root + "scintilla/lexers/Lex*.cxx")
sortListInsensitive(lexFilePaths)
lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
print(lexFiles)
for k in documents.keys():
propertyDocuments[k] = documents[k]
sortListInsensitive(lexerModules)
- del lexerProperties["fold.comment.python"]
lexerProperties = list(lexerProperties.keys())
sortListInsensitive(lexerProperties)
sortListInsensitive(documentProperties)
propertiesHTML = []
for k in documentProperties:
- propertiesHTML.append("\t<tr>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" %
- (k, propertyDocuments[k]))
-
+ propertiesHTML.append("\t<tr id='property-%s'>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" %
+ (k, k, propertyDocuments[k]))
+
# Find all the SciTE properties files
otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"]
if os.path.exists(root + "scite"):
sortListInsensitive(propFiles)
print(propFiles)
- Regenerate(root + "scintilla/src/KeyWords.cxx", "//", NATIVE, lexerModules)
- Regenerate(root + "scintilla/win32/makefile", "#", NATIVE, lexFiles)
+ Regenerate(root + "scintilla/src/Catalogue.cxx", "//", NATIVE, lexerModules)
Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
- # Use Unix EOLs for gtk Makefiles so they work for Linux users when
- # extracted from the Scintilla source ZIP (typically created on
- # Windows).
- Regenerate(root + "scintilla/gtk/makefile", "#", LF, lexFiles)
- Regenerate(root + "scintilla/gtk/scintilla.mak", "#", NATIVE, lexFiles)
- Regenerate(root + "scintilla/macosx/makefile", "#", LF, lexFiles)
if os.path.exists(root + "scite"):
- Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
- Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)
+ Regenerate(root + "scite/win32/makefile", "#", NATIVE, propFiles)
+ Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, propFiles)
Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties)
Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", NATIVE, propertiesHTML)
Generate(root + "scite/boundscheck/vcproj.gen",
root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
+ UpdateVersionNumbers(root)
+
RegenerateAll()
+++ /dev/null
-// Scintilla source code edit control
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
-/*
-This is the Lexer for Gui4Cli, included in SciLexer.dll
-- by d. Keletsekis, 2/10/2003
-
-To add to SciLexer.dll:
-1. Add the values below to INCLUDE\Scintilla.iface
-2. Run the include/HFacer.py script
-3. Run the src/lexGen.py script
-
-val SCE_GC_DEFAULT=0
-val SCE_GC_COMMENTLINE=1
-val SCE_GC_COMMENTBLOCK=2
-val SCE_GC_GLOBAL=3
-val SCE_GC_EVENT=4
-val SCE_GC_ATTRIBUTE=5
-val SCE_GC_CONTROL=6
-val SCE_GC_COMMAND=7
-val SCE_GC_STRING=8
-val SCE_GC_OPERATOR=9
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-#define debug Platform::DebugPrintf
-
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
-}
-
-inline bool isGCOperator(int ch)
-{ if (isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
- ch == '(' || ch == ')' || ch == '=' || ch == '%' ||
- ch == '[' || ch == ']' || ch == '<' || ch == '>' ||
- ch == ',' || ch == ';' || ch == ':')
- return true;
- return false;
-}
-
-#define isSpace(x) ((x)==' ' || (x)=='\t')
-#define isNL(x) ((x)=='\n' || (x)=='\r')
-#define isSpaceOrNL(x) (isSpace(x) || isNL(x))
-#define BUFFSIZE 500
-#define isFoldPoint(x) ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)
-
-static void colorFirstWord(WordList *keywordlists[], Accessor &styler,
- StyleContext *sc, char *buff, int length, int)
-{
- int c = 0;
- while (sc->More() && isSpaceOrNL(sc->ch))
- { sc->Forward();
- }
- styler.ColourTo(sc->currentPos - 1, sc->state);
-
- if (!IsAWordChar(sc->ch)) // comment, marker, etc..
- return;
-
- while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))
- { buff[c] = static_cast<char>(sc->ch);
- ++c; sc->Forward();
- }
- buff[c] = '\0';
- char *p = buff;
- while (*p) // capitalize..
- { if (islower(*p)) *p = static_cast<char>(toupper(*p));
- ++p;
- }
-
- WordList &kGlobal = *keywordlists[0]; // keyword lists set by the user
- WordList &kEvent = *keywordlists[1];
- WordList &kAttribute = *keywordlists[2];
- WordList &kControl = *keywordlists[3];
- WordList &kCommand = *keywordlists[4];
-
- int state = 0;
- // int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
- // debug ("line = %d, level = %d", line, level);
-
- if (kGlobal.InList(buff)) state = SCE_GC_GLOBAL;
- else if (kAttribute.InList(buff)) state = SCE_GC_ATTRIBUTE;
- else if (kControl.InList(buff)) state = SCE_GC_CONTROL;
- else if (kCommand.InList(buff)) state = SCE_GC_COMMAND;
- else if (kEvent.InList(buff)) state = SCE_GC_EVENT;
-
- if (state)
- { sc->ChangeState(state);
- styler.ColourTo(sc->currentPos - 1, sc->state);
- sc->ChangeState(SCE_GC_DEFAULT);
- }
- else
- { sc->ChangeState(SCE_GC_DEFAULT);
- styler.ColourTo(sc->currentPos - 1, sc->state);
- }
-}
-
-// Main colorizing function called by Scintilla
-static void
-ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler)
-{
- styler.StartAt(startPos);
-
- int quotestart = 0, oldstate, currentline = styler.GetLine(startPos);
- styler.StartSegment(startPos);
- bool noforward;
- char buff[BUFFSIZE+1]; // buffer for command name
-
- StyleContext sc(startPos, length, initStyle, styler);
- buff[0] = '\0'; // cbuff = 0;
-
- if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..
- colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
-
- while (sc.More())
- { noforward = 0;
-
- switch (sc.ch)
- {
- case '/':
- if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)
- break;
- if (sc.chNext == '/') // line comment
- { sc.SetState (SCE_GC_COMMENTLINE);
- sc.Forward();
- styler.ColourTo(sc.currentPos, sc.state);
- }
- else if (sc.chNext == '*') // block comment
- { sc.SetState(SCE_GC_COMMENTBLOCK);
- sc.Forward();
- styler.ColourTo(sc.currentPos, sc.state);
- }
- else
- styler.ColourTo(sc.currentPos, sc.state);
- break;
-
- case '*': // end of comment block, or operator..
- if (sc.state == SCE_GC_STRING)
- break;
- if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')
- { sc.Forward();
- styler.ColourTo(sc.currentPos, sc.state);
- sc.ChangeState (SCE_GC_DEFAULT);
- }
- else
- styler.ColourTo(sc.currentPos, sc.state);
- break;
-
- case '\'': case '\"': // strings..
- if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)
- break;
- if (sc.state == SCE_GC_STRING)
- { if (sc.ch == quotestart) // match same quote char..
- { styler.ColourTo(sc.currentPos, sc.state);
- sc.ChangeState(SCE_GC_DEFAULT);
- quotestart = 0;
- } }
- else
- { styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.ChangeState(SCE_GC_STRING);
- quotestart = sc.ch;
- }
- break;
-
- case ';': // end of commandline character
- if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
- sc.state != SCE_GC_STRING)
- {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
- sc.ChangeState(SCE_GC_DEFAULT);
- sc.Forward();
- colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
- noforward = 1; // don't move forward - already positioned at next char..
- }
- break;
-
- case '+': case '-': case '=': case '!': // operators..
- case '<': case '>': case '&': case '|': case '$':
- if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
- sc.state != SCE_GC_STRING)
- {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
- sc.ChangeState(SCE_GC_DEFAULT);
- }
- break;
-
- case '\\': // escape - same as operator, but also mark in strings..
- if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)
- {
- oldstate = sc.state;
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.Forward(); // mark also the next char..
- styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
- sc.ChangeState(oldstate);
- }
- break;
-
- case '\n': case '\r':
- ++currentline;
- if (sc.state == SCE_GC_COMMENTLINE)
- { styler.ColourTo(sc.currentPos, sc.state);
- sc.ChangeState (SCE_GC_DEFAULT);
- }
- else if (sc.state != SCE_GC_COMMENTBLOCK)
- { colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
- noforward = 1; // don't move forward - already positioned at next char..
- }
- break;
-
-// case ' ': case '\t':
-// default :
- }
-
- if (!noforward) sc.Forward();
-
- }
- sc.Complete();
-}
-
-// Main folding function called by Scintilla - (based on props (.ini) files function)
-static void FoldGui4Cli(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler)
-{
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
-
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- bool headerPoint = false;
-
- for (unsigned int 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_GC_EVENT || style == SCE_GC_GLOBAL)
- { headerPoint = true; // fold at events and globals
- }
-
- if (atEOL)
- { int lev = SC_FOLDLEVELBASE+1;
-
- if (headerPoint)
- lev = SC_FOLDLEVELBASE;
-
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
-
- if (headerPoint)
- lev |= SC_FOLDLEVELHEADERFLAG;
-
- if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct
- { styler.SetLevel(lineCurrent, lev);
- }
-
- lineCurrent++; // re-initialize our flags
- visibleChars = 0;
- headerPoint = false;
- }
-
- if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))
- visibleChars++;
- }
-
- int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, lev | flagsNext);
-}
-
-// I have no idea what these are for.. probably accessible by some message.
-static const char * const gui4cliWordListDesc[] = {
- "Globals", "Events", "Attributes", "Control", "Commands",
- 0
-};
-
-// Declare language & pass our function pointers to Scintilla
-LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc);
-
-#undef debug
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexHTML.cxx
- ** Lexer for HTML.
- **/
-// Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
-#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
-#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
-
-enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };
-enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
-
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-inline bool IsOperator(int ch) {
- if (isascii(ch) && isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
- ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
- ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
- ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
- ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
- ch == '?' || ch == '!' || ch == '.' || ch == '~')
- return true;
- return false;
-}
-
-static inline int MakeLowerCase(int ch) {
- if (ch < 'A' || ch > 'Z')
- return ch;
- else
- return ch - 'A' + 'a';
-}
-
-static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
- size_t i = 0;
- for (; (i < end - start + 1) && (i < len-1); i++) {
- s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
- }
- s[i] = '\0';
-}
-
-static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
-
- size_t i = 0;
- for (; i < sLen-1; i++) {
- char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
- if ((i == 0) && !IsAWordStart(ch))
- break;
- if ((i > 0) && !IsAWordChar(ch))
- break;
- s[i] = ch;
- }
- s[i] = '\0';
-
- return s;
-}
-
-static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
- char s[100];
- GetTextSegment(styler, start, end, s, sizeof(s));
- //Platform::DebugPrintf("Scripting indicator [%s]\n", s);
- if (strstr(s, "src")) // External script
- return eScriptNone;
- if (strstr(s, "vbs"))
- return eScriptVBS;
- if (strstr(s, "pyth"))
- return eScriptPython;
- if (strstr(s, "javas"))
- return eScriptJS;
- if (strstr(s, "jscr"))
- return eScriptJS;
- if (strstr(s, "php"))
- return eScriptPHP;
- if (strstr(s, "xml")) {
- const char *xml = strstr(s, "xml");
- for (const char *t=s; t<xml; t++) {
- if (!IsASpace(*t)) {
- return prevValue;
- }
- }
- return eScriptXML;
- }
-
- return prevValue;
-}
-
-static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) {
- int iResult = 0;
- char s[100];
- GetTextSegment(styler, start, end, s, sizeof(s));
- if (0 == strncmp(s, "php", 3)) {
- iResult = 3;
- }
-
- return iResult;
-}
-
-static script_type ScriptOfState(int state) {
- if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
- return eScriptPython;
- } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
- return eScriptVBS;
- } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
- return eScriptJS;
- } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) {
- return eScriptPHP;
- } else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
- return eScriptSGML;
- } else if (state == SCE_H_SGML_BLOCK_DEFAULT) {
- return eScriptSGMLblock;
- } else {
- return eScriptNone;
- }
-}
-
-static int statePrintForState(int state, script_mode inScriptType) {
- int StateToPrint = state;
-
- if (state >= SCE_HJ_START) {
- if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
- StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
- } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
- StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
- } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
- StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
- }
- }
-
- return StateToPrint;
-}
-
-static int stateForPrintState(int StateToPrint) {
- int state;
-
- if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) {
- state = StateToPrint - SCE_HA_PYTHON;
- } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {
- state = StateToPrint - SCE_HA_VBS;
- } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) {
- state = StateToPrint - SCE_HA_JS;
- } else {
- state = StateToPrint;
- }
-
- return state;
-}
-
-static inline bool IsNumber(unsigned int start, Accessor &styler) {
- return IsADigit(styler[start]) || (styler[start] == '.') ||
- (styler[start] == '-') || (styler[start] == '#');
-}
-
-static inline bool isStringState(int state) {
- bool bResult;
-
- switch (state) {
- case SCE_HJ_DOUBLESTRING:
- case SCE_HJ_SINGLESTRING:
- case SCE_HJA_DOUBLESTRING:
- case SCE_HJA_SINGLESTRING:
- case SCE_HB_STRING:
- case SCE_HBA_STRING:
- case SCE_HP_STRING:
- case SCE_HP_CHARACTER:
- case SCE_HP_TRIPLE:
- case SCE_HP_TRIPLEDOUBLE:
- case SCE_HPA_STRING:
- case SCE_HPA_CHARACTER:
- case SCE_HPA_TRIPLE:
- case SCE_HPA_TRIPLEDOUBLE:
- case SCE_HPHP_HSTRING:
- case SCE_HPHP_SIMPLESTRING:
- case SCE_HPHP_HSTRING_VARIABLE:
- case SCE_HPHP_COMPLEX_VARIABLE:
- bResult = true;
- break;
- default :
- bResult = false;
- break;
- }
- return bResult;
-}
-
-static inline bool stateAllowsTermination(int state) {
- bool allowTermination = !isStringState(state);
- if (allowTermination) {
- switch (state) {
- case SCE_HB_COMMENTLINE:
- case SCE_HPHP_COMMENT:
- case SCE_HP_COMMENTLINE:
- case SCE_HPA_COMMENTLINE:
- allowTermination = false;
- }
- }
- return allowTermination;
-}
-
-// not really well done, since it's only comments that should lex the %> and <%
-static inline bool isCommentASPState(int state) {
- bool bResult;
-
- switch (state) {
- case SCE_HJ_COMMENT:
- case SCE_HJ_COMMENTLINE:
- case SCE_HJ_COMMENTDOC:
- case SCE_HB_COMMENTLINE:
- case SCE_HP_COMMENTLINE:
- case SCE_HPHP_COMMENT:
- case SCE_HPHP_COMMENTLINE:
- bResult = true;
- break;
- default :
- bResult = false;
- break;
- }
- return bResult;
-}
-
-static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
- bool wordIsNumber = IsNumber(start, styler);
- char chAttr = SCE_H_ATTRIBUTEUNKNOWN;
- if (wordIsNumber) {
- chAttr = SCE_H_NUMBER;
- } else {
- char s[100];
- GetTextSegment(styler, start, end, s, sizeof(s));
- if (keywords.InList(s))
- chAttr = SCE_H_ATTRIBUTE;
- }
- if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords)
- // No keywords -> all are known
- chAttr = SCE_H_ATTRIBUTE;
- styler.ColourTo(end, chAttr);
-}
-
-static int classifyTagHTML(unsigned int start, unsigned int end,
- WordList &keywords, Accessor &styler, bool &tagDontFold,
- bool caseSensitive, bool isXml, bool allowScripts) {
- char s[30 + 2];
- // Copy after the '<'
- unsigned int i = 0;
- for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
- char ch = styler[cPos];
- if ((ch != '<') && (ch != '/')) {
- s[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch));
- }
- }
-
- //The following is only a quick hack, to see if this whole thing would work
- //we first need the tagname with a trailing space...
- s[i] = ' ';
- s[i+1] = '\0';
-
- // if the current language is XML, I can fold any tag
- // if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)
- //...to find it in the list of no-container-tags
- tagDontFold = (!isXml) && (NULL != strstr("meta link img area br hr input ", s));
-
- //now we can remove the trailing space
- s[i] = '\0';
-
- // No keywords -> all are known
- char chAttr = SCE_H_TAGUNKNOWN;
- if (s[0] == '!') {
- chAttr = SCE_H_SGML_DEFAULT;
- } else if (!keywords || keywords.InList(s)) {
- chAttr = SCE_H_TAG;
- }
- styler.ColourTo(end, chAttr);
- if (chAttr == SCE_H_TAG) {
- if (allowScripts && 0 == strcmp(s, "script")) {
- // check to see if this is a self-closing tag by sniffing ahead
- bool isSelfClose = false;
- for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
- char ch = styler.SafeGetCharAt(cPos, '\0');
- if (ch == '\0' || ch == '>')
- break;
- else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') {
- isSelfClose = true;
- break;
- }
- }
-
- // do not enter a script state if the tag self-closed
- if (!isSelfClose)
- chAttr = SCE_H_SCRIPT;
- } else if (!isXml && 0 == strcmp(s, "comment")) {
- chAttr = SCE_H_COMMENT;
- }
- }
- return chAttr;
-}
-
-static void classifyWordHTJS(unsigned int start, unsigned int end,
- WordList &keywords, Accessor &styler, script_mode inScriptType) {
- char chAttr = SCE_HJ_WORD;
- bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
- if (wordIsNumber)
- chAttr = SCE_HJ_NUMBER;
- else {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- }
- s[i] = '\0';
- if (keywords.InList(s))
- chAttr = SCE_HJ_KEYWORD;
- }
- styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
-}
-
-static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) {
- char chAttr = SCE_HB_IDENTIFIER;
- bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
- if (wordIsNumber)
- chAttr = SCE_HB_NUMBER;
- else {
- char s[100];
- GetTextSegment(styler, start, end, s, sizeof(s));
- if (keywords.InList(s)) {
- chAttr = SCE_HB_WORD;
- if (strcmp(s, "rem") == 0)
- chAttr = SCE_HB_COMMENTLINE;
- }
- }
- styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
- if (chAttr == SCE_HB_COMMENTLINE)
- return SCE_HB_COMMENTLINE;
- else
- return SCE_HB_DEFAULT;
-}
-
-static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType) {
- bool wordIsNumber = IsADigit(styler[start]);
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- }
- s[i] = '\0';
- char chAttr = SCE_HP_IDENTIFIER;
- if (0 == strcmp(prevWord, "class"))
- chAttr = SCE_HP_CLASSNAME;
- else if (0 == strcmp(prevWord, "def"))
- chAttr = SCE_HP_DEFNAME;
- else if (wordIsNumber)
- chAttr = SCE_HP_NUMBER;
- else if (keywords.InList(s))
- chAttr = SCE_HP_WORD;
- styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
- strcpy(prevWord, s);
-}
-
-// Update the word colour to default or keyword
-// Called when in a PHP word
-static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
- char chAttr = SCE_HPHP_DEFAULT;
- bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1]));
- if (wordIsNumber)
- chAttr = SCE_HPHP_NUMBER;
- else {
- char s[100];
- GetTextSegment(styler, start, end, s, sizeof(s));
- if (keywords.InList(s))
- chAttr = SCE_HPHP_WORD;
- }
- styler.ColourTo(end, chAttr);
-}
-
-static bool isWordHSGML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- }
- s[i] = '\0';
- return keywords.InList(s);
-}
-
-static bool isWordCdata(unsigned int start, unsigned int end, Accessor &styler) {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- }
- s[i] = '\0';
- return (0 == strcmp(s, "[CDATA["));
-}
-
-// Return the first state to reach when entering a scripting language
-static int StateForScript(script_type scriptLanguage) {
- int Result;
- switch (scriptLanguage) {
- case eScriptVBS:
- Result = SCE_HB_START;
- break;
- case eScriptPython:
- Result = SCE_HP_START;
- break;
- case eScriptPHP:
- Result = SCE_HPHP_DEFAULT;
- break;
- case eScriptXML:
- Result = SCE_H_TAGUNKNOWN;
- break;
- case eScriptSGML:
- Result = SCE_H_SGML_DEFAULT;
- break;
- case eScriptComment:
- Result = SCE_H_COMMENT;
- break;
- default :
- Result = SCE_HJ_START;
- break;
- }
- return Result;
-}
-
-static inline bool ishtmlwordchar(int ch) {
- return !isascii(ch) ||
- (isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
-}
-
-static inline bool issgmlwordchar(int ch) {
- return !isascii(ch) ||
- (isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
-}
-
-static inline bool IsPhpWordStart(int ch) {
- return (isascii(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f);
-}
-
-static inline bool IsPhpWordChar(int ch) {
- return IsADigit(ch) || IsPhpWordStart(ch);
-}
-
-static bool InTagState(int state) {
- return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
- state == SCE_H_SCRIPT ||
- state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN ||
- state == SCE_H_NUMBER || state == SCE_H_OTHER ||
- state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING;
-}
-
-static bool IsCommentState(const int state) {
- return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
-}
-
-static bool IsScriptCommentState(const int state) {
- return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT ||
- state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
-}
-
-static bool isLineEnd(int ch) {
- return ch == '\r' || ch == '\n';
-}
-
-static bool isOKBeforeRE(int ch) {
- return (ch == '(') || (ch == '=') || (ch == ',');
-}
-
-static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
- if (strlen(blockType) == 0) {
- return ((ch == '%') && (chNext == '>'));
- } else if ((0 == strcmp(blockType, "inherit")) ||
- (0 == strcmp(blockType, "namespace")) ||
- (0 == strcmp(blockType, "include")) ||
- (0 == strcmp(blockType, "page"))) {
- return ((ch == '/') && (chNext == '>'));
- } else if (0 == strcmp(blockType, "%")) {
- return isLineEnd(ch);
- } else if (0 == strcmp(blockType, "{")) {
- return ch == '}';
- } else {
- return (ch == '>');
- }
-}
-
-static bool isPHPStringState(int state) {
- return
- (state == SCE_HPHP_HSTRING) ||
- (state == SCE_HPHP_SIMPLESTRING) ||
- (state == SCE_HPHP_HSTRING_VARIABLE) ||
- (state == SCE_HPHP_COMPLEX_VARIABLE);
-}
-
-static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler, bool &isSimpleString) {
- int j;
- const int beginning = i - 1;
- bool isValidSimpleString = false;
-
- while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
- i++;
-
- char ch = styler.SafeGetCharAt(i);
- const char chNext = styler.SafeGetCharAt(i + 1);
- if (!IsPhpWordStart(ch)) {
- if (ch == '\'' && IsPhpWordStart(chNext)) {
- i++;
- ch = chNext;
- isSimpleString = true;
- } else {
- phpStringDelimiter[0] = '\0';
- return beginning;
- }
- }
- phpStringDelimiter[0] = ch;
- i++;
-
- for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) {
- if (!IsPhpWordChar(styler[j])) {
- if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) {
- isValidSimpleString = true;
- j++;
- break;
- } else {
- phpStringDelimiter[0] = '\0';
- return beginning;
- }
- }
- if (j - i < phpStringDelimiterSize - 2)
- phpStringDelimiter[j-i+1] = styler[j];
- else
- i++;
- }
- if (isSimpleString && !isValidSimpleString) {
- phpStringDelimiter[0] = '\0';
- return beginning;
- }
- phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0';
- return j - 1;
-}
-
-static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler, bool isXml) {
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords
-
- // Lexer for HTML requires more lexical states (8 bits worth) than most lexers
- styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
- char prevWord[200];
- prevWord[0] = '\0';
- char nextWord[200];
- nextWord[0] = '\0';
- char phpStringDelimiter[200]; // PHP is not limited in length, we are
- phpStringDelimiter[0] = '\0';
- int StateToPrint = initStyle;
- int state = stateForPrintState(StateToPrint);
- char makoBlockType[200];
- makoBlockType[0] = '\0';
-
- // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
- if (InTagState(state)) {
- while ((startPos > 0) && (InTagState(styler.StyleAt(startPos - 1)))) {
- startPos--;
- length++;
- }
- state = SCE_H_DEFAULT;
- }
- // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
- if (isPHPStringState(state)) {
- while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
- startPos--;
- length++;
- state = styler.StyleAt(startPos);
- }
- if (startPos == 0)
- state = SCE_H_DEFAULT;
- }
- styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
-
- int lineCurrent = styler.GetLine(startPos);
- int lineState;
- if (lineCurrent > 0) {
- lineState = styler.GetLineState(lineCurrent);
- } else {
- // Default client and ASP scripting language is JavaScript
- lineState = eScriptJS << 8;
-
- // property asp.default.language
- // Script in ASP code is initially assumed to be in JavaScript.
- // To change this to VBScript set asp.default.language to 2. Python is 3.
- lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
- }
- script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
- bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag
- bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag
- bool tagDontFold = false; //some HTML tags should not be folded
- script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name
- script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name
- int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
-
- script_type scriptLanguage = ScriptOfState(state);
- // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
- if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
- scriptLanguage = eScriptComment;
- }
-
- // property fold.html
- // Folding is turned on or off for HTML and XML files with this option.
- // The fold option must also be on for folding to occur.
- const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
-
- const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
-
- // property fold.html.preprocessor
- // Folding is turned on or off for scripts embedded in HTML files with this option.
- // The default is on.
- const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
-
- const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- // property fold.hypertext.comment
- // Allow folding for comments in scripts embedded in HTML.
- // The default is off.
- const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
-
- // property fold.hypertext.heredoc
- // Allow folding for heredocs in scripts embedded in HTML.
- // The default is off.
- const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
-
- // property html.tags.case.sensitive
- // For XML and HTML, setting this property to 1 will make tags match in a case
- // sensitive way which is the expected behaviour for XML and XHTML.
- const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
-
- // property lexer.xml.allow.scripts
- // Set to 0 to disable scripts in XML.
- const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
-
- // property lexer.html.mako
- // Set to 1 to enable the mako template language.
- const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
-
- const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
- const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
- const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
-
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- int visibleChars = 0;
- int lineStartVisibleChars = 0;
-
- int chPrev = ' ';
- int ch = ' ';
- int chPrevNonWhite = ' ';
- // look back to set chPrevNonWhite properly for better regex colouring
- if (scriptLanguage == eScriptJS && startPos > 0) {
- int back = startPos;
- int style = 0;
- while (--back) {
- style = styler.StyleAt(back);
- if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)
- // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
- break;
- }
- if (style == SCE_HJ_SYMBOLS) {
- chPrevNonWhite = static_cast<unsigned char>(styler.SafeGetCharAt(back));
- }
- }
-
- styler.StartSegment(startPos);
- const int lengthDoc = startPos + length;
- for (int i = startPos; i < lengthDoc; i++) {
- const int chPrev2 = chPrev;
- chPrev = ch;
- if (!IsASpace(ch) && state != SCE_HJ_COMMENT &&
- state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
- chPrevNonWhite = ch;
- ch = static_cast<unsigned char>(styler[i]);
- int chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- const int chNext2 = static_cast<unsigned char>(styler.SafeGetCharAt(i + 2));
-
- // Handle DBCS codepages
- if (styler.IsLeadByte(static_cast<char>(ch))) {
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if ((!IsASpace(ch) || !foldCompact) && fold)
- visibleChars++;
- if (!IsASpace(ch))
- lineStartVisibleChars++;
-
- // decide what is the current state to print (depending of the script tag)
- StateToPrint = statePrintForState(state, inScriptType);
-
- // handle script folding
- if (fold) {
- switch (scriptLanguage) {
- case eScriptJS:
- case eScriptPHP:
- //not currently supported case eScriptVBS:
-
- if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
- //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
- //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
- if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
- levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
- }
- } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
- levelCurrent--;
- }
- break;
- case eScriptPython:
- if (state != SCE_HP_COMMENTLINE) {
- if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) {
- levelCurrent++;
- } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) {
- // check if the number of tabs is lower than the level
- int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8;
- for (int j = 0; Findlevel > 0; j++) {
- char chTmp = styler.SafeGetCharAt(i + j + 1);
- if (chTmp == '\t') {
- Findlevel -= 8;
- } else if (chTmp == ' ') {
- Findlevel--;
- } else {
- break;
- }
- }
-
- if (Findlevel > 0) {
- levelCurrent -= Findlevel / 8;
- if (Findlevel % 8)
- levelCurrent--;
- }
- }
- }
- break;
- default:
- break;
- }
- }
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
- // Avoid triggering two times on Dos/Win
- // New line -> record any line state onto /next/ line
- if (fold) {
- int lev = levelPrev;
- if (visibleChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
-
- styler.SetLevel(lineCurrent, lev);
- visibleChars = 0;
- levelPrev = levelCurrent;
- }
- lineCurrent++;
- lineStartVisibleChars = 0;
- styler.SetLineState(lineCurrent,
- ((inScriptType & 0x03) << 0) |
- ((tagOpened & 0x01) << 2) |
- ((tagClosing & 0x01) << 3) |
- ((aspScript & 0x0F) << 4) |
- ((clientScript & 0x0F) << 8) |
- ((beforePreProc & 0xFF) << 12));
- }
-
- // Allow falling through to mako handling code if newline is going to end a block
- if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
- (!isMako || (0 != strcmp(makoBlockType, "%")))) {
- }
-
- // generic end of script processing
- else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
- // Check if it's the end of the script tag (or any other HTML tag)
- switch (state) {
- // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
- case SCE_H_DOUBLESTRING:
- case SCE_H_SINGLESTRING:
- case SCE_HJ_COMMENT:
- case SCE_HJ_COMMENTDOC:
- //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
- // the end of script marker from some JS interpreters.
- case SCE_HB_COMMENTLINE:
- case SCE_HBA_COMMENTLINE:
- case SCE_HJ_DOUBLESTRING:
- case SCE_HJ_SINGLESTRING:
- case SCE_HJ_REGEX:
- case SCE_HB_STRING:
- case SCE_HBA_STRING:
- case SCE_HP_STRING:
- case SCE_HP_TRIPLE:
- case SCE_HP_TRIPLEDOUBLE:
- case SCE_HPHP_HSTRING:
- case SCE_HPHP_SIMPLESTRING:
- case SCE_HPHP_COMMENT:
- case SCE_HPHP_COMMENTLINE:
- break;
- default :
- // check if the closing tag is a script tag
- if (const char *tag =
- state == SCE_HJ_COMMENTLINE || isXml ? "script" :
- state == SCE_H_COMMENT ? "comment" : 0) {
- int j = i + 2;
- int chr;
- do {
- chr = static_cast<int>(*tag++);
- } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++)));
- if (chr != 0) break;
- }
- // closing tag of the script (it's a closing HTML tag anyway)
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_TAGUNKNOWN;
- inScriptType = eHtml;
- scriptLanguage = eScriptNone;
- clientScript = eScriptJS;
- i += 2;
- visibleChars += 2;
- tagClosing = true;
- continue;
- }
- }
-
- /////////////////////////////////////
- // handle the start of PHP pre-processor = Non-HTML
- else if ((state != SCE_H_ASPAT) &&
- !isPHPStringState(state) &&
- (state != SCE_HPHP_COMMENT) &&
- (ch == '<') &&
- (chNext == '?') &&
- !IsScriptCommentState(state) ) {
- scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
- if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
- styler.ColourTo(i - 1, StateToPrint);
- beforePreProc = state;
- i++;
- visibleChars++;
- i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6);
- if (scriptLanguage == eScriptXML)
- styler.ColourTo(i, SCE_H_XMLSTART);
- else
- styler.ColourTo(i, SCE_H_QUESTION);
- state = StateForScript(scriptLanguage);
- if (inScriptType == eNonHtmlScript)
- inScriptType = eNonHtmlScriptPreProc;
- else
- inScriptType = eNonHtmlPreProc;
- // Fold whole script, but not if the XML first tag (all XML-like tags in this case)
- if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
- levelCurrent++;
- }
- // should be better
- ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
- continue;
- }
-
- // handle the start Mako template Python code
- else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
- (lineStartVisibleChars == 1 && ch == '%') ||
- (ch == '$' && chNext == '{') ||
- (ch == '<' && chNext == '/' && chNext2 == '%'))) {
- if (ch == '%')
- strcpy(makoBlockType, "%");
- else if (ch == '$')
- strcpy(makoBlockType, "{");
- else if (chNext == '/')
- GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
- else
- GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType));
- styler.ColourTo(i - 1, StateToPrint);
- beforePreProc = state;
- if (inScriptType == eNonHtmlScript)
- inScriptType = eNonHtmlScriptPreProc;
- else
- inScriptType = eNonHtmlPreProc;
-
- if (chNext == '/') {
- i += 2;
- visibleChars += 2;
- } else if (ch != '%') {
- i++;
- visibleChars++;
- }
- state = SCE_HP_START;
- scriptLanguage = eScriptPython;
- styler.ColourTo(i, SCE_H_ASP);
- if (foldHTMLPreprocessor && ch == '<')
- levelCurrent++;
-
- if (ch != '%' && ch != '$') {
- i += strlen(makoBlockType);
- visibleChars += strlen(makoBlockType);
- if (keywords4.InList(makoBlockType))
- styler.ColourTo(i, SCE_HP_WORD);
- else
- styler.ColourTo(i, SCE_H_TAGUNKNOWN);
- }
-
- ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
- continue;
- }
-
- // handle the start of ASP pre-processor = Non-HTML
- else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
- styler.ColourTo(i - 1, StateToPrint);
- beforePreProc = state;
- if (inScriptType == eNonHtmlScript)
- inScriptType = eNonHtmlScriptPreProc;
- else
- inScriptType = eNonHtmlPreProc;
-
- if (chNext2 == '@') {
- i += 2; // place as if it was the second next char treated
- visibleChars += 2;
- state = SCE_H_ASPAT;
- } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) {
- styler.ColourTo(i + 3, SCE_H_ASP);
- state = SCE_H_XCCOMMENT;
- scriptLanguage = eScriptVBS;
- continue;
- } else {
- if (chNext2 == '=') {
- i += 2; // place as if it was the second next char treated
- visibleChars += 2;
- } else {
- i++; // place as if it was the next char treated
- visibleChars++;
- }
-
- state = StateForScript(aspScript);
- }
- scriptLanguage = eScriptVBS;
- styler.ColourTo(i, SCE_H_ASP);
- // fold whole script
- if (foldHTMLPreprocessor)
- levelCurrent++;
- // should be better
- ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
- continue;
- }
-
- /////////////////////////////////////
- // handle the start of SGML language (DTD)
- else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
- (chPrev == '<') &&
- (ch == '!') &&
- (StateToPrint != SCE_H_CDATA) &&
- (!IsCommentState(StateToPrint)) &&
- (!IsScriptCommentState(StateToPrint)) ) {
- beforePreProc = state;
- styler.ColourTo(i - 2, StateToPrint);
- if ((chNext == '-') && (chNext2 == '-')) {
- state = SCE_H_COMMENT; // wait for a pending command
- styler.ColourTo(i + 2, SCE_H_COMMENT);
- i += 2; // follow styling after the --
- } else if (isWordCdata(i + 1, i + 7, styler)) {
- state = SCE_H_CDATA;
- } else {
- styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
- scriptLanguage = eScriptSGML;
- state = SCE_H_SGML_COMMAND; // wait for a pending command
- }
- // fold whole tag (-- when closing the tag)
- if (foldHTMLPreprocessor || (state == SCE_H_COMMENT))
- levelCurrent++;
- continue;
- }
-
- // handle the end of Mako Python code
- else if (isMako &&
- ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
- (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
- isMakoBlockEnd(ch, chNext, makoBlockType)) {
- if (state == SCE_H_ASPAT) {
- aspScript = segIsScriptingIndicator(styler,
- styler.GetStartSegment(), i - 1, aspScript);
- }
- if (state == SCE_HP_WORD) {
- classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
- } else {
- styler.ColourTo(i - 1, StateToPrint);
- }
- if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') {
- i++;
- visibleChars++;
- }
- if (0 != strcmp(makoBlockType, "%")) {
- styler.ColourTo(i, SCE_H_ASP);
- }
- state = beforePreProc;
- if (inScriptType == eNonHtmlScriptPreProc)
- inScriptType = eNonHtmlScript;
- else
- inScriptType = eHtml;
- if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
- levelCurrent--;
- }
- scriptLanguage = eScriptNone;
- continue;
- }
-
- // handle the end of a pre-processor = Non-HTML
- else if ((!isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
- (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
- (((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
- ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
- if (state == SCE_H_ASPAT) {
- aspScript = segIsScriptingIndicator(styler,
- styler.GetStartSegment(), i - 1, aspScript);
- }
- // Bounce out of any ASP mode
- switch (state) {
- case SCE_HJ_WORD:
- classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
- break;
- case SCE_HB_WORD:
- classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
- break;
- case SCE_HP_WORD:
- classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
- break;
- case SCE_HPHP_WORD:
- classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
- break;
- case SCE_H_XCCOMMENT:
- styler.ColourTo(i - 1, state);
- break;
- default :
- styler.ColourTo(i - 1, StateToPrint);
- break;
- }
- if (scriptLanguage != eScriptSGML) {
- i++;
- visibleChars++;
- }
- if (ch == '%')
- styler.ColourTo(i, SCE_H_ASP);
- else if (scriptLanguage == eScriptXML)
- styler.ColourTo(i, SCE_H_XMLEND);
- else if (scriptLanguage == eScriptSGML)
- styler.ColourTo(i, SCE_H_SGML_DEFAULT);
- else
- styler.ColourTo(i, SCE_H_QUESTION);
- state = beforePreProc;
- if (inScriptType == eNonHtmlScriptPreProc)
- inScriptType = eNonHtmlScript;
- else
- inScriptType = eHtml;
- // Unfold all scripting languages, except for XML tag
- if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
- levelCurrent--;
- }
- scriptLanguage = eScriptNone;
- continue;
- }
- /////////////////////////////////////
-
- switch (state) {
- case SCE_H_DEFAULT:
- if (ch == '<') {
- // in HTML, fold on tag open and unfold on tag close
- tagOpened = true;
- tagClosing = (chNext == '/');
- styler.ColourTo(i - 1, StateToPrint);
- if (chNext != '!')
- state = SCE_H_TAGUNKNOWN;
- } else if (ch == '&') {
- styler.ColourTo(i - 1, SCE_H_DEFAULT);
- state = SCE_H_ENTITY;
- }
- break;
- case SCE_H_SGML_DEFAULT:
- case SCE_H_SGML_BLOCK_DEFAULT:
-// if (scriptLanguage == eScriptSGMLblock)
-// StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
-
- if (ch == '\"') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_SGML_DOUBLESTRING;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_SGML_SIMPLESTRING;
- } else if ((ch == '-') && (chPrev == '-')) {
- if (static_cast<int>(styler.GetStartSegment()) <= (i - 2)) {
- styler.ColourTo(i - 2, StateToPrint);
- }
- state = SCE_H_SGML_COMMENT;
- } else if (isascii(ch) && isalpha(ch) && (chPrev == '%')) {
- styler.ColourTo(i - 2, StateToPrint);
- state = SCE_H_SGML_ENTITY;
- } else if (ch == '#') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_SGML_SPECIAL;
- } else if (ch == '[') {
- styler.ColourTo(i - 1, StateToPrint);
- scriptLanguage = eScriptSGMLblock;
- state = SCE_H_SGML_BLOCK_DEFAULT;
- } else if (ch == ']') {
- if (scriptLanguage == eScriptSGMLblock) {
- styler.ColourTo(i, StateToPrint);
- scriptLanguage = eScriptSGML;
- } else {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i, SCE_H_SGML_ERROR);
- }
- state = SCE_H_SGML_DEFAULT;
- } else if (scriptLanguage == eScriptSGMLblock) {
- if ((ch == '!') && (chPrev == '<')) {
- styler.ColourTo(i - 2, StateToPrint);
- styler.ColourTo(i, SCE_H_SGML_DEFAULT);
- state = SCE_H_SGML_COMMAND;
- } else if (ch == '>') {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i, SCE_H_SGML_DEFAULT);
- }
- }
- break;
- case SCE_H_SGML_COMMAND:
- if ((ch == '-') && (chPrev == '-')) {
- styler.ColourTo(i - 2, StateToPrint);
- state = SCE_H_SGML_COMMENT;
- } else if (!issgmlwordchar(ch)) {
- if (isWordHSGML(styler.GetStartSegment(), i - 1, keywords6, styler)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_SGML_1ST_PARAM;
- } else {
- state = SCE_H_SGML_ERROR;
- }
- }
- break;
- case SCE_H_SGML_1ST_PARAM:
- // wait for the beginning of the word
- if ((ch == '-') && (chPrev == '-')) {
- if (scriptLanguage == eScriptSGMLblock) {
- styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT);
- } else {
- styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
- }
- state = SCE_H_SGML_1ST_PARAM_COMMENT;
- } else if (issgmlwordchar(ch)) {
- if (scriptLanguage == eScriptSGMLblock) {
- styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT);
- } else {
- styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
- }
- // find the length of the word
- int size = 1;
- while (setHTMLWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(i + size))))
- size++;
- styler.ColourTo(i + size - 1, StateToPrint);
- i += size - 1;
- visibleChars += size - 1;
- ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
- if (scriptLanguage == eScriptSGMLblock) {
- state = SCE_H_SGML_BLOCK_DEFAULT;
- } else {
- state = SCE_H_SGML_DEFAULT;
- }
- continue;
- }
- break;
- case SCE_H_SGML_ERROR:
- if ((ch == '-') && (chPrev == '-')) {
- styler.ColourTo(i - 2, StateToPrint);
- state = SCE_H_SGML_COMMENT;
- }
- case SCE_H_SGML_DOUBLESTRING:
- if (ch == '\"') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_SGML_DEFAULT;
- }
- break;
- case SCE_H_SGML_SIMPLESTRING:
- if (ch == '\'') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_SGML_DEFAULT;
- }
- break;
- case SCE_H_SGML_COMMENT:
- if ((ch == '-') && (chPrev == '-')) {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_SGML_DEFAULT;
- }
- break;
- case SCE_H_CDATA:
- if ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_DEFAULT;
- levelCurrent--;
- }
- break;
- case SCE_H_COMMENT:
- if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_DEFAULT;
- levelCurrent--;
- }
- break;
- case SCE_H_SGML_1ST_PARAM_COMMENT:
- if ((ch == '-') && (chPrev == '-')) {
- styler.ColourTo(i, SCE_H_SGML_COMMENT);
- state = SCE_H_SGML_1ST_PARAM;
- }
- break;
- case SCE_H_SGML_SPECIAL:
- if (!(isascii(ch) && isupper(ch))) {
- styler.ColourTo(i - 1, StateToPrint);
- if (isalnum(ch)) {
- state = SCE_H_SGML_ERROR;
- } else {
- state = SCE_H_SGML_DEFAULT;
- }
- }
- break;
- case SCE_H_SGML_ENTITY:
- if (ch == ';') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_SGML_DEFAULT;
- } else if (!(isascii(ch) && isalnum(ch)) && ch != '-' && ch != '.') {
- styler.ColourTo(i, SCE_H_SGML_ERROR);
- state = SCE_H_SGML_DEFAULT;
- }
- break;
- case SCE_H_ENTITY:
- if (ch == ';') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_DEFAULT;
- }
- if (ch != '#' && !(isascii(ch) && isalnum(ch)) // Should check that '#' follows '&', but it is unlikely anyway...
- && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML
- if (!isascii(ch)) // Possibly start of a multibyte character so don't allow this byte to be in entity style
- styler.ColourTo(i-1, SCE_H_TAGUNKNOWN);
- else
- styler.ColourTo(i, SCE_H_TAGUNKNOWN);
- state = SCE_H_DEFAULT;
- }
- break;
- case SCE_H_TAGUNKNOWN:
- if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) {
- int eClass = classifyTagHTML(styler.GetStartSegment(),
- i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts);
- if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) {
- if (!tagClosing) {
- inScriptType = eNonHtmlScript;
- scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment;
- } else {
- scriptLanguage = eScriptNone;
- }
- eClass = SCE_H_TAG;
- }
- if (ch == '>') {
- styler.ColourTo(i, eClass);
- if (inScriptType == eNonHtmlScript) {
- state = StateForScript(scriptLanguage);
- } else {
- state = SCE_H_DEFAULT;
- }
- tagOpened = false;
- if (!tagDontFold) {
- if (tagClosing) {
- levelCurrent--;
- } else {
- levelCurrent++;
- }
- }
- tagClosing = false;
- } else if (ch == '/' && chNext == '>') {
- if (eClass == SCE_H_TAGUNKNOWN) {
- styler.ColourTo(i + 1, SCE_H_TAGUNKNOWN);
- } else {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i + 1, SCE_H_TAGEND);
- }
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- tagOpened = false;
- } else {
- if (eClass != SCE_H_TAGUNKNOWN) {
- if (eClass == SCE_H_SGML_DEFAULT) {
- state = SCE_H_SGML_DEFAULT;
- } else {
- state = SCE_H_OTHER;
- }
- }
- }
- }
- break;
- case SCE_H_ATTRIBUTE:
- if (!setAttributeContinue.Contains(ch)) {
- if (inScriptType == eNonHtmlScript) {
- int scriptLanguagePrev = scriptLanguage;
- clientScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, scriptLanguage);
- scriptLanguage = clientScript;
- if ((scriptLanguagePrev != scriptLanguage) && (scriptLanguage == eScriptNone))
- inScriptType = eHtml;
- }
- classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler);
- if (ch == '>') {
- styler.ColourTo(i, SCE_H_TAG);
- if (inScriptType == eNonHtmlScript) {
- state = StateForScript(scriptLanguage);
- } else {
- state = SCE_H_DEFAULT;
- }
- tagOpened = false;
- if (!tagDontFold) {
- if (tagClosing) {
- levelCurrent--;
- } else {
- levelCurrent++;
- }
- }
- tagClosing = false;
- } else if (ch == '=') {
- styler.ColourTo(i, SCE_H_OTHER);
- state = SCE_H_VALUE;
- } else {
- state = SCE_H_OTHER;
- }
- }
- break;
- case SCE_H_OTHER:
- if (ch == '>') {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i, SCE_H_TAG);
- if (inScriptType == eNonHtmlScript) {
- state = StateForScript(scriptLanguage);
- } else {
- state = SCE_H_DEFAULT;
- }
- tagOpened = false;
- if (!tagDontFold) {
- if (tagClosing) {
- levelCurrent--;
- } else {
- levelCurrent++;
- }
- }
- tagClosing = false;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_DOUBLESTRING;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_SINGLESTRING;
- } else if (ch == '=') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_H_VALUE;
- } else if (ch == '/' && chNext == '>') {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i + 1, SCE_H_TAGEND);
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- tagOpened = false;
- } else if (ch == '?' && chNext == '>') {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i + 1, SCE_H_XMLEND);
- i++;
- ch = chNext;
- state = SCE_H_DEFAULT;
- } else if (setHTMLWord.Contains(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_H_ATTRIBUTE;
- }
- break;
- case SCE_H_DOUBLESTRING:
- if (ch == '\"') {
- if (inScriptType == eNonHtmlScript) {
- scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
- }
- styler.ColourTo(i, SCE_H_DOUBLESTRING);
- state = SCE_H_OTHER;
- }
- break;
- case SCE_H_SINGLESTRING:
- if (ch == '\'') {
- if (inScriptType == eNonHtmlScript) {
- scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage);
- }
- styler.ColourTo(i, SCE_H_SINGLESTRING);
- state = SCE_H_OTHER;
- }
- break;
- case SCE_H_VALUE:
- if (!setHTMLWord.Contains(ch)) {
- if (ch == '\"' && chPrev == '=') {
- // Should really test for being first character
- state = SCE_H_DOUBLESTRING;
- } else if (ch == '\'' && chPrev == '=') {
- state = SCE_H_SINGLESTRING;
- } else {
- if (IsNumber(styler.GetStartSegment(), styler)) {
- styler.ColourTo(i - 1, SCE_H_NUMBER);
- } else {
- styler.ColourTo(i - 1, StateToPrint);
- }
- if (ch == '>') {
- styler.ColourTo(i, SCE_H_TAG);
- if (inScriptType == eNonHtmlScript) {
- state = StateForScript(scriptLanguage);
- } else {
- state = SCE_H_DEFAULT;
- }
- tagOpened = false;
- if (!tagDontFold) {
- if (tagClosing) {
- levelCurrent--;
- } else {
- levelCurrent++;
- }
- }
- tagClosing = false;
- } else {
- state = SCE_H_OTHER;
- }
- }
- }
- break;
- case SCE_HJ_DEFAULT:
- case SCE_HJ_START:
- case SCE_HJ_SYMBOLS:
- if (IsAWordStart(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_WORD;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourTo(i - 1, StateToPrint);
- if (chNext2 == '*')
- state = SCE_HJ_COMMENTDOC;
- else
- state = SCE_HJ_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_COMMENTLINE;
- } else if (ch == '/' && isOKBeforeRE(chPrevNonWhite)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_REGEX;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_DOUBLESTRING;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_SINGLESTRING;
- } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
- styler.SafeGetCharAt(i + 3) == '-') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_COMMENTLINE;
- } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_COMMENTLINE;
- i += 2;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
- state = SCE_HJ_DEFAULT;
- } else if ((ch == ' ') || (ch == '\t')) {
- if (state == SCE_HJ_START) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_DEFAULT;
- }
- }
- break;
- case SCE_HJ_WORD:
- if (!IsAWordChar(ch)) {
- classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType);
- //styler.ColourTo(i - 1, eHTJSKeyword);
- state = SCE_HJ_DEFAULT;
- if (ch == '/' && chNext == '*') {
- if (chNext2 == '*')
- state = SCE_HJ_COMMENTDOC;
- else
- state = SCE_HJ_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- state = SCE_HJ_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_HJ_DOUBLESTRING;
- } else if (ch == '\'') {
- state = SCE_HJ_SINGLESTRING;
- } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_COMMENTLINE;
- i += 2;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
- state = SCE_HJ_DEFAULT;
- }
- }
- break;
- case SCE_HJ_COMMENT:
- case SCE_HJ_COMMENTDOC:
- if (ch == '/' && chPrev == '*') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HJ_DEFAULT;
- ch = ' ';
- }
- break;
- case SCE_HJ_COMMENTLINE:
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));
- state = SCE_HJ_DEFAULT;
- ch = ' ';
- }
- break;
- case SCE_HJ_DOUBLESTRING:
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType));
- state = SCE_HJ_DEFAULT;
- } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_COMMENTLINE;
- i += 2;
- } else if (isLineEnd(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_STRINGEOL;
- }
- break;
- case SCE_HJ_SINGLESTRING:
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType));
- state = SCE_HJ_DEFAULT;
- } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_COMMENTLINE;
- i += 2;
- } else if (isLineEnd(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_STRINGEOL;
- }
- break;
- case SCE_HJ_STRINGEOL:
- if (!isLineEnd(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_DEFAULT;
- } else if (!isLineEnd(chNext)) {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HJ_DEFAULT;
- }
- break;
- case SCE_HJ_REGEX:
- if (ch == '\r' || ch == '\n' || ch == '/') {
- if (ch == '/') {
- while (isascii(chNext) && islower(chNext)) { // gobble regex flags
- i++;
- ch = chNext;
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- }
- }
- styler.ColourTo(i, StateToPrint);
- state = SCE_HJ_DEFAULT;
- } else if (ch == '\\') {
- // Gobble up the quoted character
- if (chNext == '\\' || chNext == '/') {
- i++;
- ch = chNext;
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- }
- }
- break;
- case SCE_HB_DEFAULT:
- case SCE_HB_START:
- if (IsAWordStart(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_WORD;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_COMMENTLINE;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_STRING;
- } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
- styler.SafeGetCharAt(i + 3) == '-') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_COMMENTLINE;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
- state = SCE_HB_DEFAULT;
- } else if ((ch == ' ') || (ch == '\t')) {
- if (state == SCE_HB_START) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_DEFAULT;
- }
- }
- break;
- case SCE_HB_WORD:
- if (!IsAWordChar(ch)) {
- state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
- if (state == SCE_HB_DEFAULT) {
- if (ch == '\"') {
- state = SCE_HB_STRING;
- } else if (ch == '\'') {
- state = SCE_HB_COMMENTLINE;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType));
- state = SCE_HB_DEFAULT;
- }
- }
- }
- break;
- case SCE_HB_STRING:
- if (ch == '\"') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HB_DEFAULT;
- } else if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_STRINGEOL;
- }
- break;
- case SCE_HB_COMMENTLINE:
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_DEFAULT;
- }
- break;
- case SCE_HB_STRINGEOL:
- if (!isLineEnd(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HB_DEFAULT;
- } else if (!isLineEnd(chNext)) {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HB_DEFAULT;
- }
- break;
- case SCE_HP_DEFAULT:
- case SCE_HP_START:
- if (IsAWordStart(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HP_WORD;
- } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
- styler.SafeGetCharAt(i + 3) == '-') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HP_COMMENTLINE;
- } else if (ch == '#') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HP_COMMENTLINE;
- } else if (ch == '\"') {
- styler.ColourTo(i - 1, StateToPrint);
- if (chNext == '\"' && chNext2 == '\"') {
- i += 2;
- state = SCE_HP_TRIPLEDOUBLE;
- ch = ' ';
- chPrev = ' ';
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- } else {
- // state = statePrintForState(SCE_HP_STRING,inScriptType);
- state = SCE_HP_STRING;
- }
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, StateToPrint);
- if (chNext == '\'' && chNext2 == '\'') {
- i += 2;
- state = SCE_HP_TRIPLE;
- ch = ' ';
- chPrev = ' ';
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- } else {
- state = SCE_HP_CHARACTER;
- }
- } else if (IsOperator(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
- } else if ((ch == ' ') || (ch == '\t')) {
- if (state == SCE_HP_START) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HP_DEFAULT;
- }
- }
- break;
- case SCE_HP_WORD:
- if (!IsAWordChar(ch)) {
- classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
- state = SCE_HP_DEFAULT;
- if (ch == '#') {
- state = SCE_HP_COMMENTLINE;
- } else if (ch == '\"') {
- if (chNext == '\"' && chNext2 == '\"') {
- i += 2;
- state = SCE_HP_TRIPLEDOUBLE;
- ch = ' ';
- chPrev = ' ';
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- } else {
- state = SCE_HP_STRING;
- }
- } else if (ch == '\'') {
- if (chNext == '\'' && chNext2 == '\'') {
- i += 2;
- state = SCE_HP_TRIPLE;
- ch = ' ';
- chPrev = ' ';
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- } else {
- state = SCE_HP_CHARACTER;
- }
- } else if (IsOperator(ch)) {
- styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType));
- }
- }
- break;
- case SCE_HP_COMMENTLINE:
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HP_DEFAULT;
- }
- break;
- case SCE_HP_STRING:
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HP_DEFAULT;
- }
- break;
- case SCE_HP_CHARACTER:
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1));
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HP_DEFAULT;
- }
- break;
- case SCE_HP_TRIPLE:
- if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HP_DEFAULT;
- }
- break;
- case SCE_HP_TRIPLEDOUBLE:
- if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HP_DEFAULT;
- }
- break;
- ///////////// start - PHP state handling
- case SCE_HPHP_WORD:
- if (!IsAWordChar(ch)) {
- classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
- if (ch == '/' && chNext == '*') {
- i++;
- state = SCE_HPHP_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- i++;
- state = SCE_HPHP_COMMENTLINE;
- } else if (ch == '#') {
- state = SCE_HPHP_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_HPHP_HSTRING;
- strcpy(phpStringDelimiter, "\"");
- } else if (styler.Match(i, "<<<")) {
- bool isSimpleString = false;
- i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
- if (strlen(phpStringDelimiter)) {
- state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
- if (foldHeredoc) levelCurrent++;
- }
- } else if (ch == '\'') {
- state = SCE_HPHP_SIMPLESTRING;
- strcpy(phpStringDelimiter, "\'");
- } else if (ch == '$' && IsPhpWordStart(chNext)) {
- state = SCE_HPHP_VARIABLE;
- } else if (IsOperator(ch)) {
- state = SCE_HPHP_OPERATOR;
- } else {
- state = SCE_HPHP_DEFAULT;
- }
- }
- break;
- case SCE_HPHP_NUMBER:
- // recognize bases 8,10 or 16 integers OR floating-point numbers
- if (!IsADigit(ch)
- && strchr(".xXabcdefABCDEF", ch) == NULL
- && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) {
- styler.ColourTo(i - 1, SCE_HPHP_NUMBER);
- if (IsOperator(ch))
- state = SCE_HPHP_OPERATOR;
- else
- state = SCE_HPHP_DEFAULT;
- }
- break;
- case SCE_HPHP_VARIABLE:
- if (!IsPhpWordChar(chNext)) {
- styler.ColourTo(i, SCE_HPHP_VARIABLE);
- state = SCE_HPHP_DEFAULT;
- }
- break;
- case SCE_HPHP_COMMENT:
- if (ch == '/' && chPrev == '*') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
- }
- break;
- case SCE_HPHP_COMMENTLINE:
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HPHP_DEFAULT;
- }
- break;
- case SCE_HPHP_HSTRING:
- if (ch == '\\' && (phpStringDelimiter[0] == '\"' || chNext == '$' || chNext == '{')) {
- // skip the next char
- i++;
- } else if (((ch == '{' && chNext == '$') || (ch == '$' && chNext == '{'))
- && IsPhpWordStart(chNext2)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HPHP_COMPLEX_VARIABLE;
- } else if (ch == '$' && IsPhpWordStart(chNext)) {
- styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HPHP_HSTRING_VARIABLE;
- } else if (styler.Match(i, phpStringDelimiter)) {
- if (phpStringDelimiter[0] == '\"') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
- } else if (isLineEnd(chPrev)) {
- const int psdLength = strlen(phpStringDelimiter);
- const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
- const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
- if (isLineEnd(chAfterPsd) ||
- (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
- i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
- if (foldHeredoc) levelCurrent--;
- }
- }
- }
- break;
- case SCE_HPHP_SIMPLESTRING:
- if (phpStringDelimiter[0] == '\'') {
- if (ch == '\\') {
- // skip the next char
- i++;
- } else if (ch == '\'') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
- }
- } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
- const int psdLength = strlen(phpStringDelimiter);
- const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
- const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
- if (isLineEnd(chAfterPsd) ||
- (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
- i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
- if (foldHeredoc) levelCurrent--;
- }
- }
- break;
- case SCE_HPHP_HSTRING_VARIABLE:
- if (!IsPhpWordChar(chNext)) {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_HSTRING;
- }
- break;
- case SCE_HPHP_COMPLEX_VARIABLE:
- if (ch == '}') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_HSTRING;
- }
- break;
- case SCE_HPHP_OPERATOR:
- case SCE_HPHP_DEFAULT:
- styler.ColourTo(i - 1, StateToPrint);
- if (IsADigit(ch) || (ch == '.' && IsADigit(chNext))) {
- state = SCE_HPHP_NUMBER;
- } else if (IsAWordStart(ch)) {
- state = SCE_HPHP_WORD;
- } else if (ch == '/' && chNext == '*') {
- i++;
- state = SCE_HPHP_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- i++;
- state = SCE_HPHP_COMMENTLINE;
- } else if (ch == '#') {
- state = SCE_HPHP_COMMENTLINE;
- } else if (ch == '\"') {
- state = SCE_HPHP_HSTRING;
- strcpy(phpStringDelimiter, "\"");
- } else if (styler.Match(i, "<<<")) {
- bool isSimpleString = false;
- i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
- if (strlen(phpStringDelimiter)) {
- state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
- if (foldHeredoc) levelCurrent++;
- }
- } else if (ch == '\'') {
- state = SCE_HPHP_SIMPLESTRING;
- strcpy(phpStringDelimiter, "\'");
- } else if (ch == '$' && IsPhpWordStart(chNext)) {
- state = SCE_HPHP_VARIABLE;
- } else if (IsOperator(ch)) {
- state = SCE_HPHP_OPERATOR;
- } else if ((state == SCE_HPHP_OPERATOR) && (IsASpace(ch))) {
- state = SCE_HPHP_DEFAULT;
- }
- break;
- ///////////// end - PHP state handling
- }
-
- // Some of the above terminated their lexeme but since the same character starts
- // the same class again, only reenter if non empty segment.
-
- bool nonEmptySegment = i >= static_cast<int>(styler.GetStartSegment());
- if (state == SCE_HB_DEFAULT) { // One of the above succeeded
- if ((ch == '\"') && (nonEmptySegment)) {
- state = SCE_HB_STRING;
- } else if (ch == '\'') {
- state = SCE_HB_COMMENTLINE;
- } else if (IsAWordStart(ch)) {
- state = SCE_HB_WORD;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i, SCE_HB_DEFAULT);
- }
- } else if (state == SCE_HBA_DEFAULT) { // One of the above succeeded
- if ((ch == '\"') && (nonEmptySegment)) {
- state = SCE_HBA_STRING;
- } else if (ch == '\'') {
- state = SCE_HBA_COMMENTLINE;
- } else if (IsAWordStart(ch)) {
- state = SCE_HBA_WORD;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i, SCE_HBA_DEFAULT);
- }
- } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded
- if (ch == '/' && chNext == '*') {
- if (styler.SafeGetCharAt(i + 2) == '*')
- state = SCE_HJ_COMMENTDOC;
- else
- state = SCE_HJ_COMMENT;
- } else if (ch == '/' && chNext == '/') {
- state = SCE_HJ_COMMENTLINE;
- } else if ((ch == '\"') && (nonEmptySegment)) {
- state = SCE_HJ_DOUBLESTRING;
- } else if ((ch == '\'') && (nonEmptySegment)) {
- state = SCE_HJ_SINGLESTRING;
- } else if (IsAWordStart(ch)) {
- state = SCE_HJ_WORD;
- } else if (IsOperator(ch)) {
- styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType));
- }
- }
- }
-
- switch (state) {
- case SCE_HJ_WORD:
- classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType);
- break;
- case SCE_HB_WORD:
- classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
- break;
- case SCE_HP_WORD:
- classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
- break;
- case SCE_HPHP_WORD:
- classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);
- break;
- default:
- StateToPrint = statePrintForState(state, inScriptType);
- styler.ColourTo(lengthDoc - 1, StateToPrint);
- break;
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- if (fold) {
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
- }
-}
-
-static void ColouriseXMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- // Passing in true because we're lexing XML
- ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- // Passing in false because we're notlexing XML
- ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false);
-}
-
-static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- if (startPos == 0)
- initStyle = SCE_HPHP_DEFAULT;
- ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler);
-}
-
-static const char * const htmlWordListDesc[] = {
- "HTML elements and attributes",
- "JavaScript keywords",
- "VBScript keywords",
- "Python keywords",
- "PHP keywords",
- "SGML and DTD keywords",
- 0,
-};
-
-static const char * const phpscriptWordListDesc[] = {
- "", //Unused
- "", //Unused
- "", //Unused
- "", //Unused
- "PHP keywords",
- "", //Unused
- 0,
-};
-
-LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, 8);
-LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, 8);
-LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 8);
+++ /dev/null
-/******************************************************************
- * LexHaskell.cxx
- *
- * A haskell lexer for the scintilla code control.
- * Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
- * External lexer stuff inspired from the caml external lexer.
- *
- * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
- *
- *
- * TODO:
- * * Implement a folder :)
- * * Nice Character-lexing (stuff inside '\''), LexPython has
- * this.
- *
- *
- *****************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "PropSetSimple.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#ifdef BUILD_AS_EXTERNAL_LEXER
-
-#include "ExternalLexer.h"
-#include "WindowAccessor.h"
-
-#define BUILD_EXTERNAL_LEXER 0
-
-#endif
-
-// Max level of nested comments
-#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
-
-
-enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
-
-static inline bool IsNewline(const int ch) {
- return (ch == '\n' || ch == '\r');
-}
-
-static inline bool IsWhitespace(const int ch) {
- return ( ch == ' '
- || ch == '\t'
- || IsNewline(ch) );
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
-}
-
-static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
-
- int kwLast = kwOther;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- // Check for state end
- // Operator
- if (sc.state == SCE_HA_OPERATOR) {
- kwLast = kwOther;
- sc.SetState(SCE_HA_DEFAULT);
- }
- // String
- else if (sc.state == SCE_HA_STRING) {
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_HA_DEFAULT);
- } else if (sc.ch == '\\') {
- sc.Forward();
- }
- }
- // Char
- else if (sc.state == SCE_HA_CHARACTER) {
- if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_HA_DEFAULT);
- } else if (sc.ch == '\\') {
- sc.Forward();
- }
- }
- // Number
- else if (sc.state == SCE_HA_NUMBER) {
- if (!IsADigit(sc.ch)) {
- sc.SetState(SCE_HA_DEFAULT);
- }
- }
- // Types, constructors, etc.
- else if (sc.state == SCE_HA_CAPITAL) {
- if (!IsAWordChar(sc.ch) || sc.ch == '.') {
- sc.SetState(SCE_HA_DEFAULT);
- }
- }
- // Identifier
- else if (sc.state == SCE_HA_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- int style = SCE_HA_IDENTIFIER;
- if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
- style = SCE_HA_IMPORT;
- } else if (keywords.InList(s)) {
- style = SCE_HA_KEYWORD;
- } else if (kwLast == kwData) {
- style = SCE_HA_DATA;
- } else if (kwLast == kwClass) {
- style = SCE_HA_CLASS;
- } else if (kwLast == kwModule) {
- style = SCE_HA_MODULE;
- } else if (isupper(s[0])) {
- style = SCE_HA_CAPITAL;
- }
- sc.ChangeState(style);
- sc.SetState(SCE_HA_DEFAULT);
- if (style == SCE_HA_KEYWORD) {
- if (0 == strcmp(s, "class"))
- kwLast = kwClass;
- else if (0 == strcmp(s, "data"))
- kwLast = kwData;
- else if (0 == strcmp(s, "instance"))
- kwLast = kwInstance;
- else if (0 == strcmp(s, "import"))
- kwLast = kwImport;
- else if (0 == strcmp(s, "module"))
- kwLast = kwModule;
- else
- kwLast = kwOther;
- } else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
- style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
- style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
- kwLast = kwOther;
- }
- }
- }
- // Comments
- // Oneliner
- else if (sc.state == SCE_HA_COMMENTLINE) {
- if (IsNewline(sc.ch))
- sc.SetState(SCE_HA_DEFAULT);
- }
- // Nested
- else if (sc.state >= SCE_HA_COMMENTBLOCK) {
- if (sc.Match("{-")) {
- if (sc.state < SCE_HA_COMMENTMAX)
- sc.SetState(sc.state + 1);
- }
- else if (sc.Match("-}")) {
- sc.Forward();
- if (sc.state == SCE_HA_COMMENTBLOCK)
- sc.ForwardSetState(SCE_HA_DEFAULT);
- else
- sc.ForwardSetState(sc.state - 1);
- }
- }
- // New state?
- if (sc.state == SCE_HA_DEFAULT) {
- // Digit
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_HA_NUMBER);
- if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too
- sc.Forward(1);
- }
- }
- // Comment line
- else if (sc.Match("--")) {
- sc.SetState(SCE_HA_COMMENTLINE);
- // Comment block
- }
- else if (sc.Match("{-")) {
- sc.SetState(SCE_HA_COMMENTBLOCK);
- }
- // String
- else if (sc.Match('\"')) {
- sc.SetState(SCE_HA_STRING);
- }
- // Character
- else if (sc.Match('\'')) {
- sc.SetState(SCE_HA_CHARACTER);
- }
- // Stringstart
- else if (sc.Match('\"')) {
- sc.SetState(SCE_HA_STRING);
- }
- // Operator
- else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_HA_OPERATOR);
- }
- // Keyword
- else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_HA_IDENTIFIER);
- }
-
- }
- }
- sc.Complete();
-}
-
-// External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
-// Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
-#ifdef BUILD_EXTERNAL_LEXER
-static const char* LexerName = "haskell";
-
-void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props)
-{
- PropSetSimple ps;
- ps.SetMultiple(props);
- WindowAccessor wa(window, ps);
-
- int nWL = 0;
- for (; words[nWL]; nWL++) ;
- WordList** wl = new WordList* [nWL + 1];
- int i = 0;
- for (; i<nWL; i++)
- {
- wl[i] = new WordList();
- wl[i]->Set(words[i]);
- }
- wl[i] = 0;
-
- ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
- wa.Flush();
- for (i=nWL-1;i>=0;i--)
- delete wl[i];
- delete [] wl;
-}
-
-void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props)
-{
-
-}
-
-int EXT_LEXER_DECL GetLexerCount()
-{
- return 1;
-}
-
-void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
-{
- if (buflength > 0) {
- buflength--;
- int n = strlen(LexerName);
- if (n > buflength)
- n = buflength;
- memcpy(name, LexerName, n), name[n] = '\0';
- }
-}
-#endif
-
-LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexInno.cxx
- ** Lexer for Inno Setup scripts.
- **/
-// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "CharClassify.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 void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
- int state = SCE_INNO_DEFAULT;
- char chPrev;
- char ch = 0;
- char chNext = styler[startPos];
- int lengthDoc = startPos + length;
- char *buffer = new char[length];
- int bufferCount = 0;
- bool isBOL, isEOL, isWS, isBOLWS = 0;
- bool isCode = false;
- bool isCStyleComment = false;
-
- WordList §ionKeywords = *keywordLists[0];
- WordList &standardKeywords = *keywordLists[1];
- WordList ¶meterKeywords = *keywordLists[2];
- WordList &preprocessorKeywords = *keywordLists[3];
- WordList &pascalKeywords = *keywordLists[4];
- WordList &userKeywords = *keywordLists[5];
-
- // Go through all provided text segment
- // using the hand-written state machine shown below
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- for (int i = startPos; i < lengthDoc; i++) {
- chPrev = ch;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- i++;
- continue;
- }
-
- isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
- isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
- isEOL = (ch == '\n' || ch == '\r');
- isWS = (ch == ' ' || ch == '\t');
-
- switch(state) {
- case SCE_INNO_DEFAULT:
- if (!isCode && ch == ';' && isBOLWS) {
- // Start of a comment
- state = SCE_INNO_COMMENT;
- } else if (ch == '[' && isBOLWS) {
- // Start of a section name
- bufferCount = 0;
- state = SCE_INNO_SECTION;
- } else if (ch == '#' && isBOLWS) {
- // Start of a preprocessor directive
- state = SCE_INNO_PREPROC;
- } else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
- // Start of an inline expansion
- state = SCE_INNO_INLINE_EXPANSION;
- } else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
- // Start of a Pascal comment
- state = SCE_INNO_COMMENT_PASCAL;
- isCStyleComment = false;
- } else if (isCode && ch == '/' && chNext == '/') {
- // Apparently, C-style comments are legal, too
- state = SCE_INNO_COMMENT_PASCAL;
- isCStyleComment = true;
- } else if (ch == '"') {
- // Start of a double-quote string
- state = SCE_INNO_STRING_DOUBLE;
- } else if (ch == '\'') {
- // Start of a single-quote string
- state = SCE_INNO_STRING_SINGLE;
- } else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {
- // Start of an identifier
- bufferCount = 0;
- buffer[bufferCount++] = static_cast<char>(tolower(ch));
- state = SCE_INNO_IDENTIFIER;
- } else {
- // Style it the default style
- styler.ColourTo(i,SCE_INNO_DEFAULT);
- }
- break;
-
- case SCE_INNO_COMMENT:
- if (isEOL) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_COMMENT);
- }
- break;
-
- case SCE_INNO_IDENTIFIER:
- if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
- buffer[bufferCount++] = static_cast<char>(tolower(ch));
- } else {
- state = SCE_INNO_DEFAULT;
- buffer[bufferCount] = '\0';
-
- // Check if the buffer contains a keyword
- if (!isCode && standardKeywords.InList(buffer)) {
- styler.ColourTo(i-1,SCE_INNO_KEYWORD);
- } else if (!isCode && parameterKeywords.InList(buffer)) {
- styler.ColourTo(i-1,SCE_INNO_PARAMETER);
- } else if (isCode && pascalKeywords.InList(buffer)) {
- styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
- } else if (!isCode && userKeywords.InList(buffer)) {
- styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
- } else {
- styler.ColourTo(i-1,SCE_INNO_DEFAULT);
- }
-
- // Push back the faulty character
- chNext = styler[i--];
- ch = chPrev;
- }
- break;
-
- case SCE_INNO_SECTION:
- if (ch == ']') {
- state = SCE_INNO_DEFAULT;
- buffer[bufferCount] = '\0';
-
- // Check if the buffer contains a section name
- if (sectionKeywords.InList(buffer)) {
- styler.ColourTo(i,SCE_INNO_SECTION);
- isCode = !CompareCaseInsensitive(buffer, "code");
- } else {
- styler.ColourTo(i,SCE_INNO_DEFAULT);
- }
- } else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
- buffer[bufferCount++] = static_cast<char>(tolower(ch));
- } else {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_DEFAULT);
- }
- break;
-
- case SCE_INNO_PREPROC:
- if (isWS || isEOL) {
- if (isascii(chPrev) && isalpha(chPrev)) {
- state = SCE_INNO_DEFAULT;
- buffer[bufferCount] = '\0';
-
- // Check if the buffer contains a preprocessor directive
- if (preprocessorKeywords.InList(buffer)) {
- styler.ColourTo(i-1,SCE_INNO_PREPROC);
- } else {
- styler.ColourTo(i-1,SCE_INNO_DEFAULT);
- }
-
- // Push back the faulty character
- chNext = styler[i--];
- ch = chPrev;
- }
- } else if (isascii(ch) && isalpha(ch)) {
- if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
- bufferCount = 0;
- buffer[bufferCount++] = static_cast<char>(tolower(ch));
- }
- break;
-
- case SCE_INNO_STRING_DOUBLE:
- if (ch == '"' || isEOL) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
- }
- break;
-
- case SCE_INNO_STRING_SINGLE:
- if (ch == '\'' || isEOL) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
- }
- break;
-
- case SCE_INNO_INLINE_EXPANSION:
- if (ch == '}') {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
- } else if (isEOL) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_DEFAULT);
- }
- break;
-
- case SCE_INNO_COMMENT_PASCAL:
- if (isCStyleComment) {
- if (isEOL) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
- }
- } else {
- if (ch == '}' || (ch == ')' && chPrev == '*')) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
- } else if (isEOL) {
- state = SCE_INNO_DEFAULT;
- styler.ColourTo(i,SCE_INNO_DEFAULT);
- }
- }
- break;
-
- }
- }
- delete []buffer;
-}
-
-static const char * const innoWordListDesc[] = {
- "Sections",
- "Keywords",
- "Parameters",
- "Preprocessor directives",
- "Pascal keywords",
- "User defined keywords",
- 0
-};
-
-static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- unsigned int endPos = startPos + length;
- char chNext = styler[startPos];
-
- int lineCurrent = styler.GetLine(startPos);
-
- bool sectionFlag = false;
- int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
- int level;
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler[i+1];
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- int style = styler.StyleAt(i);
-
- if (style == SCE_INNO_SECTION)
- sectionFlag = true;
-
- if (atEOL || i == endPos - 1) {
- if (sectionFlag) {
- level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
- if (level == levelPrev)
- styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
- } else {
- level = levelPrev & SC_FOLDLEVELNUMBERMASK;
- if (levelPrev & SC_FOLDLEVELHEADERFLAG)
- level++;
- }
-
- styler.SetLevel(lineCurrent, level);
-
- levelPrev = level;
- lineCurrent++;
- sectionFlag = false;
- }
- }
-}
-
-LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexKix.cxx
- ** Lexer for KIX-Scripts.
- **/
-// Copyright 2004 by Manfred Becker <manfred@becker-trdf.de>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
- return ch >= 0x80 || isalnum(ch) || ch == '_';
-}
-
-static inline bool IsOperator(const int ch) {
- return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '=');
-}
-
-static void ColouriseKixDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
-// WordList &keywords4 = *keywordlists[3];
-
- styler.StartAt(startPos);
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_KIX_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_STRING1) {
- // This is a doubles quotes string
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_STRING2) {
- // This is a single quote string
- if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_NUMBER) {
- if (!IsADigit(sc.ch)) {
- sc.SetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_VAR) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_MACRO) {
- if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
-
- if (!keywords3.InList(&s[1])) {
- sc.ChangeState(SCE_KIX_DEFAULT);
- }
- sc.SetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_OPERATOR) {
- if (!IsOperator(sc.ch)) {
- sc.SetState(SCE_KIX_DEFAULT);
- }
- } else if (sc.state == SCE_KIX_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
-
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_KIX_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_KIX_FUNCTIONS);
- }
- sc.SetState(SCE_KIX_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_KIX_DEFAULT) {
- if (sc.ch == ';') {
- sc.SetState(SCE_KIX_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_KIX_STRING1);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_KIX_STRING2);
- } else if (sc.ch == '$') {
- sc.SetState(SCE_KIX_VAR);
- } else if (sc.ch == '@') {
- sc.SetState(SCE_KIX_MACRO);
- } else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) {
- sc.SetState(SCE_KIX_NUMBER);
- } else if (IsOperator(sc.ch)) {
- sc.SetState(SCE_KIX_OPERATOR);
- } else if (IsAWordChar(sc.ch)) {
- sc.SetState(SCE_KIX_IDENTIFIER);
- }
- }
- }
- sc.Complete();
-}
-
-
-LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, "kix");
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexLisp.cxx
- ** Lexer for Lisp.
- ** Written by Alexey Yutkin.
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#define SCE_LISP_CHARACTER 29
-#define SCE_LISP_MACRO 30
-#define SCE_LISP_MACRO_DISPATCH 31
-
-static inline bool isLispoperator(char ch) {
- if (isascii(ch) && isalnum(ch))
- return false;
- if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
- return true;
- return false;
-}
-
-static inline bool isLispwordstart(char ch) {
- return isascii(ch) && ch != ';' && !isspacechar(ch) && !isLispoperator(ch) &&
- ch != '\n' && ch != '\r' && ch != '\"';
-}
-
-
-static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
- PLATFORM_ASSERT(end >= start);
- char s[100];
- unsigned int i;
- bool digit_flag = true;
- for (i = 0; (i < end - start + 1) && (i < 99); i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
- if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
- }
- char chAttr = SCE_LISP_IDENTIFIER;
-
- if(digit_flag) chAttr = SCE_LISP_NUMBER;
- else {
- if (keywords.InList(s)) {
- chAttr = SCE_LISP_KEYWORD;
- } else if (keywords_kw.InList(s)) {
- chAttr = SCE_LISP_KEYWORD_KW;
- } else if ((s[0] == '*' && s[i-1] == '*') ||
- (s[0] == '+' && s[i-1] == '+')) {
- chAttr = SCE_LISP_SPECIAL;
- }
- }
- styler.ColourTo(end, chAttr);
- return;
-}
-
-
-static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords_kw = *keywordlists[1];
-
- styler.StartAt(startPos);
-
- int state = initStyle, radix = -1;
- char chNext = styler[startPos];
- unsigned int lengthDoc = startPos + length;
- styler.StartSegment(startPos);
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- i += 1;
- continue;
- }
-
- if (state == SCE_LISP_DEFAULT) {
- if (ch == '#') {
- styler.ColourTo(i - 1, state);
- radix = -1;
- state = SCE_LISP_MACRO_DISPATCH;
- } else if (ch == ':' && isLispwordstart(chNext)) {
- styler.ColourTo(i - 1, state);
- state = SCE_LISP_SYMBOL;
- } else if (isLispwordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_LISP_IDENTIFIER;
- }
- else if (ch == ';') {
- styler.ColourTo(i - 1, state);
- state = SCE_LISP_COMMENT;
- }
- else if (isLispoperator(ch) || ch=='\'') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_LISP_OPERATOR);
- if (ch=='\'' && isLispwordstart(chNext)) {
- state = SCE_LISP_SYMBOL;
- }
- }
- else if (ch == '\"') {
- styler.ColourTo(i - 1, state);
- state = SCE_LISP_STRING;
- }
- } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
- if (!isLispwordstart(ch)) {
- if (state == SCE_LISP_IDENTIFIER) {
- classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
- } else {
- styler.ColourTo(i - 1, state);
- }
- state = SCE_LISP_DEFAULT;
- } /*else*/
- if (isLispoperator(ch) || ch=='\'') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_LISP_OPERATOR);
- if (ch=='\'' && isLispwordstart(chNext)) {
- state = SCE_LISP_SYMBOL;
- }
- }
- } else if (state == SCE_LISP_MACRO_DISPATCH) {
- if (!isdigit(ch)) {
- if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
- state = SCE_LISP_DEFAULT;
- } else {
- switch (ch) {
- case '|': state = SCE_LISP_MULTI_COMMENT; break;
- case 'o':
- case 'O': radix = 8; state = SCE_LISP_MACRO; break;
- case 'x':
- case 'X': radix = 16; state = SCE_LISP_MACRO; break;
- case 'b':
- case 'B': radix = 2; state = SCE_LISP_MACRO; break;
- case '\\': state = SCE_LISP_CHARACTER; break;
- case ':':
- case '-':
- case '+': state = SCE_LISP_MACRO; break;
- case '\'': if (isLispwordstart(chNext)) {
- state = SCE_LISP_SPECIAL;
- } else {
- styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
- styler.ColourTo(i, SCE_LISP_OPERATOR);
- state = SCE_LISP_DEFAULT;
- }
- break;
- default: if (isLispoperator(ch)) {
- styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
- styler.ColourTo(i, SCE_LISP_OPERATOR);
- }
- state = SCE_LISP_DEFAULT;
- break;
- }
- }
- }
- } else if (state == SCE_LISP_MACRO) {
- if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
- state = SCE_LISP_SPECIAL;
- } else {
- state = SCE_LISP_DEFAULT;
- }
- } else if (state == SCE_LISP_CHARACTER) {
- if (isLispoperator(ch)) {
- styler.ColourTo(i, SCE_LISP_SPECIAL);
- state = SCE_LISP_DEFAULT;
- } else if (isLispwordstart(ch)) {
- styler.ColourTo(i, SCE_LISP_SPECIAL);
- state = SCE_LISP_SPECIAL;
- } else {
- state = SCE_LISP_DEFAULT;
- }
- } else if (state == SCE_LISP_SPECIAL) {
- if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
- styler.ColourTo(i - 1, state);
- state = SCE_LISP_DEFAULT;
- }
- if (isLispoperator(ch) || ch=='\'') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_LISP_OPERATOR);
- if (ch=='\'' && isLispwordstart(chNext)) {
- state = SCE_LISP_SYMBOL;
- }
- }
- } else {
- if (state == SCE_LISP_COMMENT) {
- if (atEOL) {
- styler.ColourTo(i - 1, state);
- state = SCE_LISP_DEFAULT;
- }
- } else if (state == SCE_LISP_MULTI_COMMENT) {
- if (ch == '|' && chNext == '#') {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- styler.ColourTo(i, state);
- state = SCE_LISP_DEFAULT;
- }
- } else if (state == SCE_LISP_STRING) {
- if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, state);
- state = SCE_LISP_DEFAULT;
- }
- }
- }
-
- }
- styler.ColourTo(lengthDoc - 1, state);
-}
-
-static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
- Accessor &styler) {
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_LISP_OPERATOR) {
- if (ch == '(' || ch == '[' || ch == '{') {
- levelCurrent++;
- } else if (ch == ')' || ch == ']' || ch == '}') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const lispWordListDesc[] = {
- "Functions and special operators",
- "Keywords",
- 0
-};
-
-LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexLout.cxx
- ** Lexer for the Basser Lout (>= version 3) typesetting language
- **/
-// Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
-}
-
-static inline bool IsAnOther(const int ch) {
- return (ch < 0x80) && (ch == '{' || ch == '}' ||
- ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
- ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
- ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
- ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
- ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
-}
-
-static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
-
- int visibleChars = 0;
- int firstWordInLine = 0;
- int leadingAtSign = 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
- // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_LOUT_STRING);
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_LOUT_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_LOUT_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_LOUT_NUMBER) {
- if (!IsADigit(sc.ch) && sc.ch != '.') {
- sc.SetState(SCE_LOUT_DEFAULT);
- }
- } else if (sc.state == SCE_LOUT_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_LOUT_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_LOUT_STRINGEOL);
- sc.ForwardSetState(SCE_LOUT_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_LOUT_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
-
- if (leadingAtSign) {
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_LOUT_WORD);
- } else {
- sc.ChangeState(SCE_LOUT_WORD4);
- }
- } else if (firstWordInLine && keywords3.InList(s)) {
- sc.ChangeState(SCE_LOUT_WORD3);
- }
- sc.SetState(SCE_LOUT_DEFAULT);
- }
- } else if (sc.state == SCE_LOUT_OPERATOR) {
- if (!IsAnOther(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
-
- if (keywords2.InList(s)) {
- sc.ChangeState(SCE_LOUT_WORD2);
- }
- sc.SetState(SCE_LOUT_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_LOUT_DEFAULT) {
- if (sc.ch == '#') {
- sc.SetState(SCE_LOUT_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_LOUT_STRING);
- } else if (IsADigit(sc.ch) ||
- (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_LOUT_NUMBER);
- } else if (IsAWordChar(sc.ch)) {
- firstWordInLine = (visibleChars == 0);
- leadingAtSign = (sc.ch == '@');
- sc.SetState(SCE_LOUT_IDENTIFIER);
- } else if (IsAnOther(sc.ch)) {
- sc.SetState(SCE_LOUT_OPERATOR);
- }
- }
-
- if (sc.atLineEnd) {
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- visibleChars = 0;
- }
- if (!IsASpace(sc.ch)) {
- visibleChars++;
- }
- }
- sc.Complete();
-}
-
-static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- int styleNext = styler.StyleAt(startPos);
- char s[10];
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (style == SCE_LOUT_WORD) {
- if (ch == '@') {
- for (unsigned int j = 0; j < 8; j++) {
- if (!IsAWordChar(styler[i + j])) {
- break;
- }
- s[j] = styler[i + j];
- s[j + 1] = '\0';
- }
- if (strcmp(s, "@Begin") == 0) {
- levelCurrent++;
- } else if (strcmp(s, "@End") == 0) {
- levelCurrent--;
- }
- }
- } else if (style == SCE_LOUT_OPERATOR) {
- if (ch == '{') {
- levelCurrent++;
- } else if (ch == '}') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact) {
- lev |= SC_FOLDLEVELWHITEFLAG;
- }
- if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const loutWordLists[] = {
- "Predefined identifiers",
- "Predefined delimiters",
- "Predefined keywords",
- 0,
- };
-
-LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexLua.cxx
- ** Lexer for Lua language.
- **
- ** Written by Paul Winwood.
- ** Folder by Alexey Yutkin.
- ** Modified by Marcos E. Wurzius & Philippe Lhoste
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],
-// return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.
-// The maximum number of '=' characters allowed is 254.
-static int LongDelimCheck(StyleContext &sc) {
- int sep = 1;
- while (sc.GetRelative(sep) == '=' && sep < 0xFF)
- sep++;
- if (sc.GetRelative(sep) == sc.ch)
- return sep;
- return 0;
-}
-
-static void ColouriseLuaDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
- WordList &keywords8 = *keywordlists[7];
-
- // Accepts accented characters
- CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
- // Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
- CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
- CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
-
- int currentLine = styler.GetLine(startPos);
- // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
- // if we are inside such a string. Block comment was introduced in Lua 5.0,
- // blocks with separators [=[ ... ]=] in Lua 5.1.
- int nestLevel = 0;
- int sepCount = 0;
- if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
- int lineState = styler.GetLineState(currentLine - 1);
- nestLevel = lineState >> 8;
- sepCount = lineState & 0xFF;
- }
-
- // Do not leak onto next line
- if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
- initStyle = SCE_LUA_DEFAULT;
- }
-
- StyleContext sc(startPos, length, initStyle, styler);
- if (startPos == 0 && sc.ch == '#') {
- // shbang line: # is a comment only if first char of the script
- sc.SetState(SCE_LUA_COMMENTLINE);
- }
- for (; sc.More(); sc.Forward()) {
- if (sc.atLineEnd) {
- // Update the line state, so it can be seen by next line
- currentLine = styler.GetLine(sc.currentPos);
- switch (sc.state) {
- case SCE_LUA_LITERALSTRING:
- case SCE_LUA_COMMENT:
- // Inside a literal string or block comment, we set the line state
- styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
- break;
- default:
- // Reset the line state
- styler.SetLineState(currentLine, 0);
- break;
- }
- }
- if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {
- // Prevent SCE_LUA_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_LUA_STRING);
- }
-
- // Handle string line continuation
- if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&
- sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_LUA_OPERATOR) {
- sc.SetState(SCE_LUA_DEFAULT);
- } else if (sc.state == SCE_LUA_NUMBER) {
- // We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
- if (!setNumber.Contains(sc.ch)) {
- sc.SetState(SCE_LUA_DEFAULT);
- } else if (sc.ch == '-' || sc.ch == '+') {
- if (sc.chPrev != 'E' && sc.chPrev != 'e')
- sc.SetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_IDENTIFIER) {
- if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD4);
- } else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD5);
- } else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD6);
- } else if (keywords7.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD7);
- } else if (keywords8.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD8);
- }
- sc.SetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_COMMENTLINE || sc.state == SCE_LUA_PREPROCESSOR) {
- if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_STRING) {
- if (sc.ch == '\\') {
- if (setEscapeSkip.Contains(sc.chNext)) {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_LUA_STRINGEOL);
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_CHARACTER) {
- if (sc.ch == '\\') {
- if (setEscapeSkip.Contains(sc.chNext)) {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_LUA_STRINGEOL);
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) {
- if (sc.ch == '[') {
- int sep = LongDelimCheck(sc);
- if (sep == 1 && sepCount == 1) { // [[-only allowed to nest
- nestLevel++;
- sc.Forward();
- }
- } else if (sc.ch == ']') {
- int sep = LongDelimCheck(sc);
- if (sep == 1 && sepCount == 1) { // un-nest with ]]-only
- nestLevel--;
- sc.Forward();
- if (nestLevel == 0) {
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- }
- } else if (sep > 1 && sep == sepCount) { // ]=]-style delim
- sc.Forward(sep);
- sc.ForwardSetState(SCE_LUA_DEFAULT);
- }
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_LUA_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_LUA_NUMBER);
- if (sc.ch == '0' && toupper(sc.chNext) == 'X') {
- sc.Forward();
- }
- } else if (setWordStart.Contains(sc.ch)) {
- sc.SetState(SCE_LUA_IDENTIFIER);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_LUA_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_LUA_CHARACTER);
- } else if (sc.ch == '[') {
- sepCount = LongDelimCheck(sc);
- if (sepCount == 0) {
- sc.SetState(SCE_LUA_OPERATOR);
- } else {
- nestLevel = 1;
- sc.SetState(SCE_LUA_LITERALSTRING);
- sc.Forward(sepCount);
- }
- } else if (sc.Match('-', '-')) {
- sc.SetState(SCE_LUA_COMMENTLINE);
- if (sc.Match("--[")) {
- sc.Forward(2);
- sepCount = LongDelimCheck(sc);
- if (sepCount > 0) {
- nestLevel = 1;
- sc.ChangeState(SCE_LUA_COMMENT);
- sc.Forward(sepCount);
- }
- } else {
- sc.Forward();
- }
- } else if (sc.atLineStart && sc.Match('$')) {
- sc.SetState(SCE_LUA_PREPROCESSOR); // Obsolete since Lua 4.0, but still in old code
- } else if (setLuaOperator.Contains(sc.ch)) {
- sc.SetState(SCE_LUA_OPERATOR);
- }
- }
- }
-
- if (setWord.Contains(sc.chPrev)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD4);
- } else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD5);
- } else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD6);
- } else if (keywords7.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD7);
- } else if (keywords8.InList(s)) {
- sc.ChangeState(SCE_LUA_WORD8);
- }
- }
-
- sc.Complete();
-}
-
-static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
- Accessor &styler) {
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- int styleNext = styler.StyleAt(startPos);
- char s[10];
-
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_LUA_WORD) {
- if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
- for (unsigned int j = 0; j < 8; j++) {
- if (!iswordchar(styler[i + j])) {
- break;
- }
- s[j] = styler[i + j];
- s[j + 1] = '\0';
- }
-
- if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) {
- levelCurrent++;
- }
- if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) {
- levelCurrent--;
- }
- }
- } else if (style == SCE_LUA_OPERATOR) {
- if (ch == '{' || ch == '(') {
- levelCurrent++;
- } else if (ch == '}' || ch == ')') {
- levelCurrent--;
- }
- } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
- if (ch == '[') {
- levelCurrent++;
- } else if (ch == ']') {
- levelCurrent--;
- }
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact) {
- lev |= SC_FOLDLEVELWHITEFLAG;
- }
- if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch)) {
- visibleChars++;
- }
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
-
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const luaWordListDesc[] = {
- "Keywords",
- "Basic functions",
- "String, (table) & math functions",
- "(coroutines), I/O & system facilities",
- "user1",
- "user2",
- "user3",
- "user4",
- 0
-};
-
-LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexMMIXAL.cxx
- ** Lexer for MMIX Assembler Language.
- ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
- ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
- **/
-// Copyright 1998-2003 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
-}
-
-inline bool isMMIXALOperator(char ch) {
- if (isalnum(ch))
- return false;
- if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
- ch == '*' || ch == '/' || ch == '/' ||
- ch == '%' || ch == '<' || ch == '>' || ch == '&' ||
- ch == '~' || ch == '$' ||
- ch == ',' || ch == '(' || ch == ')' ||
- ch == '[' || ch == ']')
- return true;
- return false;
-}
-
-static void ColouriseMMIXALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &opcodes = *keywordlists[0];
- WordList &special_register = *keywordlists[1];
- WordList &predef_symbols = *keywordlists[2];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
- // No EOL continuation
- if (sc.atLineStart) {
- if (sc.ch == '@' && sc.chNext == 'i') {
- sc.SetState(SCE_MMIXAL_INCLUDE);
- } else {
- sc.SetState(SCE_MMIXAL_LEADWS);
- }
- }
-
- // Check if first non whitespace character in line is alphanumeric
- if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) { // LEADWS
- if(!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_MMIXAL_COMMENT);
- } else {
- if(sc.atLineStart) {
- sc.SetState(SCE_MMIXAL_LABEL);
- } else {
- sc.SetState(SCE_MMIXAL_OPCODE_PRE);
- }
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_MMIXAL_OPERATOR) { // OPERATOR
- sc.SetState(SCE_MMIXAL_OPERANDS);
- } else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER
- if (!isdigit(sc.ch)) {
- if (IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- sc.ChangeState(SCE_MMIXAL_REF);
- sc.SetState(SCE_MMIXAL_REF);
- } else {
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- }
- } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
- if (!IsAWordChar(sc.ch) ) {
- sc.SetState(SCE_MMIXAL_OPCODE_PRE);
- }
- } else if (sc.state == SCE_MMIXAL_REF) { // REF
- if (!IsAWordChar(sc.ch) ) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (*s == ':') { // ignore base prefix for match
- for (size_t i = 0; i != sizeof(s); ++i) {
- *(s+i) = *(s+i+1);
- }
- }
- if (special_register.InList(s)) {
- sc.ChangeState(SCE_MMIXAL_REGISTER);
- } else if (predef_symbols.InList(s)) {
- sc.ChangeState(SCE_MMIXAL_SYMBOL);
- }
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
- if (!isspace(sc.ch)) {
- sc.SetState(SCE_MMIXAL_OPCODE);
- }
- } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
- if (!IsAWordChar(sc.ch) ) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (opcodes.InList(s)) {
- sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
- } else {
- sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
- }
- sc.SetState(SCE_MMIXAL_OPCODE_POST);
- }
- } else if (sc.state == SCE_MMIXAL_STRING) { // STRING
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
- if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
- if (!isdigit(sc.ch)) {
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_HEX) { // HEX
- if (!isxdigit(sc.ch)) {
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST
- sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS
- if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
- if (!sc.atLineEnd) {
- sc.SetState(SCE_MMIXAL_COMMENT);
- }
- } else if (isdigit(sc.ch)) {
- sc.SetState(SCE_MMIXAL_NUMBER);
- } else if (IsAWordChar(sc.ch) || sc.Match('@')) {
- sc.SetState(SCE_MMIXAL_REF);
- } else if (sc.Match('\"')) {
- sc.SetState(SCE_MMIXAL_STRING);
- } else if (sc.Match('\'')) {
- sc.SetState(SCE_MMIXAL_CHAR);
- } else if (sc.Match('$')) {
- sc.SetState(SCE_MMIXAL_REGISTER);
- } else if (sc.Match('#')) {
- sc.SetState(SCE_MMIXAL_HEX);
- } else if (isMMIXALOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_MMIXAL_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-static const char * const MMIXALWordListDesc[] = {
- "Operation Codes",
- "Special Register",
- "Predefined Symbols",
- 0
-};
-
-LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexMPT.cxx
- ** Lexer for MPT specific files. Based on LexOthers.cxx
- ** LOT = the text log file created by the MPT application while running a test program
- ** Other MPT specific files to be added later.
- **/
-// Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <string>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static int GetLotLineState(std::string &line) {
- if (line.length()) {
- // Most of the time the first non-blank character in line determines that line's type
- // Now finds the first non-blank character
- unsigned i; // Declares counter here to make it persistent after the for loop
- for (i = 0; i < line.length(); ++i) {
- if (!isspace(line[i]))
- break;
- }
-
- // Checks if it was a blank line
- if (i == line.length())
- return SCE_LOT_DEFAULT;
-
- switch (line[i]) {
- case '*': // Fail measurement
- return SCE_LOT_FAIL;
-
- case '+': // Header
- case '|': // Header
- return SCE_LOT_HEADER;
-
- case ':': // Set test limits
- return SCE_LOT_SET;
-
- case '-': // Section break
- return SCE_LOT_BREAK;
-
- default: // Any other line
- // Checks for message at the end of lot file
- if (line.find("PASSED") != std::string::npos) {
- return SCE_LOT_PASS;
- }
- else if (line.find("FAILED") != std::string::npos) {
- return SCE_LOT_FAIL;
- }
- else if (line.find("ABORTED") != std::string::npos) {
- return SCE_LOT_ABORT;
- }
- else {
- return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
- }
- }
- }
- else {
- return SCE_LOT_DEFAULT;
- }
-}
-
-static void ColourizeLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- bool atLineStart = true;// Arms the 'at line start' flag
- char chNext = styler.SafeGetCharAt(startPos);
- std::string line("");
- line.reserve(256); // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
-
- // Styles LOT document
- unsigned int i; // Declared here because it's used after the for loop
- for (i = startPos; i < startPos + length; ++i) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- line += ch;
- atLineStart = false;
-
- // LOT files are only used on the Win32 platform, thus EOL == CR+LF
- // Searches for the end of line
- if (ch == '\r' && chNext == '\n') {
- line += chNext; // Gets the '\n'
- ++i; // Advances past the '\n'
- chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line
- styler.ColourTo(i, GetLotLineState(line));
- line = "";
- atLineStart = true; // Arms flag for next line
- }
- }
-
- // Last line may not have a line ending
- if (!atLineStart) {
- styler.ColourTo(i - 1, GetLotLineState(line));
- }
-}
-
-// Folds an MPT LOT file: the blocks that can be folded are:
-// sections (headed by a set line)
-// passes (contiguous pass results within a section)
-// fails (contiguous fail results within a section)
-static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
-
- char chNext = styler.SafeGetCharAt(startPos);
- int style = SCE_LOT_DEFAULT;
- int styleNext = styler.StyleAt(startPos);
- int lev = SC_FOLDLEVELBASE;
-
- // Gets style of previous line if not at the beginning of the document
- if (startPos > 1)
- style = styler.StyleAt(startPos - 2);
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (ch == '\r' && chNext == '\n') {
- // TO DO:
- // Should really get the state of the previous line from the styler
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 2);
-
- switch (style) {
-/*
- case SCE_LOT_SET:
- lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
- break;
-*/
- case SCE_LOT_FAIL:
-/*
- if (stylePrev != SCE_LOT_FAIL)
- lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
- else
- lev = SC_FOLDLEVELBASE + 1;
-*/
- lev = SC_FOLDLEVELBASE;
- break;
-
- default:
- if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
- lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
- else
- lev = SC_FOLDLEVELBASE + 1;
-
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- break;
- }
-
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
-
- lineCurrent++;
- visibleChars = 0;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, lev | flagsNext);
-}
-
-static const char * const emptyWordListDesc[] = {
- 0
-};
-
-LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexMSSQL.cxx
- ** Lexer for MSSQL.
- **/
-// By Filip Yaghob <fyaghob@gmail.com>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-#define KW_MSSQL_STATEMENTS 0
-#define KW_MSSQL_DATA_TYPES 1
-#define KW_MSSQL_SYSTEM_TABLES 2
-#define KW_MSSQL_GLOBAL_VARIABLES 3
-#define KW_MSSQL_FUNCTIONS 4
-#define KW_MSSQL_STORED_PROCEDURES 5
-#define KW_MSSQL_OPERATORS 6
-
-static bool isMSSQLOperator(char ch) {
- if (isascii(ch) && isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
- ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
- ch == '<' || ch == '>' || ch == '/' ||
- ch == '!' || ch == '~' || ch == '(' || ch == ')' ||
- ch == ',')
- return true;
- return false;
-}
-
-static char classifyWordSQL(unsigned int start,
- unsigned int end,
- WordList *keywordlists[],
- Accessor &styler,
- unsigned int actualState,
- unsigned int prevState) {
- char s[256];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
-
- WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
- WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
- WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
- WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
- WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
- WordList &kwStoredProcedures = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
- WordList &kwOperators = *keywordlists[KW_MSSQL_OPERATORS];
-
- for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- s[i + 1] = '\0';
- }
- char chAttr = SCE_MSSQL_IDENTIFIER;
-
- if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {
-
- if (kwGlobalVariables.InList(&s[2]))
- chAttr = SCE_MSSQL_GLOBAL_VARIABLE;
-
- } else if (wordIsNumber) {
- chAttr = SCE_MSSQL_NUMBER;
-
- } else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
- // Look first in datatypes
- if (kwDataTypes.InList(s))
- chAttr = SCE_MSSQL_DATATYPE;
- else if (kwOperators.InList(s))
- chAttr = SCE_MSSQL_OPERATOR;
- else if (kwStatements.InList(s))
- chAttr = SCE_MSSQL_STATEMENT;
- else if (kwSystemTables.InList(s))
- chAttr = SCE_MSSQL_SYSTABLE;
- else if (kwFunctions.InList(s))
- chAttr = SCE_MSSQL_FUNCTION;
- else if (kwStoredProcedures.InList(s))
- chAttr = SCE_MSSQL_STORED_PROCEDURE;
-
- } else {
- if (kwOperators.InList(s))
- chAttr = SCE_MSSQL_OPERATOR;
- else if (kwStatements.InList(s))
- chAttr = SCE_MSSQL_STATEMENT;
- else if (kwSystemTables.InList(s))
- chAttr = SCE_MSSQL_SYSTABLE;
- else if (kwFunctions.InList(s))
- chAttr = SCE_MSSQL_FUNCTION;
- else if (kwStoredProcedures.InList(s))
- chAttr = SCE_MSSQL_STORED_PROCEDURE;
- else if (kwDataTypes.InList(s))
- chAttr = SCE_MSSQL_DATATYPE;
- }
-
- styler.ColourTo(end, chAttr);
-
- return chAttr;
-}
-
-static void ColouriseMSSQLDoc(unsigned int startPos, int length,
- int initStyle, WordList *keywordlists[], Accessor &styler) {
-
-
- styler.StartAt(startPos);
-
- bool fold = styler.GetPropertyInt("fold") != 0;
- int lineCurrent = styler.GetLine(startPos);
- int spaceFlags = 0;
-
- int state = initStyle;
- int prevState = initStyle;
- char chPrev = ' ';
- char chNext = styler[startPos];
- styler.StartSegment(startPos);
- unsigned int lengthDoc = startPos + length;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
- int lev = indentCurrent;
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
- if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- if (fold) {
- styler.SetLevel(lineCurrent, lev);
- }
- }
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- // When the last char isn't part of the state (have to deal with it too)...
- if ( (state == SCE_MSSQL_IDENTIFIER) ||
- (state == SCE_MSSQL_STORED_PROCEDURE) ||
- (state == SCE_MSSQL_DATATYPE) ||
- //~ (state == SCE_MSSQL_COLUMN_NAME) ||
- (state == SCE_MSSQL_FUNCTION) ||
- //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
- (state == SCE_MSSQL_VARIABLE)) {
- if (!iswordchar(ch)) {
- int stateTmp;
-
- if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
- styler.ColourTo(i - 1, state);
- stateTmp = state;
- } else
- stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
-
- prevState = state;
-
- if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
- state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
- else
- state = SCE_MSSQL_DEFAULT;
- }
- } else if (state == SCE_MSSQL_LINE_COMMENT) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- prevState = state;
- state = SCE_MSSQL_DEFAULT;
- }
- } else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
- if ((ch != '@') && !iswordchar(ch)) {
- classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
- prevState = state;
- state = SCE_MSSQL_DEFAULT;
- }
- }
-
- // If is the default or one of the above succeeded
- if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
- if (iswordstart(ch)) {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- state = SCE_MSSQL_IDENTIFIER;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- state = SCE_MSSQL_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- state = SCE_MSSQL_LINE_COMMENT;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- state = SCE_MSSQL_STRING;
- } else if (ch == '"') {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- state = SCE_MSSQL_COLUMN_NAME;
- } else if (ch == '[') {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- state = SCE_MSSQL_COLUMN_NAME_2;
- } else if (isMSSQLOperator(ch)) {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- styler.ColourTo(i, SCE_MSSQL_OPERATOR);
- //~ style = SCE_MSSQL_DEFAULT;
- prevState = state;
- state = SCE_MSSQL_DEFAULT;
- } else if (ch == '@') {
- styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
- prevState = state;
- if (chNext == '@') {
- state = SCE_MSSQL_GLOBAL_VARIABLE;
-// i += 2;
- } else
- state = SCE_MSSQL_VARIABLE;
- }
-
-
- // When the last char is part of the state...
- } else if (state == SCE_MSSQL_COMMENT) {
- if (ch == '/' && chPrev == '*') {
- if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
- (styler.GetStartSegment() == startPos)))) {
- styler.ColourTo(i, state);
- //~ state = SCE_MSSQL_COMMENT;
- prevState = state;
- state = SCE_MSSQL_DEFAULT;
- }
- }
- } else if (state == SCE_MSSQL_STRING) {
- if (ch == '\'') {
- if ( chNext == '\'' ) {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- styler.ColourTo(i, state);
- prevState = state;
- state = SCE_MSSQL_DEFAULT;
- //i++;
- }
- //ch = chNext;
- //chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (state == SCE_MSSQL_COLUMN_NAME) {
- if (ch == '"') {
- if (chNext == '"') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- styler.ColourTo(i, state);
- prevState = state;
- state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
- //i++;
- }
- }
- } else if (state == SCE_MSSQL_COLUMN_NAME_2) {
- if (ch == ']') {
- styler.ColourTo(i, state);
- prevState = state;
- state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
- //i++;
- }
- }
-
- chPrev = ch;
- }
- styler.ColourTo(lengthDoc - 1, state);
-}
-
-static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
- char s[10];
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styler.StyleAt(i);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- // Comment folding
- if (foldComment) {
- if (!inComment && (style == SCE_MSSQL_COMMENT))
- levelCurrent++;
- else if (inComment && (style != SCE_MSSQL_COMMENT))
- levelCurrent--;
- inComment = (style == SCE_MSSQL_COMMENT);
- }
- if (style == SCE_MSSQL_STATEMENT) {
- // Folding between begin or case and end
- if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') {
- for (unsigned int j = 0; j < 5; j++) {
- if (!iswordchar(styler[i + j])) {
- break;
- }
- s[j] = static_cast<char>(tolower(styler[i + j]));
- s[j + 1] = '\0';
- }
- if ((strcmp(s, "begin") == 0) || (strcmp(s, "case") == 0)) {
- levelCurrent++;
- }
- if (strcmp(s, "end") == 0) {
- levelCurrent--;
- }
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const sqlWordListDesc[] = {
- "Statements",
- "Data Types",
- "System tables",
- "Global variables",
- "Functions",
- "System Stored Procedures",
- "Operators",
- 0,
-};
-
-LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/**
- * @file LexMagik.cxx
- * Lexer for GE(r) Smallworld(tm) MagikSF
- */
-// Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-/**
- * Is it a core character (C isalpha(), exclamation and question mark)
- *
- * \param ch The character
- * \return True if ch is a character, False otherwise
- */
-static inline bool IsAlphaCore(int ch) {
- return (isalpha(ch) || ch == '!' || ch == '?');
-}
-
-/**
- * Is it a character (IsAlphaCore() and underscore)
- *
- * \param ch The character
- * \return True if ch is a character, False otherwise
- */
-static inline bool IsAlpha(int ch) {
- return (IsAlphaCore(ch) || ch == '_');
-}
-
-/**
- * Is it a symbolic character (IsAlpha() and colon)
- *
- * \param ch The character
- * \return True if ch is a character, False otherwise
- */
-static inline bool IsAlphaSym(int ch) {
- return (IsAlpha(ch) || ch == ':');
-}
-
-/**
- * Is it a numerical character (IsAlpha() and 0 - 9)
- *
- * \param ch The character
- * \return True if ch is a character, False otherwise
- */
-static inline bool IsAlNum(int ch) {
- return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
-}
-
-/**
- * Is it a symbolic numerical character (IsAlNum() and colon)
- *
- * \param ch The character
- * \return True if ch is a character, False otherwise
- */
-static inline bool IsAlNumSym(int ch) {
- return (IsAlNum(ch) || ch == ':');
-}
-
-/**
- * The lexer function
- *
- * \param startPos Where to start scanning
- * \param length Where to scan to
- * \param initStyle The style at the initial point, not used in this folder
- * \param keywordslists The keywordslists, currently, number 5 is used
- * \param styler The styler
- */
-static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- styler.StartAt(startPos);
-
- WordList &keywords = *keywordlists[0];
- WordList &pragmatics = *keywordlists[1];
- WordList &containers = *keywordlists[2];
- WordList &flow = *keywordlists[3];
- WordList &characters = *keywordlists[4];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
-
- for (; sc.More(); sc.Forward()) {
-
- repeat:
-
- if(sc.ch == '#') {
- if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
- else sc.SetState(SCE_MAGIK_COMMENT);
- for(; sc.More() && !(sc.atLineEnd); sc.Forward());
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
-
- if(sc.ch == '"') {
- sc.SetState(SCE_MAGIK_STRING);
-
- if(sc.More())
- {
- sc.Forward();
- for(; sc.More() && sc.ch != '"'; sc.Forward());
- }
-
- sc.ForwardSetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
-
- // The default state
- if(sc.state == SCE_MAGIK_DEFAULT) {
-
- // A certain keyword has been detected
- if (sc.ch == '_' && (
- sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
- char keyword[50];
- memset(keyword, '\0', 50);
-
- for(
- int scanPosition = 0;
- scanPosition < 50;
- scanPosition++) {
- char keywordChar = static_cast<char>(
- tolower(styler.SafeGetCharAt(
- scanPosition +
- static_cast<int>(sc.currentPos+1), ' ')));
- if(IsAlpha(keywordChar)) {
- keyword[scanPosition] = keywordChar;
- } else {
- break;
- }
- }
-
- // It is a pragma
- if(pragmatics.InList(keyword)) {
- sc.SetState(SCE_MAGIK_PRAGMA);
- }
-
- // it is a normal keyword like _local, _self, etc.
- else if(keywords.InList(keyword)) {
- sc.SetState(SCE_MAGIK_KEYWORD);
- }
-
- // It is a container keyword, such as _method, _proc, etc.
- else if(containers.InList(keyword)) {
- sc.SetState(SCE_MAGIK_CONTAINER);
- }
-
- // It is a flow keyword, such as _for, _if, _try, etc.
- else if(flow.InList(keyword)) {
- sc.SetState(SCE_MAGIK_FLOW);
- }
-
- // Interpret as unknown keyword
- else {
- sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
- }
- }
-
- // Symbolic expression
- else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
- sc.SetState(SCE_MAGIK_SYMBOL);
- bool firstTrip = true;
- for(sc.Forward(); sc.More(); sc.Forward()) {
- if(firstTrip && IsAlphaSym(sc.ch));
- else if(!firstTrip && IsAlNumSym(sc.ch));
- else if(sc.ch == '|') {
- for(sc.Forward();
- sc.More() && sc.ch != '|';
- sc.Forward());
- }
- else break;
-
- firstTrip = false;
- }
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
-
- // Identifier (label) expression
- else if(sc.ch == '@') {
- sc.SetState(SCE_MAGIK_IDENTIFIER);
- bool firstTrip = true;
- for(sc.Forward(); sc.More(); sc.Forward()) {
- if(firstTrip && IsAlphaCore(sc.ch)) {
- firstTrip = false;
- }
- else if(!firstTrip && IsAlpha(sc.ch));
- else break;
- }
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
-
- // Start of a character
- else if(sc.ch == '%') {
- sc.SetState(SCE_MAGIK_CHARACTER);
- sc.Forward();
- char keyword[50];
- memset(keyword, '\0', 50);
-
- for(
- int scanPosition = 0;
- scanPosition < 50;
- scanPosition++) {
- char keywordChar = static_cast<char>(
- tolower(styler.SafeGetCharAt(
- scanPosition +
- static_cast<int>(sc.currentPos), ' ')));
- if(IsAlpha(keywordChar)) {
- keyword[scanPosition] = keywordChar;
- } else {
- break;
- }
- }
-
- if(characters.InList(keyword)) {
- sc.Forward(strlen(keyword));
- } else {
- sc.Forward();
- }
-
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
-
- // Operators
- else if(
- sc.ch == '>' ||
- sc.ch == '<' ||
- sc.ch == '.' ||
- sc.ch == ',' ||
- sc.ch == '+' ||
- sc.ch == '-' ||
- sc.ch == '/' ||
- sc.ch == '*' ||
- sc.ch == '~' ||
- sc.ch == '$' ||
- sc.ch == '=') {
- sc.SetState(SCE_MAGIK_OPERATOR);
- }
-
- // Braces
- else if(sc.ch == '(' || sc.ch == ')') {
- sc.SetState(SCE_MAGIK_BRACE_BLOCK);
- }
-
- // Brackets
- else if(sc.ch == '{' || sc.ch == '}') {
- sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
- }
-
- // Square Brackets
- else if(sc.ch == '[' || sc.ch == ']') {
- sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
- }
-
-
- }
-
- // It is an operator
- else if(
- sc.state == SCE_MAGIK_OPERATOR ||
- sc.state == SCE_MAGIK_BRACE_BLOCK ||
- sc.state == SCE_MAGIK_BRACKET_BLOCK ||
- sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
-
- // It is the pragma state
- else if(sc.state == SCE_MAGIK_PRAGMA) {
- if(!IsAlpha(sc.ch)) {
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
- }
-
- // It is the keyword state
- else if(
- sc.state == SCE_MAGIK_KEYWORD ||
- sc.state == SCE_MAGIK_CONTAINER ||
- sc.state == SCE_MAGIK_FLOW ||
- sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
- if(!IsAlpha(sc.ch)) {
- sc.SetState(SCE_MAGIK_DEFAULT);
- goto repeat;
- }
- }
- }
-
- sc.Complete();
-}
-
-/**
- * The word list description
- */
-static const char * const magikWordListDesc[] = {
- "Accessors (local, global, self, super, thisthread)",
- "Pragmatic (pragma, private)",
- "Containers (method, block, proc)",
- "Flow (if, then, elif, else)",
- "Characters (space, tab, newline, return)",
- "Fold Containers (method, proc, block, if, loop)",
- 0};
-
-/**
- * This function detects keywords which are able to have a body. Note that it
- * uses the Fold Containers word description, not the containers description. It
- * only works when the style at that particular position is set on Containers
- * or Flow (number 3 or 4).
- *
- * \param keywordslist The list of keywords that are scanned, they should only
- * contain the start keywords, not the end keywords
- * \param The actual keyword
- * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
- * 0 otherwise
- */
-static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
- if(
- strlen(keyword) > 3 &&
- keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
- if (keywordslist.InList(keyword + 3)) {
- return -1;
- }
-
- } else {
- if(keywordslist.InList(keyword)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-/**
- * The folding function
- *
- * \param startPos Where to start scanning
- * \param length Where to scan to
- * \param keywordslists The keywordslists, currently, number 5 is used
- * \param styler The styler
- */
-static void FoldMagikDoc(unsigned int startPos, int length, int,
- WordList *keywordslists[], Accessor &styler) {
-
- bool compact = styler.GetPropertyInt("fold.compact") != 0;
-
- WordList &foldingElements = *keywordslists[5];
- int endPos = startPos + length;
- int line = styler.GetLine(startPos);
- int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
- int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
-
- for(
- int currentPos = startPos;
- currentPos < endPos;
- currentPos++) {
- char currentState = styler.StyleAt(currentPos);
- char c = styler.SafeGetCharAt(currentPos, ' ');
- int prevLine = styler.GetLine(currentPos - 1);
- line = styler.GetLine(currentPos);
-
- // Default situation
- if(prevLine < line) {
- styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
- flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
- }
-
- if(
- (
- currentState == SCE_MAGIK_CONTAINER ||
- currentState == SCE_MAGIK_FLOW
- ) &&
- c == '_') {
-
- char keyword[50];
- memset(keyword, '\0', 50);
-
- for(
- int scanPosition = 0;
- scanPosition < 50;
- scanPosition++) {
- char keywordChar = static_cast<char>(
- tolower(styler.SafeGetCharAt(
- scanPosition +
- currentPos + 1, ' ')));
- if(IsAlpha(keywordChar)) {
- keyword[scanPosition] = keywordChar;
- } else {
- break;
- }
- }
-
- if(IsFoldingContainer(foldingElements, keyword) > 0) {
- styler.SetLevel(
- line,
- styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
- level++;
- } else if(IsFoldingContainer(foldingElements, keyword) < 0) {
- styler.SetLevel(line, styler.LevelAt(line));
- level--;
- }
- }
-
- if(
- compact && (
- currentState == SCE_MAGIK_BRACE_BLOCK ||
- currentState == SCE_MAGIK_BRACKET_BLOCK ||
- currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
- if(c == '{' || c == '[' || c == '(') {
- styler.SetLevel(
- line,
- styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
- level++;
- } else if(c == '}' || c == ']' || c == ')') {
- styler.SetLevel(line, styler.LevelAt(line));
- level--;
- }
- }
- }
-
-}
-
-/**
- * Injecting the module
- */
-LexerModule lmMagikSF(
- SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);
-
+++ /dev/null
-/******************************************************************
- * LexMarkdown.cxx
- *
- * A simple Markdown lexer for scintilla.
- *
- * Includes highlighting for some extra features from the
- * Pandoc implementation; strikeout, using '#.' as a default
- * ordered list item marker, and delimited code blocks.
- *
- * Limitations:
- *
- * Standard indented code blocks are not highlighted at all,
- * as it would conflict with other indentation schemes. Use
- * delimited code blocks for blanket highlighting of an
- * entire code block. Embedded HTML is not highlighted either.
- * Blanket HTML highlighting has issues, because some Markdown
- * implementations allow Markdown markup inside of the HTML. Also,
- * there is a following blank line issue that can't be ignored,
- * explained in the next paragraph. Embedded HTML and code
- * blocks would be better supported with language specific
- * highlighting.
- *
- * The highlighting aims to accurately reflect correct syntax,
- * but a few restrictions are relaxed. Delimited code blocks are
- * highlighted, even if the line following the code block is not blank.
- * Requiring a blank line after a block, breaks the highlighting
- * in certain cases, because of the way Scintilla ends up calling
- * the lexer.
- *
- * Written by Jon Strait - jstrait@moonloop.net
- *
- * The License.txt file describes the conditions under which this
- * software may be distributed.
- *
- *****************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsNewline(const int ch) {
- return (ch == '\n' || ch == '\r');
-}
-
-// True if can follow ch down to the end with possibly trailing whitespace
-static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
- unsigned int i = 0;
- while (sc.GetRelative(++i) == ch)
- ;
- // Skip over whitespace
- while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
- ++i;
- if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
- sc.Forward(i);
- sc.ChangeState(state);
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- return true;
- }
- else return false;
-}
-
-// Set the state on text section from current to length characters,
-// then set the rest until the newline to default, except for any characters matching token
-static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
- sc.SetState(state);
- sc.Forward(length);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- sc.Forward();
- bool started = false;
- while (sc.More() && !IsNewline(sc.ch)) {
- if (sc.ch == token && !started) {
- sc.SetState(state);
- started = true;
- }
- else if (sc.ch != token) {
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- started = false;
- }
- sc.Forward();
- }
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
-}
-
-// Does the previous line have more than spaces and tabs?
-static bool HasPrevLineContent(StyleContext &sc) {
- int i = 0;
- // Go back to the previous newline
- while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
- ;
- while (--i + sc.currentPos) {
- if (IsNewline(sc.GetRelative(i)))
- break;
- if (!IsASpaceOrTab(sc.GetRelative(i)))
- return true;
- }
- return false;
-}
-
-static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
- int c, count = 1;
- unsigned int i = 0;
- while (++i) {
- c = sc.GetRelative(i);
- if (c == sc.ch)
- ++count;
- // hit a terminating character
- else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
- // Are we a valid HRULE
- if ((IsNewline(c) || sc.currentPos + i == endPos) &&
- count >= 3 && !HasPrevLineContent(sc)) {
- sc.SetState(SCE_MARKDOWN_HRULE);
- sc.Forward(i);
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- return true;
- }
- else {
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- return false;
- }
- }
- }
- return false;
-}
-
-static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle,
- WordList **, Accessor &styler) {
- unsigned int endPos = startPos + length;
- int precharCount = 0;
- // Don't advance on a new loop iteration and retry at the same position.
- // Useful in the corner case of having to start at the beginning file position
- // in the default state.
- bool freezeCursor = false;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- while (sc.More()) {
- // Skip past escaped characters
- if (sc.ch == '\\') {
- sc.Forward();
- continue;
- }
-
- // A blockquotes resets the line semantics
- if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
-
- // Conditional state-based actions
- if (sc.state == SCE_MARKDOWN_CODE2) {
- if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
- sc.Forward(2);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- else if (sc.state == SCE_MARKDOWN_CODE) {
- if (sc.ch == '`' && sc.chPrev != ' ')
- sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
- }
- /* De-activated because it gets in the way of other valid indentation
- * schemes, for example multiple paragraphs inside a list item.
- // Code block
- else if (sc.state == SCE_MARKDOWN_CODEBK) {
- bool d = true;
- if (IsNewline(sc.ch)) {
- if (sc.chNext != '\t') {
- for (int c = 1; c < 5; ++c) {
- if (sc.GetRelative(c) != ' ')
- d = false;
- }
- }
- }
- else if (sc.atLineStart) {
- if (sc.ch != '\t' ) {
- for (int i = 0; i < 4; ++i) {
- if (sc.GetRelative(i) != ' ')
- d = false;
- }
- }
- }
- if (!d)
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- }
- */
- // Strong
- else if (sc.state == SCE_MARKDOWN_STRONG1) {
- if (sc.Match("**") && sc.chPrev != ' ') {
- sc.Forward(2);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- else if (sc.state == SCE_MARKDOWN_STRONG2) {
- if (sc.Match("__") && sc.chPrev != ' ') {
- sc.Forward(2);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- // Emphasis
- else if (sc.state == SCE_MARKDOWN_EM1) {
- if (sc.ch == '*' && sc.chPrev != ' ')
- sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
- }
- else if (sc.state == SCE_MARKDOWN_EM2) {
- if (sc.ch == '_' && sc.chPrev != ' ')
- sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
- }
- else if (sc.state == SCE_MARKDOWN_CODEBK) {
- if (sc.atLineStart && sc.Match("~~~")) {
- int i = 1;
- while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
- i++;
- sc.Forward(i);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- else if (sc.state == SCE_MARKDOWN_STRIKEOUT) {
- if (sc.Match("~~") && sc.chPrev != ' ') {
- sc.Forward(2);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) {
- // Header
- if (sc.Match("######"))
- SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc);
- else if (sc.Match("#####"))
- SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc);
- else if (sc.Match("####"))
- SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc);
- else if (sc.Match("###"))
- SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc);
- else if (sc.Match("##"))
- SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc);
- else if (sc.Match("#")) {
- // Catch the special case of an unordered list
- if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
- precharCount = 0;
- sc.SetState(SCE_MARKDOWN_PRECHAR);
- }
- else
- SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc);
- }
- // Code block
- else if (sc.Match("~~~")) {
- if (!HasPrevLineContent(sc))
- sc.SetState(SCE_MARKDOWN_CODEBK);
- else
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- else if (sc.ch == '=') {
- if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc))
- ;
- else
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- else if (sc.ch == '-') {
- if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc))
- ;
- else {
- precharCount = 0;
- sc.SetState(SCE_MARKDOWN_PRECHAR);
- }
- }
- else if (IsNewline(sc.ch))
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- else {
- precharCount = 0;
- sc.SetState(SCE_MARKDOWN_PRECHAR);
- }
- }
-
- // The header lasts until the newline
- else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
- sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
- sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) {
- if (IsNewline(sc.ch))
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- }
-
- // New state only within the initial whitespace
- if (sc.state == SCE_MARKDOWN_PRECHAR) {
- // Blockquote
- if (sc.ch == '>' && precharCount < 5)
- sc.SetState(SCE_MARKDOWN_BLOCKQUOTE);
- /*
- // Begin of code block
- else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
- sc.SetState(SCE_MARKDOWN_CODEBK);
- */
- // HRule - Total of three or more hyphens, asterisks, or underscores
- // on a line by themselves
- else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
- ;
- // Unordered list
- else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) {
- sc.SetState(SCE_MARKDOWN_ULIST_ITEM);
- sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
- }
- // Ordered list
- else if (IsADigit(sc.ch)) {
- int digitCount = 0;
- while (IsADigit(sc.GetRelative(++digitCount)))
- ;
- if (sc.GetRelative(digitCount) == '.' &&
- IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
- sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
- sc.Forward(digitCount + 1);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- // Alternate Ordered list
- else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
- sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
- sc.Forward(2);
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- }
- else if (sc.ch != ' ' || precharCount > 2)
- sc.SetState(SCE_MARKDOWN_DEFAULT);
- else
- ++precharCount;
- }
-
- // New state anywhere in doc
- if (sc.state == SCE_MARKDOWN_DEFAULT) {
- if (sc.atLineStart && sc.ch == '#') {
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- freezeCursor = true;
- }
- // Links and Images
- if (sc.Match("![") || sc.ch == '[') {
- int i = 0, j = 0, k = 0;
- int len = endPos - sc.currentPos;
- while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
- ;
- if (sc.GetRelative(i) == ']') {
- j = i;
- if (sc.GetRelative(++i) == '(') {
- while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\'))
- ;
- if (sc.GetRelative(i) == ')')
- k = i;
- }
- else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
- while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
- ;
- if (sc.GetRelative(i) == ']')
- k = i;
- }
- }
- // At least a link text
- if (j) {
- sc.SetState(SCE_MARKDOWN_LINK);
- sc.Forward(j);
- // Also has a URL or reference portion
- if (k)
- sc.Forward(k - j);
- sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
- }
- }
- // Code - also a special case for alternate inside spacing
- if (sc.Match("``") && sc.GetRelative(3) != ' ') {
- sc.SetState(SCE_MARKDOWN_CODE2);
- sc.Forward();
- }
- else if (sc.ch == '`' && sc.chNext != ' ') {
- sc.SetState(SCE_MARKDOWN_CODE);
- }
- // Strong
- else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
- sc.SetState(SCE_MARKDOWN_STRONG1);
- sc.Forward();
- }
- else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
- sc.SetState(SCE_MARKDOWN_STRONG2);
- sc.Forward();
- }
- // Emphasis
- else if (sc.ch == '*' && sc.chNext != ' ')
- sc.SetState(SCE_MARKDOWN_EM1);
- else if (sc.ch == '_' && sc.chNext != ' ')
- sc.SetState(SCE_MARKDOWN_EM2);
- // Strikeout
- else if (sc.Match("~~") && sc.GetRelative(2) != ' ') {
- sc.SetState(SCE_MARKDOWN_STRIKEOUT);
- sc.Forward();
- }
- // Beginning of line
- else if (IsNewline(sc.ch))
- sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
- }
- // Advance if not holding back the cursor for this iteration.
- if (!freezeCursor)
- sc.Forward();
- freezeCursor = false;
- }
- sc.Complete();
-}
-
-LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown");
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexMatlab.cxx
- ** Lexer for Matlab.
- ** Written by José Fonseca
- **
- ** Changes by Christoph Dalitz 2003/12/04:
- ** - added support for Octave
- ** - Strings can now be included both in single or double quotes
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 bool IsMatlabCommentChar(int c) {
- return (c == '%') ;
-}
-
-static bool IsOctaveCommentChar(int c) {
- return (c == '%' || c == '#') ;
-}
-
-static bool IsMatlabComment(Accessor &styler, int pos, int len) {
- return len > 0 && IsMatlabCommentChar(styler[pos]) ;
-}
-
-static bool IsOctaveComment(Accessor &styler, int pos, int len) {
- return len > 0 && IsOctaveCommentChar(styler[pos]) ;
-}
-
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static void ColouriseMatlabOctaveDoc(
- unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler,
- bool (*IsCommentChar)(int)) {
-
- WordList &keywords = *keywordlists[0];
-
- styler.StartAt(startPos);
-
- bool transpose = false;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_MATLAB_OPERATOR) {
- if (sc.chPrev == '.') {
- if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
- sc.ForwardSetState(SCE_MATLAB_DEFAULT);
- transpose = false;
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_MATLAB_DEFAULT);
- transpose = true;
- } else {
- sc.SetState(SCE_MATLAB_DEFAULT);
- }
- } else {
- sc.SetState(SCE_MATLAB_DEFAULT);
- }
- } else if (sc.state == SCE_MATLAB_KEYWORD) {
- if (!isalnum(sc.ch) && sc.ch != '_') {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.SetState(SCE_MATLAB_DEFAULT);
- transpose = false;
- } else {
- sc.ChangeState(SCE_MATLAB_IDENTIFIER);
- sc.SetState(SCE_MATLAB_DEFAULT);
- transpose = true;
- }
- }
- } else if (sc.state == SCE_MATLAB_NUMBER) {
- if (!isdigit(sc.ch) && sc.ch != '.'
- && !(sc.ch == 'e' || sc.ch == 'E')
- && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
- sc.SetState(SCE_MATLAB_DEFAULT);
- transpose = true;
- }
- } else if (sc.state == SCE_MATLAB_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_MATLAB_DEFAULT);
- }
- } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_MATLAB_DEFAULT);
- }
- } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_MATLAB_DEFAULT);
- transpose = false;
- }
- }
-
- if (sc.state == SCE_MATLAB_DEFAULT) {
- if (IsCommentChar(sc.ch)) {
- sc.SetState(SCE_MATLAB_COMMENT);
- } else if (sc.ch == '!' && sc.chNext != '=' ) {
- sc.SetState(SCE_MATLAB_COMMAND);
- } else if (sc.ch == '\'') {
- if (transpose) {
- sc.SetState(SCE_MATLAB_OPERATOR);
- } else {
- sc.SetState(SCE_MATLAB_STRING);
- }
- } else if (sc.ch == '"') {
- sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
- } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
- sc.SetState(SCE_MATLAB_NUMBER);
- } else if (isalpha(sc.ch)) {
- sc.SetState(SCE_MATLAB_KEYWORD);
- } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
- if (sc.ch == ')' || sc.ch == ']') {
- transpose = true;
- } else {
- transpose = false;
- }
- sc.SetState(SCE_MATLAB_OPERATOR);
- } else {
- transpose = false;
- }
- }
- }
- sc.Complete();
-}
-
-static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
-}
-
-static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
-}
-
-static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler,
- bool (*IsComment)(Accessor&, int, int)) {
-
- int endPos = startPos + length;
-
- // Backtrack to previous line in case need to fix its fold status
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
- char chNext = styler[startPos];
- for (int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- }
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- }
- }
-}
-
-static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
-}
-
-static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
-}
-
-static const char * const matlabWordListDesc[] = {
- "Keywords",
- 0
-};
-
-static const char * const octaveWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
-
-LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-
-// File: LexMetapost.cxx - general context conformant metapost coloring scheme
-// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
-// Version: September 28, 2003
-// Modified by instanton: July 10, 2007
-// Folding based on keywordlists[]
-
-// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-// This lexer is derived from the one written for the texwork environment (1999++) which in
-// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-// val SCE_METAPOST_DEFAULT = 0
-// val SCE_METAPOST_SPECIAL = 1
-// val SCE_METAPOST_GROUP = 2
-// val SCE_METAPOST_SYMBOL = 3
-// val SCE_METAPOST_COMMAND = 4
-// val SCE_METAPOST_TEXT = 5
-
-// Definitions in SciTEGlobal.properties:
-//
-// Metapost Highlighting
-//
-// # Default
-// style.metapost.0=fore:#7F7F00
-// # Special
-// style.metapost.1=fore:#007F7F
-// # Group
-// style.metapost.2=fore:#880000
-// # Symbol
-// style.metapost.3=fore:#7F7F00
-// # Command
-// style.metapost.4=fore:#008800
-// # Text
-// style.metapost.5=fore:#000000
-
-// lexer.tex.comment.process=0
-
-// Auxiliary functions:
-
-static inline bool endOfLine(Accessor &styler, unsigned int i) {
- return
- (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
-}
-
-static inline bool isMETAPOSTcomment(int ch) {
- return
- (ch == '%') ;
-}
-
-static inline bool isMETAPOSTone(int ch) {
- return
- (ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') ||
- (ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') ||
- (ch == '{') || (ch == '}') || (ch == '\'') || (ch == '\"') ;
-}
-
-static inline bool isMETAPOSTtwo(int ch) {
- return
- (ch == ';') || (ch == '$') || (ch == '@') || (ch == '#');
-}
-
-static inline bool isMETAPOSTthree(int ch) {
- return
- (ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') ||
- (ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') ||
- (ch == '!') || (ch == '?') || (ch == '^') || (ch == '&') ||
- (ch == '%') ;
-}
-
-static inline bool isMETAPOSTidentifier(int ch) {
- return
- ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
- (ch == '_') ;
-}
-
-static inline bool isMETAPOSTnumber(int ch) {
- return
- (ch >= '0') && (ch <= '9') ;
-}
-
-static inline bool isMETAPOSTstring(int ch) {
- return
- (ch == '\"') ;
-}
-
-static inline bool isMETAPOSTcolon(int ch) {
- return
- (ch == ':') ;
-}
-
-static inline bool isMETAPOSTequal(int ch) {
- return
- (ch == '=') ;
-}
-
-static int CheckMETAPOSTInterface(
- unsigned int startPos,
- int length,
- Accessor &styler,
- int defaultInterface) {
-
- char lineBuffer[1024] ;
- unsigned int linePos = 0 ;
-
- // some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)...
-
- if (styler.SafeGetCharAt(0) == '%') {
- for (unsigned int i = 0; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
- if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
- lineBuffer[linePos] = '\0';
- if (strstr(lineBuffer, "interface=none")) {
- return 0 ;
- } else if (strstr(lineBuffer, "interface=metapost") || strstr(lineBuffer, "interface=mp")) {
- return 1 ;
- } else if (strstr(lineBuffer, "interface=metafun")) {
- return 2 ;
- } else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) {
- // better would be to limit the search to just one line
- return 2 ;
- } else {
- return defaultInterface ;
- }
- }
- }
- }
-
- return defaultInterface ;
-}
-
-static void ColouriseMETAPOSTDoc(
- unsigned int startPos,
- int length,
- int,
- WordList *keywordlists[],
- Accessor &styler) {
-
- styler.StartAt(startPos) ;
- styler.StartSegment(startPos) ;
-
- bool processComment = styler.GetPropertyInt("lexer.metapost.comment.process", 0) == 1 ;
- int defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ;
-
- int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
-
- // 0 no keyword highlighting
- // 1 metapost keyword hightlighting
- // 2+ metafun keyword hightlighting
-
- int extraInterface = 0 ;
-
- if (currentInterface != 0) {
- extraInterface = currentInterface ;
- }
-
- WordList &keywords = *keywordlists[0] ;
- WordList &keywords2 = *keywordlists[extraInterface-1] ;
-
- StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;
-
- char key[100] ;
-
- bool inTeX = false ;
- bool inComment = false ;
- bool inString = false ;
- bool inClause = false ;
-
- bool going = sc.More() ; // needed because of a fuzzy end of file state
-
- for (; going; sc.Forward()) {
-
- if (! sc.More()) { going = false ; } // we need to go one behind the end of text
-
- if (inClause) {
- sc.SetState(SCE_METAPOST_TEXT) ;
- inClause = false ;
- }
-
- if (inComment) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_METAPOST_TEXT) ;
- inTeX = false ;
- inComment = false ;
- inClause = false ;
- inString = false ; // not correct but we want to stimulate one-lines
- }
- } else if (inString) {
- if (isMETAPOSTstring(sc.ch)) {
- sc.SetState(SCE_METAPOST_SPECIAL) ;
- sc.ForwardSetState(SCE_METAPOST_TEXT) ;
- inString = false ;
- } else if (sc.atLineEnd) {
- sc.SetState(SCE_METAPOST_TEXT) ;
- inTeX = false ;
- inComment = false ;
- inClause = false ;
- inString = false ; // not correct but we want to stimulate one-lines
- }
- } else {
- if ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) {
- if (sc.state == SCE_METAPOST_COMMAND) {
- sc.GetCurrent(key, sizeof(key)) ;
- if ((strcmp(key,"btex") == 0) || (strcmp(key,"verbatimtex") == 0)) {
- sc.ChangeState(SCE_METAPOST_GROUP) ;
- inTeX = true ;
- } else if (inTeX) {
- if (strcmp(key,"etex") == 0) {
- sc.ChangeState(SCE_METAPOST_GROUP) ;
- inTeX = false ;
- } else {
- sc.ChangeState(SCE_METAPOST_TEXT) ;
- }
- } else {
- if (keywords && keywords.InList(key)) {
- sc.ChangeState(SCE_METAPOST_COMMAND) ;
- } else if (keywords2 && keywords2.InList(key)) {
- sc.ChangeState(SCE_METAPOST_EXTRA) ;
- } else {
- sc.ChangeState(SCE_METAPOST_TEXT) ;
- }
- }
- }
- }
- if (isMETAPOSTcomment(sc.ch)) {
- if (! inTeX) {
- sc.SetState(SCE_METAPOST_SYMBOL) ;
- sc.ForwardSetState(SCE_METAPOST_DEFAULT) ;
- inComment = ! processComment ;
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- } else if (isMETAPOSTstring(sc.ch)) {
- if (! inTeX) {
- sc.SetState(SCE_METAPOST_SPECIAL) ;
- if (! isMETAPOSTstring(sc.chNext)) {
- sc.ForwardSetState(SCE_METAPOST_TEXT) ;
- }
- inString = true ;
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- } else if (isMETAPOSTcolon(sc.ch)) {
- if (! inTeX) {
- if (! isMETAPOSTequal(sc.chNext)) {
- sc.SetState(SCE_METAPOST_COMMAND) ;
- inClause = true ;
- } else {
- sc.SetState(SCE_METAPOST_SPECIAL) ;
- }
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- } else if (isMETAPOSTone(sc.ch)) {
- if (! inTeX) {
- sc.SetState(SCE_METAPOST_SPECIAL) ;
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- } else if (isMETAPOSTtwo(sc.ch)) {
- if (! inTeX) {
- sc.SetState(SCE_METAPOST_GROUP) ;
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- } else if (isMETAPOSTthree(sc.ch)) {
- if (! inTeX) {
- sc.SetState(SCE_METAPOST_SYMBOL) ;
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- } else if (isMETAPOSTidentifier(sc.ch)) {
- if (sc.state != SCE_METAPOST_COMMAND) {
- sc.SetState(SCE_METAPOST_TEXT) ;
- sc.ChangeState(SCE_METAPOST_COMMAND) ;
- }
- } else if (isMETAPOSTnumber(sc.ch)) {
- // rather redundant since for the moment we don't handle numbers
- sc.SetState(SCE_METAPOST_TEXT) ;
- } else if (sc.atLineEnd) {
- sc.SetState(SCE_METAPOST_TEXT) ;
- inTeX = false ;
- inComment = false ;
- inClause = false ;
- inString = false ;
- } else {
- sc.SetState(SCE_METAPOST_TEXT) ;
- }
- }
-
- }
-
- sc.Complete();
-
-}
-
-// Hooks info the system:
-
-static const char * const metapostWordListDesc[] = {
- "MetaPost",
- "MetaFun",
- 0
-} ;
-
-static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {
- WordList& keywordsStart=*keywordlists[3];
- WordList& keywordsStop1=*keywordlists[4];
-
- if (keywordsStart.InList(s)) {return 1;}
- else if (keywordsStop1.InList(s)) {return -1;}
- return 0;
-
-}
-
-static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
-{
- int length=0;
- char ch=styler.SafeGetCharAt(pos);
- *word=0;
-
- while(isMETAPOSTidentifier(ch) && isalpha(ch) && length<100){
- word[length]=ch;
- length++;
- ch=styler.SafeGetCharAt(pos+length);
- }
- word[length]=0;
- return length;
-}
-
-static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler)
-{
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos+length;
- int visibleChars=0;
- int lineCurrent=styler.GetLine(startPos);
- int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent=levelPrev;
- char chNext=styler[startPos];
-
- char buffer[100]="";
-
- for (unsigned int i=startPos; i < endPos; i++) {
- char ch=chNext;
- chNext=styler.SafeGetCharAt(i+1);
- char chPrev=styler.SafeGetCharAt(i-1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if(i==0 || chPrev == '\r' || chPrev=='\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$')
- {
- ParseMetapostWord(i, styler, buffer);
- levelCurrent += classifyFoldPointMetapost(buffer,keywordlists);
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-
-}
-
-
-LexerModule lmMETAPOST(SCLEX_METAPOST, ColouriseMETAPOSTDoc, "metapost", FoldMetapostDoc, metapostWordListDesc);
+++ /dev/null
-/**
- * Scintilla source code edit control
- * @file LexMySQL.cxx
- * Lexer for MySQL
- *
- * Improved by Mike Lischke <mike.lischke@sun.com>
- * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com>
- * Original work by Neil Hodgson <neilh@scintilla.org>
- * Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return (ch < 0x80) && (isalpha(ch) || ch == '_');
-}
-
-static inline bool IsADoxygenChar(int ch) {
- return (islower(ch) || ch == '$' || ch == '@' ||
- ch == '\\' || ch == '&' || ch == '<' ||
- ch == '>' || ch == '#' || ch == '{' ||
- ch == '}' || ch == '[' || ch == ']');
-}
-
-static inline bool IsANumberChar(int ch) {
- // Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- return (ch < 0x80) &&
- (isdigit(ch) || toupper(ch) == 'E' ||
- ch == '.' || ch == '-' || ch == '+');
-}
-
-//--------------------------------------------------------------------------------------------------
-
-/**
- * Check if the current content context represent a keyword and set the context state if so.
- */
-static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[])
-{
- int length = sc.LengthCurrent() + 1; // +1 for the next char
- char* s = new char[length];
- sc.GetCurrentLowered(s, length);
- if (keywordlists[0]->InList(s))
- sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
- else
- if (keywordlists[1]->InList(s))
- sc.ChangeState(SCE_MYSQL_KEYWORD);
- else
- if (keywordlists[2]->InList(s))
- sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
- else
- if (keywordlists[3]->InList(s))
- sc.ChangeState(SCE_MYSQL_FUNCTION);
- else
- if (keywordlists[5]->InList(s))
- sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
- else
- if (keywordlists[6]->InList(s))
- sc.ChangeState(SCE_MYSQL_USER1);
- else
- if (keywordlists[7]->InList(s))
- sc.ChangeState(SCE_MYSQL_USER2);
- else
- if (keywordlists[8]->InList(s))
- sc.ChangeState(SCE_MYSQL_USER3);
- delete [] s;
-}
-
-//--------------------------------------------------------------------------------------------------
-
-static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler)
-{
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
- // Determine if the current state should terminate.
- switch (sc.state)
- {
- case SCE_MYSQL_OPERATOR:
- sc.SetState(SCE_MYSQL_DEFAULT);
- break;
- case SCE_MYSQL_NUMBER:
- // We stop the number definition on non-numerical non-dot non-eE non-sign char.
- if (!IsANumberChar(sc.ch))
- sc.SetState(SCE_MYSQL_DEFAULT);
- break;
- case SCE_MYSQL_IDENTIFIER:
- // Switch from identifier to keyword state and open a new state for the new char.
- if (!IsAWordChar(sc.ch))
- {
- CheckForKeyword(sc, keywordlists);
-
- // Additional check for function keywords needed.
- // A function name must be followed by an opening parenthesis.
- if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
- sc.ChangeState(SCE_MYSQL_DEFAULT);
-
- sc.SetState(SCE_MYSQL_DEFAULT);
- }
- break;
- case SCE_MYSQL_VARIABLE:
- if (!IsAWordChar(sc.ch))
- sc.SetState(SCE_MYSQL_DEFAULT);
- break;
- case SCE_MYSQL_SYSTEMVARIABLE:
- if (!IsAWordChar(sc.ch))
- {
- int length = sc.LengthCurrent() + 1;
- char* s = new char[length];
- sc.GetCurrentLowered(s, length);
-
- // Check for known system variables here.
- if (keywordlists[4]->InList(&s[2]))
- sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
- delete [] s;
-
- sc.SetState(SCE_MYSQL_DEFAULT);
- }
- break;
- case SCE_MYSQL_QUOTEDIDENTIFIER:
- if (sc.ch == '`')
- {
- if (sc.chNext == '`')
- sc.Forward(); // Ignore it
- else
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
- }
- break;
- case SCE_MYSQL_COMMENT:
- case SCE_MYSQL_HIDDENCOMMAND:
- if (sc.Match('*', '/'))
- {
- sc.Forward();
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
- }
- break;
- case SCE_MYSQL_COMMENTLINE:
- if (sc.atLineStart)
- sc.SetState(SCE_MYSQL_DEFAULT);
- break;
- case SCE_MYSQL_SQSTRING:
- if (sc.ch == '\\')
- sc.Forward(); // Escape sequence
- else
- if (sc.ch == '\'')
- {
- // End of single quoted string reached?
- if (sc.chNext == '\'')
- sc.Forward();
- else
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
- }
- break;
- case SCE_MYSQL_DQSTRING:
- if (sc.ch == '\\')
- sc.Forward(); // Escape sequence
- else
- if (sc.ch == '\"')
- {
- // End of single quoted string reached?
- if (sc.chNext == '\"')
- sc.Forward();
- else
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
- }
- break;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_MYSQL_DEFAULT)
- {
- switch (sc.ch)
- {
- case '@':
- if (sc.chNext == '@')
- {
- sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
- sc.Forward(2); // Skip past @@.
- }
- else
- if (IsAWordStart(sc.ch))
- {
- sc.SetState(SCE_MYSQL_VARIABLE);
- sc.Forward(); // Skip past @.
- }
- else
- sc.SetState(SCE_MYSQL_OPERATOR);
- break;
- case '`':
- sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
- break;
- case '#':
- sc.SetState(SCE_MYSQL_COMMENTLINE);
- break;
- case '\'':
- sc.SetState(SCE_MYSQL_SQSTRING);
- break;
- case '\"':
- sc.SetState(SCE_MYSQL_DQSTRING);
- break;
- default:
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
- sc.SetState(SCE_MYSQL_NUMBER);
- else
- if (IsAWordStart(sc.ch))
- sc.SetState(SCE_MYSQL_IDENTIFIER);
- else
- if (sc.Match('/', '*'))
- {
- sc.SetState(SCE_MYSQL_COMMENT);
-
- // Skip comment introducer and check for hidden command.
- sc.Forward(2);
- if (sc.ch == '!')
- {
- sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
- sc.Forward();
- }
- }
- else
- if (sc.Match("--"))
- {
- // Special MySQL single line comment.
- sc.SetState(SCE_MYSQL_COMMENTLINE);
- sc.Forward(2);
-
- // Check the third character too. It must be a space or EOL.
- if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
- sc.ChangeState(SCE_MYSQL_OPERATOR);
- }
- else
- if (isoperator(static_cast<char>(sc.ch)))
- sc.SetState(SCE_MYSQL_OPERATOR);
- }
- }
- }
-
- // Do a final check for keywords if we currently have an identifier, to highlight them
- // also at the end of a line.
- if (sc.state == SCE_MYSQL_IDENTIFIER)
- {
- CheckForKeyword(sc, keywordlists);
-
- // Additional check for function keywords needed.
- // A function name must be followed by an opening parenthesis.
- if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
- sc.ChangeState(SCE_MYSQL_DEFAULT);
- }
-
- sc.Complete();
-}
-
-//--------------------------------------------------------------------------------------------------
-
-/**
- * Helper function to determine if we have a foldable comment currently.
- */
-static bool IsStreamCommentStyle(int style)
-{
- return style == SCE_MYSQL_COMMENT;
-}
-
-//--------------------------------------------------------------------------------------------------
-
-/**
- * Code copied from StyleContext and modified to work here. Should go into Accessor as a
- * companion to Match()...
- */
-bool MatchIgnoreCase(Accessor &styler, int currentPos, const char *s)
-{
- for (int n = 0; *s; n++)
- {
- if (*s != tolower(styler.SafeGetCharAt(currentPos + n)))
- return false;
- s++;
- }
- return true;
-}
-
-//--------------------------------------------------------------------------------------------------
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment.
-static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)
-{
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
-
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
- int levelNext = levelCurrent;
-
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
-
- bool endFound = false;
- bool whenFound = false;
- bool elseFound = false;
-
- char nextChar = styler.SafeGetCharAt(startPos);
- for (unsigned int i = startPos; length > 0; i++, length--)
- {
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
-
- char currentChar = nextChar;
- nextChar = styler.SafeGetCharAt(i + 1);
- bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
-
- switch (style)
- {
- case SCE_MYSQL_COMMENT:
- if (foldComment)
- {
- // Multiline comment style /* .. */.
- if (IsStreamCommentStyle(style))
- {
- // Increase level if we just start a foldable comment.
- if (!IsStreamCommentStyle(stylePrev))
- levelNext++;
- else
- // If we are in the middle of a foldable comment check if it ends now.
- // Don't end at the line end, though.
- if (!IsStreamCommentStyle(styleNext) && !atEOL)
- levelNext--;
- }
- }
- break;
- case SCE_MYSQL_COMMENTLINE:
- if (foldComment)
- {
- // Not really a standard, but we add support for single line comments
- // with special curly braces syntax as foldable comments too.
- // MySQL needs -- comments to be followed by space or control char
- if (styler.Match(i, "--"))
- {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- char chNext3 = styler.SafeGetCharAt(i + 3);
- if (chNext2 == '{' || chNext3 == '{')
- levelNext++;
- else
- if (chNext2 == '}' || chNext3 == '}')
- levelNext--;
- }
- }
- break;
- case SCE_MYSQL_HIDDENCOMMAND:
- if (style != stylePrev)
- levelNext++;
- else
- if (style != styleNext)
- levelNext--;
- break;
- case SCE_MYSQL_OPERATOR:
- if (currentChar == '(')
- levelNext++;
- else
- if (currentChar == ')')
- levelNext--;
- break;
- case SCE_MYSQL_MAJORKEYWORD:
- case SCE_MYSQL_KEYWORD:
- case SCE_MYSQL_FUNCTION:
- case SCE_MYSQL_PROCEDUREKEYWORD:
- // Reserved and other keywords.
- if (style != stylePrev)
- {
- bool beginFound = MatchIgnoreCase(styler, i, "begin");
- bool ifFound = MatchIgnoreCase(styler, i, "if");
- bool thenFound = MatchIgnoreCase(styler, i, "then");
- bool whileFound = MatchIgnoreCase(styler, i, "while");
- bool loopFound = MatchIgnoreCase(styler, i, "loop");
- bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
-
- if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
- {
- endFound = false;
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE)
- levelNext = SC_FOLDLEVELBASE;
-
- // Note that "else" is special here. It may or may not be followed by an "if .. then",
- // but in any case the level stays the same. When followed by an "if .. then" the level
- // will be increased later, if not, then at eol.
- }
- else
- if (!foldOnlyBegin && MatchIgnoreCase(styler, i, "else"))
- {
- levelNext--;
- elseFound = true;
- }
- else
- if (!foldOnlyBegin && thenFound)
- {
- if (whenFound)
- whenFound = false;
- else
- levelNext++;
- }
- else
- if (ifFound)
- elseFound = false;
- else
- if (MatchIgnoreCase(styler, i, "when"))
- whenFound = true;
- else
- {
- if (beginFound)
- levelNext++;
- else
- if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
- {
- if (endFound)
- endFound = false;
- else
- levelNext++;
- }
- else
- if (MatchIgnoreCase(styler, i, "end"))
- {
- // Multiple "end" in a row are counted multiple times!
- if (endFound)
- {
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE)
- levelNext = SC_FOLDLEVELBASE;
- }
- endFound = true;
- whenFound = false;
- }
- }
- }
- break;
- }
-
- // Handle the case of a trailing end without an if / while etc, as in the case of a begin.
- if (endFound)
- {
- endFound = false;
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE)
- levelNext = SC_FOLDLEVELBASE;
- }
-
- if (atEOL)
- {
- if (elseFound)
- {
- levelNext++;
- elseFound = false;
- }
-
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
-
- lineCurrent++;
- levelCurrent = levelNext;
- visibleChars = 0;
- endFound = false;
- whenFound = false;
- }
-
- if (!isspacechar(currentChar))
- visibleChars++;
- }
-}
-
-//--------------------------------------------------------------------------------------------------
-
-static const char * const mysqlWordListDesc[] = {
- "Major Keywords",
- "Keywords",
- "Database Objects",
- "Functions",
- "System Variables",
- "Procedure keywords",
- "User Keywords 1",
- "User Keywords 2",
- "User Keywords 3",
- 0
-};
-
-LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-// Nimrod lexer
-// (c) 2009 Andreas Rumpf
-/** @file LexNimrod.cxx
- ** Lexer for Nimrod.
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(int ch) {
- return (ch >= 0x80) || isalnum(ch) || ch == '_';
-}
-
-static int tillEndOfTripleQuote(Accessor &styler, int pos, int max) {
- /* search for """ */
- for (;;) {
- if (styler.SafeGetCharAt(pos, '\0') == '\0') return pos;
- if (pos >= max) return pos;
- if (styler.Match(pos, "\"\"\"")) {
- return pos + 2;
- }
- pos++;
- }
-}
-
-#define CR 13 /* use both because Scite allows changing the line ending */
-#define LF 10
-
-static bool inline isNewLine(int ch) {
- return ch == CR || ch == LF;
-}
-
-static int scanString(Accessor &styler, int pos, int max, bool rawMode) {
- for (;;) {
- if (pos >= max) return pos;
- char ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == CR || ch == LF || ch == '\0') return pos;
- if (ch == '"') return pos;
- if (ch == '\\' && !rawMode) {
- pos += 2;
- } else {
- pos++;
- }
- }
-}
-
-static int scanChar(Accessor &styler, int pos, int max) {
- for (;;) {
- if (pos >= max) return pos;
- char ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == CR || ch == LF || ch == '\0') return pos;
- if (ch == '\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\0')) )
- return pos;
- if (ch == '\\') {
- pos += 2;
- } else {
- pos++;
- }
- }
-}
-
-static int scanIdent(Accessor &styler, int pos, WordList &keywords) {
- char buf[100]; /* copy to lowercase and ignore underscores */
- int i = 0;
-
- for (;;) {
- char ch = styler.SafeGetCharAt(pos, '\0');
- if (!IsAWordChar(ch)) break;
- if (ch != '_' && i < ((int)sizeof(buf))-1) {
- buf[i] = static_cast<char>(tolower(ch));
- i++;
- }
- pos++;
- }
- buf[i] = '\0';
- /* look for keyword */
- if (keywords.InList(buf)) {
- styler.ColourTo(pos-1, SCE_P_WORD);
- } else {
- styler.ColourTo(pos-1, SCE_P_IDENTIFIER);
- }
- return pos;
-}
-
-static int scanNumber(Accessor &styler, int pos) {
- char ch, ch2;
- ch = styler.SafeGetCharAt(pos, '\0');
- ch2 = styler.SafeGetCharAt(pos+1, '\0');
- if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) {
- /* binary number: */
- pos += 2;
- for (;;) {
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
- else break;
- }
- } else if (ch == '0' &&
- (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
- /* octal number: */
- pos += 2;
- for (;;) {
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos;
- else break;
- }
- } else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) {
- /* hexadecimal number: */
- pos += 2;
- for (;;) {
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '_' || (ch >= '0' && ch <= '9')
- || (ch >= 'a' && ch <= 'f')
- || (ch >= 'A' && ch <= 'F')) ++pos;
- else break;
- }
- } else {
- // skip decimal part:
- for (;;) {
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
- else break;
- }
- ch2 = styler.SafeGetCharAt(pos+1, '\0');
- if (ch == '.' && ch2 >= '0' && ch2 <= '9') {
- ++pos; // skip '.'
- for (;;) {
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
- else break;
- }
- }
- if (ch == 'e' || ch == 'E') {
- ++pos;
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '-' || ch == '+') ++pos;
- for (;;) {
- ch = styler.SafeGetCharAt(pos, '\0');
- if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
- else break;
- }
- }
- }
- if (ch == '\'') {
- /* a type suffix: */
- pos++;
- for (;;) {
- ch = styler.SafeGetCharAt(pos);
- if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')
- || (ch >= 'a' && ch <= 'z') || ch == '_') ++pos;
- else break;
- }
- }
- styler.ColourTo(pos-1, SCE_P_NUMBER);
- return pos;
-}
-
-/* rewritten from scratch, because I couldn't get rid of the bugs...
- (A character based approach sucks!)
-*/
-static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- int pos = startPos;
- int max = startPos + length;
- char ch;
- WordList &keywords = *keywordlists[0];
-
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
-
- switch (initStyle) {
- /* check where we are: */
- case SCE_P_TRIPLEDOUBLE:
- pos = tillEndOfTripleQuote(styler, pos, max);
- styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
- pos++;
- break;
- default: /* nothing to do: */
- break;
- }
- while (pos < max) {
- ch = styler.SafeGetCharAt(pos, '\0');
- switch (ch) {
- case '\0': return;
- case '#': {
- bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
- while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
- if (doccomment)
- styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
- else
- styler.ColourTo(pos, SCE_P_COMMENTLINE);
- } break;
- case 'r': case 'R': {
- if (styler.SafeGetCharAt(pos+1) == '"') {
- pos = scanString(styler, pos+2, max, true);
- styler.ColourTo(pos, SCE_P_STRING);
- pos++;
- } else {
- pos = scanIdent(styler, pos, keywords);
- }
- } break;
- case '"':
- if (styler.Match(pos+1, "\"\"")) {
- pos = tillEndOfTripleQuote(styler, pos+3, max);
- styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
- } else {
- pos = scanString(styler, pos+1, max, false);
- styler.ColourTo(pos, SCE_P_STRING);
- }
- pos++;
- break;
- case '\'':
- pos = scanChar(styler, pos+1, max);
- styler.ColourTo(pos, SCE_P_CHARACTER);
- pos++;
- break;
- default: // identifers, numbers, operators, whitespace
- if (ch >= '0' && ch <= '9') {
- pos = scanNumber(styler, pos);
- } else if (IsAWordChar(ch)) {
- pos = scanIdent(styler, pos, keywords);
- } else if (ch == '`') {
- pos++;
- while (pos < max) {
- ch = styler.SafeGetCharAt(pos, LF);
- if (ch == '`') {
- ++pos;
- break;
- }
- if (ch == CR || ch == LF) break;
- ++pos;
- }
- styler.ColourTo(pos, SCE_P_IDENTIFIER);
- } else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", ch)) {
- styler.ColourTo(pos, SCE_P_OPERATOR);
- pos++;
- } else {
- styler.ColourTo(pos, SCE_P_DEFAULT);
- pos++;
- }
- break;
- }
- }
-}
-
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eol_pos; i++) {
- char ch = styler[i];
- if (ch == '#')
- return true;
- else if (ch != ' ' && ch != '\t')
- return false;
- }
- return false;
-}
-
-static bool IsQuoteLine(int line, Accessor &styler) {
- int style = styler.StyleAt(styler.LineStart(line)) & 31;
- return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
-}
-
-
-static void FoldNimrodDoc(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.nimrod") != 0;
- const bool foldQuotes = styler.GetPropertyInt("fold.quotes.nimrod") != 0;
-
- // Backtrack to previous non-blank line so we can determine indent level
- // for any white space lines (needed esp. within triple quoted strings)
- // 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)) &&
- (!IsQuoteLine(lineCurrent, styler)))
- break;
- }
- int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
-
- // Set up initial loop state
- startPos = styler.LineStart(lineCurrent);
- int prev_state = SCE_P_DEFAULT & 31;
- if (lineCurrent >= 1)
- prev_state = styler.StyleAt(startPos - 1) & 31;
- int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||
- (prev_state == SCE_P_TRIPLEDOUBLE));
- int prevComment = 0;
- if (lineCurrent >= 1)
- prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
-
- // Process all characters to end of requested range or end of any triple quote
- // or comment that hangs over the end of the range. Cap processing in all cases
- // to end of document (in case of unclosed quote or comment at end).
- while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||
- prevQuote || prevComment)) {
-
- // Gather info
- int lev = indentCurrent;
- int lineNext = lineCurrent + 1;
- int indentNext = indentCurrent;
- int quote = false;
- if (lineNext <= docLines) {
- // Information about next line is only available if not at end of document
- indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
- int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
- quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
- }
- const int quote_start = (quote && !prevQuote);
- const int quote_continue = (quote && prevQuote);
- const int comment = foldComment && IsCommentLine(lineCurrent, styler);
- const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
- IsCommentLine(lineNext, styler) &&
- (lev > SC_FOLDLEVELBASE));
- const int comment_continue = (comment && prevComment);
- if ((!quote || !prevQuote) && !comment)
- indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
- if (quote)
- indentNext = indentCurrentLevel;
- if (indentNext & SC_FOLDLEVELWHITEFLAG)
- indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
-
- if (quote_start) {
- // Place fold point at start of triple quoted string
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (quote_continue || prevQuote) {
- // Add level to rest of lines in the string
- lev = lev + 1;
- } else if (comment_start) {
- // Place fold point at start of a block of comments
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (comment_continue) {
- // Add level to rest of lines in the block
- lev = lev + 1;
- }
-
- // Skip past any blank lines for next indent level info; we skip also
- // comments (all comments, not just those starting in column 0)
- // which effectively folds them into surrounding code rather
- // than screwing up folding.
-
- while (!quote &&
- (lineNext < docLines) &&
- ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
- (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
-
- lineNext++;
- indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
- }
-
- const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
- const int levelBeforeComments =
- Platform::Maximum(indentCurrentLevel,levelAfterComments);
-
- // Now set all the indent levels on the lines we skipped
- // Do this from end to start. Once we encounter one line
- // which is indented more than the line after the end of
- // the comment-block, use the level of the block before
-
- int skipLine = lineNext;
- int skipLevel = levelAfterComments;
-
- while (--skipLine > lineCurrent) {
- int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
-
- if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
- skipLevel = levelBeforeComments;
-
- int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
-
- styler.SetLevel(skipLine, skipLevel | whiteFlag);
- }
-
- // Set fold header on non-quote/non-comment line
- if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <
- (indentNext & SC_FOLDLEVELNUMBERMASK))
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
-
- // Keep track of triple quote and block comment state of previous line
- prevQuote = quote;
- prevComment = comment_start || comment_continue;
-
- // Set fold level for this line and move to next line
- styler.SetLevel(lineCurrent, lev);
- indentCurrent = indentNext;
- lineCurrent = lineNext;
- }
-
- // NOTE: Cannot set level of last line here because indentCurrent doesn't have
- // header flag set; the loop above is crafted to take care of this case!
- //styler.SetLevel(lineCurrent, indentCurrent);
-}
-
-static const char * const nimrodWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, "nimrod", FoldNimrodDoc,
- nimrodWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexNsis.cxx
- ** Lexer for NSIS
- **/
-// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
-// Last Updated: 03/13/2005
-// The License.txt file describes the conditions under which this software may be distributed.
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-/*
-// located in SciLexer.h
-#define SCLEX_NSIS 43
-
-#define SCE_NSIS_DEFAULT 0
-#define SCE_NSIS_COMMENT 1
-#define SCE_NSIS_STRINGDQ 2
-#define SCE_NSIS_STRINGLQ 3
-#define SCE_NSIS_STRINGRQ 4
-#define SCE_NSIS_FUNCTION 5
-#define SCE_NSIS_VARIABLE 6
-#define SCE_NSIS_LABEL 7
-#define SCE_NSIS_USERDEFINED 8
-#define SCE_NSIS_SECTIONDEF 9
-#define SCE_NSIS_SUBSECTIONDEF 10
-#define SCE_NSIS_IFDEFINEDEF 11
-#define SCE_NSIS_MACRODEF 12
-#define SCE_NSIS_STRINGVAR 13
-#define SCE_NSIS_NUMBER 14
-// ADDED for Scintilla v1.63
-#define SCE_NSIS_SECTIONGROUP 15
-#define SCE_NSIS_PAGEEX 16
-#define SCE_NSIS_FUNCTIONDEF 17
-#define SCE_NSIS_COMMENTBOX 18
-*/
-
-static bool isNsisNumber(char ch)
-{
- return (ch >= '0' && ch <= '9');
-}
-
-static bool isNsisChar(char ch)
-{
- return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-}
-
-static bool isNsisLetter(char ch)
-{
- return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-}
-
-static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
-{
- int nNextLine = -1;
- for( unsigned int i = start; i < end; i++ )
- {
- char cNext = styler.SafeGetCharAt( i );
- if( cNext == '\n' )
- {
- nNextLine = i+1;
- break;
- }
- }
-
- if( nNextLine == -1 ) // We never found the next line...
- return false;
-
- for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
- {
- char cNext = styler.SafeGetCharAt( firstChar );
- if( cNext == ' ' )
- continue;
- if( cNext == '\t' )
- continue;
- if( cNext == '!' )
- {
- if( styler.Match(firstChar, "!else") )
- return true;
- }
- break;
- }
-
- return false;
-}
-
-static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )
-{
- if( bIgnoreCase )
- return CompareCaseInsensitive( s1, s2);
-
- return strcmp( s1, s2 );
-}
-
-static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
-{
- int style = styler.StyleAt(end);
-
- // If the word is too long, it is not what we are looking for
- if( end - start > 20 )
- return foldlevel;
-
- if( foldUtilityCmd )
- {
- // Check the style at this point, if it is not valid, then return zero
- if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
- style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
- style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
- style != SCE_NSIS_PAGEEX )
- return foldlevel;
- }
- else
- {
- if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
- style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
- style != SCE_NSIS_PAGEEX )
- return foldlevel;
- }
-
- int newFoldlevel = foldlevel;
- bool bIgnoreCase = false;
- if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
- bIgnoreCase = true;
-
- char s[20]; // The key word we are looking for has atmost 13 characters
- for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
- {
- s[i] = static_cast<char>( styler[ start + i ] );
- s[i + 1] = '\0';
- }
-
- if( s[0] == '!' )
- {
- if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
- newFoldlevel++;
- else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
- newFoldlevel--;
- else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
- newFoldlevel++;
- }
- else
- {
- if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
- newFoldlevel++;
- else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
- newFoldlevel--;
- }
-
- return newFoldlevel;
-}
-
-static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
-{
- bool bIgnoreCase = false;
- if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
- bIgnoreCase = true;
-
- bool bUserVars = false;
- if( styler.GetPropertyInt("nsis.uservars") == 1 )
- bUserVars = true;
-
- char s[100];
-
- WordList &Functions = *keywordLists[0];
- WordList &Variables = *keywordLists[1];
- WordList &Lables = *keywordLists[2];
- WordList &UserDefined = *keywordLists[3];
-
- for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)
- {
- if( bIgnoreCase )
- s[i] = static_cast<char>( tolower(styler[ start + i ] ) );
- else
- s[i] = static_cast<char>( styler[ start + i ] );
- s[i + 1] = '\0';
- }
-
- // Check for special words...
- if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
- return SCE_NSIS_MACRODEF;
-
- if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
- return SCE_NSIS_IFDEFINEDEF;
-
- if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // Covers !if and else
- return SCE_NSIS_IFDEFINEDEF;
-
- if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 ) // Covers !ifmacrodef and !ifnmacrodef
- return SCE_NSIS_IFDEFINEDEF;
-
- if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
- return SCE_NSIS_SECTIONGROUP;
-
- if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
- return SCE_NSIS_SECTIONDEF;
-
- if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
- return SCE_NSIS_SUBSECTIONDEF;
-
- if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
- return SCE_NSIS_PAGEEX;
-
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
- return SCE_NSIS_FUNCTIONDEF;
-
- if ( Functions.InList(s) )
- return SCE_NSIS_FUNCTION;
-
- if ( Variables.InList(s) )
- return SCE_NSIS_VARIABLE;
-
- if ( Lables.InList(s) )
- return SCE_NSIS_LABEL;
-
- if( UserDefined.InList(s) )
- return SCE_NSIS_USERDEFINED;
-
- if( strlen(s) > 3 )
- {
- if( s[1] == '{' && s[strlen(s)-1] == '}' )
- return SCE_NSIS_VARIABLE;
- }
-
- // See if the variable is a user defined variable
- if( s[0] == '$' && bUserVars )
- {
- bool bHasSimpleNsisChars = true;
- for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
- {
- if( !isNsisChar( s[j] ) )
- {
- bHasSimpleNsisChars = false;
- break;
- }
- }
-
- if( bHasSimpleNsisChars )
- return SCE_NSIS_VARIABLE;
- }
-
- // To check for numbers
- if( isNsisNumber( s[0] ) )
- {
- bool bHasSimpleNsisNumber = true;
- for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
- {
- if( !isNsisNumber( s[j] ) )
- {
- bHasSimpleNsisNumber = false;
- break;
- }
- }
-
- if( bHasSimpleNsisNumber )
- return SCE_NSIS_NUMBER;
- }
-
- return SCE_NSIS_DEFAULT;
-}
-
-static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
-{
- int state = SCE_NSIS_DEFAULT;
- if( startPos > 0 )
- state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
-
- styler.StartAt( startPos );
- styler.GetLine( startPos );
-
- unsigned int nLengthDoc = startPos + length;
- styler.StartSegment( startPos );
-
- char cCurrChar;
- bool bVarInString = false;
- bool bClassicVarInString = false;
-
- unsigned int i;
- for( i = startPos; i < nLengthDoc; i++ )
- {
- cCurrChar = styler.SafeGetCharAt( i );
- char cNextChar = styler.SafeGetCharAt(i+1);
-
- switch(state)
- {
- case SCE_NSIS_DEFAULT:
- if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line
- {
- styler.ColourTo(i-1, state );
- state = SCE_NSIS_COMMENT;
- break;
- }
- if( cCurrChar == '"' )
- {
- styler.ColourTo(i-1, state );
- state = SCE_NSIS_STRINGDQ;
- bVarInString = false;
- bClassicVarInString = false;
- break;
- }
- if( cCurrChar == '\'' )
- {
- styler.ColourTo(i-1, state );
- state = SCE_NSIS_STRINGRQ;
- bVarInString = false;
- bClassicVarInString = false;
- break;
- }
- if( cCurrChar == '`' )
- {
- styler.ColourTo(i-1, state );
- state = SCE_NSIS_STRINGLQ;
- bVarInString = false;
- bClassicVarInString = false;
- break;
- }
-
- // NSIS KeyWord,Function, Variable, UserDefined:
- if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )
- {
- styler.ColourTo(i-1,state);
- state = SCE_NSIS_FUNCTION;
-
- // If it is a number, we must check and set style here first...
- if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
- styler.ColourTo( i, SCE_NSIS_NUMBER);
-
- break;
- }
-
- if( cCurrChar == '/' && cNextChar == '*' )
- {
- styler.ColourTo(i-1,state);
- state = SCE_NSIS_COMMENTBOX;
- break;
- }
-
- break;
- case SCE_NSIS_COMMENT:
- if( cNextChar == '\n' || cNextChar == '\r' )
- {
- // Special case:
- if( cCurrChar == '\\' )
- {
- styler.ColourTo(i-2,state);
- styler.ColourTo(i,SCE_NSIS_DEFAULT);
- }
- else
- {
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
- }
- }
- break;
- case SCE_NSIS_STRINGDQ:
- case SCE_NSIS_STRINGLQ:
- case SCE_NSIS_STRINGRQ:
-
- if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
- break; // Ignore the next character, even if it is a quote of some sort
-
- if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
- {
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
- break;
- }
-
- if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
- {
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
- break;
- }
-
- if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
- {
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
- break;
- }
-
- if( cNextChar == '\r' || cNextChar == '\n' )
- {
- int nCurLine = styler.GetLine(i+1);
- int nBack = i;
- // We need to check if the previous line has a \ in it...
- bool bNextLine = false;
-
- while( nBack > 0 )
- {
- if( styler.GetLine(nBack) != nCurLine )
- break;
-
- char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
-
- if( cTemp == '\\' )
- {
- bNextLine = true;
- break;
- }
- if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
- break;
-
- nBack--;
- }
-
- if( bNextLine )
- {
- styler.ColourTo(i+1,state);
- }
- if( bNextLine == false )
- {
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
- }
- }
- break;
-
- case SCE_NSIS_FUNCTION:
-
- // NSIS KeyWord:
- if( cCurrChar == '$' )
- state = SCE_NSIS_DEFAULT;
- else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
- state = SCE_NSIS_DEFAULT;
- else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
- {
- state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
- styler.ColourTo( i, state);
- state = SCE_NSIS_DEFAULT;
- }
- else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )
- {
- if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )
- styler.ColourTo( i-1, SCE_NSIS_NUMBER );
-
- state = SCE_NSIS_DEFAULT;
-
- if( cCurrChar == '"' )
- {
- state = SCE_NSIS_STRINGDQ;
- bVarInString = false;
- bClassicVarInString = false;
- }
- else if( cCurrChar == '`' )
- {
- state = SCE_NSIS_STRINGLQ;
- bVarInString = false;
- bClassicVarInString = false;
- }
- else if( cCurrChar == '\'' )
- {
- state = SCE_NSIS_STRINGRQ;
- bVarInString = false;
- bClassicVarInString = false;
- }
- else if( cCurrChar == '#' || cCurrChar == ';' )
- {
- state = SCE_NSIS_COMMENT;
- }
- }
- break;
- case SCE_NSIS_COMMENTBOX:
-
- if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
- {
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
- }
- break;
- }
-
- if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
- {
- styler.ColourTo(i,state);
- }
- else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )
- {
- bool bIngoreNextDollarSign = false;
- bool bUserVars = false;
- if( styler.GetPropertyInt("nsis.uservars") == 1 )
- bUserVars = true;
-
- if( bVarInString && cCurrChar == '$' )
- {
- bVarInString = false;
- bIngoreNextDollarSign = true;
- }
- else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
- {
- styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
- bVarInString = false;
- bIngoreNextDollarSign = false;
- }
-
- // Covers "$INSTDIR and user vars like $MYVAR"
- else if( bVarInString && !isNsisChar(cNextChar) )
- {
- int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
- if( nWordState == SCE_NSIS_VARIABLE )
- styler.ColourTo( i, SCE_NSIS_STRINGVAR);
- else if( bUserVars )
- styler.ColourTo( i, SCE_NSIS_STRINGVAR);
- bVarInString = false;
- }
- // Covers "${TEST}..."
- else if( bClassicVarInString && cNextChar == '}' )
- {
- styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
- bClassicVarInString = false;
- }
-
- // Start of var in string
- if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )
- {
- styler.ColourTo( i-1, state);
- bClassicVarInString = true;
- bVarInString = false;
- }
- else if( !bIngoreNextDollarSign && cCurrChar == '$' )
- {
- styler.ColourTo( i-1, state);
- bVarInString = true;
- bClassicVarInString = false;
- }
- }
- }
-
- // Colourise remaining document
- styler.ColourTo(nLengthDoc-1,state);
-}
-
-static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
-{
- // No folding enabled, no reason to continue...
- if( styler.GetPropertyInt("fold") == 0 )
- return;
-
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
- bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
- bool blockComment = false;
-
- int lineCurrent = styler.GetLine(startPos);
- unsigned int safeStartPos = styler.LineStart( lineCurrent );
-
- bool bArg1 = true;
- int nWordStart = -1;
-
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelNext = levelCurrent;
- int style = styler.StyleAt(safeStartPos);
- if( style == SCE_NSIS_COMMENTBOX )
- {
- if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
- levelNext++;
- blockComment = true;
- }
-
- for (unsigned int i = safeStartPos; i < startPos + length; i++)
- {
- char chCurr = styler.SafeGetCharAt(i);
- style = styler.StyleAt(i);
- if( blockComment && style != SCE_NSIS_COMMENTBOX )
- {
- levelNext--;
- blockComment = false;
- }
- else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
- {
- levelNext++;
- blockComment = true;
- }
-
- if( bArg1 && !blockComment)
- {
- if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
- {
- nWordStart = i;
- }
- else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
- {
- int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
-
- if( newLevel == levelNext )
- {
- if( foldAtElse && foldUtilityCmd )
- {
- if( NsisNextLineHasElse(i, startPos + length, styler) )
- levelNext--;
- }
- }
- else
- levelNext = newLevel;
- bArg1 = false;
- }
- }
-
- if( chCurr == '\n' )
- {
- if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
- {
- if( NsisNextLineHasElse(i, startPos + length, styler) )
- levelNext--;
- }
-
- // If we are on a new line...
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext )
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
-
- lineCurrent++;
- levelCurrent = levelNext;
- bArg1 = true; // New line, lets look at first argument again
- nWordStart = -1;
- }
- }
-
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
-}
-
-static const char * const nsisWordLists[] = {
- "Functions",
- "Variables",
- "Lables",
- "UserDefined",
- 0, };
-
-
-LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexOpal.cxx
- ** Lexer for OPAL (functional language similar to Haskell)
- ** Written by Sebastian Pipping <webmaster@hartwork.org>
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len )
-{
- unsigned int i = 0;
- while( ( i < end - start + 1 ) && ( i < len - 1 ) )
- {
- s[i] = static_cast<char>( styler[ start + i ] );
- i++;
- }
- s[ i ] = '\0';
-}
-
-inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
-{
- char ch;
-
- // Wait for string to close
- bool even_backslash_count = true; // Without gaps in between
- cur++; // Skip initial quote
- for( ; ; )
- {
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_STRING );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( ( ch == '\015' ) || ( ch == '\012' ) ) // Deny multi-line strings
- {
- styler.ColourTo( cur - 1, SCE_OPAL_STRING );
- styler.StartSegment( cur );
- return true;
- }
- else
- {
- if( even_backslash_count )
- {
- if( ch == '"' )
- {
- styler.ColourTo( cur, SCE_OPAL_STRING );
- cur++;
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
- }
- else if( ch == '\\' )
- {
- even_backslash_count = false;
- }
- }
- else
- {
- even_backslash_count = true;
- }
- }
-
- cur++;
- }
-}
-
-inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
-{
- char ch;
-
- if( could_fail )
- {
- cur++;
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( ch != '*' )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- styler.StartSegment( cur );
- return true;
- }
- }
-
- // Wait for comment close
- cur++;
- bool star_found = false;
- for( ; ; )
- {
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( star_found )
- {
- if( ch == '/' )
- {
- styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
- cur++;
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
- }
- else if( ch != '*' )
- {
- star_found = false;
- }
- }
- else if( ch == '*' )
- {
- star_found = true;
- }
- cur++;
- }
-}
-
-inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
-{
- char ch;
-
- if( could_fail )
- {
- cur++;
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( ch != '-' )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- styler.StartSegment( cur );
- return true;
- }
-
- cur++;
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( ( ch != ' ' ) && ( ch != '\t' ) )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- styler.StartSegment( cur );
- return true;
- }
- }
-
- // Wait for end of line
- bool fifteen_found = false;
-
- for( ; ; )
- {
- cur++;
-
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( fifteen_found )
- {
-/*
- if( ch == '\012' )
- {
- // One newline on Windows (015, 012)
- }
- else
- {
- // One newline on MAC (015) and another char
- }
-*/
- cur--;
- styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
- styler.StartSegment( cur );
- return true;
- }
- else
- {
- if( ch == '\015' )
- {
- fifteen_found = true;
- }
- else if( ch == '\012' )
- {
- // One newline on Linux (012)
- styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
- styler.StartSegment( cur );
- return true;
- }
- }
- }
-}
-
-inline bool HandlePar( unsigned int & cur, Accessor & styler )
-{
- styler.ColourTo( cur, SCE_OPAL_PAR );
-
- cur++;
-
- styler.StartSegment( cur );
- return true;
-}
-
-inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
-{
- char ch;
-
- cur++;
- for( ; ; )
- {
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
- return false;
- }
-
- ch = styler.SafeGetCharAt( cur );
- switch( ch )
- {
- case ' ':
- case '\t':
- case '\015':
- case '\012':
- cur++;
- break;
-
- default:
- styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
- styler.StartSegment( cur );
- return true;
- }
- }
-}
-
-inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
-{
- char ch;
-
- for( ; ; )
- {
- cur++;
- if( cur >= one_too_much )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
- return false; // STOP
- }
-
- ch = styler.SafeGetCharAt( cur );
- if( !isdigit( ch ) )
- {
- styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
- styler.StartSegment( cur );
- return true;
- }
- }
-}
-
-inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] )
-{
- char ch;
- const unsigned int beg = cur;
-
- cur++;
- for( ; ; )
- {
- ch = styler.SafeGetCharAt( cur );
- if( ( ch != '_' ) && ( ch != '-' ) &&
- !islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;
-
- cur++;
- if( cur >= one_too_much )
- {
- break;
- }
- }
-
- const int ide_len = cur - beg + 1;
- char * ide = new char[ ide_len ];
- getRange( beg, cur, styler, ide, ide_len );
-
- WordList & keywords = *keywordlists[ 0 ];
- WordList & classwords = *keywordlists[ 1 ];
-
- if( keywords.InList( ide ) ) // Keyword
- {
- delete [] ide;
-
- styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
- }
- else if( classwords.InList( ide ) ) // Sort
- {
- delete [] ide;
-
- styler.ColourTo( cur - 1, SCE_OPAL_SORT );
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
- }
- else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
- {
- delete [] ide;
-
- styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
- }
- else // Unknown keyword
- {
- delete [] ide;
-
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
- }
-
-}
-
-inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
-{
- cur++;
- styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
- if( cur >= one_too_much )
- {
- return false; // STOP
- }
- else
- {
- styler.StartSegment( cur );
- return true;
- }
-}
-
-static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor & styler )
-{
- styler.StartAt( startPos );
- styler.StartSegment( startPos );
-
- unsigned int & cur = startPos;
- const unsigned int one_too_much = startPos + length;
-
- int state = initStyle;
-
- for( ; ; )
- {
- switch( state )
- {
- case SCE_OPAL_KEYWORD:
- case SCE_OPAL_SORT:
- if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
- state = SCE_OPAL_DEFAULT;
- break;
-
- case SCE_OPAL_INTEGER:
- if( !HandleInteger( cur, one_too_much, styler ) ) return;
- state = SCE_OPAL_DEFAULT;
- break;
-
- case SCE_OPAL_COMMENT_BLOCK:
- if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
- state = SCE_OPAL_DEFAULT;
- break;
-
- case SCE_OPAL_COMMENT_LINE:
- if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
- state = SCE_OPAL_DEFAULT;
- break;
-
- case SCE_OPAL_STRING:
- if( !HandleString( cur, one_too_much, styler ) ) return;
- state = SCE_OPAL_DEFAULT;
- break;
-
- default: // SCE_OPAL_DEFAULT:
- {
- char ch = styler.SafeGetCharAt( cur );
-
- switch( ch )
- {
- // String
- case '"':
- if( !HandleString( cur, one_too_much, styler ) ) return;
- break;
-
- // Comment block
- case '/':
- if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
- break;
-
- // Comment line
- case '-':
- if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
- break;
-
- // Par
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- if( !HandlePar( cur, styler ) ) return;
- break;
-
- // Whitespace
- case ' ':
- case '\t':
- case '\015':
- case '\012':
- if( !HandleSpace( cur, one_too_much, styler ) ) return;
- break;
-
- default:
- {
- // Integer
- if( isdigit( ch ) )
- {
- if( !HandleInteger( cur, one_too_much, styler ) ) return;
- }
-
- // Keyword
- else if( islower( ch ) || isupper( ch ) )
- {
- if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
-
- }
-
- // Skip
- else
- {
- if( !HandleSkip( cur, one_too_much, styler ) ) return;
- }
- }
- }
-
- break;
- }
- }
- }
-}
-
-static const char * const opalWordListDesc[] = {
- "Keywords",
- "Sorts",
- 0
-};
-
-LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexOthers.cxx
- ** Lexers for batch files, diff results, properties files, make files and error lists.
- ** Also lexer for LaTeX documents.
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static bool strstart(const char *haystack, const char *needle) {
- return strncmp(haystack, needle, strlen(needle)) == 0;
-}
-
-static bool Is0To9(char ch) {
- return (ch >= '0') && (ch <= '9');
-}
-
-static bool Is1To9(char ch) {
- return (ch >= '1') && (ch <= '9');
-}
-
-static inline bool AtEOL(Accessor &styler, unsigned int i) {
- return (styler[i] == '\n') ||
- ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
-}
-
-// Tests for BATCH Operators
-static bool IsBOperator(char ch) {
- return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
- (ch == '|') || (ch == '?') || (ch == '*');
-}
-
-// Tests for BATCH Separators
-static bool IsBSeparator(char ch) {
- return (ch == '\\') || (ch == '.') || (ch == ';') ||
- (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
-}
-
-static void ColouriseBatchLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startLine,
- unsigned int endPos,
- WordList *keywordlists[],
- Accessor &styler) {
-
- unsigned int offset = 0; // Line Buffer Offset
- unsigned int cmdLoc; // External Command / Program Location
- char wordBuffer[81]; // Word Buffer - large to catch long paths
- unsigned int wbl; // Word Buffer Length
- unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
- WordList &keywords = *keywordlists[0]; // Internal Commands
- WordList &keywords2 = *keywordlists[1]; // External Commands (optional)
-
- // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
- // Toggling Regular Keyword Checking off improves readability
- // Other Regular Keywords and External Commands / Programs might also benefit from toggling
- // Need a more robust algorithm to properly toggle Regular Keyword Checking
- bool continueProcessing = true; // Used to toggle Regular Keyword Checking
- // Special Keywords are those that allow certain characters without whitespace after the command
- // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
- // Special Keyword Buffer used to determine if the first n characters is a Keyword
- char sKeywordBuffer[10]; // Special Keyword Buffer
- bool sKeywordFound; // Exit Special Keyword for-loop if found
-
- // Skip initial spaces
- while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
- offset++;
- }
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
- // Set External Command / Program Location
- cmdLoc = offset;
-
- // Check for Fake Label (Comment) or Real Label - return if found
- if (lineBuffer[offset] == ':') {
- if (lineBuffer[offset + 1] == ':') {
- // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
- styler.ColourTo(endPos, SCE_BAT_COMMENT);
- } else {
- // Colorize Real Label
- styler.ColourTo(endPos, SCE_BAT_LABEL);
- }
- return;
- // Check for Drive Change (Drive Change is internal command) - return if found
- } else if ((isalpha(lineBuffer[offset])) &&
- (lineBuffer[offset + 1] == ':') &&
- ((isspacechar(lineBuffer[offset + 2])) ||
- (((lineBuffer[offset + 2] == '\\')) &&
- (isspacechar(lineBuffer[offset + 3]))))) {
- // Colorize Regular Keyword
- styler.ColourTo(endPos, SCE_BAT_WORD);
- return;
- }
-
- // Check for Hide Command (@ECHO OFF/ON)
- if (lineBuffer[offset] == '@') {
- styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
- offset++;
- }
- // Skip next spaces
- while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
- offset++;
- }
-
- // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
- while (offset < lengthLine) {
- if (offset > startLine) {
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
- }
- // Copy word from Line Buffer into Word Buffer
- wbl = 0;
- for (; offset < lengthLine && wbl < 80 &&
- !isspacechar(lineBuffer[offset]); wbl++, offset++) {
- wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
- }
- wordBuffer[wbl] = '\0';
- wbo = 0;
-
- // Check for Comment - return if found
- if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
- styler.ColourTo(endPos, SCE_BAT_COMMENT);
- return;
- }
- // Check for Separator
- if (IsBSeparator(wordBuffer[0])) {
- // Check for External Command / Program
- if ((cmdLoc == offset - wbl) &&
- ((wordBuffer[0] == ':') ||
- (wordBuffer[0] == '\\') ||
- (wordBuffer[0] == '.'))) {
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 1);
- // Colorize External Command / Program
- if (!keywords2) {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
- } else if (keywords2.InList(wordBuffer)) {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
- } else {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
- }
- // Reset External Command / Program Location
- cmdLoc = offset;
- } else {
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 1);
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
- }
- // Check for Regular Keyword in list
- } else if ((keywords.InList(wordBuffer)) &&
- (continueProcessing)) {
- // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
- if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "set") == 0)) {
- continueProcessing = false;
- }
- // Identify External Command / Program Location for ERRORLEVEL, and EXIST
- if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
- // Reset External Command / Program Location
- cmdLoc = offset;
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Skip comparison
- while ((cmdLoc < lengthLine) &&
- (!isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
- } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "do") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
- (CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
- // Reset External Command / Program Location
- cmdLoc = offset;
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- }
- // Colorize Regular keyword
- styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
- // No need to Reset Offset
- // Check for Special Keyword in list, External Command / Program, or Default Text
- } else if ((wordBuffer[0] != '%') &&
- (wordBuffer[0] != '!') &&
- (!IsBOperator(wordBuffer[0])) &&
- (continueProcessing)) {
- // Check for Special Keyword
- // Affected Commands are in Length range 2-6
- // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
- sKeywordFound = false;
- for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
- wbo = 0;
- // Copy Keyword Length from Word Buffer into Special Keyword Buffer
- for (; wbo < keywordLength; wbo++) {
- sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
- }
- sKeywordBuffer[wbo] = '\0';
- // Check for Special Keyword in list
- if ((keywords.InList(sKeywordBuffer)) &&
- ((IsBOperator(wordBuffer[wbo])) ||
- (IsBSeparator(wordBuffer[wbo])))) {
- sKeywordFound = true;
- // ECHO requires no further Regular Keyword Checking
- if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
- continueProcessing = false;
- }
- // Colorize Special Keyword as Regular Keyword
- styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- }
- }
- // Check for External Command / Program or Default Text
- if (!sKeywordFound) {
- wbo = 0;
- // Check for External Command / Program
- if (cmdLoc == offset - wbl) {
- // Read up to %, Operator or Separator
- while ((wbo < wbl) &&
- (wordBuffer[wbo] != '%') &&
- (wordBuffer[wbo] != '!') &&
- (!IsBOperator(wordBuffer[wbo])) &&
- (!IsBSeparator(wordBuffer[wbo]))) {
- wbo++;
- }
- // Reset External Command / Program Location
- cmdLoc = offset - (wbl - wbo);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- // CHOICE requires no further Regular Keyword Checking
- if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
- continueProcessing = false;
- }
- // Check for START (and its switches) - What follows is External Command \ Program
- if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
- // Reset External Command / Program Location
- cmdLoc = offset;
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Reset External Command / Program Location if command switch detected
- if (lineBuffer[cmdLoc] == '/') {
- // Skip command switch
- while ((cmdLoc < lengthLine) &&
- (!isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- }
- }
- // Colorize External Command / Program
- if (!keywords2) {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
- } else if (keywords2.InList(wordBuffer)) {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
- } else {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
- }
- // No need to Reset Offset
- // Check for Default Text
- } else {
- // Read up to %, Operator or Separator
- while ((wbo < wbl) &&
- (wordBuffer[wbo] != '%') &&
- (wordBuffer[wbo] != '!') &&
- (!IsBOperator(wordBuffer[wbo])) &&
- (!IsBSeparator(wordBuffer[wbo]))) {
- wbo++;
- }
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- }
- }
- // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
- } else if (wordBuffer[0] == '%') {
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
- wbo++;
- // Search to end of word for second % (can be a long path)
- while ((wbo < wbl) &&
- (wordBuffer[wbo] != '%') &&
- (!IsBOperator(wordBuffer[wbo])) &&
- (!IsBSeparator(wordBuffer[wbo]))) {
- wbo++;
- }
- // Check for Argument (%n) or (%*)
- if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
- (wordBuffer[wbo] != '%')) {
- // Check for External Command / Program
- if (cmdLoc == offset - wbl) {
- cmdLoc = offset - (wbl - 2);
- }
- // Colorize Argument
- styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 2);
- // Check for Expanded Argument (%~...) / Variable (%%~...)
- } else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
- ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
- // Check for External Command / Program
- if (cmdLoc == offset - wbl) {
- cmdLoc = offset - (wbl - wbo);
- }
- // Colorize Expanded Argument / Variable
- styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- // Check for Environment Variable (%x...%)
- } else if ((wordBuffer[1] != '%') &&
- (wordBuffer[wbo] == '%')) {
- wbo++;
- // Check for External Command / Program
- if (cmdLoc == offset - wbl) {
- cmdLoc = offset - (wbl - wbo);
- }
- // Colorize Environment Variable
- styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- // Check for Local Variable (%%a)
- } else if (
- (wbl > 2) &&
- (wordBuffer[1] == '%') &&
- (wordBuffer[2] != '%') &&
- (!IsBOperator(wordBuffer[2])) &&
- (!IsBSeparator(wordBuffer[2]))) {
- // Check for External Command / Program
- if (cmdLoc == offset - wbl) {
- cmdLoc = offset - (wbl - 3);
- }
- // Colorize Local Variable
- styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 3);
- }
- // Check for Environment Variable (!x...!)
- } else if (wordBuffer[0] == '!') {
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
- wbo++;
- // Search to end of word for second ! (can be a long path)
- while ((wbo < wbl) &&
- (wordBuffer[wbo] != '!') &&
- (!IsBOperator(wordBuffer[wbo])) &&
- (!IsBSeparator(wordBuffer[wbo]))) {
- wbo++;
- }
- if (wordBuffer[wbo] == '!') {
- wbo++;
- // Check for External Command / Program
- if (cmdLoc == offset - wbl) {
- cmdLoc = offset - (wbl - wbo);
- }
- // Colorize Environment Variable
- styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- }
- // Check for Operator
- } else if (IsBOperator(wordBuffer[0])) {
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
- // Check for Comparison Operator
- if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
- // Identify External Command / Program Location for IF
- cmdLoc = offset;
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Colorize Comparison Operator
- styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 2);
- // Check for Pipe Operator
- } else if (wordBuffer[0] == '|') {
- // Reset External Command / Program Location
- cmdLoc = offset - wbl + 1;
- // Skip next spaces
- while ((cmdLoc < lengthLine) &&
- (isspacechar(lineBuffer[cmdLoc]))) {
- cmdLoc++;
- }
- // Colorize Pipe Operator
- styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 1);
- // Check for Other Operator
- } else {
- // Check for > Operator
- if (wordBuffer[0] == '>') {
- // Turn Keyword and External Command / Program checking back on
- continueProcessing = true;
- }
- // Colorize Other Operator
- styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - 1);
- }
- // Check for Default Text
- } else {
- // Read up to %, Operator or Separator
- while ((wbo < wbl) &&
- (wordBuffer[wbo] != '%') &&
- (wordBuffer[wbo] != '!') &&
- (!IsBOperator(wordBuffer[wbo])) &&
- (!IsBSeparator(wordBuffer[wbo]))) {
- wbo++;
- }
- // Colorize Default Text
- styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
- // Reset Offset to re-process remainder of word
- offset -= (wbl - wbo);
- }
- // Skip next spaces - nothing happens if Offset was Reset
- while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
- offset++;
- }
- }
- // Colorize Default Text for remainder of line - currently not lexed
- styler.ColourTo(endPos, SCE_BAT_DEFAULT);
-}
-
-static void ColouriseBatchDoc(
- unsigned int startPos,
- int length,
- int /*initStyle*/,
- 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';
- ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
- linePos = 0;
- startLine = i + 1;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- lineBuffer[linePos] = '\0';
- ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
- keywordlists, styler);
- }
-}
-
-static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
- // It is needed to remember the current state to recognize starting
- // comment lines before the first "diff " or "--- ". If a real
- // difference starts then each line starting with ' ' is a whitespace
- // otherwise it is considered a comment (Only in..., Binary file...)
- if (0 == strncmp(lineBuffer, "diff ", 5)) {
- styler.ColourTo(endLine, SCE_DIFF_COMMAND);
- } else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff
- styler.ColourTo(endLine, SCE_DIFF_COMMAND);
- } else if (0 == strncmp(lineBuffer, "---", 3)) {
- // In a context diff, --- appears in both the header and the position markers
- if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- else
- styler.ColourTo(endLine, SCE_DIFF_HEADER);
- } else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
- // I don't know of any diff where "+++ " is a position marker, but for
- // consistency, do the same as with "--- " and "*** ".
- if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- else
- styler.ColourTo(endLine, SCE_DIFF_HEADER);
- } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff
- styler.ColourTo(endLine, SCE_DIFF_HEADER);
- } else if (0 == strncmp(lineBuffer, "***", 3)) {
- // In a context diff, *** appears in both the header and the position markers.
- // Also ******** is a chunk header, but here it's treated as part of the
- // position marker since there is no separate style for a chunk header.
- if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- else if (lineBuffer[3] == '*')
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- else
- styler.ColourTo(endLine, SCE_DIFF_HEADER);
- } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib
- styler.ColourTo(endLine, SCE_DIFF_HEADER);
- } else if (lineBuffer[0] == '@') {
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- } else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {
- styler.ColourTo(endLine, SCE_DIFF_POSITION);
- } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
- styler.ColourTo(endLine, SCE_DIFF_DELETED);
- } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
- styler.ColourTo(endLine, SCE_DIFF_ADDED);
- } else if (lineBuffer[0] == '!') {
- styler.ColourTo(endLine, SCE_DIFF_CHANGED);
- } else if (lineBuffer[0] != ' ') {
- styler.ColourTo(endLine, SCE_DIFF_COMMENT);
- } else {
- styler.ColourTo(endLine, SCE_DIFF_DEFAULT);
- }
-}
-
-static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[1024];
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- unsigned int linePos = 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';
- ColouriseDiffLine(lineBuffer, i, styler);
- linePos = 0;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- ColouriseDiffLine(lineBuffer, startPos + length - 1, styler);
- }
-}
-
-static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- int curLine = styler.GetLine(startPos);
- int curLineStart = styler.LineStart(curLine);
- int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;
- int nextLevel;
-
- do {
- int lineType = styler.StyleAt(curLineStart);
- if (lineType == SCE_DIFF_COMMAND)
- nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
- else if (lineType == SCE_DIFF_HEADER)
- nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
- else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')
- nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
- else if (prevLevel & SC_FOLDLEVELHEADERFLAG)
- nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
- else
- nextLevel = prevLevel;
-
- if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
- styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
-
- styler.SetLevel(curLine, nextLevel);
- prevLevel = nextLevel;
-
- curLineStart = styler.LineStart(++curLine);
- } while (static_cast<int>(startPos) + length > curLineStart);
-}
-
-static void ColourisePoLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startLine,
- unsigned int endPos,
- Accessor &styler) {
-
- unsigned int i = 0;
- static unsigned int state = SCE_PO_DEFAULT;
- unsigned int state_start = SCE_PO_DEFAULT;
-
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
- i++;
- if (i < lengthLine) {
- if (lineBuffer[i] == '#') {
- // check if the comment contains any flags ("#, ") and
- // then whether the flags contain "fuzzy"
- if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
- styler.ColourTo(endPos, SCE_PO_FUZZY);
- else
- styler.ColourTo(endPos, SCE_PO_COMMENT);
- } else {
- if (lineBuffer[0] == '"') {
- // line continuation, use previous style
- styler.ColourTo(endPos, state);
- return;
- // this implicitly also matches "msgid_plural"
- } else if (strstart(lineBuffer, "msgid")) {
- state_start = SCE_PO_MSGID;
- state = SCE_PO_MSGID_TEXT;
- } else if (strstart(lineBuffer, "msgstr")) {
- state_start = SCE_PO_MSGSTR;
- state = SCE_PO_MSGSTR_TEXT;
- } else if (strstart(lineBuffer, "msgctxt")) {
- state_start = SCE_PO_MSGCTXT;
- state = SCE_PO_MSGCTXT_TEXT;
- }
- if (state_start != SCE_PO_DEFAULT) {
- // find the next space
- while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
- i++;
- styler.ColourTo(startLine + i - 1, state_start);
- styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
- styler.ColourTo(endPos, state);
- }
- }
- } else {
- styler.ColourTo(endPos, SCE_PO_DEFAULT);
- }
-}
-
-static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], 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';
- ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
- linePos = 0;
- startLine = i + 1;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
- }
-}
-
-static inline bool isassignchar(unsigned char ch) {
- return (ch == '=') || (ch == ':');
-}
-
-static void ColourisePropsLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startLine,
- unsigned int endPos,
- Accessor &styler,
- bool allowInitialSpaces) {
-
- unsigned int 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(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[1024];
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- unsigned int linePos = 0;
- unsigned int 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 (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';
- 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(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
-
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- bool headerPoint = false;
- int lev;
-
- for (unsigned int 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 void ColouriseMakeLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startLine,
- unsigned int endPos,
- Accessor &styler) {
-
- unsigned int i = 0;
- int lastNonSpace = -1;
- unsigned int state = SCE_MAKE_DEFAULT;
- bool bSpecial = false;
-
- // check for a tab character in column 0 indicating a command
- bool bCommand = false;
- if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
- bCommand = true;
-
- // Skip initial spaces
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
- i++;
- }
- if (lineBuffer[i] == '#') { // Comment
- styler.ColourTo(endPos, SCE_MAKE_COMMENT);
- return;
- }
- if (lineBuffer[i] == '!') { // Special directive
- styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
- return;
- }
- while (i < lengthLine) {
- if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
- styler.ColourTo(startLine + i - 1, state);
- state = SCE_MAKE_IDENTIFIER;
- } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
- styler.ColourTo(startLine + i, state);
- state = SCE_MAKE_DEFAULT;
- }
-
- // skip identifier and target styling if this is a command line
- if (!bSpecial && !bCommand) {
- if (lineBuffer[i] == ':') {
- if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
- // it's a ':=', so style as an identifier
- if (lastNonSpace >= 0)
- styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
- styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
- styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
- } else {
- // We should check that no colouring was made since the beginning of the line,
- // to avoid colouring stuff like /OUT:file
- if (lastNonSpace >= 0)
- styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
- styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
- styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
- }
- bSpecial = true; // Only react to the first ':' of the line
- state = SCE_MAKE_DEFAULT;
- } else if (lineBuffer[i] == '=') {
- if (lastNonSpace >= 0)
- styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
- styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
- styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
- bSpecial = true; // Only react to the first '=' of the line
- state = SCE_MAKE_DEFAULT;
- }
- }
- if (!isspacechar(lineBuffer[i])) {
- lastNonSpace = i;
- }
- i++;
- }
- if (state == SCE_MAKE_IDENTIFIER) {
- styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended
- } else {
- styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
- }
-}
-
-static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], 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';
- ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler);
- linePos = 0;
- startLine = i + 1;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
- }
-}
-
-static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) {
- if (lineBuffer[0] == '>') {
- // Command or return status
- return SCE_ERR_CMD;
- } else if (lineBuffer[0] == '<') {
- // Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
- return SCE_ERR_DEFAULT;
- } else if (lineBuffer[0] == '!') {
- return SCE_ERR_DIFF_CHANGED;
- } else if (lineBuffer[0] == '+') {
- if (strstart(lineBuffer, "+++ ")) {
- return SCE_ERR_DIFF_MESSAGE;
- } else {
- return SCE_ERR_DIFF_ADDITION;
- }
- } else if (lineBuffer[0] == '-') {
- if (strstart(lineBuffer, "--- ")) {
- return SCE_ERR_DIFF_MESSAGE;
- } else {
- return SCE_ERR_DIFF_DELETION;
- }
- } else if (strstart(lineBuffer, "cf90-")) {
- // Absoft Pro Fortran 90/95 v8.2 error and/or warning message
- return SCE_ERR_ABSF;
- } else if (strstart(lineBuffer, "fortcom:")) {
- // Intel Fortran Compiler v8.0 error/warning message
- return SCE_ERR_IFORT;
- } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
- return SCE_ERR_PYTHON;
- } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
- return SCE_ERR_PHP;
- } else if ((strstart(lineBuffer, "Error ") ||
- strstart(lineBuffer, "Warning ")) &&
- strstr(lineBuffer, " at (") &&
- strstr(lineBuffer, ") : ") &&
- (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
- // Intel Fortran Compiler error/warning message
- return SCE_ERR_IFC;
- } else if (strstart(lineBuffer, "Error ")) {
- // Borland error message
- return SCE_ERR_BORLAND;
- } else if (strstart(lineBuffer, "Warning ")) {
- // Borland warning message
- return SCE_ERR_BORLAND;
- } else if (strstr(lineBuffer, "at line " ) &&
- (strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
- strstr(lineBuffer, "file ") &&
- (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
- // Lua 4 error message
- return SCE_ERR_LUA;
- } else if (strstr(lineBuffer, " at " ) &&
- (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
- strstr(lineBuffer, " line ") &&
- (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
- (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
- // perl error message
- return SCE_ERR_PERL;
- } else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
- strstr(lineBuffer, ":line ")) {
- // A .NET traceback
- return SCE_ERR_NET;
- } else if (strstart(lineBuffer, "Line ") &&
- strstr(lineBuffer, ", file ")) {
- // Essential Lahey Fortran error message
- return SCE_ERR_ELF;
- } else if (strstart(lineBuffer, "line ") &&
- strstr(lineBuffer, " column ")) {
- // HTML tidy style: line 42 column 1
- return SCE_ERR_TIDY;
- } else if (strstart(lineBuffer, "\tat ") &&
- strstr(lineBuffer, "(") &&
- strstr(lineBuffer, ".java:")) {
- // Java stack back trace
- return SCE_ERR_JAVA_STACK;
- } else {
- // Look for one of the following formats:
- // GCC: <filename>:<line>:<message>
- // Microsoft: <filename>(<line>) :<message>
- // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal
- // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal
- // Microsoft: <filename>(<line>,<column>)<message>
- // CTags: \t<message>
- // Lua 5 traceback: \t<filename>:<line>:<message>
- // Lua 5.1: <exe>: <filename>:<line>:<message>
- bool initialTab = (lineBuffer[0] == '\t');
- bool initialColonPart = false;
- enum { stInitial,
- stGccStart, stGccDigit, stGcc,
- stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
- stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
- stUnrecognized
- } state = stInitial;
- for (unsigned int i = 0; i < lengthLine; i++) {
- char ch = lineBuffer[i];
- char chNext = ' ';
- if ((i + 1) < lengthLine)
- chNext = lineBuffer[i + 1];
- if (state == stInitial) {
- if (ch == ':') {
- // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
- if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) {
- // This check is not completely accurate as may be on
- // GTK+ with a file name that includes ':'.
- state = stGccStart;
- } else if (chNext == ' ') { // indicates a Lua 5.1 error message
- initialColonPart = true;
- }
- } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
- // May be Microsoft
- // Check against '0' often removes phone numbers
- state = stMsStart;
- } else if ((ch == '\t') && (!initialTab)) {
- // May be CTags
- state = stCtagsStart;
- }
- } else if (state == stGccStart) { // <filename>:
- state = Is1To9(ch) ? stGccDigit : stUnrecognized;
- } else if (state == stGccDigit) { // <filename>:<line>
- if (ch == ':') {
- state = stGcc; // :9.*: is GCC
- startValue = i + 1;
- break;
- } else if (!Is0To9(ch)) {
- state = stUnrecognized;
- }
- } else if (state == stMsStart) { // <filename>(
- state = Is0To9(ch) ? stMsDigit : stUnrecognized;
- } else if (state == stMsDigit) { // <filename>(<line>
- if (ch == ',') {
- state = stMsDigitComma;
- } else if (ch == ')') {
- state = stMsBracket;
- } else if ((ch != ' ') && !Is0To9(ch)) {
- state = stUnrecognized;
- }
- } else if (state == stMsBracket) { // <filename>(<line>)
- if ((ch == ' ') && (chNext == ':')) {
- state = stMsVc;
- } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {
- // Possibly Delphi.. don't test against chNext as it's one of the strings below.
- char word[512];
- unsigned int j, chPos;
- unsigned numstep;
- chPos = 0;
- if (ch == ' ')
- numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
- else
- numstep = 2; // otherwise add 2.
- for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
- word[chPos++] = lineBuffer[j];
- word[chPos] = 0;
- if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
- !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") ||
- !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) {
- state = stMsVc;
- } else
- state = stUnrecognized;
- } else {
- state = stUnrecognized;
- }
- } else if (state == stMsDigitComma) { // <filename>(<line>,
- if (ch == ')') {
- state = stMsDotNet;
- break;
- } else if ((ch != ' ') && !Is0To9(ch)) {
- state = stUnrecognized;
- }
- } else if (state == stCtagsStart) {
- if ((lineBuffer[i - 1] == '\t') &&
- ((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) {
- state = stCtags;
- break;
- } else if ((ch == '/') && (lineBuffer[i + 1] == '^')) {
- state = stCtagsStartString;
- }
- } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) {
- state = stCtagsStringDollar;
- break;
- }
- }
- if (state == stGcc) {
- return initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC;
- } else if ((state == stMsVc) || (state == stMsDotNet)) {
- return SCE_ERR_MS;
- } else if ((state == stCtagsStringDollar) || (state == stCtags)) {
- return SCE_ERR_CTAG;
- } else {
- return SCE_ERR_DEFAULT;
- }
- }
-}
-
-static void ColouriseErrorListLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int endPos,
- Accessor &styler,
- bool valueSeparate) {
- int startValue = -1;
- int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue);
- if (valueSeparate && (startValue >= 0)) {
- styler.ColourTo(endPos - (lengthLine - startValue), style);
- styler.ColourTo(endPos, SCE_ERR_VALUE);
- } else {
- styler.ColourTo(endPos, style);
- }
-}
-
-static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[10000];
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- unsigned int linePos = 0;
-
- // property lexer.errorlist.value.separate
- // For lines in the output pane that are matches from Find in Files or GCC-style
- // diagnostics, style the path and line number separately from the rest of the
- // line with style 21 used for the rest of the line.
- // This allows matched text to be more easily distinguished from its location.
- bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 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';
- ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate);
- linePos = 0;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate);
- }
-}
-
-static int isSpecial(char s) {
- return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') ||
- (s == '\"') || (s == '`') || (s == '^') || (s == '~');
-}
-
-static int isTag(int start, Accessor &styler) {
- char s[6];
- unsigned int i = 0, e = 1;
- while (i < 5 && e) {
- s[i] = styler[start + i];
- i++;
- e = styler[start + i] != '{';
- }
- s[i] = '\0';
- return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
-}
-
-static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
-
- styler.StartAt(startPos);
-
- int state = initStyle;
- char chNext = styler[startPos];
- styler.StartSegment(startPos);
- int lengthDoc = startPos + length;
-
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- i++;
- continue;
- }
- switch (state) {
- case SCE_L_DEFAULT :
- switch (ch) {
- case '\\' :
- styler.ColourTo(i - 1, state);
- if (isSpecial(styler[i + 1])) {
- styler.ColourTo(i + 1, SCE_L_COMMAND);
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- if (isTag(i + 1, styler))
- state = SCE_L_TAG;
- else
- state = SCE_L_COMMAND;
- }
- break;
- case '$' :
- styler.ColourTo(i - 1, state);
- state = SCE_L_MATH;
- if (chNext == '$') {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- break;
- case '%' :
- styler.ColourTo(i - 1, state);
- state = SCE_L_COMMENT;
- break;
- }
- break;
- case SCE_L_COMMAND :
- if (chNext == '[' || chNext == '{' || chNext == '}' ||
- chNext == ' ' || chNext == '\r' || chNext == '\n') {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- break;
- case SCE_L_TAG :
- if (ch == '}') {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- }
- break;
- case SCE_L_MATH :
- if (ch == '$') {
- if (chNext == '$') {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- }
- break;
- case SCE_L_COMMENT :
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_L_DEFAULT;
- }
- }
- }
- styler.ColourTo(lengthDoc-1, state);
-}
-
-static const char * const batchWordListDesc[] = {
- "Internal Commands",
- "External Commands",
- 0
-};
-
-static const char * const emptyWordListDesc[] = {
- 0
-};
-
-static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- // Null language means all style bytes are 0 so just mark the end - no need to fill in.
- if (length > 0) {
- styler.StartAt(startPos + length - 1);
- styler.StartSegment(startPos + length - 1);
- styler.ColourTo(startPos + length - 1, 0);
- }
-}
-
-LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
-LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
-LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
-LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
-LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
-LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
-LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
-LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
+++ /dev/null
-// Scintilla source code edit control
-// @file LexPB.cxx
-// Lexer for PowerBasic by Roland Walter, roland@rowalt.de (for PowerBasic see www.powerbasic.com)
-//
-// Changes:
-// 17.10.2003: Toggling of subs/functions now until next sub/function - this gives better results
-// 29.10.2003: 1. Bug: Toggling didn't work for subs/functions added in editor
-// 2. Own colors for PB constants and Inline Assembler SCE_B_CONSTANT and SCE_B_ASM
-// 3. Several smaller syntax coloring improvements and speed optimizations
-// 12.07.2004: 1. Toggling for macros added
-// 2. Further folding speed optimitations (for people dealing with very large listings)
-//
-// Necessary changes for the PB lexer in Scintilla project:
-// - In SciLexer.h and Scintilla.iface:
-//
-// #define SCLEX_POWERBASIC 51 //ID for PowerBasic lexer
-// (...)
-// #define SCE_B_DEFAULT 0 //in both VB and PB lexer
-// #define SCE_B_COMMENT 1 //in both VB and PB lexer
-// #define SCE_B_NUMBER 2 //in both VB and PB lexer
-// #define SCE_B_KEYWORD 3 //in both VB and PB lexer
-// #define SCE_B_STRING 4 //in both VB and PB lexer
-// #define SCE_B_PREPROCESSOR 5 //VB lexer only, not in PB lexer
-// #define SCE_B_OPERATOR 6 //in both VB and PB lexer
-// #define SCE_B_IDENTIFIER 7 //in both VB and PB lexer
-// #define SCE_B_DATE 8 //VB lexer only, not in PB lexer
-// #define SCE_B_CONSTANT 13 //PB lexer only, not in VB lexer
-// #define SCE_B_ASM 14 //PB lexer only, not in VB lexer
-
-// - Statement added to KeyWords.cxx: 'LINK_LEXER(lmPB);'
-// - Statement added to scintilla_vc6.mak: '$(DIR_O)\LexPB.obj: ...\src\LexPB.cxx $(LEX_HEADERS)'
-//
-// Copyright for Scintilla: 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsTypeCharacter(const int ch)
-{
- return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$' || ch == '?';
-}
-
-static inline bool IsAWordChar(const int ch)
-{
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(const int ch)
-{
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-bool MatchUpperCase(Accessor &styler, int pos, const char *s) //Same as styler.Match() but uppercase comparison (a-z,A-Z and space only)
-{
- char ch;
- for (int i=0; *s; i++)
- {
- ch=styler.SafeGetCharAt(pos+i);
- if (ch > 0x60) ch -= '\x20';
- if (*s != ch) return false;
- s++;
- }
- return true;
-}
-
-static void ColourisePBDoc(unsigned int startPos, int length, int initStyle,WordList *keywordlists[],Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
-
- styler.StartAt(startPos);
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
- switch (sc.state)
- {
- case SCE_B_OPERATOR:
- {
- sc.SetState(SCE_B_DEFAULT);
- break;
- }
- case SCE_B_KEYWORD:
- {
- if (!IsAWordChar(sc.ch))
- {
- if (!IsTypeCharacter(sc.ch))
- {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s))
- {
- if (strcmp(s, "rem") == 0)
- {
- sc.ChangeState(SCE_B_COMMENT);
- if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
- }
- else if (strcmp(s, "asm") == 0)
- {
- sc.ChangeState(SCE_B_ASM);
- if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
- }
- else
- {
- sc.SetState(SCE_B_DEFAULT);
- }
- }
- else
- {
- sc.ChangeState(SCE_B_IDENTIFIER);
- sc.SetState(SCE_B_DEFAULT);
- }
- }
- }
- break;
- }
- case SCE_B_NUMBER:
- {
- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);}
- break;
- }
- case SCE_B_STRING:
- {
- if (sc.ch == '\"'){sc.ForwardSetState(SCE_B_DEFAULT);}
- break;
- }
- case SCE_B_CONSTANT:
- {
- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);}
- break;
- }
- case SCE_B_COMMENT:
- {
- if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
- break;
- }
- case SCE_B_ASM:
- {
- if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);}
- break;
- }
- } //switch (sc.state)
-
- // Determine if a new state should be entered:
- if (sc.state == SCE_B_DEFAULT)
- {
- if (sc.ch == '\'') {sc.SetState(SCE_B_COMMENT);}
- else if (sc.ch == '\"') {sc.SetState(SCE_B_STRING);}
- else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {sc.SetState(SCE_B_NUMBER);}
- else if (sc.ch == '&' && tolower(sc.chNext) == 'b') {sc.SetState(SCE_B_NUMBER);}
- else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {sc.SetState(SCE_B_NUMBER);}
- else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_B_NUMBER);}
- else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_B_KEYWORD);}
- else if (sc.ch == '%') {sc.SetState(SCE_B_CONSTANT);}
- else if (sc.ch == '$') {sc.SetState(SCE_B_CONSTANT);}
- else if (sc.ch == '#') {sc.SetState(SCE_B_KEYWORD);}
- else if (sc.ch == '!') {sc.SetState(SCE_B_ASM);}
- else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {sc.SetState(SCE_B_OPERATOR);}
- }
- } //for (; sc.More(); sc.Forward())
- sc.Complete();
-}
-
-//The folding routine for PowerBasic toggles SUBs and FUNCTIONs only. This was exactly what I wanted,
-//nothing more. I had worked with this kind of toggling for several years when I used the great good old
-//GFA Basic which is dead now. After testing the feature of toggling FOR-NEXT loops, WHILE-WEND loops
-//and so on too I found this is more disturbing then helping (for me). So if You think in another way
-//you can (or must) write Your own toggling routine ;-)
-static void FoldPBDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
-{
- // No folding enabled, no reason to continue...
- if( styler.GetPropertyInt("fold") == 0 )
- return;
-
- unsigned int endPos = startPos + length;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
-
- bool fNewLine=true;
- bool fMightBeMultiLineMacro=false;
- bool fBeginOfCommentFound=false;
- for (unsigned int i = startPos; i < endPos; i++)
- {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (fNewLine) //Begin of a new line (The Sub/Function/Macro keywords may occur at begin of line only)
- {
- fNewLine=false;
- fBeginOfCommentFound=false;
- switch (ch)
- {
- case ' ': //Most lines start with space - so check this first, the code is the same as for 'default:'
- case '\t': //Handle tab too
- {
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- styler.SetLevel(lineCurrent, lev);
- break;
- }
- case 'F':
- case 'f':
- {
- switch (chNext)
- {
- case 'U':
- case 'u':
- {
- if( MatchUpperCase(styler,i,"FUNCTION") )
- {
- styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
- levelNext=SC_FOLDLEVELBASE+1;
- }
- break;
- }
- }
- break;
- }
- case 'S':
- case 's':
- {
- switch (chNext)
- {
- case 'U':
- case 'u':
- {
- if( MatchUpperCase(styler,i,"SUB") )
- {
- styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
- levelNext=SC_FOLDLEVELBASE+1;
- }
- break;
- }
- case 'T':
- case 't':
- {
- if( MatchUpperCase(styler,i,"STATIC FUNCTION") )
- {
- styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
- levelNext=SC_FOLDLEVELBASE+1;
- }
- else if( MatchUpperCase(styler,i,"STATIC SUB") )
- {
- styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
- levelNext=SC_FOLDLEVELBASE+1;
- }
- break;
- }
- }
- break;
- }
- case 'C':
- case 'c':
- {
- switch (chNext)
- {
- case 'A':
- case 'a':
- {
- if( MatchUpperCase(styler,i,"CALLBACK FUNCTION") )
- {
- styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
- levelNext=SC_FOLDLEVELBASE+1;
- }
- break;
- }
- }
- break;
- }
- case 'M':
- case 'm':
- {
- switch (chNext)
- {
- case 'A':
- case 'a':
- {
- if( MatchUpperCase(styler,i,"MACRO") )
- {
- fMightBeMultiLineMacro=true; //Set folder level at end of line, we have to check for single line macro
- }
- break;
- }
- }
- break;
- }
- default:
- {
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- styler.SetLevel(lineCurrent, lev);
- break;
- }
- } //switch (ch)
- } //if( fNewLine )
-
- switch (ch)
- {
- case '=': //To test single line macros
- {
- if (fBeginOfCommentFound==false)
- fMightBeMultiLineMacro=false; //The found macro is a single line macro only;
- break;
- }
- case '\'': //A comment starts
- {
- fBeginOfCommentFound=true;
- break;
- }
- case '\n':
- {
- if (fMightBeMultiLineMacro) //The current line is the begin of a multi line macro
- {
- fMightBeMultiLineMacro=false;
- styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG);
- levelNext=SC_FOLDLEVELBASE+1;
- }
- lineCurrent++;
- levelCurrent = levelNext;
- fNewLine=true;
- break;
- }
- case '\r':
- {
- if (chNext != '\n')
- {
- lineCurrent++;
- levelCurrent = levelNext;
- fNewLine=true;
- }
- break;
- }
- } //switch (ch)
- } //for (unsigned int i = startPos; i < endPos; i++)
-}
-
-static const char * const pbWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmPB(SCLEX_POWERBASIC, ColourisePBDoc, "powerbasic", FoldPBDoc, pbWordListDesc);
+++ /dev/null
-// Copyright (c) 1990-2007, Scientific Toolworks, Inc.
-// Author: Jason Haslam
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void GetRange(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- i++;
- }
- s[i] = '\0';
-}
-
-static void ColourisePlmDoc(unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
-{
- unsigned int endPos = startPos + length;
- int state = initStyle;
-
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = styler.SafeGetCharAt(i);
- char chNext = styler.SafeGetCharAt(i + 1);
-
- if (state == SCE_PLM_DEFAULT) {
- if (ch == '/' && chNext == '*') {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_COMMENT;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_STRING;
- } else if (isdigit(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_NUMBER;
- } else if (isalpha(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_IDENTIFIER;
- } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
- ch == '=' || ch == '<' || ch == '>' || ch == ':') {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_OPERATOR;
- } else if (ch == '$') {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_CONTROL;
- }
- } else if (state == SCE_PLM_COMMENT) {
- if (ch == '*' && chNext == '/') {
- i++;
- styler.ColourTo(i, state);
- state = SCE_PLM_DEFAULT;
- }
- } else if (state == SCE_PLM_STRING) {
- if (ch == '\'') {
- if (chNext == '\'') {
- i++;
- } else {
- styler.ColourTo(i, state);
- state = SCE_PLM_DEFAULT;
- }
- }
- } else if (state == SCE_PLM_NUMBER) {
- if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
- i--;
- styler.ColourTo(i, state);
- state = SCE_PLM_DEFAULT;
- }
- } else if (state == SCE_PLM_IDENTIFIER) {
- if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
- // Get the entire identifier.
- char word[1024];
- int segmentStart = styler.GetStartSegment();
- GetRange(segmentStart, i - 1, styler, word, sizeof(word));
-
- i--;
- if (keywordlists[0]->InList(word))
- styler.ColourTo(i, SCE_PLM_KEYWORD);
- else
- styler.ColourTo(i, state);
- state = SCE_PLM_DEFAULT;
- }
- } else if (state == SCE_PLM_OPERATOR) {
- if (ch != '=' && ch != '>') {
- i--;
- styler.ColourTo(i, state);
- state = SCE_PLM_DEFAULT;
- }
- } else if (state == SCE_PLM_CONTROL) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_PLM_DEFAULT;
- }
- }
- }
- styler.ColourTo(endPos - 1, state);
-}
-
-static void FoldPlmDoc(unsigned int startPos,
- int length,
- int initStyle,
- WordList *[],
- Accessor &styler)
-{
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- int startKeyword = 0;
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD)
- startKeyword = i;
-
- if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) {
- char word[1024];
- GetRange(startKeyword, i, styler, word, sizeof(word));
-
- if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0)
- levelCurrent++;
- else if (strcmp(word, "end") == 0)
- levelCurrent--;
- }
-
- if (foldComment) {
- if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT)
- levelCurrent++;
- else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT)
- levelCurrent--;
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char *const plmWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, "PL/M", FoldPlmDoc, plmWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexPOV.cxx
- ** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language).
- ** Written by Philippe Lhoste but this is mostly a derivative of LexCPP...
- **/
-// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-// Some points that distinguish from a simple C lexer:
-// Identifiers start only by a character.
-// No line continuation character.
-// Strings are limited to 256 characters.
-// Directives are similar to preprocessor commands,
-// but we match directive keywords and colorize incorrect ones.
-// Block comments can be nested (code stolen from my code in LexLua).
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(int ch) {
- return ch < 0x80 && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return ch < 0x80 && isalpha(ch);
-}
-
-static inline bool IsANumberChar(int ch) {
- // Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- return (ch < 0x80) &&
- (isdigit(ch) || toupper(ch) == 'E' ||
- ch == '.' || ch == '-' || ch == '+');
-}
-
-static void ColourisePovDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords1 = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
- WordList &keywords8 = *keywordlists[7];
-
- int currentLine = styler.GetLine(startPos);
- // Initialize the block comment /* */ nesting level, if we are inside such a comment.
- int blockCommentLevel = 0;
- if (initStyle == SCE_POV_COMMENT) {
- blockCommentLevel = styler.GetLineState(currentLine - 1);
- }
-
- // Do not leak onto next line
- if (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) {
- initStyle = SCE_POV_DEFAULT;
- }
-
- short stringLen = 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
- if (sc.atLineEnd) {
- // Update the line state, so it can be seen by next line
- currentLine = styler.GetLine(sc.currentPos);
- if (sc.state == SCE_POV_COMMENT) {
- // Inside a block comment, we set the line state
- styler.SetLineState(currentLine, blockCommentLevel);
- } else {
- // Reset the line state
- styler.SetLineState(currentLine, 0);
- }
- }
-
- if (sc.atLineStart && (sc.state == SCE_POV_STRING)) {
- // Prevent SCE_POV_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_POV_STRING);
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_POV_OPERATOR) {
- sc.SetState(SCE_POV_DEFAULT);
- } else if (sc.state == SCE_POV_NUMBER) {
- // We stop the number definition on non-numerical non-dot non-eE non-sign char
- if (!IsANumberChar(sc.ch)) {
- sc.SetState(SCE_POV_DEFAULT);
- }
- } else if (sc.state == SCE_POV_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (keywords2.InList(s)) {
- sc.ChangeState(SCE_POV_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_POV_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_POV_WORD4);
- } else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_POV_WORD5);
- } else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_POV_WORD6);
- } else if (keywords7.InList(s)) {
- sc.ChangeState(SCE_POV_WORD7);
- } else if (keywords8.InList(s)) {
- sc.ChangeState(SCE_POV_WORD8);
- }
- sc.SetState(SCE_POV_DEFAULT);
- }
- } else if (sc.state == SCE_POV_DIRECTIVE) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- char *p;
- sc.GetCurrent(s, sizeof(s));
- p = s;
- // Skip # and whitespace between # and directive word
- do {
- p++;
- } while ((*p == ' ' || *p == '\t') && *p != '\0');
- if (!keywords1.InList(p)) {
- sc.ChangeState(SCE_POV_BADDIRECTIVE);
- }
- sc.SetState(SCE_POV_DEFAULT);
- }
- } else if (sc.state == SCE_POV_COMMENT) {
- if (sc.Match('/', '*')) {
- blockCommentLevel++;
- sc.Forward();
- } else if (sc.Match('*', '/') && blockCommentLevel > 0) {
- blockCommentLevel--;
- sc.Forward();
- if (blockCommentLevel == 0) {
- sc.ForwardSetState(SCE_POV_DEFAULT);
- }
- }
- } else if (sc.state == SCE_POV_COMMENTLINE) {
- if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_POV_DEFAULT);
- }
- } else if (sc.state == SCE_POV_STRING) {
- if (sc.ch == '\\') {
- stringLen++;
- if (strchr("abfnrtuv0'\"", sc.chNext)) {
- // Compound characters are counted as one.
- // Note: for Unicode chars \u, we shouldn't count the next 4 digits...
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_POV_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_POV_STRINGEOL);
- sc.ForwardSetState(SCE_POV_DEFAULT);
- } else {
- stringLen++;
- }
- if (stringLen > 256) {
- // Strings are limited to 256 chars
- sc.SetState(SCE_POV_STRINGEOL);
- }
- } else if (sc.state == SCE_POV_STRINGEOL) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_POV_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_POV_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_POV_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_POV_IDENTIFIER);
- } else if (sc.Match('/', '*')) {
- blockCommentLevel = 1;
- sc.SetState(SCE_POV_COMMENT);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- sc.SetState(SCE_POV_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_POV_STRING);
- stringLen = 0;
- } else if (sc.ch == '#') {
- sc.SetState(SCE_POV_DIRECTIVE);
- // Skip whitespace between # and directive word
- do {
- sc.Forward();
- } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.atLineEnd) {
- sc.SetState(SCE_POV_DEFAULT);
- }
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_POV_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-static void FoldPovDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *[],
- Accessor &styler) {
-
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldDirective = styler.GetPropertyInt("fold.directive") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && (style == SCE_POV_COMMENT)) {
- if (stylePrev != SCE_POV_COMMENT) {
- levelCurrent++;
- } else if ((styleNext != SCE_POV_COMMENT) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelCurrent--;
- }
- }
- if (foldComment && (style == SCE_POV_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
- if (foldDirective && (style == SCE_POV_DIRECTIVE)) {
- if (ch == '#') {
- unsigned int j=i+1;
- while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- }
- }
- if (style == SCE_POV_OPERATOR) {
- if (ch == '{') {
- levelCurrent++;
- } else if (ch == '}') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const povWordLists[] = {
- "Language directives",
- "Objects & CSG & Appearance",
- "Types & Modifiers & Items",
- "Predefined Identifiers",
- "Predefined Functions",
- "User defined 1",
- "User defined 2",
- "User defined 3",
- 0,
-};
-
-LexerModule lmPOV(SCLEX_POV, ColourisePovDoc, "pov", FoldPovDoc, povWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexPS.cxx
- ** Lexer for PostScript
- **
- ** Written by Nigel Hathaway <nigel@bprj.co.uk>.
- ** The License.txt file describes the conditions under which this software may be distributed.
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#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 inline bool IsASelfDelimitingChar(const int ch) {
- return (ch == '[' || ch == ']' || ch == '{' || ch == '}' ||
- ch == '/' || ch == '<' || ch == '>' ||
- ch == '(' || ch == ')' || ch == '%');
-}
-
-static inline bool IsAWhitespaceChar(const int ch) {
- return (ch == ' ' || ch == '\t' || ch == '\r' ||
- ch == '\n' || ch == '\f' || ch == '\0');
-}
-
-static bool IsABaseNDigit(const int ch, const int base) {
- int maxdig = '9';
- int letterext = -1;
-
- if (base <= 10)
- maxdig = '0' + base - 1;
- else
- letterext = base - 11;
-
- return ((ch >= '0' && ch <= maxdig) ||
- (ch >= 'A' && ch <= ('A' + letterext)) ||
- (ch >= 'a' && ch <= ('a' + letterext)));
-}
-
-static inline bool IsABase85Char(const int ch) {
- return ((ch >= '!' && ch <= 'u') || ch == 'z');
-}
-
-static void ColourisePSDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords1 = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- bool tokenizing = styler.GetPropertyInt("ps.tokenize") != 0;
- int pslevel = styler.GetPropertyInt("ps.level", 3);
- int lineCurrent = styler.GetLine(startPos);
- int nestTextCurrent = 0;
- if (lineCurrent > 0 && initStyle == SCE_PS_TEXT)
- nestTextCurrent = styler.GetLineState(lineCurrent - 1);
- int numRadix = 0;
- bool numHasPoint = false;
- bool numHasExponent = false;
- bool numHasSign = false;
-
- // Clear out existing tokenization
- if (tokenizing && length > 0) {
- styler.StartAt(startPos, static_cast<char>(INDIC2_MASK));
- styler.ColourTo(startPos + length-1, 0);
- styler.Flush();
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- }
-
- for (; sc.More(); sc.Forward()) {
- if (sc.atLineStart)
- lineCurrent = styler.GetLine(sc.currentPos);
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_PS_COMMENT || sc.state == SCE_PS_DSC_VALUE) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_PS_DSC_COMMENT) {
- if (sc.ch == ':') {
- sc.Forward();
- if (!sc.atLineEnd)
- sc.SetState(SCE_PS_DSC_VALUE);
- else
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (IsAWhitespaceChar(sc.ch) && sc.ch != '\r') {
- sc.ChangeState(SCE_PS_COMMENT);
- }
- } else if (sc.state == SCE_PS_NUMBER) {
- if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {
- if ((sc.chPrev == '+' || sc.chPrev == '-' ||
- sc.chPrev == 'E' || sc.chPrev == 'e') && numRadix == 0)
- sc.ChangeState(SCE_PS_NAME);
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.ch == '#') {
- if (numHasPoint || numHasExponent || numHasSign || numRadix != 0) {
- sc.ChangeState(SCE_PS_NAME);
- } else {
- char szradix[5];
- sc.GetCurrent(szradix, 4);
- numRadix = atoi(szradix);
- if (numRadix < 2 || numRadix > 36)
- sc.ChangeState(SCE_PS_NAME);
- }
- } else if ((sc.ch == 'E' || sc.ch == 'e') && numRadix == 0) {
- if (numHasExponent) {
- sc.ChangeState(SCE_PS_NAME);
- } else {
- numHasExponent = true;
- if (sc.chNext == '+' || sc.chNext == '-')
- sc.Forward();
- }
- } else if (sc.ch == '.') {
- if (numHasPoint || numHasExponent || numRadix != 0) {
- sc.ChangeState(SCE_PS_NAME);
- } else {
- numHasPoint = true;
- }
- } else if (numRadix == 0) {
- if (!IsABaseNDigit(sc.ch, 10))
- sc.ChangeState(SCE_PS_NAME);
- } else {
- if (!IsABaseNDigit(sc.ch, numRadix))
- sc.ChangeState(SCE_PS_NAME);
- }
- } else if (sc.state == SCE_PS_NAME || sc.state == SCE_PS_KEYWORD) {
- if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if ((pslevel >= 1 && keywords1.InList(s)) ||
- (pslevel >= 2 && keywords2.InList(s)) ||
- (pslevel >= 3 && keywords3.InList(s)) ||
- keywords4.InList(s) || keywords5.InList(s)) {
- sc.ChangeState(SCE_PS_KEYWORD);
- }
- sc.SetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_PS_LITERAL || sc.state == SCE_PS_IMMEVAL) {
- if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch))
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.state == SCE_PS_PAREN_ARRAY || sc.state == SCE_PS_PAREN_DICT ||
- sc.state == SCE_PS_PAREN_PROC) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.state == SCE_PS_TEXT) {
- if (sc.ch == '(') {
- nestTextCurrent++;
- } else if (sc.ch == ')') {
- if (--nestTextCurrent == 0)
- sc.ForwardSetState(SCE_PS_DEFAULT);
- } else if (sc.ch == '\\') {
- sc.Forward();
- }
- } else if (sc.state == SCE_PS_HEXSTRING) {
- if (sc.ch == '>') {
- sc.ForwardSetState(SCE_PS_DEFAULT);
- } else if (!IsABaseNDigit(sc.ch, 16) && !IsAWhitespaceChar(sc.ch)) {
- sc.SetState(SCE_PS_HEXSTRING);
- styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
- }
- } else if (sc.state == SCE_PS_BASE85STRING) {
- if (sc.Match('~', '>')) {
- sc.Forward();
- sc.ForwardSetState(SCE_PS_DEFAULT);
- } else if (!IsABase85Char(sc.ch) && !IsAWhitespaceChar(sc.ch)) {
- sc.SetState(SCE_PS_BASE85STRING);
- styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_C_DEFAULT) {
- unsigned int tokenpos = sc.currentPos;
-
- if (sc.ch == '[' || sc.ch == ']') {
- sc.SetState(SCE_PS_PAREN_ARRAY);
- } else if (sc.ch == '{' || sc.ch == '}') {
- sc.SetState(SCE_PS_PAREN_PROC);
- } else if (sc.ch == '/') {
- if (sc.chNext == '/') {
- sc.SetState(SCE_PS_IMMEVAL);
- sc.Forward();
- } else {
- sc.SetState(SCE_PS_LITERAL);
- }
- } else if (sc.ch == '<') {
- if (sc.chNext == '<') {
- sc.SetState(SCE_PS_PAREN_DICT);
- sc.Forward();
- } else if (sc.chNext == '~') {
- sc.SetState(SCE_PS_BASE85STRING);
- sc.Forward();
- } else {
- sc.SetState(SCE_PS_HEXSTRING);
- }
- } else if (sc.ch == '>' && sc.chNext == '>') {
- sc.SetState(SCE_PS_PAREN_DICT);
- sc.Forward();
- } else if (sc.ch == '>' || sc.ch == ')') {
- sc.SetState(SCE_C_DEFAULT);
- styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
- } else if (sc.ch == '(') {
- sc.SetState(SCE_PS_TEXT);
- nestTextCurrent = 1;
- } else if (sc.ch == '%') {
- if (sc.chNext == '%' && sc.atLineStart) {
- sc.SetState(SCE_PS_DSC_COMMENT);
- sc.Forward();
- if (sc.chNext == '+') {
- sc.Forward();
- sc.ForwardSetState(SCE_PS_DSC_VALUE);
- }
- } else {
- sc.SetState(SCE_PS_COMMENT);
- }
- } else if ((sc.ch == '+' || sc.ch == '-' || sc.ch == '.') &&
- IsABaseNDigit(sc.chNext, 10)) {
- sc.SetState(SCE_PS_NUMBER);
- numRadix = 0;
- numHasPoint = (sc.ch == '.');
- numHasExponent = false;
- numHasSign = (sc.ch == '+' || sc.ch == '-');
- } else if ((sc.ch == '+' || sc.ch == '-') && sc.chNext == '.' &&
- IsABaseNDigit(sc.GetRelative(2), 10)) {
- sc.SetState(SCE_PS_NUMBER);
- numRadix = 0;
- numHasPoint = false;
- numHasExponent = false;
- numHasSign = true;
- } else if (IsABaseNDigit(sc.ch, 10)) {
- sc.SetState(SCE_PS_NUMBER);
- numRadix = 0;
- numHasPoint = false;
- numHasExponent = false;
- numHasSign = false;
- } else if (!IsAWhitespaceChar(sc.ch)) {
- sc.SetState(SCE_PS_NAME);
- }
-
- // Mark the start of tokens
- if (tokenizing && sc.state != SCE_C_DEFAULT && sc.state != SCE_PS_COMMENT &&
- sc.state != SCE_PS_DSC_COMMENT && sc.state != SCE_PS_DSC_VALUE) {
- styler.Flush();
- styler.StartAt(tokenpos, static_cast<char>(INDIC2_MASK));
- styler.ColourTo(tokenpos, INDIC2_MASK);
- styler.Flush();
- styler.StartAt(tokenpos);
- styler.StartSegment(tokenpos);
- }
- }
-
- if (sc.atLineEnd)
- styler.SetLineState(lineCurrent, nestTextCurrent);
- }
-
- sc.Complete();
-}
-
-static void FoldPSDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); //mac??
- if ((style & 31) == SCE_PS_PAREN_PROC) {
- if (ch == '{') {
- // Measure the minimum before a '{' to allow
- // folding on "} {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- if (atEOL) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
-}
-
-static const char * const psWordListDesc[] = {
- "PS Level 1 operators",
- "PS Level 2 operators",
- "PS Level 3 operators",
- "RIP-specific operators",
- "User-defined operators",
- 0
-};
-
-LexerModule lmPS(SCLEX_PS, ColourisePSDoc, "ps", FoldPSDoc, psWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexPascal.cxx
- ** Lexer for Pascal.
- ** Written by Laurent le Tynevez
- ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
- ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
- ** Completely rewritten by Marko Njezic <sf@maxempire.com> October 2008
- **/
-
-/*
-
-A few words about features of the new completely rewritten LexPascal...
-
-Generally speaking LexPascal tries to support all available Delphi features (up
-to Delphi 2009 at this time), including .NET specific features.
-
-~ HIGHLIGHTING:
-
-If you enable "lexer.pascal.smart.highlighting" property, some keywords will
-only be highlighted in appropriate context. As implemented those are keywords
-related to property and DLL exports declarations (similar to how Delphi IDE
-works).
-
-For example, keywords "read" and "write" will only be highlighted if they are in
-property declaration:
-
-property MyProperty: boolean read FMyProperty write FMyProperty;
-
-~ FOLDING:
-
-Folding is supported in the following cases:
-
-- Folding of stream-like comments
-- Folding of groups of consecutive line comments
-- Folding of preprocessor blocks (the following preprocessor blocks are
-supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION
-blocks), including nesting of preprocessor blocks up to 255 levels
-- Folding of code blocks on appropriate keywords (the following code blocks are
-supported: "begin, asm, record, try, case / end" blocks, class & object
-declarations and interface declarations)
-
-Remarks:
-
-- Folding of code blocks tries to handle all special cases in which folding
-should not occur. As implemented those are:
-
-1. Structure "record case / end" (there's only one "end" statement and "case" is
-ignored as fold point)
-2. Forward class declarations ("type TMyClass = class;") and object method
-declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are
-ignored as fold points
-3. Simplified complete class declarations ("type TMyClass = class(TObject);")
-are ignored as fold points
-4. Every other situation when class keyword doesn't actually start class
-declaration ("class procedure", "class function", "class of", "class var",
-"class property" and "class operator")
-
-- Folding of code blocks inside preprocessor blocks is disabled (any comments
-inside them will be folded fine) because there is no guarantee that complete
-code block will be contained inside folded preprocessor block in which case
-folded code block could end prematurely at the end of preprocessor block if
-there is no closing statement inside. This was done in order to properly process
-document that may contain something like this:
-
-type
-{$IFDEF UNICODE}
- TMyClass = class(UnicodeAncestor)
-{$ELSE}
- TMyClass = class(AnsiAncestor)
-{$ENDIF}
- private
- ...
- public
- ...
- published
- ...
-end;
-
-If class declarations were folded, then the second class declaration would end
-at "$ENDIF" statement, first class statement would end at "end;" statement and
-preprocessor "$IFDEF" block would go all the way to the end of document.
-However, having in mind all this, if you want to enable folding of code blocks
-inside preprocessor blocks, you can disable folding of preprocessor blocks by
-changing "fold.preprocessor" property, in which case everything inside them
-would be folded.
-
-~ KEYWORDS:
-
-The list of keywords that can be used in pascal.properties file (up to Delphi
-2009):
-
-- Keywords: absolute abstract and array as asm assembler automated begin case
-cdecl class const constructor deprecated destructor dispid dispinterface div do
-downto dynamic else end except export exports external far file final
-finalization finally for forward function goto if implementation in inherited
-initialization inline interface is label library message mod near nil not object
-of on or out overload override packed pascal platform private procedure program
-property protected public published raise record register reintroduce repeat
-resourcestring safecall sealed set shl shr static stdcall strict string then
-threadvar to try type unit unsafe until uses var varargs virtual while with xor
-
-- Keywords related to the "smart highlithing" feature: add default implements
-index name nodefault read readonly remove stored write writeonly
-
-- Keywords related to Delphi packages (in addition to all above): package
-contains requires
-
-*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void GetRangeLowered(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- i++;
- }
- s[i] = '\0';
-}
-
-static void GetForwardRangeLowered(unsigned int start,
- CharacterSet &charSet,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
- s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
- i++;
- }
- s[i] = '\0';
-
-}
-
-enum {
- stateInAsm = 0x1000,
- stateInProperty = 0x2000,
- stateInExport = 0x4000,
- stateFoldInPreprocessor = 0x0100,
- stateFoldInRecord = 0x0200,
- stateFoldInPreprocessorLevelMask = 0x00FF,
- stateFoldMaskAll = 0x0FFF
-};
-
-static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) {
- WordList& keywords = *keywordlists[0];
-
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- if (curLineState & stateInAsm) {
- if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') {
- curLineState &= ~stateInAsm;
- sc.ChangeState(SCE_PAS_WORD);
- } else {
- sc.ChangeState(SCE_PAS_ASM);
- }
- } else {
- bool ignoreKeyword = false;
- if (strcmp(s, "asm") == 0) {
- curLineState |= stateInAsm;
- } else if (bSmartHighlighting) {
- if (strcmp(s, "property") == 0) {
- curLineState |= stateInProperty;
- } else if (strcmp(s, "exports") == 0) {
- curLineState |= stateInExport;
- } else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) {
- ignoreKeyword = true;
- } else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) {
- ignoreKeyword = true;
- } else if (!(curLineState & stateInProperty) &&
- (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 ||
- strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 ||
- strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 ||
- strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 ||
- strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) {
- ignoreKeyword = true;
- }
- }
- if (!ignoreKeyword) {
- sc.ChangeState(SCE_PAS_WORD);
- }
- }
- } else if (curLineState & stateInAsm) {
- sc.ChangeState(SCE_PAS_ASM);
- }
- sc.SetState(SCE_PAS_DEFAULT);
-}
-
-static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0;
-
- CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
- CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
- CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
- CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}");
-
- int curLine = styler.GetLine(startPos);
- int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
- if (sc.atLineEnd) {
- // Update the line state, so it can be seen by next line
- curLine = styler.GetLine(sc.currentPos);
- styler.SetLineState(curLine, curLineState);
- }
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_PAS_NUMBER:
- if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
- sc.SetState(SCE_PAS_DEFAULT);
- } else if (sc.ch == '-' || sc.ch == '+') {
- if (sc.chPrev != 'E' && sc.chPrev != 'e') {
- sc.SetState(SCE_PAS_DEFAULT);
- }
- }
- break;
- case SCE_PAS_IDENTIFIER:
- if (!setWord.Contains(sc.ch)) {
- ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
- }
- break;
- case SCE_PAS_HEXNUMBER:
- if (!setHexNumber.Contains(sc.ch)) {
- sc.SetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_COMMENT:
- case SCE_PAS_PREPROCESSOR:
- if (sc.ch == '}') {
- sc.ForwardSetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_COMMENT2:
- case SCE_PAS_PREPROCESSOR2:
- if (sc.Match('*', ')')) {
- sc.Forward();
- sc.ForwardSetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_COMMENTLINE:
- if (sc.atLineStart) {
- sc.SetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_STRING:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_PAS_STRINGEOL);
- } else if (sc.ch == '\'' && sc.chNext == '\'') {
- sc.Forward();
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_STRINGEOL:
- if (sc.atLineStart) {
- sc.SetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_CHARACTER:
- if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
- sc.SetState(SCE_PAS_DEFAULT);
- }
- break;
- case SCE_PAS_OPERATOR:
- if (bSmartHighlighting && sc.chPrev == ';') {
- curLineState &= ~(stateInProperty | stateInExport);
- }
- sc.SetState(SCE_PAS_DEFAULT);
- break;
- case SCE_PAS_ASM:
- sc.SetState(SCE_PAS_DEFAULT);
- break;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_PAS_DEFAULT) {
- if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) {
- sc.SetState(SCE_PAS_NUMBER);
- } else if (setWordStart.Contains(sc.ch)) {
- sc.SetState(SCE_PAS_IDENTIFIER);
- } else if (sc.ch == '$' && !(curLineState & stateInAsm)) {
- sc.SetState(SCE_PAS_HEXNUMBER);
- } else if (sc.Match('{', '$')) {
- sc.SetState(SCE_PAS_PREPROCESSOR);
- } else if (sc.ch == '{') {
- sc.SetState(SCE_PAS_COMMENT);
- } else if (sc.Match("(*$")) {
- sc.SetState(SCE_PAS_PREPROCESSOR2);
- } else if (sc.Match('(', '*')) {
- sc.SetState(SCE_PAS_COMMENT2);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- sc.SetState(SCE_PAS_COMMENTLINE);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_PAS_STRING);
- } else if (sc.ch == '#') {
- sc.SetState(SCE_PAS_CHARACTER);
- } else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) {
- sc.SetState(SCE_PAS_OPERATOR);
- } else if (curLineState & stateInAsm) {
- sc.SetState(SCE_PAS_ASM);
- }
- }
- }
-
- if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) {
- ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
- }
-
- sc.Complete();
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2;
-}
-
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eolPos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eolPos; i++) {
- char ch = styler[i];
- char chNext = styler.SafeGetCharAt(i + 1);
- int style = styler.StyleAt(i);
- if (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) {
- return true;
- } else if (!IsASpaceOrTab(ch)) {
- return false;
- }
- }
- return false;
-}
-
-static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
- return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
-}
-
-static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
- lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
- lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
-}
-
-static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
- unsigned int startPos, Accessor &styler) {
- CharacterSet setWord(CharacterSet::setAlpha);
-
- char s[11]; // Size of the longest possible keyword + one additional character + null
- GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
-
- unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
-
- if (strcmp(s, "if") == 0 ||
- strcmp(s, "ifdef") == 0 ||
- strcmp(s, "ifndef") == 0 ||
- strcmp(s, "ifopt") == 0 ||
- strcmp(s, "region") == 0) {
- nestLevel++;
- SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
- lineFoldStateCurrent |= stateFoldInPreprocessor;
- levelCurrent++;
- } else if (strcmp(s, "endif") == 0 ||
- strcmp(s, "ifend") == 0 ||
- strcmp(s, "endregion") == 0) {
- nestLevel--;
- SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
- if (nestLevel == 0) {
- lineFoldStateCurrent &= ~stateFoldInPreprocessor;
- }
- levelCurrent--;
- if (levelCurrent < SC_FOLDLEVELBASE) {
- levelCurrent = SC_FOLDLEVELBASE;
- }
- }
-}
-
-static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos,
- Accessor &styler, bool includeChars = false) {
- CharacterSet setWord(CharacterSet::setAlphaNum, "_");
- unsigned int j = currentPos + 1;
- char ch = styler.SafeGetCharAt(j);
- while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
- IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
- j++;
- ch = styler.SafeGetCharAt(j);
- }
- return j;
-}
-
-static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
- int startPos, unsigned int endPos,
- unsigned int lastStart, unsigned int currentPos, Accessor &styler) {
- char s[100];
- GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
-
- if (strcmp(s, "record") == 0) {
- lineFoldStateCurrent |= stateFoldInRecord;
- levelCurrent++;
- } else if (strcmp(s, "begin") == 0 ||
- strcmp(s, "asm") == 0 ||
- strcmp(s, "try") == 0 ||
- (strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {
- levelCurrent++;
- } else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) {
- // "class" & "object" keywords require special handling...
- bool ignoreKeyword = false;
- unsigned int j = SkipWhiteSpace(currentPos, endPos, styler);
- if (j < endPos) {
- CharacterSet setWordStart(CharacterSet::setAlpha, "_");
- CharacterSet setWord(CharacterSet::setAlphaNum, "_");
-
- if (styler.SafeGetCharAt(j) == ';') {
- // Handle forward class declarations ("type TMyClass = class;")
- // and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;")
- ignoreKeyword = true;
- } else if (strcmp(s, "class") == 0) {
- // "class" keyword has a few more special cases...
- if (styler.SafeGetCharAt(j) == '(') {
- // Handle simplified complete class declarations ("type TMyClass = class(TObject);")
- j = SkipWhiteSpace(j, endPos, styler, true);
- if (j < endPos && styler.SafeGetCharAt(j) == ')') {
- j = SkipWhiteSpace(j, endPos, styler);
- if (j < endPos && styler.SafeGetCharAt(j) == ';') {
- ignoreKeyword = true;
- }
- }
- } else if (setWordStart.Contains(styler.SafeGetCharAt(j))) {
- char s2[11]; // Size of the longest possible keyword + one additional character + null
- GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));
-
- if (strcmp(s2, "procedure") == 0 ||
- strcmp(s2, "function") == 0 ||
- strcmp(s2, "of") == 0 ||
- strcmp(s2, "var") == 0 ||
- strcmp(s2, "property") == 0 ||
- strcmp(s2, "operator") == 0) {
- ignoreKeyword = true;
- }
- }
- }
- }
- if (!ignoreKeyword) {
- levelCurrent++;
- }
- } else if (strcmp(s, "interface") == 0) {
- // "interface" keyword requires special handling...
- bool ignoreKeyword = true;
- int j = lastStart - 1;
- char ch = styler.SafeGetCharAt(j);
- while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
- IsStreamCommentStyle(styler.StyleAt(j)))) {
- j--;
- ch = styler.SafeGetCharAt(j);
- }
- if (j >= startPos && styler.SafeGetCharAt(j) == '=') {
- ignoreKeyword = false;
- }
- if (!ignoreKeyword) {
- levelCurrent++;
- }
- } else if (strcmp(s, "end") == 0) {
- lineFoldStateCurrent &= ~stateFoldInRecord;
- levelCurrent--;
- if (levelCurrent < SC_FOLDLEVELBASE) {
- levelCurrent = SC_FOLDLEVELBASE;
- }
- }
-}
-
-static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
-
- int lastStart = 0;
- CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelCurrent++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelCurrent--;
- }
- }
- if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
- {
- if (!IsCommentLine(lineCurrent - 1, styler)
- && IsCommentLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsCommentLine(lineCurrent - 1, styler)
- && !IsCommentLine(lineCurrent+1, styler))
- levelCurrent--;
- }
- if (foldPreprocessor) {
- if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
- ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
- } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*'
- && styler.SafeGetCharAt(i + 2) == '$') {
- ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
- }
- }
-
- if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD)
- {
- // Store last word start point.
- lastStart = i;
- }
- if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) {
- if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
- ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler);
- }
- }
-
- if (!IsASpace(ch))
- visibleChars++;
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
- styler.SetLineState(lineCurrent, newLineState);
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- }
-
- // If we didn't reach the EOL in previous loop, store line level and whitespace information.
- // The rest will be filled in later...
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- styler.SetLevel(lineCurrent, lev);
-}
-
-static const char * const pascalWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexPerl.cxx
- ** Lexer for Perl.
- **/
-// Copyright 1998-2008 by Neil Hodgson <neilh@scintilla.org>
-// Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-// Info for HERE document handling from perldata.pod (reformatted):
-// ----------------------------------------------------------------
-// A line-oriented form of quoting is based on the shell ``here-doc'' syntax.
-// Following a << you specify a string to terminate the quoted material, and
-// all lines following the current line down to the terminating string are
-// the value of the item.
-// * The terminating string may be either an identifier (a word), or some
-// quoted text.
-// * If quoted, the type of quotes you use determines the treatment of the
-// text, just as in regular quoting.
-// * An unquoted identifier works like double quotes.
-// * There must be no space between the << and the identifier.
-// (If you put a space it will be treated as a null identifier,
-// which is valid, and matches the first empty line.)
-// (This is deprecated, -w warns of this syntax)
-// * The terminating string must appear by itself (unquoted and
-// with no surrounding whitespace) on the terminating line.
-
-#define HERE_DELIM_MAX 256 // maximum length of HERE doc delimiter
-
-#define PERLNUM_BINARY 1 // order is significant: 1-4 cannot have a dot
-#define PERLNUM_HEX 2
-#define PERLNUM_OCTAL 3
-#define PERLNUM_FLOAT_EXP 4 // exponent part only
-#define PERLNUM_DECIMAL 5 // 1-5 are numbers; 6-7 are strings
-#define PERLNUM_VECTOR 6
-#define PERLNUM_V_VECTOR 7
-#define PERLNUM_BAD 8
-
-#define BACK_NONE 0 // lookback state for bareword disambiguation:
-#define BACK_OPERATOR 1 // whitespace/comments are insignificant
-#define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation
-
-static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler)
-{
- // old-style keyword matcher; needed because GetCurrent() needs
- // current segment to be committed, but we may abandon early...
- char s[100];
- unsigned int i, len = end - start;
- if (len > 30) { len = 30; }
- for (i = 0; i < len; i++, start++) s[i] = styler[start];
- s[i] = '\0';
- return keywords.InList(s);
-}
-
-static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int fw,
- int backFlag, unsigned int backPos, unsigned int endPos)
-{
- // identifiers are recognized by Perl as barewords under some
- // conditions, the following attempts to do the disambiguation
- // by looking backward and forward; result in 2 LSB
- int result = 0;
- bool moreback = false; // true if passed newline/comments
- bool brace = false; // true if opening brace found
- // if BACK_NONE, neither operator nor keyword, so skip test
- if (backFlag == BACK_NONE)
- return result;
- // first look backwards past whitespace/comments to set EOL flag
- // (some disambiguation patterns must be on a single line)
- if (backPos <= static_cast<unsigned int>(styler.LineStart(styler.GetLine(bk))))
- moreback = true;
- // look backwards at last significant lexed item for disambiguation
- bk = backPos - 1;
- int ch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
- if (ch == '{' && !moreback) {
- // {bareword: possible variable spec
- brace = true;
- } else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&')
- // &bareword: subroutine call
- || styler.Match(bk - 1, "->")
- // ->bareword: part of variable spec
- || styler.Match(bk - 2, "sub")) {
- // sub bareword: subroutine declaration
- // (implied BACK_KEYWORD, no keywords end in 'sub'!)
- result |= 1;
- }
- // next, scan forward after word past tab/spaces only;
- // if ch isn't one of '[{(,' we can skip the test
- if ((ch == '{' || ch == '(' || ch == '['|| ch == ',')
- && fw < endPos) {
- while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)),
- IsASpaceOrTab(ch) && fw < endPos) {
- fw++;
- }
- if ((ch == '}' && brace)
- // {bareword}: variable spec
- || styler.Match(fw, "=>")) {
- // [{(, bareword=>: hash literal
- result |= 2;
- }
- }
- return result;
-}
-
-static void skipWhitespaceComment(Accessor &styler, unsigned int &p)
-{
- // when backtracking, we need to skip whitespace and comments
- int style;
- while ((p > 0) && (style = styler.StyleAt(p),
- style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
- p--;
-}
-
-static int styleBeforeBracePair(Accessor &styler, unsigned int bk)
-{
- // backtrack to find open '{' corresponding to a '}', balanced
- // return significant style to be tested for '/' disambiguation
- int braceCount = 1;
- if (bk == 0)
- return SCE_PL_DEFAULT;
- while (--bk > 0) {
- if (styler.StyleAt(bk) == SCE_PL_OPERATOR) {
- int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
- if (bkch == ';') { // early out
- break;
- } else if (bkch == '}') {
- braceCount++;
- } else if (bkch == '{') {
- if (--braceCount == 0) break;
- }
- }
- }
- if (bk > 0 && braceCount == 0) {
- // balanced { found, bk > 0, skip more whitespace/comments
- bk--;
- skipWhitespaceComment(styler, bk);
- return styler.StyleAt(bk);
- }
- return SCE_PL_DEFAULT;
-}
-
-static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
-{
- // backtrack to classify sub-styles of identifier under test
- // return sub-style to be tested for '/' disambiguation
- if (styler.SafeGetCharAt(bk) == '>') // inputsymbol, like <foo>
- return 1;
- // backtrack to check for possible "->" or "::" before identifier
- while (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) {
- bk--;
- }
- while (bk > 0) {
- int bkstyle = styler.StyleAt(bk);
- if (bkstyle == SCE_PL_DEFAULT
- || bkstyle == SCE_PL_COMMENTLINE) {
- // skip whitespace, comments
- } else if (bkstyle == SCE_PL_OPERATOR) {
- // test for "->" and "::"
- if (styler.Match(bk - 1, "->") || styler.Match(bk - 1, "::"))
- return 2;
- } else
- return 3; // bare identifier
- bk--;
- }
- return 0;
-}
-
-static int inputsymbolScan(Accessor &styler, unsigned int pos, unsigned int endPos)
-{
- // looks forward for matching > on same line; a bit ugly
- unsigned int fw = pos;
- while (++fw < endPos) {
- int fwch = static_cast<unsigned char>(styler.SafeGetCharAt(fw));
- if (fwch == '\r' || fwch == '\n') {
- return 0;
- } else if (fwch == '>') {
- if (styler.Match(fw - 2, "<=>")) // '<=>' case
- return 0;
- return fw - pos;
- }
- }
- return 0;
-}
-
-static int podLineScan(Accessor &styler, unsigned int &pos, unsigned int endPos)
-{
- // forward scan the current line to classify line for POD style
- int state = -1;
- while (pos <= endPos) {
- int ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
- if (ch == '\n' || ch == '\r' || pos >= endPos) {
- if (ch == '\r' && styler.SafeGetCharAt(pos + 1) == '\n') pos++;
- break;
- }
- if (IsASpaceOrTab(ch)) { // whitespace, take note
- if (state == -1)
- state = SCE_PL_DEFAULT;
- } else if (state == SCE_PL_DEFAULT) { // verbatim POD line
- state = SCE_PL_POD_VERB;
- } else if (state != SCE_PL_POD_VERB) { // regular POD line
- state = SCE_PL_POD;
- }
- pos++;
- }
- if (state == -1)
- state = SCE_PL_DEFAULT;
- return state;
-}
-
-static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
-{
- // backtrack to identify if we're starting a subroutine prototype
- // we also need to ignore whitespace/comments:
- // 'sub' [whitespace|comment] <identifier> [whitespace|comment]
- styler.Flush();
- skipWhitespaceComment(styler, bk);
- if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier
- return false;
- while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) {
- bk--;
- }
- skipWhitespaceComment(styler, bk);
- if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword
- || !styler.Match(bk - 2, "sub")) // assume suffix is unique!
- return false;
- return true;
-}
-
-static bool isMatch(const char *sref, char *s)
-{
- // match per-line delimiter - must kill trailing CR if CRLF
- int i = strlen(s);
- if (i != 0 && s[i - 1] == '\r')
- s[i - 1] = '\0';
- return (strcmp(sref, s) == 0);
-}
-
-static int actualNumStyle(int numberStyle) {
- if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) {
- return SCE_PL_STRING;
- } else if (numberStyle == PERLNUM_BAD) {
- return SCE_PL_ERROR;
- }
- return SCE_PL_NUMBER;
-}
-
-static int opposite(int ch) {
- if (ch == '(') return ')';
- if (ch == '[') return ']';
- if (ch == '{') return '}';
- if (ch == '<') return '>';
- return ch;
-}
-
-static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
-
- // keywords that forces /PATTERN/ at all times; should track vim's behaviour
- WordList reWords;
- reWords.Set("elsif if split while");
-
- // charset classes
- CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
- CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMAC");
- // lexing of "%*</" operators is non-trivial; these are missing in the set below
- CharacterSet setPerlOperator(CharacterSet::setNone, "^&\\()-+=|{}[]:;>,?!.~");
- CharacterSet setQDelim(CharacterSet::setNone, "qrwx");
- CharacterSet setModifiers(CharacterSet::setAlpha);
- CharacterSet setPreferRE(CharacterSet::setNone, "*/<%");
- // setArray and setHash also accepts chars for special vars like $_,
- // which are then truncated when the next char does not match setVar
- CharacterSet setVar(CharacterSet::setAlphaNum, "#$_'", 0x80, true);
- CharacterSet setArray(CharacterSet::setAlpha, "#$_+-", 0x80, true);
- CharacterSet setHash(CharacterSet::setAlpha, "#$_!^+-", 0x80, true);
- CharacterSet &setPOD = setModifiers;
- CharacterSet setNonHereDoc(CharacterSet::setDigits, "=$@");
- CharacterSet setHereDocDelim(CharacterSet::setAlphaNum, "_");
- CharacterSet setSubPrototype(CharacterSet::setNone, "\\[$@%&*];");
- // for format identifiers
- CharacterSet setFormatStart(CharacterSet::setAlpha, "_=");
- CharacterSet &setFormat = setHereDocDelim;
-
- // Lexer for perl often has to backtrack to start of current style to determine
- // which characters are being used as quotes, how deeply nested is the
- // start position and what the termination string is for HERE documents.
-
- class HereDocCls { // Class to manage HERE doc sequence
- public:
- int State; // 0: '<<' encountered
- // 1: collect the delimiter
- // 2: here doc text (lines after the delimiter)
- int Quote; // the char after '<<'
- bool Quoted; // true if Quote in ('\'','"','`')
- int DelimiterLength; // strlen(Delimiter)
- char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
- HereDocCls() {
- State = 0;
- Quote = 0;
- Quoted = false;
- DelimiterLength = 0;
- Delimiter = new char[HERE_DELIM_MAX];
- Delimiter[0] = '\0';
- }
- void Append(int ch) {
- Delimiter[DelimiterLength++] = static_cast<char>(ch);
- Delimiter[DelimiterLength] = '\0';
- }
- ~HereDocCls() {
- delete []Delimiter;
- }
- };
- HereDocCls HereDoc; // TODO: FIFO for stacked here-docs
-
- class QuoteCls { // Class to manage quote pairs
- public:
- int Rep;
- int Count;
- int Up, Down;
- QuoteCls() {
- this->New(1);
- }
- void New(int r = 1) {
- Rep = r;
- Count = 0;
- Up = '\0';
- Down = '\0';
- }
- void Open(int u) {
- Count++;
- Up = u;
- Down = opposite(Up);
- }
- };
- QuoteCls Quote;
-
- // additional state for number lexing
- int numState = PERLNUM_DECIMAL;
- int dotCount = 0;
-
- unsigned int endPos = startPos + length;
-
- // Backtrack to beginning of style if required...
- // If in a long distance lexical state, backtrack to find quote characters.
- // Includes strings (may be multi-line), numbers (additional state), format
- // bodies, as well as POD sections.
- if (initStyle == SCE_PL_HERE_Q
- || initStyle == SCE_PL_HERE_QQ
- || initStyle == SCE_PL_HERE_QX
- || initStyle == SCE_PL_FORMAT
- ) {
- int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;
- while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {
- startPos--;
- }
- startPos = styler.LineStart(styler.GetLine(startPos));
- initStyle = styler.StyleAt(startPos - 1);
- }
- if (initStyle == SCE_PL_STRING_Q
- || initStyle == SCE_PL_STRING_QQ
- || initStyle == SCE_PL_STRING_QX
- || initStyle == SCE_PL_STRING_QR
- || initStyle == SCE_PL_STRING_QW
- || initStyle == SCE_PL_REGEX
- || initStyle == SCE_PL_REGSUBST
- || initStyle == SCE_PL_STRING
- || initStyle == SCE_PL_BACKTICKS
- || initStyle == SCE_PL_CHARACTER
- || initStyle == SCE_PL_NUMBER
- || initStyle == SCE_PL_IDENTIFIER
- || initStyle == SCE_PL_ERROR
- || initStyle == SCE_PL_SUB_PROTOTYPE
- ) {
- while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
- startPos--;
- }
- initStyle = SCE_PL_DEFAULT;
- } else if (initStyle == SCE_PL_POD
- || initStyle == SCE_PL_POD_VERB
- ) {
- // POD backtracking finds preceeding blank lines and goes back past them
- int ln = styler.GetLine(startPos);
- if (ln > 0) {
- initStyle = styler.StyleAt(styler.LineStart(--ln));
- if (initStyle == SCE_PL_POD || initStyle == SCE_PL_POD_VERB) {
- while (ln > 0 && styler.GetLineState(ln) == SCE_PL_DEFAULT)
- ln--;
- }
- startPos = styler.LineStart(++ln);
- initStyle = styler.StyleAt(startPos - 1);
- } else {
- startPos = 0;
- initStyle = SCE_PL_DEFAULT;
- }
- }
-
- // backFlag, backPos are additional state to aid identifier corner cases.
- // Look backwards past whitespace and comments in order to detect either
- // operator or keyword. Later updated as we go along.
- int backFlag = BACK_NONE;
- unsigned int backPos = startPos;
- if (backPos > 0) {
- backPos--;
- skipWhitespaceComment(styler, backPos);
- if (styler.StyleAt(backPos) == SCE_PL_OPERATOR)
- backFlag = BACK_OPERATOR;
- else if (styler.StyleAt(backPos) == SCE_PL_WORD)
- backFlag = BACK_KEYWORD;
- backPos++;
- }
-
- StyleContext sc(startPos, endPos - startPos, initStyle, styler, static_cast<char>(STYLE_MAX));
-
- for (; sc.More(); sc.Forward()) {
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_PL_OPERATOR:
- sc.SetState(SCE_PL_DEFAULT);
- backFlag = BACK_OPERATOR;
- backPos = sc.currentPos;
- break;
- case SCE_PL_IDENTIFIER: // identifier, bareword, inputsymbol
- if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
- || sc.Match('.', '.')
- || sc.chPrev == '>') { // end of inputsymbol
- sc.SetState(SCE_PL_DEFAULT);
- }
- break;
- case SCE_PL_WORD: // keyword, plus special cases
- if (!setWord.Contains(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
- sc.ChangeState(SCE_PL_DATASECTION);
- } else {
- if ((strcmp(s, "format") == 0)) {
- sc.SetState(SCE_PL_FORMAT_IDENT);
- HereDoc.State = 0;
- } else {
- sc.SetState(SCE_PL_DEFAULT);
- }
- backFlag = BACK_KEYWORD;
- backPos = sc.currentPos;
- }
- }
- break;
- case SCE_PL_SCALAR:
- case SCE_PL_ARRAY:
- case SCE_PL_HASH:
- case SCE_PL_SYMBOLTABLE:
- if (sc.Match(':', ':')) { // skip ::
- sc.Forward();
- } else if (!setVar.Contains(sc.ch)) {
- if (sc.LengthCurrent() == 1) {
- // Special variable: $(, $_ etc.
- sc.Forward();
- }
- sc.SetState(SCE_PL_DEFAULT);
- }
- break;
- case SCE_PL_NUMBER:
- // if no early break, number style is terminated at "(go through)"
- if (sc.ch == '.') {
- if (sc.chNext == '.') {
- // double dot is always an operator (go through)
- } else if (numState <= PERLNUM_FLOAT_EXP) {
- // non-decimal number or float exponent, consume next dot
- sc.SetState(SCE_PL_OPERATOR);
- break;
- } else { // decimal or vectors allows dots
- dotCount++;
- if (numState == PERLNUM_DECIMAL) {
- if (dotCount <= 1) // number with one dot in it
- break;
- if (IsADigit(sc.chNext)) { // really a vector
- numState = PERLNUM_VECTOR;
- break;
- }
- // number then dot (go through)
- } else if (IsADigit(sc.chNext)) // vectors
- break;
- // vector then dot (go through)
- }
- } else if (sc.ch == '_') {
- // permissive underscoring for number and vector literals
- break;
- } else if (numState == PERLNUM_DECIMAL) {
- if (sc.ch == 'E' || sc.ch == 'e') { // exponent, sign
- numState = PERLNUM_FLOAT_EXP;
- if (sc.chNext == '+' || sc.chNext == '-') {
- sc.Forward();
- }
- break;
- } else if (IsADigit(sc.ch))
- break;
- // number then word (go through)
- } else if (numState == PERLNUM_HEX) {
- if (IsADigit(sc.ch, 16))
- break;
- } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
- if (IsADigit(sc.ch)) // vector
- break;
- if (setWord.Contains(sc.ch) && dotCount == 0) { // change to word
- sc.ChangeState(SCE_PL_IDENTIFIER);
- break;
- }
- // vector then word (go through)
- } else if (IsADigit(sc.ch)) {
- if (numState == PERLNUM_FLOAT_EXP) {
- break;
- } else if (numState == PERLNUM_OCTAL) {
- if (sc.ch <= '7') break;
- } else if (numState == PERLNUM_BINARY) {
- if (sc.ch <= '1') break;
- }
- // mark invalid octal, binary numbers (go through)
- numState = PERLNUM_BAD;
- break;
- }
- // complete current number or vector
- sc.ChangeState(actualNumStyle(numState));
- sc.SetState(SCE_PL_DEFAULT);
- break;
- case SCE_PL_COMMENTLINE:
- if (sc.atLineEnd) {
- sc.SetState(SCE_PL_DEFAULT);
- }
- break;
- case SCE_PL_HERE_DELIM:
- if (HereDoc.State == 0) { // '<<' encountered
- int delim_ch = sc.chNext;
- int ws_skip = 0;
- HereDoc.State = 1; // pre-init HERE doc class
- HereDoc.Quote = sc.chNext;
- HereDoc.Quoted = false;
- HereDoc.DelimiterLength = 0;
- HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- if (IsASpaceOrTab(delim_ch)) {
- // skip whitespace; legal only for quoted delimiters
- unsigned int i = sc.currentPos + 1;
- while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
- i++;
- delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
- }
- ws_skip = i - sc.currentPos - 1;
- }
- if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
- // a quoted here-doc delimiter; skip any whitespace
- sc.Forward(ws_skip + 1);
- HereDoc.Quote = delim_ch;
- HereDoc.Quoted = true;
- } else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
- || ws_skip > 0) {
- // left shift << or <<= operator cases
- // restore position if operator
- sc.ChangeState(SCE_PL_OPERATOR);
- sc.ForwardSetState(SCE_PL_DEFAULT);
- backFlag = BACK_OPERATOR;
- backPos = sc.currentPos;
- HereDoc.State = 0;
- } else {
- // specially handle initial '\' for identifier
- if (ws_skip == 0 && HereDoc.Quote == '\\')
- sc.Forward();
- // an unquoted here-doc delimiter, no special handling
- // (cannot be prefixed by spaces/tabs), or
- // symbols terminates; deprecated zero-length delimiter
- }
- } else if (HereDoc.State == 1) { // collect the delimiter
- backFlag = BACK_NONE;
- if (HereDoc.Quoted) { // a quoted here-doc delimiter
- if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
- sc.ForwardSetState(SCE_PL_DEFAULT);
- } else if (!sc.atLineEnd) {
- if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
- sc.Forward();
- }
- if (sc.ch != '\r') { // skip CR if CRLF
- HereDoc.Append(sc.ch);
- }
- }
- } else { // an unquoted here-doc delimiter
- if (setHereDocDelim.Contains(sc.ch)) {
- HereDoc.Append(sc.ch);
- } else {
- sc.SetState(SCE_PL_DEFAULT);
- }
- }
- if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
- sc.SetState(SCE_PL_ERROR);
- HereDoc.State = 0;
- }
- }
- break;
- case SCE_PL_HERE_Q:
- case SCE_PL_HERE_QQ:
- case SCE_PL_HERE_QX: {
- // also implies HereDoc.State == 2
- sc.Complete();
- while (!sc.atLineEnd)
- sc.Forward();
- char s[HERE_DELIM_MAX];
- sc.GetCurrent(s, sizeof(s));
- if (isMatch(HereDoc.Delimiter, s)) {
- sc.SetState(SCE_PL_DEFAULT);
- backFlag = BACK_NONE;
- HereDoc.State = 0;
- }
- } break;
- case SCE_PL_POD:
- case SCE_PL_POD_VERB: {
- unsigned int fw = sc.currentPos;
- int ln = styler.GetLine(fw);
- if (sc.atLineStart && sc.Match("=cut")) { // end of POD
- sc.SetState(SCE_PL_POD);
- sc.Forward(4);
- sc.SetState(SCE_PL_DEFAULT);
- styler.SetLineState(ln, SCE_PL_POD);
- break;
- }
- int pod = podLineScan(styler, fw, endPos); // classify POD line
- styler.SetLineState(ln, pod);
- if (pod == SCE_PL_DEFAULT) {
- if (sc.state == SCE_PL_POD_VERB) {
- unsigned int fw2 = fw;
- while (fw2 <= endPos && pod == SCE_PL_DEFAULT) {
- fw = fw2++; // penultimate line (last blank line)
- pod = podLineScan(styler, fw2, endPos);
- styler.SetLineState(styler.GetLine(fw2), pod);
- }
- if (pod == SCE_PL_POD) { // truncate verbatim POD early
- sc.SetState(SCE_PL_POD);
- } else
- fw = fw2;
- } else
- pod = SCE_PL_POD;
- } else {
- if (pod == SCE_PL_POD_VERB // still part of current paragraph
- && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
- pod = SCE_PL_POD;
- styler.SetLineState(ln, pod);
- } else if (pod == SCE_PL_POD
- && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
- pod = SCE_PL_POD_VERB;
- styler.SetLineState(ln, pod);
- }
- sc.SetState(pod);
- }
- sc.Forward(fw - sc.currentPos); // commit style
- } break;
- case SCE_PL_REGEX:
- case SCE_PL_STRING_QR:
- if (Quote.Rep <= 0) {
- if (!setModifiers.Contains(sc.ch))
- sc.SetState(SCE_PL_DEFAULT);
- } else if (!Quote.Up && !IsASpace(sc.ch)) {
- Quote.Open(sc.ch);
- } else if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0)
- Quote.Rep--;
- } else if (sc.ch == Quote.Up) {
- Quote.Count++;
- }
- break;
- case SCE_PL_REGSUBST:
- if (Quote.Rep <= 0) {
- if (!setModifiers.Contains(sc.ch))
- sc.SetState(SCE_PL_DEFAULT);
- } else if (!Quote.Up && !IsASpace(sc.ch)) {
- Quote.Open(sc.ch);
- } else if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (Quote.Count == 0 && Quote.Rep == 1) {
- // We matched something like s(...) or tr{...}, Perl 5.10
- // appears to allow almost any character for use as the
- // next delimiters. Whitespace and comments are accepted in
- // between, but we'll limit to whitespace here.
- // For '#', if no whitespace in between, it's a delimiter.
- if (IsASpace(sc.ch)) {
- // Keep going
- } else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) {
- sc.SetState(SCE_PL_DEFAULT);
- } else {
- Quote.Open(sc.ch);
- }
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0)
- Quote.Rep--;
- if (Quote.Up == Quote.Down)
- Quote.Count++;
- } else if (sc.ch == Quote.Up) {
- Quote.Count++;
- }
- break;
- case SCE_PL_STRING_Q:
- case SCE_PL_STRING_QQ:
- case SCE_PL_STRING_QX:
- case SCE_PL_STRING_QW:
- case SCE_PL_STRING:
- case SCE_PL_CHARACTER:
- case SCE_PL_BACKTICKS:
- if (!Quote.Down && !IsASpace(sc.ch)) {
- Quote.Open(sc.ch);
- } else if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0)
- sc.ForwardSetState(SCE_PL_DEFAULT);
- } else if (sc.ch == Quote.Up) {
- Quote.Count++;
- }
- break;
- case SCE_PL_SUB_PROTOTYPE: {
- int i = 0;
- // forward scan; must all be valid proto characters
- while (setSubPrototype.Contains(sc.GetRelative(i)))
- i++;
- if (sc.GetRelative(i) == ')') { // valid sub prototype
- sc.Forward(i);
- sc.ForwardSetState(SCE_PL_DEFAULT);
- } else {
- // abandon prototype, restart from '('
- sc.ChangeState(SCE_PL_OPERATOR);
- sc.SetState(SCE_PL_DEFAULT);
- }
- } break;
- case SCE_PL_FORMAT: {
- sc.Complete();
- while (!sc.atLineEnd)
- sc.Forward();
- char s[10];
- sc.GetCurrent(s, sizeof(s));
- if (isMatch(".", s))
- sc.SetState(SCE_PL_DEFAULT);
- } break;
- case SCE_PL_ERROR:
- break;
- }
- // Needed for specific continuation styles (one follows the other)
- switch (sc.state) {
- // continued from SCE_PL_WORD
- case SCE_PL_FORMAT_IDENT:
- // occupies HereDoc state 3 to avoid clashing with HERE docs
- if (IsASpaceOrTab(sc.ch)) { // skip whitespace
- sc.ChangeState(SCE_PL_DEFAULT);
- while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
- sc.Forward();
- sc.SetState(SCE_PL_FORMAT_IDENT);
- }
- if (setFormatStart.Contains(sc.ch)) { // identifier or '='
- if (sc.ch != '=') {
- do {
- sc.Forward();
- } while (setFormat.Contains(sc.ch));
- }
- while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
- sc.Forward();
- if (sc.ch == '=') {
- sc.ForwardSetState(SCE_PL_DEFAULT);
- HereDoc.State = 3;
- } else {
- // invalid indentifier; inexact fallback, but hey
- sc.ChangeState(SCE_PL_IDENTIFIER);
- sc.SetState(SCE_PL_DEFAULT);
- }
- } else {
- sc.ChangeState(SCE_PL_DEFAULT); // invalid indentifier
- }
- backFlag = BACK_NONE;
- break;
- }
-
- // Must check end of HereDoc states here before default state is handled
- if (HereDoc.State == 1 && sc.atLineEnd) {
- // Begin of here-doc (the line after the here-doc delimiter):
- // Lexically, the here-doc starts from the next line after the >>, but the
- // first line of here-doc seem to follow the style of the last EOL sequence
- int st_new = SCE_PL_HERE_QQ;
- HereDoc.State = 2;
- if (HereDoc.Quoted) {
- if (sc.state == SCE_PL_HERE_DELIM) {
- // Missing quote at end of string! We are stricter than perl.
- // Colour here-doc anyway while marking this bit as an error.
- sc.ChangeState(SCE_PL_ERROR);
- }
- switch (HereDoc.Quote) {
- case '\'': st_new = SCE_PL_HERE_Q ; break;
- case '"' : st_new = SCE_PL_HERE_QQ; break;
- case '`' : st_new = SCE_PL_HERE_QX; break;
- }
- } else {
- if (HereDoc.Quote == '\\')
- st_new = SCE_PL_HERE_Q;
- }
- sc.SetState(st_new);
- }
- if (HereDoc.State == 3 && sc.atLineEnd) {
- // Start of format body.
- HereDoc.State = 0;
- sc.SetState(SCE_PL_FORMAT);
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_PL_DEFAULT) {
- if (IsADigit(sc.ch) ||
- (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
- sc.SetState(SCE_PL_NUMBER);
- backFlag = BACK_NONE;
- numState = PERLNUM_DECIMAL;
- dotCount = 0;
- if (sc.ch == '0') { // hex,bin,octal
- if (sc.chNext == 'x') {
- numState = PERLNUM_HEX;
- } else if (sc.chNext == 'b') {
- numState = PERLNUM_BINARY;
- } else if (IsADigit(sc.chNext)) {
- numState = PERLNUM_OCTAL;
- }
- if (numState != PERLNUM_DECIMAL) {
- sc.Forward();
- }
- } else if (sc.ch == 'v') { // vector
- numState = PERLNUM_V_VECTOR;
- }
- } else if (setWord.Contains(sc.ch)) {
- // if immediately prefixed by '::', always a bareword
- sc.SetState(SCE_PL_WORD);
- if (sc.chPrev == ':' && sc.GetRelative(-2) == ':') {
- sc.ChangeState(SCE_PL_IDENTIFIER);
- }
- unsigned int bk = sc.currentPos;
- unsigned int fw = sc.currentPos + 1;
- // first check for possible quote-like delimiter
- if (sc.ch == 's' && !setWord.Contains(sc.chNext)) {
- sc.ChangeState(SCE_PL_REGSUBST);
- Quote.New(2);
- } else if (sc.ch == 'm' && !setWord.Contains(sc.chNext)) {
- sc.ChangeState(SCE_PL_REGEX);
- Quote.New();
- } else if (sc.ch == 'q' && !setWord.Contains(sc.chNext)) {
- sc.ChangeState(SCE_PL_STRING_Q);
- Quote.New();
- } else if (sc.ch == 'y' && !setWord.Contains(sc.chNext)) {
- sc.ChangeState(SCE_PL_REGSUBST);
- Quote.New(2);
- } else if (sc.Match('t', 'r') && !setWord.Contains(sc.GetRelative(2))) {
- sc.ChangeState(SCE_PL_REGSUBST);
- Quote.New(2);
- sc.Forward();
- fw++;
- } else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext)
- && !setWord.Contains(sc.GetRelative(2))) {
- if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
- else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);
- else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);
- else sc.ChangeState(SCE_PL_STRING_QW); // sc.chNext == 'w'
- Quote.New();
- sc.Forward();
- fw++;
- } else if (sc.ch == 'x' && (sc.chNext == '=' || // repetition
- !setWord.Contains(sc.chNext) ||
- (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
- sc.ChangeState(SCE_PL_OPERATOR);
- }
- // if potentially a keyword, scan forward and grab word, then check
- // if it's really one; if yes, disambiguation test is performed
- // otherwise it is always a bareword and we skip a lot of scanning
- if (sc.state == SCE_PL_WORD) {
- while (setWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(fw))))
- fw++;
- if (!isPerlKeyword(styler.GetStartSegment(), fw, keywords, styler)) {
- sc.ChangeState(SCE_PL_IDENTIFIER);
- }
- }
- // if already SCE_PL_IDENTIFIER, then no ambiguity, skip this
- // for quote-like delimiters/keywords, attempt to disambiguate
- // to select for bareword, change state -> SCE_PL_IDENTIFIER
- if (sc.state != SCE_PL_IDENTIFIER && bk > 0) {
- if (disambiguateBareword(styler, bk, fw, backFlag, backPos, endPos))
- sc.ChangeState(SCE_PL_IDENTIFIER);
- }
- backFlag = BACK_NONE;
- } else if (sc.ch == '#') {
- sc.SetState(SCE_PL_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_PL_STRING);
- Quote.New();
- Quote.Open(sc.ch);
- backFlag = BACK_NONE;
- } else if (sc.ch == '\'') {
- if (sc.chPrev == '&' && setWordStart.Contains(sc.chNext)) {
- // Archaic call
- sc.SetState(SCE_PL_IDENTIFIER);
- } else {
- sc.SetState(SCE_PL_CHARACTER);
- Quote.New();
- Quote.Open(sc.ch);
- }
- backFlag = BACK_NONE;
- } else if (sc.ch == '`') {
- sc.SetState(SCE_PL_BACKTICKS);
- Quote.New();
- Quote.Open(sc.ch);
- backFlag = BACK_NONE;
- } else if (sc.ch == '$') {
- sc.SetState(SCE_PL_SCALAR);
- if (sc.chNext == '{') {
- sc.ForwardSetState(SCE_PL_OPERATOR);
- } else if (IsASpace(sc.chNext)) {
- sc.ForwardSetState(SCE_PL_DEFAULT);
- } else {
- sc.Forward();
- if (sc.Match('`', '`') || sc.Match(':', ':')) {
- sc.Forward();
- }
- }
- backFlag = BACK_NONE;
- } else if (sc.ch == '@') {
- sc.SetState(SCE_PL_ARRAY);
- if (setArray.Contains(sc.chNext)) {
- // no special treatment
- } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
- sc.Forward(2);
- } else if (sc.chNext == '{' || sc.chNext == '[') {
- sc.ForwardSetState(SCE_PL_OPERATOR);
- } else {
- sc.ChangeState(SCE_PL_OPERATOR);
- }
- backFlag = BACK_NONE;
- } else if (setPreferRE.Contains(sc.ch)) {
- // Explicit backward peeking to set a consistent preferRE for
- // any slash found, so no longer need to track preferRE state.
- // Find first previous significant lexed element and interpret.
- // A few symbols shares this code for disambiguation.
- bool preferRE = false;
- bool isHereDoc = sc.Match('<', '<');
- bool hereDocSpace = false; // for: SCALAR [whitespace] '<<'
- unsigned int bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0;
- unsigned int bkend;
- sc.Complete();
- styler.Flush();
- if (styler.StyleAt(bk) == SCE_PL_DEFAULT)
- hereDocSpace = true;
- skipWhitespaceComment(styler, bk);
- if (bk == 0) {
- // avoid backward scanning breakage
- preferRE = true;
- } else {
- int bkstyle = styler.StyleAt(bk);
- int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
- switch(bkstyle) {
- case SCE_PL_OPERATOR:
- preferRE = true;
- if (bkch == ')' || bkch == ']') {
- preferRE = false;
- } else if (bkch == '}') {
- // backtrack by counting balanced brace pairs
- // needed to test for variables like ${}, @{} etc.
- bkstyle = styleBeforeBracePair(styler, bk);
- if (bkstyle == SCE_PL_SCALAR
- || bkstyle == SCE_PL_ARRAY
- || bkstyle == SCE_PL_HASH
- || bkstyle == SCE_PL_SYMBOLTABLE
- || bkstyle == SCE_PL_OPERATOR) {
- preferRE = false;
- }
- } else if (bkch == '+' || bkch == '-') {
- if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1))
- && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
- // exceptions for operators: unary suffixes ++, --
- preferRE = false;
- }
- break;
- case SCE_PL_IDENTIFIER:
- preferRE = true;
- bkstyle = styleCheckIdentifier(styler, bk);
- if ((bkstyle == 1) || (bkstyle == 2)) {
- // inputsymbol or var with "->" or "::" before identifier
- preferRE = false;
- } else if (bkstyle == 3) {
- // bare identifier, test cases follows:
- if (sc.ch == '/') {
- // if '/', /PATTERN/ unless digit/space immediately after '/'
- // if '//', always expect defined-or operator to follow identifier
- if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')
- preferRE = false;
- } else if (sc.ch == '*' || sc.ch == '%') {
- if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))
- preferRE = false;
- } else if (sc.ch == '<') {
- if (IsASpace(sc.chNext) || sc.chNext == '=')
- preferRE = false;
- }
- }
- break;
- case SCE_PL_SCALAR: // for $var<< case:
- if (isHereDoc && hereDocSpace) // if SCALAR whitespace '<<', *always* a HERE doc
- preferRE = true;
- break;
- case SCE_PL_WORD:
- preferRE = true;
- // for HERE docs, always true
- if (sc.ch == '/') {
- // adopt heuristics similar to vim-style rules:
- // keywords always forced as /PATTERN/: split, if, elsif, while
- // everything else /PATTERN/ unless digit/space immediately after '/'
- // for '//', defined-or favoured unless special keywords
- bkend = bk + 1;
- while (bk > 0 && styler.StyleAt(bk - 1) == SCE_PL_WORD) {
- bk--;
- }
- if (isPerlKeyword(bk, bkend, reWords, styler))
- break;
- if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')
- preferRE = false;
- } else if (sc.ch == '*' || sc.ch == '%') {
- if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))
- preferRE = false;
- } else if (sc.ch == '<') {
- if (IsASpace(sc.chNext) || sc.chNext == '=')
- preferRE = false;
- }
- break;
- // other styles uses the default, preferRE=false
- case SCE_PL_POD:
- case SCE_PL_HERE_Q:
- case SCE_PL_HERE_QQ:
- case SCE_PL_HERE_QX:
- preferRE = true;
- break;
- }
- }
- backFlag = BACK_NONE;
- if (isHereDoc) { // handle '<<', HERE doc
- if (preferRE) {
- sc.SetState(SCE_PL_HERE_DELIM);
- HereDoc.State = 0;
- } else { // << operator
- sc.SetState(SCE_PL_OPERATOR);
- sc.Forward();
- }
- } else if (sc.ch == '*') { // handle '*', typeglob
- if (preferRE) {
- sc.SetState(SCE_PL_SYMBOLTABLE);
- if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
- sc.Forward(2);
- } else if (sc.chNext == '{') {
- sc.ForwardSetState(SCE_PL_OPERATOR);
- } else {
- sc.Forward();
- }
- } else {
- sc.SetState(SCE_PL_OPERATOR);
- if (sc.chNext == '*') // exponentiation
- sc.Forward();
- }
- } else if (sc.ch == '%') { // handle '%', hash
- if (preferRE) {
- sc.SetState(SCE_PL_HASH);
- if (setHash.Contains(sc.chNext)) {
- sc.Forward();
- } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
- sc.Forward(2);
- } else if (sc.chNext == '{') {
- sc.ForwardSetState(SCE_PL_OPERATOR);
- } else {
- sc.ChangeState(SCE_PL_OPERATOR);
- }
- } else {
- sc.SetState(SCE_PL_OPERATOR);
- }
- } else if (sc.ch == '<') { // handle '<', inputsymbol
- if (preferRE) {
- // forward scan
- int i = inputsymbolScan(styler, sc.currentPos, endPos);
- if (i > 0) {
- sc.SetState(SCE_PL_IDENTIFIER);
- sc.Forward(i);
- } else {
- sc.SetState(SCE_PL_OPERATOR);
- }
- } else {
- sc.SetState(SCE_PL_OPERATOR);
- }
- } else { // handle '/', regexp
- if (preferRE) {
- sc.SetState(SCE_PL_REGEX);
- Quote.New();
- Quote.Open(sc.ch);
- } else { // / and // operators
- sc.SetState(SCE_PL_OPERATOR);
- if (sc.chNext == '/') {
- sc.Forward();
- }
- }
- }
- } else if (sc.ch == '=' // POD
- && setPOD.Contains(sc.chNext)
- && sc.atLineStart) {
- sc.SetState(SCE_PL_POD);
- backFlag = BACK_NONE;
- } else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) { // extended '-' cases
- unsigned int bk = sc.currentPos;
- unsigned int fw = 2;
- if (setSingleCharOp.Contains(sc.chNext) && // file test operators
- !setWord.Contains(sc.GetRelative(2))) {
- sc.SetState(SCE_PL_WORD);
- } else {
- // nominally a minus and bareword; find extent of bareword
- while (setWord.Contains(sc.GetRelative(fw)))
- fw++;
- sc.SetState(SCE_PL_OPERATOR);
- }
- // force to bareword for hash key => or {variable literal} cases
- if (disambiguateBareword(styler, bk, bk + fw, backFlag, backPos, endPos) & 2) {
- sc.ChangeState(SCE_PL_IDENTIFIER);
- }
- backFlag = BACK_NONE;
- } else if (sc.ch == '(' && sc.currentPos > 0) { // '(' or subroutine prototype
- sc.Complete();
- if (styleCheckSubPrototype(styler, sc.currentPos - 1)) {
- sc.SetState(SCE_PL_SUB_PROTOTYPE);
- backFlag = BACK_NONE;
- } else {
- sc.SetState(SCE_PL_OPERATOR);
- }
- } else if (setPerlOperator.Contains(sc.ch)) { // operators
- sc.SetState(SCE_PL_OPERATOR);
- if (sc.Match('.', '.')) { // .. and ...
- sc.Forward();
- if (sc.chNext == '.') sc.Forward();
- }
- } else if (sc.ch == 4 || sc.ch == 26) { // ^D and ^Z ends valid perl source
- sc.SetState(SCE_PL_DATASECTION);
- } else {
- // keep colouring defaults
- sc.Complete();
- }
- }
- }
- sc.Complete();
-}
-
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eol_pos; i++) {
- char ch = styler[i];
- int style = styler.StyleAt(i);
- if (ch == '#' && style == SCE_PL_COMMENTLINE)
- return true;
- else if (!IsASpaceOrTab(ch))
- return false;
- }
- return false;
-}
-
-static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- // Custom folding of POD and packages
-
- // property fold.perl.pod
- // Enable folding Pod blocks when using the Perl lexer.
- bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
-
- // property fold.perl.package
- // Enable folding packages when using the Perl lexer.
- bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- char chPrev = styler.SafeGetCharAt(startPos - 1);
- int styleNext = styler.StyleAt(startPos);
- // Used at end of line to determine if the line was a package definition
- bool isPackageLine = false;
- bool isPodHeading = false;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;
- // Comment folding
- if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
- {
- if (!IsCommentLine(lineCurrent - 1, styler)
- && IsCommentLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsCommentLine(lineCurrent - 1, styler)
- && !IsCommentLine(lineCurrent+1, styler))
- levelCurrent--;
- }
- if (style == SCE_PL_OPERATOR) {
- if (ch == '{') {
- levelCurrent++;
- } else if (ch == '}') {
- levelCurrent--;
- }
- }
- // Custom POD folding
- if (foldPOD && atLineStart) {
- int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
- if (style == SCE_PL_POD) {
- if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
- levelCurrent++;
- else if (styler.Match(i, "=cut"))
- levelCurrent--;
- else if (styler.Match(i, "=head"))
- isPodHeading = true;
- } else if (style == SCE_PL_DATASECTION) {
- if (ch == '=' && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
- levelCurrent++;
- else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
- levelCurrent--;
- else if (styler.Match(i, "=head"))
- isPodHeading = true;
- // if package used or unclosed brace, level > SC_FOLDLEVELBASE!
- // reset needed as level test is vs. SC_FOLDLEVELBASE
- else if (styler.Match(i, "__END__"))
- levelCurrent = SC_FOLDLEVELBASE;
- }
- }
- // Custom package folding
- if (foldPackage && atLineStart) {
- if (style == SCE_PL_WORD && styler.Match(i, "package")) {
- isPackageLine = true;
- }
- }
-
- if (atEOL) {
- int lev = levelPrev;
- if (isPodHeading) {
- lev = levelPrev - 1;
- lev |= SC_FOLDLEVELHEADERFLAG;
- isPodHeading = false;
- }
- // Check if line was a package declaration
- // because packages need "special" treatment
- if (isPackageLine) {
- lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
- levelCurrent = SC_FOLDLEVELBASE + 1;
- isPackageLine = false;
- }
- lev |= levelCurrent << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- chPrev = ch;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const perlWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc, 8);
+++ /dev/null
-// Scintilla source code edit control
-// @file LexPowerPro.cxx
-// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com
-// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net)
-//
-// Lexer code heavily borrowed from:
-// LexAU3.cxx by Jos van der Zande
-// LexCPP.cxx by Neil Hodgson
-// LexVB.cxx by Neil Hodgson
-//
-// Changes:
-// 2008-10-25 - Initial release
-// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that
-// local isFunction = "" and local functions = "" don't get falsely highlighted
-// 2008-12-14 - Added bounds checking for szKeyword and szDo
-// - Replaced SetOfCharacters with CharacterSet
-// - Made sure that CharacterSet::Contains is passed only positive values
-// - Made sure that the return value of Accessor::SafeGetCharAt is positive before
-// passsing to functions that require positive values like isspacechar()
-// - Removed unused visibleChars processing from ColourisePowerProDoc()
-// - Fixed bug with folding logic where line continuations didn't end where
-// they were supposed to
-// - Moved all helper functions to the top of the file
-//
-// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "CharacterSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static inline bool IsStreamCommentStyle(int style) {
- return style == SCE_POWERPRO_COMMENTBLOCK;
-}
-
-static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
-{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine + 1) - 2;
- while (nsPos < nePos)
- {
- int stylech = styler.StyleAt(nsPos);
- if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
- char ch = styler.SafeGetCharAt(nePos);
- char chPrev = styler.SafeGetCharAt(nePos-1);
- char chPrevPrev = styler.SafeGetCharAt(nePos-2);
- if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) {
- if (chPrevPrev == ';' && chPrev == ';' && ch == '+')
- return true;
- else
- return false;
- }
- }
- nePos--; // skip to next char
- }
- return false;
-}
-
-// Routine to find first none space on the current line and return its Style
-// needed for comment lines not starting on pos 1
-static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
-{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine+1) - 1;
- char ch = styler.SafeGetCharAt(nsPos);
-
- while (ch > 0 && isspacechar(ch) && nsPos < nePos)
- {
- nsPos++; // skip to next char
- ch = styler.SafeGetCharAt(nsPos);
-
- }
- return styler.StyleAt(nsPos);
-}
-
-//returns true if there is a function to highlight
-//used to highlight <name> in 'function <name>'
-static bool HasFunction(Accessor &styler, unsigned int currentPos) {
-
- //check for presence of 'function '
- return (styler.SafeGetCharAt(currentPos) == ' '
- && tolower(styler.SafeGetCharAt(currentPos-1)) == 'n'
- && tolower(styler.SafeGetCharAt(currentPos-2)) == 'o'
- && tolower(styler.SafeGetCharAt(currentPos-3)) == 'i'
- && tolower(styler.SafeGetCharAt(currentPos-4)) == 't'
- && tolower(styler.SafeGetCharAt(currentPos-5)) == 'c'
- && tolower(styler.SafeGetCharAt(currentPos-6)) == 'n'
- && tolower(styler.SafeGetCharAt(currentPos-7)) == 'u'
- && tolower(styler.SafeGetCharAt(currentPos-8)) == 'f'
- //only allow 'function ' to appear at the beginning of a line
- && (styler.SafeGetCharAt(currentPos-9) == '\n'
- || styler.SafeGetCharAt(currentPos-9) == '\r'
- || (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line
- );
-}
-
-static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler, bool caseSensitive) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- //define the character sets
- CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
-
- StyleContext sc(startPos, length, initStyle, styler);
- char s_save[100]; //for last line highlighting
-
- for (; sc.More(); sc.Forward()) {
-
- // **********************************************
- // save the total current word for eof processing
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
-
- if ((sc.ch > 0) && setWord.Contains(sc.ch))
- {
- strcpy(s_save,s);
- int tp = strlen(s_save);
- if (tp < 99) {
- s_save[tp] = static_cast<char>(tolower(sc.ch));
- s_save[tp+1] = '\0';
- }
- }
- // **********************************************
- //
-
- if (sc.atLineStart) {
- if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
- // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which
- // ends with a line continuation by locking in the state upto this position.
- sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
- }
- }
-
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_POWERPRO_OPERATOR:
- sc.SetState(SCE_POWERPRO_DEFAULT);
- break;
-
- case SCE_POWERPRO_NUMBER:
-
- if (!IsADigit(sc.ch))
- sc.SetState(SCE_POWERPRO_DEFAULT);
-
- break;
-
- case SCE_POWERPRO_IDENTIFIER:
- //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized
- if ((sc.ch > 0) && !setWord.Contains(sc.ch)){ // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately
- char s[1000];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_POWERPRO_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_POWERPRO_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_POWERPRO_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_POWERPRO_WORD4);
- }
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_LINECONTINUE:
- if (sc.atLineStart) {
- sc.SetState(SCE_POWERPRO_DEFAULT);
- } else if (sc.Match('/', '*') || sc.Match('/', '/')) {
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_COMMENTBLOCK:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_COMMENTLINE:
- if (sc.atLineStart) {
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_DOUBLEQUOTEDSTRING:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_POWERPRO_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_SINGLEQUOTEDSTRING:
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_POWERPRO_STRINGEOL);
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_STRINGEOL:
- if (sc.atLineStart) {
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- break;
-
- case SCE_POWERPRO_VERBATIM:
- if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
- }
- }
- break;
-
- case SCE_POWERPRO_ALTQUOTE:
- if (sc.ch == '#') {
- if (sc.chNext == '#') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
- }
- }
- break;
-
- case SCE_POWERPRO_FUNCTION:
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- break;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_POWERPRO_DEFAULT) {
- if (sc.Match('?', '\"')) {
- sc.SetState(SCE_POWERPRO_VERBATIM);
- sc.Forward();
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_POWERPRO_NUMBER);
- }else if (sc.Match('?','#')) {
- if (sc.ch == '?' && sc.chNext == '#') {
- sc.SetState(SCE_POWERPRO_ALTQUOTE);
- sc.Forward();
- }
- } else if (HasFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
- sc.SetState(SCE_POWERPRO_FUNCTION);
- } else if (sc.ch == '@' && sc.atLineStart) { //alternate function definition [label]
- sc.SetState(SCE_POWERPRO_FUNCTION);
- } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
- sc.SetState(SCE_POWERPRO_IDENTIFIER);
- } else if (sc.Match(";;+")) {
- sc.SetState(SCE_POWERPRO_LINECONTINUE);
- } else if (sc.Match('/', '*')) {
- sc.SetState(SCE_POWERPRO_COMMENTBLOCK);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- sc.SetState(SCE_POWERPRO_COMMENTLINE);
- } else if (sc.atLineStart && sc.ch == ';') { //legacy comment that can only appear at the beginning of a line
- sc.SetState(SCE_POWERPRO_COMMENTLINE);
- } else if (sc.Match(";;")) {
- sc.SetState(SCE_POWERPRO_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_POWERPRO_OPERATOR);
- }
- }
- }
-
- //*************************************
- // Colourize the last word correctly
- //*************************************
- if (sc.state == SCE_POWERPRO_IDENTIFIER)
- {
- if (keywords.InList(s_save)) {
- sc.ChangeState(SCE_POWERPRO_WORD);
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- else if (keywords2.InList(s_save)) {
- sc.ChangeState(SCE_POWERPRO_WORD2);
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- else if (keywords3.InList(s_save)) {
- sc.ChangeState(SCE_POWERPRO_WORD3);
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- else if (keywords4.InList(s_save)) {
- sc.ChangeState(SCE_POWERPRO_WORD4);
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- else {
- sc.SetState(SCE_POWERPRO_DEFAULT);
- }
- }
- sc.Complete();
-}
-
-static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
-{
- //define the character sets
- CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
-
- bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
- int endPos = startPos + length;
- int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
-
- // get settings from the config files for folding comments and preprocessor lines
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
- bool foldCompact = true;
-
- // Backtrack to previous line in case need to fix its fold status
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- isFoldingAll = false;
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- // vars for style of previous/current/next lines
- int style = GetStyleFirstWord(lineCurrent,styler);
- int stylePrev = 0;
-
- // find the first previous line without continuation character at the end
- while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
- (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- if (lineCurrent > 0) {
- stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
- }
- // vars for getting first word to check for keywords
- bool FirstWordStart = false;
- bool FirstWordEnd = false;
-
- const unsigned int KEYWORD_MAX = 10;
- char szKeyword[KEYWORD_MAX]="";
- unsigned int szKeywordlen = 0;
-
- char szDo[3]="";
- int szDolen = 0;
- bool DoFoundLast = false;
-
- // var for indentlevel
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0) {
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- }
- int levelNext = levelCurrent;
-
- int visibleChars = 0;
- int functionCount = 0;
-
- char chNext = styler.SafeGetCharAt(startPos);
- char chPrev = '\0';
- char chPrevPrev = '\0';
- char chPrevPrevPrev = '\0';
-
- for (int i = startPos; i < endPos; i++) {
-
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch > 0) && setWord.Contains(ch)) {
- visibleChars++;
- }
-
- // get the syle for the current character neede to check in comment
- int stylech = styler.StyleAt(i);
-
- // get first word for the line for indent check max 9 characters
- if (FirstWordStart && (!(FirstWordEnd))) {
- if ((ch > 0) && !setWord.Contains(ch)) {
- FirstWordEnd = true;
- }
- else if (szKeywordlen < KEYWORD_MAX - 1) {
- szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
- szKeyword[szKeywordlen] = '\0';
- }
- }
-
- // start the capture of the first word
- if (!(FirstWordStart)) {
- if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) {
- FirstWordStart = true;
- if (szKeywordlen < KEYWORD_MAX - 1) {
- szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
- szKeyword[szKeywordlen] = '\0';
- }
- }
- }
- // only process this logic when not in comment section
- if (stylech != SCE_POWERPRO_COMMENTLINE) {
- if (DoFoundLast) {
- if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) {
- DoFoundLast = false;
- }
- }
- // find out if the word "do" is the last on a "if" line
- if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
- if (szDolen == 2) {
- szDo[0] = szDo[1];
- szDo[1] = static_cast<char>(tolower(ch));
- szDo[2] = '\0';
- if (strcmp(szDo,"do") == 0 ) {
- DoFoundLast = true;
- }
- }
- else if (szDolen < 2) {
- szDo[szDolen++] = static_cast<char>(tolower(ch));
- szDo[szDolen] = '\0';
- }
- }
- }
-
- // End of Line found so process the information
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
-
- // **************************
- // Folding logic for Keywords
- // **************************
-
- // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
- // and we are not inside a commentblock.
- if (szKeywordlen > 0 &&
- (!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) &&
- ((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
-
- // only fold "if" last keyword is "then" (else its a one line if)
- if (strcmp(szKeyword,"if") == 0 && DoFoundLast) {
- levelNext++;
- }
- // create new fold for these words
- if (strcmp(szKeyword,"for") == 0) {
- levelNext++;
- }
-
- //handle folding for functions/labels
- //Note: Functions and labels don't have an explicit end like [end function]
- // 1. functions/labels end at the start of another function
- // 2. functions/labels end at the end of the file
- if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) {
- if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
-
- if (functionCount > 0) {
- levelCurrent--;
- } else {
- levelNext++;
- }
- functionCount++;
-
- } else { //if just folding a small piece (by clicking on the minus sign next to the word)
- levelCurrent--;
- }
- }
-
- // end the fold for these words before the current line
- if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) {
- levelNext--;
- levelCurrent--;
- }
- // end the fold for these words before the current line and Start new fold
- if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) {
- levelCurrent--;
- }
- }
- // Preprocessor and Comment folding
- int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
-
- // *********************************
- // Folding logic for Comment blocks
- // *********************************
- if (foldComment && IsStreamCommentStyle(style)) {
- // Start of a comment block
- if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
- levelNext++;
- }
- // fold till the last line for normal comment lines
- else if (IsStreamCommentStyle(stylePrev)
- && !(styleNext == SCE_POWERPRO_COMMENTLINE)
- && stylePrev == SCE_POWERPRO_COMMENTLINE
- && style == SCE_POWERPRO_COMMENTLINE) {
- levelNext--;
- }
- // fold till the one but last line for Blockcomment lines
- else if (IsStreamCommentStyle(stylePrev)
- && !(styleNext == SCE_POWERPRO_COMMENTBLOCK)
- && style == SCE_POWERPRO_COMMENTBLOCK) {
- levelNext--;
- levelCurrent--;
- }
- }
-
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
-
- // reset values for the next line
- lineCurrent++;
- stylePrev = style;
- style = styleNext;
- levelCurrent = levelNext;
- visibleChars = 0;
-
- // if the last characters are ;;+ then don't reset since the line continues on the next line.
- if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') {
- //do nothing
- } else {
- szKeywordlen = 0;
- szDolen = 0;
- FirstWordStart = false;
- FirstWordEnd = false;
- DoFoundLast = false;
- //blank out keyword
- for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
- szKeyword[i] = '\0';
- }
- }
- }
-
- // save the last processed characters
- if ((ch > 0) && !isspacechar(ch)) {
- chPrevPrevPrev = chPrevPrev;
- chPrevPrev = chPrev;
- chPrev = ch;
- visibleChars++;
- }
- }
-
- //close folds on the last line - without this a 'phantom'
- //fold can appear when an open fold is on the last line
- //this can occur because functions and labels don't have an explicit end
- if (lineCurrent >= lastLine) {
- int lev = 0;
- lev |= SC_FOLDLEVELWHITEFLAG;
- styler.SetLevel(lineCurrent, lev);
- }
-
-}
-
-static const char * const powerProWordLists[] = {
- "Keyword list 1",
- "Keyword list 2",
- "Keyword list 3",
- "Keyword list 4",
- 0,
- };
-
-static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false);
-}
-
-LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexPowerShell.cxx
- ** Lexer for PowerShell scripts.
- **/
-// Copyright 2008 by Tim Gerundt <tim@gerundt.de>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
- return ch >= 0x80 || isalnum(ch) || ch == '-';
-}
-
-static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
-
- styler.StartAt(startPos);
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_POWERSHELL_COMMENT) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_POWERSHELL_DEFAULT);
- }
- } else if (sc.state == SCE_POWERSHELL_STRING) {
- // This is a doubles quotes string
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
- }
- } else if (sc.state == SCE_POWERSHELL_CHARACTER) {
- // This is a single quote string
- if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
- }
- } else if (sc.state == SCE_POWERSHELL_NUMBER) {
- if (!IsADigit(sc.ch)) {
- sc.SetState(SCE_POWERSHELL_DEFAULT);
- }
- } else if (sc.state == SCE_POWERSHELL_VARIABLE) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_POWERSHELL_DEFAULT);
- }
- } else if (sc.state == SCE_POWERSHELL_OPERATOR) {
- if (!isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_POWERSHELL_DEFAULT);
- }
- } else if (sc.state == SCE_POWERSHELL_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
-
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_POWERSHELL_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_POWERSHELL_CMDLET);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_POWERSHELL_ALIAS);
- }
- sc.SetState(SCE_POWERSHELL_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_POWERSHELL_DEFAULT) {
- if (sc.ch == '#') {
- sc.SetState(SCE_POWERSHELL_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_POWERSHELL_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_POWERSHELL_CHARACTER);
- } else if (sc.ch == '$') {
- sc.SetState(SCE_POWERSHELL_VARIABLE);
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_POWERSHELL_NUMBER);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_POWERSHELL_OPERATOR);
- } else if (IsAWordChar(sc.ch)) {
- sc.SetState(SCE_POWERSHELL_IDENTIFIER);
- }
- }
- }
- sc.Complete();
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldPowerShellDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_POWERSHELL_OPERATOR) {
- if (ch == '{') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- if (!IsASpace(ch))
- visibleChars++;
- if (atEOL || (i == endPos-1)) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- }
-}
-
-static const char * const powershellWordLists[] = {
- "Commands",
- "Cmdlets",
- "Aliases",
- 0
-};
-
-LexerModule lmPowerShell(SCLEX_POWERSHELL, ColourisePowerShellDoc, "powershell", FoldPowerShellDoc, powershellWordLists);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexProgress.cxx
- ** Lexer for Progress 4GL.
- ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>
- **/
-// Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-/** TODO:
-WebSpeed support in html lexer
-Support "end triggers" expression of the triggers phrase
-Support more than 6 comments levels
-**/
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return (ch < 0x80) && (isalpha(ch) || ch == '_');
-}
-
-enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0
-
-static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords1 = *keywordlists[0]; // regular keywords
- WordList &keywords2 = *keywordlists[1]; // block opening keywords, only when SentenceStart
- WordList &keywords3 = *keywordlists[2]; // block opening keywords
- //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented
-
-
- int visibleChars = 0;
- int mask;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart) {
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- visibleChars = 0;
- }
-
- // Handle line continuation generically.
- if ((sc.state & 0xf) < SCE_4GL_COMMENT1) {
- if (sc.ch == '~') {
- if (sc.chNext > ' ') {
- // skip special char after ~
- sc.Forward();
- continue;
- }
- else {
- // Skip whitespace between ~ and EOL
- while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) {
- sc.Forward();
- }
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- sc.Forward();
- continue;
- }
- }
- }
- }
- // Determine if a new state should be terminated.
- mask = sc.state & 0x10;
- switch (sc.state & 0xf) {
- case SCE_4GL_OPERATOR:
- sc.SetState(SCE_4GL_DEFAULT | mask);
- break;
- case SCE_4GL_NUMBER:
- if (!(IsADigit(sc.ch))) {
- sc.SetState(SCE_4GL_DEFAULT | mask);
- }
- break;
- case SCE_4GL_IDENTIFIER:
- if (!IsAWordChar(sc.ch) && sc.ch != '-') {
- char s[1000];
- sc.GetCurrentLowered(s, sizeof(s));
- if ((((sc.state & 0x10) == 0) && keywords2.InList(s)) || keywords3.InList(s)) {
- sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);
- }
- else if (keywords1.InList(s)) {
- if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') ||
- (s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) {
- sc.ChangeState(SCE_4GL_END | ResetSentenceStart);
- }
- else if ((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') ||
- (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) {
- sc.ChangeState(SCE_4GL_WORD & SetSentenceStart);
- }
- else {
- sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart);
- }
- }
- sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10));
- }
- break;
- case SCE_4GL_PREPROCESSOR:
- if (sc.atLineStart) {
- sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);
- }
- /* code removed to allow comments inside preprocessor
- else if (sc.ch == '*' && sc.chNext == '/') {
- sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState); } */
- break;
- case SCE_4GL_STRING:
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
- }
- break;
- case SCE_4GL_CHARACTER:
- if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
- }
- break;
- default:
- if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) {
- if (sc.ch == '*' && sc.chNext == '/') {
- sc.Forward();
- if ((sc.state & 0xf) == SCE_4GL_COMMENT1) {
- sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
- }
- else
- sc.SetState((sc.state & 0x1f) - 1);
- } else if (sc.ch == '/' && sc.chNext == '*') {
- sc.Forward();
- sc.SetState((sc.state & 0x1f) + 1);
- }
- }
- }
-
- // Determine if a new state should be entered.
- mask = sc.state & 0x10;
- if ((sc.state & 0xf) == SCE_4GL_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart);
- } else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {
- sc.SetState(SCE_4GL_IDENTIFIER | mask);
- } else if (sc.ch == '/' && sc.chNext == '*') {
- sc.SetState(SCE_4GL_COMMENT1 | mask);
- sc.Forward();
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_4GL_STRING | ResetSentenceStart);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart);
- } else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) {
- sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart);
- // Skip whitespace between & and preprocessor word
- do {
- sc.Forward();
- } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- // Handle syntactical line termination
- } else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {
- sc.SetState(sc.state & SetSentenceStart);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- /* This code allows highlight of handles. Alas, it would cause the phrase "last-event:function"
- to be recognized as a BlockBegin */
-
- if (sc.ch == ':')
- sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
- /* else */
- sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);
- }
- }
-
- if (!IsASpace(sc.ch)) {
- visibleChars++;
- }
- }
- sc.Complete();
-}
-
-static bool IsStreamCommentStyle(int style) {
- return (style & 0xf) >= SCE_4GL_COMMENT1 ;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle,
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = static_cast<char>(tolower(styler[startPos]));
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelNext++;
- } else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- }
- else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) {
- levelNext++;
- }
- else if ((style & 0xf) == SCE_4GL_END && (ch == 'e' || ch == 'f')) {
- levelNext--;
- }
- if (atEOL) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
-}
-
-static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- FoldNoBox4glDoc(startPos, length, initStyle, styler);
-}
-
-static const char * const FglWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- "Unused",
- "Global classes and typedefs",
- 0,
- };
-
-LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexPython.cxx
- ** Lexer for Python.
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-/* kwCDef, kwCTypeName only used for Cython */
-enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
-
-static const int indicatorWhitespace = 1;
-
-static bool IsPyComment(Accessor &styler, int pos, int len) {
- return len > 0 && styler[pos] == '#';
-}
-
-enum literalsAllowed { litNone=0, litU=1, litB=2};
-
-static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
- return
- ((allowed & litB) && (ch == 'b' || ch == 'B')) ||
- ((allowed & litU) && (ch == 'u' || ch == 'U'));
-}
-
-static bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
- if (ch == '\'' || ch == '"')
- return true;
- if (IsPyStringTypeChar(ch, allowed)) {
- if (chNext == '"' || chNext == '\'')
- return true;
- if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
- return true;
- }
- if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\''))
- return true;
-
- return false;
-}
-
-/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
-static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex, literalsAllowed allowed) {
- char ch = styler.SafeGetCharAt(i);
- char chNext = styler.SafeGetCharAt(i + 1);
-
- // Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
- if (ch == 'r' || ch == 'R') {
- i++;
- ch = styler.SafeGetCharAt(i);
- chNext = styler.SafeGetCharAt(i + 1);
- } else if (IsPyStringTypeChar(ch, allowed)) {
- if (chNext == 'r' || chNext == 'R')
- i += 2;
- else
- i += 1;
- ch = styler.SafeGetCharAt(i);
- chNext = styler.SafeGetCharAt(i + 1);
- }
-
- if (ch != '"' && ch != '\'') {
- *nextIndex = i + 1;
- return SCE_P_DEFAULT;
- }
-
- if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {
- *nextIndex = i + 3;
-
- if (ch == '"')
- return SCE_P_TRIPLEDOUBLE;
- else
- return SCE_P_TRIPLE;
- } else {
- *nextIndex = i + 1;
-
- if (ch == '"')
- return SCE_P_STRING;
- else
- return SCE_P_CHARACTER;
- }
-}
-
-static inline bool IsAWordChar(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- int endPos = startPos + length;
-
- // Backtrack to previous line in case need to fix its tab whinging
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- // Look for backslash-continued lines
- while (lineCurrent > 0) {
- int eolPos = styler.LineStart(lineCurrent) - 1;
- int eolStyle = styler.StyleAt(eolPos);
- if (eolStyle == SCE_P_STRING
- || eolStyle == SCE_P_CHARACTER
- || eolStyle == SCE_P_STRINGEOL) {
- lineCurrent -= 1;
- } else {
- break;
- }
- }
- startPos = styler.LineStart(lineCurrent);
- }
- initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1);
- }
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
-
- // property tab.timmy.whinge.level
- // For Python code, checks whether indenting is consistent.
- // The default, 0 turns off indentation checking,
- // 1 checks whether each line is potentially inconsistent with the previous line,
- // 2 checks whether any space characters occur before a tab character in the indentation,
- // 3 checks whether any spaces are in the indentation, and
- // 4 checks for any tab characters in the indentation.
- // 1 is a good level to use.
- const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
-
- // property lexer.python.literals.binary
- // Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.
- bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0;
-
- // property lexer.python.strings.u
- // Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.
- literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone;
-
- // property lexer.python.strings.b
- // Set to 0 to not recognise Python 3 bytes literals b"x".
- if (styler.GetPropertyInt("lexer.python.strings.b", 1))
- allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
-
- // property lexer.python.strings.over.newline
- // Set to 1 to allow strings to span newline characters.
- bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
-
- initStyle = initStyle & 31;
- if (initStyle == SCE_P_STRINGEOL) {
- initStyle = SCE_P_DEFAULT;
- }
-
- kwType kwLast = kwOther;
- int spaceFlags = 0;
- styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
- bool base_n_number = false;
-
- StyleContext sc(startPos, endPos - startPos, initStyle, styler);
-
- bool indentGood = true;
- int startIndicator = sc.currentPos;
- bool inContinuedString = false;
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart) {
- styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
- indentGood = true;
- if (whingeLevel == 1) {
- indentGood = (spaceFlags & wsInconsistent) == 0;
- } else if (whingeLevel == 2) {
- indentGood = (spaceFlags & wsSpaceTab) == 0;
- } else if (whingeLevel == 3) {
- indentGood = (spaceFlags & wsSpace) == 0;
- } else if (whingeLevel == 4) {
- indentGood = (spaceFlags & wsTab) == 0;
- }
- if (!indentGood) {
- styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
- startIndicator = sc.currentPos;
- }
- }
-
- if (sc.atLineEnd) {
- if ((sc.state == SCE_P_DEFAULT) ||
- (sc.state == SCE_P_TRIPLE) ||
- (sc.state == SCE_P_TRIPLEDOUBLE)) {
- // Perform colourisation of white space and triple quoted strings at end of each line to allow
- // tab marking to work inside white space and triple quoted strings
- sc.SetState(sc.state);
- }
- lineCurrent++;
- if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
- if (inContinuedString || stringsOverNewline) {
- inContinuedString = false;
- } else {
- sc.ChangeState(SCE_P_STRINGEOL);
- sc.ForwardSetState(SCE_P_DEFAULT);
- }
- }
- if (!sc.More())
- break;
- }
-
- bool needEOLCheck = false;
-
- // Check for a state end
- if (sc.state == SCE_P_OPERATOR) {
- kwLast = kwOther;
- sc.SetState(SCE_P_DEFAULT);
- } else if (sc.state == SCE_P_NUMBER) {
- if (!IsAWordChar(sc.ch) &&
- !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
- sc.SetState(SCE_P_DEFAULT);
- }
- } else if (sc.state == SCE_P_IDENTIFIER) {
- if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- int style = SCE_P_IDENTIFIER;
- if ((kwLast == kwImport) && (strcmp(s, "as") == 0)) {
- style = SCE_P_WORD;
- } else if (keywords.InList(s)) {
- style = SCE_P_WORD;
- } else if (kwLast == kwClass) {
- style = SCE_P_CLASSNAME;
- } else if (kwLast == kwDef) {
- style = SCE_P_DEFNAME;
- } else if (kwLast == kwCDef) {
- int pos = sc.currentPos;
- unsigned char ch = styler.SafeGetCharAt(pos, '\0');
- while (ch != '\0') {
- if (ch == '(') {
- style = SCE_P_DEFNAME;
- break;
- } else if (ch == ':') {
- style = SCE_P_CLASSNAME;
- break;
- } else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
- pos++;
- ch = styler.SafeGetCharAt(pos, '\0');
- } else {
- break;
- }
- }
- } else if (keywords2.InList(s)) {
- style = SCE_P_WORD2;
- }
- sc.ChangeState(style);
- sc.SetState(SCE_P_DEFAULT);
- if (style == SCE_P_WORD) {
- if (0 == strcmp(s, "class"))
- kwLast = kwClass;
- else if (0 == strcmp(s, "def"))
- kwLast = kwDef;
- else if (0 == strcmp(s, "import"))
- kwLast = kwImport;
- else if (0 == strcmp(s, "cdef"))
- kwLast = kwCDef;
- else if (0 == strcmp(s, "cimport"))
- kwLast = kwImport;
- else if (kwLast != kwCDef)
- kwLast = kwOther;
- } else if (kwLast != kwCDef) {
- kwLast = kwOther;
- }
- }
- } else if ((sc.state == SCE_P_COMMENTLINE) || (sc.state == SCE_P_COMMENTBLOCK)) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_P_DEFAULT);
- }
- } else if (sc.state == SCE_P_DECORATOR) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_P_DEFAULT);
- }
- } else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
- if (sc.ch == '\\') {
- if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
- sc.Forward();
- }
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- inContinuedString = true;
- } else {
- // Don't roll over the newline.
- sc.Forward();
- }
- } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
- sc.ForwardSetState(SCE_P_DEFAULT);
- needEOLCheck = true;
- } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
- sc.ForwardSetState(SCE_P_DEFAULT);
- needEOLCheck = true;
- }
- } else if (sc.state == SCE_P_TRIPLE) {
- if (sc.ch == '\\') {
- sc.Forward();
- } else if (sc.Match("\'\'\'")) {
- sc.Forward();
- sc.Forward();
- sc.ForwardSetState(SCE_P_DEFAULT);
- needEOLCheck = true;
- }
- } else if (sc.state == SCE_P_TRIPLEDOUBLE) {
- if (sc.ch == '\\') {
- sc.Forward();
- } else if (sc.Match("\"\"\"")) {
- sc.Forward();
- sc.Forward();
- sc.ForwardSetState(SCE_P_DEFAULT);
- needEOLCheck = true;
- }
- }
-
- if (!indentGood && !IsASpaceOrTab(sc.ch)) {
- styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
- startIndicator = sc.currentPos;
- indentGood = true;
- }
-
- // One cdef line, clear kwLast only at end of line
- if (kwLast == kwCDef && sc.atLineEnd) {
- kwLast = kwOther;
- }
-
- // State exit code may have moved on to end of line
- if (needEOLCheck && sc.atLineEnd) {
- lineCurrent++;
- styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
- if (!sc.More())
- break;
- }
-
- // Check for a new state starting character
- if (sc.state == SCE_P_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
- base_n_number = true;
- sc.SetState(SCE_P_NUMBER);
- } else if (sc.ch == '0' &&
- (sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
- if (base2or8Literals) {
- base_n_number = true;
- sc.SetState(SCE_P_NUMBER);
- } else {
- sc.SetState(SCE_P_NUMBER);
- sc.ForwardSetState(SCE_P_IDENTIFIER);
- }
- } else {
- base_n_number = false;
- sc.SetState(SCE_P_NUMBER);
- }
- } else if ((isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') {
- sc.SetState(SCE_P_OPERATOR);
- } else if (sc.ch == '#') {
- sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
- } else if (sc.ch == '@') {
- sc.SetState(SCE_P_DECORATOR);
- } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) {
- unsigned int nextIndex = 0;
- sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals));
- while (nextIndex > (sc.currentPos + 1) && sc.More()) {
- sc.Forward();
- }
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_P_IDENTIFIER);
- }
- }
- }
- styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
- sc.Complete();
-}
-
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eol_pos; i++) {
- char ch = styler[i];
- if (ch == '#')
- return true;
- else if (ch != ' ' && ch != '\t')
- return false;
- }
- return false;
-}
-
-static bool IsQuoteLine(int line, Accessor &styler) {
- int style = styler.StyleAt(styler.LineStart(line)) & 31;
- return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
-}
-
-
-static void FoldPyDoc(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
-
- // property fold.comment.python
- // This option enables folding multi-line comments when using the Python lexer.
- const bool foldComment = styler.GetPropertyInt("fold.comment.python") != 0;
-
- // property fold.quotes.python
- // This option enables folding multi-line quoted strings when using the Python lexer.
- const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0;
-
- const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
-
- // Backtrack to previous non-blank line so we can determine indent level
- // for any white space lines (needed esp. within triple quoted strings)
- // 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)) &&
- (!IsQuoteLine(lineCurrent, styler)))
- break;
- }
- int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
-
- // Set up initial loop state
- startPos = styler.LineStart(lineCurrent);
- int prev_state = SCE_P_DEFAULT & 31;
- if (lineCurrent >= 1)
- prev_state = styler.StyleAt(startPos - 1) & 31;
- int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));
- int prevComment = 0;
- if (lineCurrent >= 1)
- prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
-
- // Process all characters to end of requested range or end of any triple quote
- // or comment that hangs over the end of the range. Cap processing in all cases
- // to end of document (in case of unclosed quote or comment at end).
- while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote || prevComment)) {
-
- // Gather info
- int lev = indentCurrent;
- int lineNext = lineCurrent + 1;
- int indentNext = indentCurrent;
- int quote = false;
- if (lineNext <= docLines) {
- // Information about next line is only available if not at end of document
- indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
- int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
- quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
- }
- const int quote_start = (quote && !prevQuote);
- const int quote_continue = (quote && prevQuote);
- const int comment = foldComment && IsCommentLine(lineCurrent, styler);
- const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
- IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
- const int comment_continue = (comment && prevComment);
- if ((!quote || !prevQuote) && !comment)
- indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
- if (quote)
- indentNext = indentCurrentLevel;
- if (indentNext & SC_FOLDLEVELWHITEFLAG)
- indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
-
- if (quote_start) {
- // Place fold point at start of triple quoted string
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (quote_continue || prevQuote) {
- // Add level to rest of lines in the string
- lev = lev + 1;
- } else if (comment_start) {
- // Place fold point at start of a block of comments
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (comment_continue) {
- // Add level to rest of lines in the block
- lev = lev + 1;
- }
-
- // Skip past any blank lines for next indent level info; we skip also
- // comments (all comments, not just those starting in column 0)
- // which effectively folds them into surrounding code rather
- // than screwing up folding.
-
- while (!quote &&
- (lineNext < docLines) &&
- ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
- (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
-
- lineNext++;
- indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
- }
-
- const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
- const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
-
- // Now set all the indent levels on the lines we skipped
- // Do this from end to start. Once we encounter one line
- // which is indented more than the line after the end of
- // the comment-block, use the level of the block before
-
- int skipLine = lineNext;
- int skipLevel = levelAfterComments;
-
- while (--skipLine > lineCurrent) {
- int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
-
- if (foldCompact) {
- if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
- skipLevel = levelBeforeComments;
-
- int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
-
- styler.SetLevel(skipLine, skipLevel | whiteFlag);
- } else {
- if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
- !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
- !IsCommentLine(skipLine, styler))
- skipLevel = levelBeforeComments;
-
- styler.SetLevel(skipLine, skipLevel);
- }
- }
-
- // Set fold header on non-quote/non-comment line
- if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
-
- // Keep track of triple quote and block comment state of previous line
- prevQuote = quote;
- prevComment = comment_start || comment_continue;
-
- // Set fold level for this line and move to next line
- styler.SetLevel(lineCurrent, lev);
- indentCurrent = indentNext;
- lineCurrent = lineNext;
- }
-
- // NOTE: Cannot set level of last line here because indentCurrent doesn't have
- // header flag set; the loop above is crafted to take care of this case!
- //styler.SetLevel(lineCurrent, indentCurrent);
-}
-
-static const char * const pythonWordListDesc[] = {
- "Keywords",
- "Highlighted identifiers",
- 0
-};
-
-LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
- pythonWordListDesc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file Lexr.cxx
- ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
- **
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAnOperator(const int ch) {
- if (isascii(ch) && isalnum(ch))
- return false;
- // '.' left out as it is used to make up numbers
- if (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||
- ch == '?' || ch == ':' || ch == '*' || ch == '/' ||
- ch == '^' || ch == '<' || ch == '>' || ch == '=' ||
- ch == '&' || ch == '|' || ch == '$' || ch == '(' ||
- ch == ')' || ch == '}' || ch == '{' || ch == '[' ||
- ch == ']')
- return true;
- return false;
-}
-
-static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
-
-
- // Do not leak onto next line
- if (initStyle == SCE_R_INFIXEOL)
- initStyle = SCE_R_DEFAULT;
-
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart && (sc.state == SCE_R_STRING)) {
- // Prevent SCE_R_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_R_STRING);
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_R_OPERATOR) {
- sc.SetState(SCE_R_DEFAULT);
- } else if (sc.state == SCE_R_NUMBER) {
- if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_R_DEFAULT);
- }
- } else if (sc.state == SCE_R_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_R_KWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_R_BASEKWORD);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_R_OTHERKWORD);
- }
- sc.SetState(SCE_R_DEFAULT);
- }
- } else if (sc.state == SCE_R_COMMENT) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_R_DEFAULT);
- }
- } else if (sc.state == SCE_R_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_R_DEFAULT);
- }
- } else if (sc.state == SCE_R_INFIX) {
- if (sc.ch == '%') {
- sc.ForwardSetState(SCE_R_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_R_INFIXEOL);
- sc.ForwardSetState(SCE_R_DEFAULT);
- }
- }else if (sc.state == SCE_R_STRING2) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_R_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_R_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_R_NUMBER);
- } else if (IsAWordStart(sc.ch) ) {
- sc.SetState(SCE_R_IDENTIFIER);
- } else if (sc.Match('#')) {
- sc.SetState(SCE_R_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_R_STRING);
- } else if (sc.ch == '%') {
- sc.SetState(SCE_R_INFIX);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_R_STRING2);
- } else if (IsAnOperator(sc.ch)) {
- sc.SetState(SCE_R_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldRDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_R_OPERATOR) {
- if (ch == '{') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- if (atEOL) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
-}
-
-
-static const char * const RWordLists[] = {
- "Language Keywords",
- "Base / Default package function",
- "Other Package Functions",
- "Unused",
- "Unused",
- 0,
- };
-
-
-
-LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexRebol.cxx
- ** Lexer for REBOL.
- ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste
- **
- ** History:
- ** 2005-04-07 First release.
- ** 2005-04-10 Closing parens and brackets go now in default style
- ** String and comment nesting should be more safe
- **/
-// Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static inline bool IsAWordChar(const int ch) {
- return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
-}
-
-static inline bool IsAWordStart(const int ch, const int ch2) {
- return ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) ||
- (isalpha(ch) || ch == '?' || ch == '!' || ch == '\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
-}
-
-static inline bool IsAnOperator(const int ch, const int ch2, const int ch3) {
- // One char operators
- if (IsASpaceOrTab(ch2)) {
- return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?';
- }
-
- // Two char operators
- if (IsASpaceOrTab(ch3)) {
- return (ch == '*' && ch2 == '*') ||
- (ch == '/' && ch2 == '/') ||
- (ch == '<' && (ch2 == '=' || ch2 == '>')) ||
- (ch == '>' && ch2 == '=') ||
- (ch == '=' && (ch2 == '=' || ch2 == '?')) ||
- (ch == '?' && ch2 == '?');
- }
-
- return false;
-}
-
-static inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) {
- return (ch == '#' && ch2 == '{') ||
- (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) ||
- (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' );
-}
-
-
-static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
- WordList &keywords8 = *keywordlists[7];
-
- int currentLine = styler.GetLine(startPos);
- // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string.
- int stringLevel = 0;
- if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) {
- stringLevel = styler.GetLineState(currentLine - 1);
- }
-
- bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK;
- int dotCount = 0;
-
- // Do not leak onto next line
- if (initStyle == SCE_REBOL_COMMENTLINE) {
- initStyle = SCE_REBOL_DEFAULT;
- }
-
- StyleContext sc(startPos, length, initStyle, styler);
- if (startPos == 0) {
- sc.SetState(SCE_REBOL_PREFACE);
- }
- for (; sc.More(); sc.Forward()) {
-
- //--- What to do at line end ?
- if (sc.atLineEnd) {
- // Can be either inside a {} string or simply at eol
- if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK &&
- sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE)
- sc.SetState(SCE_REBOL_DEFAULT);
-
- // Update the line state, so it can be seen by next line
- currentLine = styler.GetLine(sc.currentPos);
- switch (sc.state) {
- case SCE_REBOL_BRACEDSTRING:
- case SCE_REBOL_COMMENTBLOCK:
- // Inside a braced string, we set the line state
- styler.SetLineState(currentLine, stringLevel);
- break;
- default:
- // Reset the line state
- styler.SetLineState(currentLine, 0);
- break;
- }
-
- // continue with next char
- continue;
- }
-
- //--- What to do on white-space ?
- if (IsASpaceOrTab(sc.ch))
- {
- // Return to default if any of these states
- if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER ||
- sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR ||
- sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE ||
- sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME ||
- sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE ||
- sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) {
- sc.SetState(SCE_REBOL_DEFAULT);
- }
- }
-
- //--- Specialize state ?
- // URL, Email look like identifier
- if (sc.state == SCE_REBOL_IDENTIFIER)
- {
- if (sc.ch == ':' && !IsASpace(sc.chNext)) {
- sc.ChangeState(SCE_REBOL_URL);
- } else if (sc.ch == '@') {
- sc.ChangeState(SCE_REBOL_EMAIL);
- } else if (sc.ch == '$') {
- sc.ChangeState(SCE_REBOL_MONEY);
- }
- }
- // Words look like identifiers
- if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) {
- // Keywords ?
- if (!IsAWordChar(sc.ch) || sc.Match('/')) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- blockComment = strcmp(s, "comment") == 0;
- if (keywords8.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD8);
- } else if (keywords7.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD7);
- } else if (keywords6.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD6);
- } else if (keywords5.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD5);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD4);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD3);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD2);
- } else if (keywords.InList(s)) {
- sc.ChangeState(SCE_REBOL_WORD);
- }
- // Keep same style if there are refinements
- if (!sc.Match('/')) {
- sc.SetState(SCE_REBOL_DEFAULT);
- }
- }
- // special numbers
- } else if (sc.state == SCE_REBOL_NUMBER) {
- switch (sc.ch) {
- case 'x': sc.ChangeState(SCE_REBOL_PAIR);
- break;
- case ':': sc.ChangeState(SCE_REBOL_TIME);
- break;
- case '-':
- case '/': sc.ChangeState(SCE_REBOL_DATE);
- break;
- case '.': if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE);
- break;
- }
- }
-
- //--- Determine if the current state should terminate
- if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) {
- if (sc.ch == '^' && sc.chNext == '\"') {
- sc.Forward();
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_REBOL_DEFAULT);
- }
- } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) {
- if (sc.ch == '}') {
- if (--stringLevel == 0) {
- sc.ForwardSetState(SCE_REBOL_DEFAULT);
- }
- } else if (sc.ch == '{') {
- stringLevel++;
- }
- } else if (sc.state == SCE_REBOL_BINARY) {
- if (sc.ch == '}') {
- sc.ForwardSetState(SCE_REBOL_DEFAULT);
- }
- } else if (sc.state == SCE_REBOL_TAG) {
- if (sc.ch == '>') {
- sc.ForwardSetState(SCE_REBOL_DEFAULT);
- }
- } else if (sc.state == SCE_REBOL_PREFACE) {
- if (sc.MatchIgnoreCase("rebol"))
- {
- int i;
- for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++);
- if (sc.GetRelative(i) == '[')
- sc.SetState(SCE_REBOL_DEFAULT);
- }
- }
-
- //--- Parens and bracket changes to default style when the current is a number
- if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE ||
- sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL ||
- sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) {
- if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') {
- sc.SetState(SCE_REBOL_DEFAULT);
- }
- }
-
- //--- Determine if a new state should be entered.
- if (sc.state == SCE_REBOL_DEFAULT) {
- if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) {
- sc.SetState(SCE_REBOL_OPERATOR);
- } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) {
- sc.SetState(SCE_REBOL_BINARY);
- } else if (IsAWordStart(sc.ch, sc.chNext)) {
- sc.SetState(SCE_REBOL_IDENTIFIER);
- } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') {
- dotCount = 0;
- sc.SetState(SCE_REBOL_NUMBER);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_REBOL_QUOTEDSTRING);
- } else if (sc.ch == '{') {
- sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING);
- ++stringLevel;
- } else if (sc.ch == ';') {
- sc.SetState(SCE_REBOL_COMMENTLINE);
- } else if (sc.ch == '$') {
- sc.SetState(SCE_REBOL_MONEY);
- } else if (sc.ch == '%') {
- sc.SetState(SCE_REBOL_FILE);
- } else if (sc.ch == '<') {
- sc.SetState(SCE_REBOL_TAG);
- } else if (sc.ch == '#' && sc.chNext == '"') {
- sc.SetState(SCE_REBOL_CHARACTER);
- sc.Forward();
- } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) {
- sc.SetState(SCE_REBOL_ISSUE);
- }
- }
- }
- sc.Complete();
-}
-
-
-static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
- Accessor &styler) {
- unsigned int lengthDoc = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_REBOL_DEFAULT) {
- if (ch == '[') {
- levelCurrent++;
- } else if (ch == ']') {
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const rebolWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, "rebol", FoldRebolDoc, rebolWordListDesc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexRuby.cxx
- ** Lexer for Ruby.
- **/
-// Copyright 2001- by Clemens Wyss <wys@helbling.ch>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-//XXX Identical to Perl, put in common area
-static inline bool isEOLChar(char ch) {
- return (ch == '\r') || (ch == '\n');
-}
-
-#define isSafeASCII(ch) ((unsigned int)(ch) <= 127)
-// This one's redundant, but makes for more readable code
-#define isHighBitChar(ch) ((unsigned int)(ch) > 127)
-
-static inline bool isSafeAlpha(char ch) {
- return (isSafeASCII(ch) && isalpha(ch)) || ch == '_';
-}
-
-static inline bool isSafeAlnum(char ch) {
- return (isSafeASCII(ch) && isalnum(ch)) || ch == '_';
-}
-
-static inline bool isSafeAlnumOrHigh(char ch) {
- return isHighBitChar(ch) || isalnum(ch) || ch == '_';
-}
-
-static inline bool isSafeDigit(char ch) {
- return isSafeASCII(ch) && isdigit(ch);
-}
-
-static inline bool isSafeWordcharOrHigh(char ch) {
- // Error: scintilla's KeyWords.h includes '.' as a word-char
- // we want to separate things that can take methods from the
- // methods.
- return isHighBitChar(ch) || isalnum(ch) || ch == '_';
-}
-
-static bool inline iswhitespace(char ch) {
- return ch == ' ' || ch == '\t';
-}
-
-#define MAX_KEYWORD_LENGTH 200
-
-#define STYLE_MASK 63
-#define actual_style(style) (style & STYLE_MASK)
-
-static bool followsDot(unsigned int pos, Accessor &styler) {
- styler.Flush();
- for (; pos >= 1; --pos) {
- int style = actual_style(styler.StyleAt(pos));
- char ch;
- switch (style) {
- case SCE_RB_DEFAULT:
- ch = styler[pos];
- if (ch == ' ' || ch == '\t') {
- //continue
- } else {
- return false;
- }
- break;
-
- case SCE_RB_OPERATOR:
- return styler[pos] == '.';
-
- default:
- return false;
- }
- }
- return false;
-}
-
-// Forward declarations
-static bool keywordIsAmbiguous(const char *prevWord);
-static bool keywordDoStartsLoop(int pos,
- Accessor &styler);
-static bool keywordIsModifier(const char *word,
- int pos,
- Accessor &styler);
-
-static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
- char s[MAX_KEYWORD_LENGTH];
- unsigned int i, j;
- unsigned int lim = end - start + 1; // num chars to copy
- if (lim >= MAX_KEYWORD_LENGTH) {
- lim = MAX_KEYWORD_LENGTH - 1;
- }
- for (i = start, j = 0; j < lim; i++, j++) {
- s[j] = styler[i];
- }
- s[j] = '\0';
- int chAttr;
- if (0 == strcmp(prevWord, "class"))
- chAttr = SCE_RB_CLASSNAME;
- else if (0 == strcmp(prevWord, "module"))
- chAttr = SCE_RB_MODULE_NAME;
- else if (0 == strcmp(prevWord, "def"))
- chAttr = SCE_RB_DEFNAME;
- else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
- if (keywordIsAmbiguous(s)
- && keywordIsModifier(s, start, styler)) {
-
- // Demoted keywords are colored as keywords,
- // but do not affect changes in indentation.
- //
- // Consider the word 'if':
- // 1. <<if test ...>> : normal
- // 2. <<stmt if test>> : demoted
- // 3. <<lhs = if ...>> : normal: start a new indent level
- // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
-
- chAttr = SCE_RB_WORD_DEMOTED;
- } else {
- chAttr = SCE_RB_WORD;
- }
- } else
- chAttr = SCE_RB_IDENTIFIER;
- styler.ColourTo(end, chAttr);
- if (chAttr == SCE_RB_WORD) {
- strcpy(prevWord, s);
- } else {
- prevWord[0] = 0;
- }
- return chAttr;
-}
-
-
-//XXX Identical to Perl, put in common area
-static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
- if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
- return false;
- }
- while (*val) {
- if (*val != styler[pos++]) {
- return false;
- }
- val++;
- }
- return true;
-}
-
-// Do Ruby better -- find the end of the line, work back,
-// and then check for leading white space
-
-// Precondition: the here-doc target can be indented
-static bool lookingAtHereDocDelim(Accessor &styler,
- int pos,
- int lengthDoc,
- const char *HereDocDelim)
-{
- if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {
- return false;
- }
- while (--pos > 0) {
- char ch = styler[pos];
- if (isEOLChar(ch)) {
- return true;
- } else if (ch != ' ' && ch != '\t') {
- return false;
- }
- }
- return false;
-}
-
-//XXX Identical to Perl, put in common area
-static char opposite(char ch) {
- if (ch == '(')
- return ')';
- if (ch == '[')
- return ']';
- if (ch == '{')
- return '}';
- if (ch == '<')
- return '>';
- return ch;
-}
-
-// Null transitions when we see we've reached the end
-// and need to relex the curr char.
-
-static void redo_char(int &i, char &ch, char &chNext, char &chNext2,
- int &state) {
- i--;
- chNext2 = chNext;
- chNext = ch;
- state = SCE_RB_DEFAULT;
-}
-
-static void advance_char(int &i, char &ch, char &chNext, char &chNext2) {
- i++;
- ch = chNext;
- chNext = chNext2;
-}
-
-// precondition: startPos points to one after the EOL char
-static bool currLineContainsHereDelims(int& startPos,
- Accessor &styler) {
- if (startPos <= 1)
- return false;
-
- int pos;
- for (pos = startPos - 1; pos > 0; pos--) {
- char ch = styler.SafeGetCharAt(pos);
- if (isEOLChar(ch)) {
- // Leave the pointers where they are -- there are no
- // here doc delims on the current line, even if
- // the EOL isn't default style
-
- return false;
- } else {
- styler.Flush();
- if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {
- break;
- }
- }
- }
- if (pos == 0) {
- return false;
- }
- // Update the pointers so we don't have to re-analyze the string
- startPos = pos;
- return true;
-}
-
-// This class is used by the enter and exit methods, so it needs
-// to be hoisted out of the function.
-
-class QuoteCls {
- public:
- int Count;
- char Up;
- char Down;
- QuoteCls() {
- this->New();
- }
- void New() {
- Count = 0;
- Up = '\0';
- Down = '\0';
- }
- void Open(char u) {
- Count++;
- Up = u;
- Down = opposite(Up);
- }
- QuoteCls(const QuoteCls& q) {
- // copy constructor -- use this for copying in
- Count = q.Count;
- Up = q.Up;
- Down = q.Down;
- }
- QuoteCls& operator=(const QuoteCls& q) { // assignment constructor
- if (this != &q) {
- Count = q.Count;
- Up = q.Up;
- Down = q.Down;
- }
- return *this;
- }
-
-};
-
-
-static void enterInnerExpression(int *p_inner_string_types,
- int *p_inner_expn_brace_counts,
- QuoteCls *p_inner_quotes,
- int& inner_string_count,
- int& state,
- int& brace_counts,
- QuoteCls curr_quote
- ) {
- p_inner_string_types[inner_string_count] = state;
- state = SCE_RB_DEFAULT;
- p_inner_expn_brace_counts[inner_string_count] = brace_counts;
- brace_counts = 0;
- p_inner_quotes[inner_string_count] = curr_quote;
- ++inner_string_count;
-}
-
-static void exitInnerExpression(int *p_inner_string_types,
- int *p_inner_expn_brace_counts,
- QuoteCls *p_inner_quotes,
- int& inner_string_count,
- int& state,
- int& brace_counts,
- QuoteCls& curr_quote
- ) {
- --inner_string_count;
- state = p_inner_string_types[inner_string_count];
- brace_counts = p_inner_expn_brace_counts[inner_string_count];
- curr_quote = p_inner_quotes[inner_string_count];
-}
-
-static bool isEmptyLine(int pos,
- Accessor &styler) {
- int spaceFlags = 0;
- int lineCurrent = styler.GetLine(pos);
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
- return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;
-}
-
-static bool RE_CanFollowKeyword(const char *keyword) {
- if (!strcmp(keyword, "and")
- || !strcmp(keyword, "begin")
- || !strcmp(keyword, "break")
- || !strcmp(keyword, "case")
- || !strcmp(keyword, "do")
- || !strcmp(keyword, "else")
- || !strcmp(keyword, "elsif")
- || !strcmp(keyword, "if")
- || !strcmp(keyword, "next")
- || !strcmp(keyword, "return")
- || !strcmp(keyword, "when")
- || !strcmp(keyword, "unless")
- || !strcmp(keyword, "until")
- || !strcmp(keyword, "not")
- || !strcmp(keyword, "or")) {
- return true;
- }
- return false;
-}
-
-// Look at chars up to but not including endPos
-// Don't look at styles in case we're looking forward
-
-static int skipWhitespace(int startPos,
- int endPos,
- Accessor &styler) {
- for (int i = startPos; i < endPos; i++) {
- if (!iswhitespace(styler[i])) {
- return i;
- }
- }
- return endPos;
-}
-
-// This routine looks for false positives like
-// undef foo, <<
-// There aren't too many.
-//
-// iPrev points to the start of <<
-
-static bool sureThisIsHeredoc(int iPrev,
- Accessor &styler,
- char *prevWord) {
-
- // Not so fast, since Ruby's so dynamic. Check the context
- // to make sure we're OK.
- int prevStyle;
- int lineStart = styler.GetLine(iPrev);
- int lineStartPosn = styler.LineStart(lineStart);
- styler.Flush();
-
- // Find the first word after some whitespace
- int firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler);
- if (firstWordPosn >= iPrev) {
- // Have something like {^ <<}
- //XXX Look at the first previous non-comment non-white line
- // to establish the context. Not too likely though.
- return true;
- } else {
- switch (prevStyle = styler.StyleAt(firstWordPosn)) {
- case SCE_RB_WORD:
- case SCE_RB_WORD_DEMOTED:
- case SCE_RB_IDENTIFIER:
- break;
- default:
- return true;
- }
- }
- int firstWordEndPosn = firstWordPosn;
- char *dst = prevWord;
- for (;;) {
- if (firstWordEndPosn >= iPrev ||
- styler.StyleAt(firstWordEndPosn) != prevStyle) {
- *dst = 0;
- break;
- }
- *dst++ = styler[firstWordEndPosn];
- firstWordEndPosn += 1;
- }
- //XXX Write a style-aware thing to regex scintilla buffer objects
- if (!strcmp(prevWord, "undef")
- || !strcmp(prevWord, "def")
- || !strcmp(prevWord, "alias")) {
- // These keywords are what we were looking for
- return false;
- }
- return true;
-}
-
-// Routine that saves us from allocating a buffer for the here-doc target
-// targetEndPos points one past the end of the current target
-static bool haveTargetMatch(int currPos,
- int lengthDoc,
- int targetStartPos,
- int targetEndPos,
- Accessor &styler) {
- if (lengthDoc - currPos < targetEndPos - targetStartPos) {
- return false;
- }
- int i, j;
- for (i = targetStartPos, j = currPos;
- i < targetEndPos && j < lengthDoc;
- i++, j++) {
- if (styler[i] != styler[j]) {
- return false;
- }
- }
- return true;
-}
-
-// We need a check because the form
-// [identifier] <<[target]
-// is ambiguous. The Ruby lexer/parser resolves it by
-// looking to see if [identifier] names a variable or a
-// function. If it's the first, it's the start of a here-doc.
-// If it's a var, it's an operator. This lexer doesn't
-// maintain a symbol table, so it looks ahead to see what's
-// going on, in cases where we have
-// ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target]
-//
-// If there's no occurrence of [target] on a line, assume we don't.
-
-// return true == yes, we have no heredocs
-
-static bool sureThisIsNotHeredoc(int lt2StartPos,
- Accessor &styler) {
- int prevStyle;
- // Use full document, not just part we're styling
- int lengthDoc = styler.Length();
- int lineStart = styler.GetLine(lt2StartPos);
- int lineStartPosn = styler.LineStart(lineStart);
- styler.Flush();
- const bool definitely_not_a_here_doc = true;
- const bool looks_like_a_here_doc = false;
-
- // Find the first word after some whitespace
- int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);
- if (firstWordPosn >= lt2StartPos) {
- return definitely_not_a_here_doc;
- }
- prevStyle = styler.StyleAt(firstWordPosn);
- // If we have '<<' following a keyword, it's not a heredoc
- if (prevStyle != SCE_RB_IDENTIFIER) {
- return definitely_not_a_here_doc;
- }
- int newStyle = prevStyle;
- // Some compilers incorrectly warn about uninit newStyle
- for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
- // Inner loop looks at the name
- for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
- newStyle = styler.StyleAt(firstWordPosn);
- if (newStyle != prevStyle) {
- break;
- }
- }
- // Do we have '::' or '.'?
- if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) {
- char ch = styler[firstWordPosn];
- if (ch == '.') {
- // yes
- } else if (ch == ':') {
- if (styler.StyleAt(++firstWordPosn) != SCE_RB_OPERATOR) {
- return definitely_not_a_here_doc;
- } else if (styler[firstWordPosn] != ':') {
- return definitely_not_a_here_doc;
- }
- } else {
- break;
- }
- } else {
- break;
- }
- }
- // Skip next batch of white-space
- firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);
- if (firstWordPosn != lt2StartPos) {
- // Have [[^ws[identifier]ws[*something_else*]ws<<
- return definitely_not_a_here_doc;
- }
- // OK, now 'j' will point to the current spot moving ahead
- int j = firstWordPosn + 1;
- if (styler.StyleAt(j) != SCE_RB_OPERATOR || styler[j] != '<') {
- // This shouldn't happen
- return definitely_not_a_here_doc;
- }
- int nextLineStartPosn = styler.LineStart(lineStart + 1);
- if (nextLineStartPosn >= lengthDoc) {
- return definitely_not_a_here_doc;
- }
- j = skipWhitespace(j + 1, nextLineStartPosn, styler);
- if (j >= lengthDoc) {
- return definitely_not_a_here_doc;
- }
- bool allow_indent;
- int target_start, target_end;
- // From this point on no more styling, since we're looking ahead
- if (styler[j] == '-') {
- allow_indent = true;
- j++;
- } else {
- allow_indent = false;
- }
-
- // Allow for quoted targets.
- char target_quote = 0;
- switch (styler[j]) {
- case '\'':
- case '"':
- case '`':
- target_quote = styler[j];
- j += 1;
- }
-
- if (isSafeAlnum(styler[j])) {
- // Init target_end because some compilers think it won't
- // be initialized by the time it's used
- target_start = target_end = j;
- j++;
- } else {
- return definitely_not_a_here_doc;
- }
- for (; j < lengthDoc; j++) {
- if (!isSafeAlnum(styler[j])) {
- if (target_quote && styler[j] != target_quote) {
- // unquoted end
- return definitely_not_a_here_doc;
- }
-
- // And for now make sure that it's a newline
- // don't handle arbitrary expressions yet
-
- target_end = j;
- if (target_quote) {
- // Now we can move to the character after the string delimiter.
- j += 1;
- }
- j = skipWhitespace(j, lengthDoc, styler);
- if (j >= lengthDoc) {
- return definitely_not_a_here_doc;
- } else {
- char ch = styler[j];
- if (ch == '#' || isEOLChar(ch)) {
- // This is OK, so break and continue;
- break;
- } else {
- return definitely_not_a_here_doc;
- }
- }
- }
- }
-
- // Just look at the start of each line
- int last_line = styler.GetLine(lengthDoc - 1);
- // But don't go too far
- if (last_line > lineStart + 50) {
- last_line = lineStart + 50;
- }
- for (int line_num = lineStart + 1; line_num <= last_line; line_num++) {
- if (allow_indent) {
- j = skipWhitespace(styler.LineStart(line_num), lengthDoc, styler);
- } else {
- j = styler.LineStart(line_num);
- }
- // target_end is one past the end
- if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) {
- // We got it
- return looks_like_a_here_doc;
- }
- }
- return definitely_not_a_here_doc;
-}
-
-//todo: if we aren't looking at a stdio character,
-// move to the start of the first line that is not in a
-// multi-line construct
-
-static void synchronizeDocStart(unsigned int& startPos,
- int &length,
- int &initStyle,
- Accessor &styler,
- bool skipWhiteSpace=false) {
-
- styler.Flush();
- int style = actual_style(styler.StyleAt(startPos));
- switch (style) {
- case SCE_RB_STDIN:
- case SCE_RB_STDOUT:
- case SCE_RB_STDERR:
- // Don't do anything else with these.
- return;
- }
-
- int pos = startPos;
- // Quick way to characterize each line
- int lineStart;
- for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {
- // Now look at the style before the previous line's EOL
- pos = styler.LineStart(lineStart) - 1;
- if (pos <= 10) {
- lineStart = 0;
- break;
- }
- char ch = styler.SafeGetCharAt(pos);
- char chPrev = styler.SafeGetCharAt(pos - 1);
- if (ch == '\n' && chPrev == '\r') {
- pos--;
- }
- if (styler.SafeGetCharAt(pos - 1) == '\\') {
- // Continuation line -- keep going
- } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {
- // Part of multi-line construct -- keep going
- } else if (currLineContainsHereDelims(pos, styler)) {
- // Keep going, with pos and length now pointing
- // at the end of the here-doc delimiter
- } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {
- // Keep going
- } else {
- break;
- }
- }
- pos = styler.LineStart(lineStart);
- length += (startPos - pos);
- startPos = pos;
- initStyle = SCE_RB_DEFAULT;
-}
-
-static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
-
- // Lexer for Ruby often has to backtrack to start of current style to determine
- // which characters are being used as quotes, how deeply nested is the
- // start position and what the termination string is for here documents
-
- WordList &keywords = *keywordlists[0];
-
- class HereDocCls {
- public:
- int State;
- // States
- // 0: '<<' encountered
- // 1: collect the delimiter
- // 1b: text between the end of the delimiter and the EOL
- // 2: here doc text (lines after the delimiter)
- char Quote; // the char after '<<'
- bool Quoted; // true if Quote in ('\'','"','`')
- int DelimiterLength; // strlen(Delimiter)
- char Delimiter[256]; // the Delimiter, limit of 256: from Perl
- bool CanBeIndented;
- HereDocCls() {
- State = 0;
- DelimiterLength = 0;
- Delimiter[0] = '\0';
- CanBeIndented = false;
- }
- };
- HereDocCls HereDoc;
-
- QuoteCls Quote;
-
- int numDots = 0; // For numbers --
- // Don't start lexing in the middle of a num
-
- synchronizeDocStart(startPos, length, initStyle, styler, // ref args
- false);
-
- bool preferRE = true;
- int state = initStyle;
- int lengthDoc = startPos + length;
-
- char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
- prevWord[0] = '\0';
- if (length == 0)
- return;
-
- char chPrev = styler.SafeGetCharAt(startPos - 1);
- char chNext = styler.SafeGetCharAt(startPos);
- bool is_real_number = true; // Differentiate between constants and ?-sequences.
- // Ruby uses a different mask because bad indentation is marked by oring with 32
- styler.StartAt(startPos, 127);
- styler.StartSegment(startPos);
-
- static int q_states[] = {SCE_RB_STRING_Q,
- SCE_RB_STRING_QQ,
- SCE_RB_STRING_QR,
- SCE_RB_STRING_QW,
- SCE_RB_STRING_QW,
- SCE_RB_STRING_QX};
- static const char* q_chars = "qQrwWx";
-
- // In most cases a value of 2 should be ample for the code in the
- // Ruby library, and the code the user is likely to enter.
- // For example,
- // fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}"
- // if options[:verbose]
- // from fileutils.rb nests to a level of 2
- // If the user actually hits a 6th occurrence of '#{' in a double-quoted
- // string (including regex'es, %Q, %<sym>, %w, and other strings
- // that interpolate), it will stay as a string. The problem with this
- // is that quotes might flip, a 7th '#{' will look like a comment,
- // and code-folding might be wrong.
-
- // If anyone runs into this problem, I recommend raising this
- // value slightly higher to replacing the fixed array with a linked
- // list. Keep in mind this code will be called everytime the lexer
- // is invoked.
-
-#define INNER_STRINGS_MAX_COUNT 5
- // These vars track our instances of "...#{,,,%Q<..#{,,,}...>,,,}..."
- int inner_string_types[INNER_STRINGS_MAX_COUNT];
- // Track # braces when we push a new #{ thing
- int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT];
- QuoteCls inner_quotes[INNER_STRINGS_MAX_COUNT];
- int inner_string_count = 0;
- int brace_counts = 0; // Number of #{ ... } things within an expression
-
- int i;
- for (i = 0; i < INNER_STRINGS_MAX_COUNT; i++) {
- inner_string_types[i] = 0;
- inner_expn_brace_counts[i] = 0;
- }
- for (i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- char chNext2 = styler.SafeGetCharAt(i + 2);
-
- if (styler.IsLeadByte(ch)) {
- chNext = chNext2;
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- // skip on DOS/Windows
- //No, don't, because some things will get tagged on,
- // so we won't recognize keywords, for example
-#if 0
- if (ch == '\r' && chNext == '\n') {
- continue;
- }
-#endif
-
- if (HereDoc.State == 1 && isEOLChar(ch)) {
- // Begin of here-doc (the line after the here-doc delimiter):
- HereDoc.State = 2;
- styler.ColourTo(i-1, state);
- // Don't check for a missing quote, just jump into
- // the here-doc state
- state = SCE_RB_HERE_Q;
- }
-
- // Regular transitions
- if (state == SCE_RB_DEFAULT) {
- if (isSafeDigit(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_NUMBER;
- is_real_number = true;
- numDots = 0;
- } else if (isHighBitChar(ch) || iswordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_WORD;
- } else if (ch == '#') {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_COMMENTLINE;
- } else if (ch == '=') {
- // =begin indicates the start of a comment (doc) block
- if (i == 0 || (isEOLChar(chPrev)
- && chNext == 'b'
- && styler.SafeGetCharAt(i + 2) == 'e'
- && styler.SafeGetCharAt(i + 3) == 'g'
- && styler.SafeGetCharAt(i + 4) == 'i'
- && styler.SafeGetCharAt(i + 5) == 'n'
- && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6)))) {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_POD;
- } else {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_RB_OPERATOR);
- preferRE = true;
- }
- } else if (ch == '"') {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_STRING;
- Quote.New();
- Quote.Open(ch);
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_CHARACTER;
- Quote.New();
- Quote.Open(ch);
- } else if (ch == '`') {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_BACKTICKS;
- Quote.New();
- Quote.Open(ch);
- } else if (ch == '@') {
- // Instance or class var
- styler.ColourTo(i - 1, state);
- if (chNext == '@') {
- state = SCE_RB_CLASS_VAR;
- advance_char(i, ch, chNext, chNext2); // pass by ref
- } else {
- state = SCE_RB_INSTANCE_VAR;
- }
- } else if (ch == '$') {
- // Check for a builtin global
- styler.ColourTo(i - 1, state);
- // Recognize it bit by bit
- state = SCE_RB_GLOBAL;
- } else if (ch == '/' && preferRE) {
- // Ambigous operator
- styler.ColourTo(i - 1, state);
- state = SCE_RB_REGEX;
- Quote.New();
- Quote.Open(ch);
- } else if (ch == '<' && chNext == '<' && chNext2 != '=') {
-
- // Recognise the '<<' symbol - either a here document or a binary op
- styler.ColourTo(i - 1, state);
- i++;
- chNext = chNext2;
- styler.ColourTo(i, SCE_RB_OPERATOR);
-
- if (! (strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) {
- // It's definitely not a here-doc,
- // based on Ruby's lexer/parser in the
- // heredoc_identifier routine.
- // Nothing else to do.
- } else if (preferRE) {
- if (sureThisIsHeredoc(i - 1, styler, prevWord)) {
- state = SCE_RB_HERE_DELIM;
- HereDoc.State = 0;
- }
- // else leave it in default state
- } else {
- if (sureThisIsNotHeredoc(i - 1, styler)) {
- // leave state as default
- // We don't have all the heuristics Perl has for indications
- // of a here-doc, because '<<' is overloadable and used
- // for so many other classes.
- } else {
- state = SCE_RB_HERE_DELIM;
- HereDoc.State = 0;
- }
- }
- preferRE = (state != SCE_RB_HERE_DELIM);
- } else if (ch == ':') {
- styler.ColourTo(i - 1, state);
- if (chNext == ':') {
- // Mark "::" as an operator, not symbol start
- styler.ColourTo(i + 1, SCE_RB_OPERATOR);
- advance_char(i, ch, chNext, chNext2); // pass by ref
- state = SCE_RB_DEFAULT;
- preferRE = false;
- } else if (isSafeWordcharOrHigh(chNext)) {
- state = SCE_RB_SYMBOL;
- } else if (strchr("[*!~+-*/%=<>&^|", chNext)) {
- // Do the operator analysis in-line, looking ahead
- // Based on the table in pickaxe 2nd ed., page 339
- bool doColoring = true;
- switch (chNext) {
- case '[':
- if (chNext2 == ']' ) {
- char ch_tmp = styler.SafeGetCharAt(i + 3);
- if (ch_tmp == '=') {
- i += 3;
- ch = ch_tmp;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- i += 2;
- ch = chNext2;
- chNext = ch_tmp;
- }
- } else {
- doColoring = false;
- }
- break;
-
- case '*':
- if (chNext2 == '*') {
- i += 2;
- ch = chNext2;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- advance_char(i, ch, chNext, chNext2);
- }
- break;
-
- case '!':
- if (chNext2 == '=' || chNext2 == '~') {
- i += 2;
- ch = chNext2;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- advance_char(i, ch, chNext, chNext2);
- }
- break;
-
- case '<':
- if (chNext2 == '<') {
- i += 2;
- ch = chNext2;
- chNext = styler.SafeGetCharAt(i + 1);
- } else if (chNext2 == '=') {
- char ch_tmp = styler.SafeGetCharAt(i + 3);
- if (ch_tmp == '>') { // <=> operator
- i += 3;
- ch = ch_tmp;
- chNext = styler.SafeGetCharAt(i + 1);
- } else {
- i += 2;
- ch = chNext2;
- chNext = ch_tmp;
- }
- } else {
- advance_char(i, ch, chNext, chNext2);
- }
- break;
-
- default:
- // Simple one-character operators
- advance_char(i, ch, chNext, chNext2);
- break;
- }
- if (doColoring) {
- styler.ColourTo(i, SCE_RB_SYMBOL);
- state = SCE_RB_DEFAULT;
- }
- } else if (!preferRE) {
- // Don't color symbol strings (yet)
- // Just color the ":" and color rest as string
- styler.ColourTo(i, SCE_RB_SYMBOL);
- state = SCE_RB_DEFAULT;
- } else {
- styler.ColourTo(i, SCE_RB_OPERATOR);
- state = SCE_RB_DEFAULT;
- preferRE = true;
- }
- } else if (ch == '%') {
- styler.ColourTo(i - 1, state);
- bool have_string = false;
- if (strchr(q_chars, chNext) && !isSafeWordcharOrHigh(chNext2)) {
- Quote.New();
- const char *hit = strchr(q_chars, chNext);
- if (hit != NULL) {
- state = q_states[hit - q_chars];
- Quote.Open(chNext2);
- i += 2;
- ch = chNext2;
- chNext = styler.SafeGetCharAt(i + 1);
- have_string = true;
- }
- } else if (preferRE && !isSafeWordcharOrHigh(chNext)) {
- // Ruby doesn't allow high bit chars here,
- // but the editor host might
- state = SCE_RB_STRING_QQ;
- Quote.Open(chNext);
- advance_char(i, ch, chNext, chNext2); // pass by ref
- have_string = true;
- }
- if (!have_string) {
- styler.ColourTo(i, SCE_RB_OPERATOR);
- // stay in default
- preferRE = true;
- }
- } else if (ch == '?') {
- styler.ColourTo(i - 1, state);
- if (iswhitespace(chNext) || chNext == '\n' || chNext == '\r') {
- styler.ColourTo(i, SCE_RB_OPERATOR);
- } else {
- // It's the start of a character code escape sequence
- // Color it as a number.
- state = SCE_RB_NUMBER;
- is_real_number = false;
- }
- } else if (isoperator(ch) || ch == '.') {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_RB_OPERATOR);
- // If we're ending an expression or block,
- // assume it ends an object, and the ambivalent
- // constructs are binary operators
- //
- // So if we don't have one of these chars,
- // we aren't ending an object exp'n, and ops
- // like : << / are unary operators.
-
- if (ch == '{') {
- ++brace_counts;
- preferRE = true;
- } else if (ch == '}' && --brace_counts < 0
- && inner_string_count > 0) {
- styler.ColourTo(i, SCE_RB_OPERATOR);
- exitInnerExpression(inner_string_types,
- inner_expn_brace_counts,
- inner_quotes,
- inner_string_count,
- state, brace_counts, Quote);
- } else {
- preferRE = (strchr(")}].", ch) == NULL);
- }
- // Stay in default state
- } else if (isEOLChar(ch)) {
- // Make sure it's a true line-end, with no backslash
- if ((ch == '\r' || (ch == '\n' && chPrev != '\r'))
- && chPrev != '\\') {
- // Assume we've hit the end of the statement.
- preferRE = true;
- }
- }
- } else if (state == SCE_RB_WORD) {
- if (ch == '.' || !isSafeWordcharOrHigh(ch)) {
- // Words include x? in all contexts,
- // and <letters>= after either 'def' or a dot
- // Move along until a complete word is on our left
-
- // Default accessor treats '.' as word-chars,
- // but we don't for now.
-
- if (ch == '='
- && isSafeWordcharOrHigh(chPrev)
- && (chNext == '('
- || strchr(" \t\n\r", chNext) != NULL)
- && (!strcmp(prevWord, "def")
- || followsDot(styler.GetStartSegment(), styler))) {
- // <name>= is a name only when being def'd -- Get it the next time
- // This means that <name>=<name> is always lexed as
- // <name>, (op, =), <name>
- } else if ((ch == '?' || ch == '!')
- && isSafeWordcharOrHigh(chPrev)
- && !isSafeWordcharOrHigh(chNext)) {
- // <name>? is a name -- Get it the next time
- // But <name>?<name> is always lexed as
- // <name>, (op, ?), <name>
- // Same with <name>! to indicate a method that
- // modifies its target
- } else if (isEOLChar(ch)
- && isMatch(styler, lengthDoc, i - 7, "__END__")) {
- styler.ColourTo(i, SCE_RB_DATASECTION);
- state = SCE_RB_DATASECTION;
- // No need to handle this state -- we'll just move to the end
- preferRE = false;
- } else {
- int wordStartPos = styler.GetStartSegment();
- int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord);
- switch (word_style) {
- case SCE_RB_WORD:
- preferRE = RE_CanFollowKeyword(prevWord);
- break;
-
- case SCE_RB_WORD_DEMOTED:
- preferRE = true;
- break;
-
- case SCE_RB_IDENTIFIER:
- if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
- preferRE = true;
- } else if (isEOLChar(ch)) {
- preferRE = true;
- } else {
- preferRE = false;
- }
- break;
- default:
- preferRE = false;
- }
- if (ch == '.') {
- // We might be redefining an operator-method
- preferRE = false;
- }
- // And if it's the first
- redo_char(i, ch, chNext, chNext2, state); // pass by ref
- }
- }
- } else if (state == SCE_RB_NUMBER) {
- if (!is_real_number) {
- if (ch != '\\') {
- styler.ColourTo(i, state);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- } else if (strchr("\\ntrfvaebs", chNext)) {
- // Terminal escape sequence -- handle it next time
- // Nothing more to do this time through the loop
- } else if (chNext == 'C' || chNext == 'M') {
- if (chNext2 != '-') {
- // \C or \M ends the sequence -- handle it next time
- } else {
- // Move from abc?\C-x
- // ^
- // to
- // ^
- i += 2;
- ch = chNext2;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (chNext == 'c') {
- // Stay here, \c is a combining sequence
- advance_char(i, ch, chNext, chNext2); // pass by ref
- } else {
- // ?\x, including ?\\ is final.
- styler.ColourTo(i + 1, state);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- advance_char(i, ch, chNext, chNext2);
- }
- } else if (isSafeAlnumOrHigh(ch) || ch == '_') {
- // Keep going
- } else if (ch == '.' && ++numDots == 1) {
- // Keep going
- } else {
- styler.ColourTo(i - 1, state);
- redo_char(i, ch, chNext, chNext2, state); // pass by ref
- preferRE = false;
- }
- } else if (state == SCE_RB_COMMENTLINE) {
- if (isEOLChar(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_DEFAULT;
- // Use whatever setting we had going into the comment
- }
- } else if (state == SCE_RB_HERE_DELIM) {
- // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
- // Slightly different: if we find an immediate '-',
- // the target can appear indented.
-
- if (HereDoc.State == 0) { // '<<' encountered
- HereDoc.State = 1;
- HereDoc.DelimiterLength = 0;
- if (ch == '-') {
- HereDoc.CanBeIndented = true;
- advance_char(i, ch, chNext, chNext2); // pass by ref
- } else {
- HereDoc.CanBeIndented = false;
- }
- if (isEOLChar(ch)) {
- // Bail out of doing a here doc if there's no target
- state = SCE_RB_DEFAULT;
- preferRE = false;
- } else {
- HereDoc.Quote = ch;
-
- if (ch == '\'' || ch == '"' || ch == '`') {
- HereDoc.Quoted = true;
- HereDoc.Delimiter[0] = '\0';
- } else {
- HereDoc.Quoted = false;
- HereDoc.Delimiter[0] = ch;
- HereDoc.Delimiter[1] = '\0';
- HereDoc.DelimiterLength = 1;
- }
- }
- } else if (HereDoc.State == 1) { // collect the delimiter
- if (isEOLChar(ch)) {
- // End the quote now, and go back for more
- styler.ColourTo(i - 1, state);
- state = SCE_RB_DEFAULT;
- i--;
- chNext = ch;
- chNext2 = chNext;
- preferRE = false;
- } else if (HereDoc.Quoted) {
- if (ch == HereDoc.Quote) { // closing quote => end of delimiter
- styler.ColourTo(i, state);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- } else {
- if (ch == '\\' && !isEOLChar(chNext)) {
- advance_char(i, ch, chNext, chNext2);
- }
- HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
- HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- }
- } else { // an unquoted here-doc delimiter
- if (isSafeAlnumOrHigh(ch) || ch == '_') {
- HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
- HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- } else {
- styler.ColourTo(i - 1, state);
- redo_char(i, ch, chNext, chNext2, state);
- preferRE = false;
- }
- }
- if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_ERROR;
- preferRE = false;
- }
- }
- } else if (state == SCE_RB_HERE_Q) {
- // Not needed: HereDoc.State == 2
- // Indentable here docs: look backwards
- // Non-indentable: look forwards, like in Perl
- //
- // Why: so we can quickly resolve things like <<-" abc"
-
- if (!HereDoc.CanBeIndented) {
- if (isEOLChar(chPrev)
- && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
- styler.ColourTo(i - 1, state);
- i += HereDoc.DelimiterLength - 1;
- chNext = styler.SafeGetCharAt(i + 1);
- if (isEOLChar(chNext)) {
- styler.ColourTo(i, SCE_RB_HERE_DELIM);
- state = SCE_RB_DEFAULT;
- HereDoc.State = 0;
- preferRE = false;
- }
- // Otherwise we skipped through the here doc faster.
- }
- } else if (isEOLChar(chNext)
- && lookingAtHereDocDelim(styler,
- i - HereDoc.DelimiterLength + 1,
- lengthDoc,
- HereDoc.Delimiter)) {
- styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state);
- styler.ColourTo(i, SCE_RB_HERE_DELIM);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- HereDoc.State = 0;
- }
- } else if (state == SCE_RB_CLASS_VAR
- || state == SCE_RB_INSTANCE_VAR
- || state == SCE_RB_SYMBOL) {
- if (!isSafeWordcharOrHigh(ch)) {
- styler.ColourTo(i - 1, state);
- redo_char(i, ch, chNext, chNext2, state); // pass by ref
- preferRE = false;
- }
- } else if (state == SCE_RB_GLOBAL) {
- if (!isSafeWordcharOrHigh(ch)) {
- // handle special globals here as well
- if (chPrev == '$') {
- if (ch == '-') {
- // Include the next char, like $-a
- advance_char(i, ch, chNext, chNext2);
- }
- styler.ColourTo(i, state);
- state = SCE_RB_DEFAULT;
- } else {
- styler.ColourTo(i - 1, state);
- redo_char(i, ch, chNext, chNext2, state); // pass by ref
- }
- preferRE = false;
- }
- } else if (state == SCE_RB_POD) {
- // PODs end with ^=end\s, -- any whitespace can follow =end
- if (strchr(" \t\n\r", ch) != NULL
- && i > 5
- && isEOLChar(styler[i - 5])
- && isMatch(styler, lengthDoc, i - 4, "=end")) {
- styler.ColourTo(i - 1, state);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- }
- } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {
- if (ch == '\\' && Quote.Up != '\\') {
- // Skip one
- advance_char(i, ch, chNext, chNext2);
- } else if (ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0) {
- // Include the options
- while (isSafeAlpha(chNext)) {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- styler.ColourTo(i, state);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- }
- } else if (ch == Quote.Up) {
- // Only if close quoter != open quoter
- Quote.Count++;
-
- } else if (ch == '#' ) {
- if (chNext == '{'
- && inner_string_count < INNER_STRINGS_MAX_COUNT) {
- // process #{ ... }
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i + 1, SCE_RB_OPERATOR);
- enterInnerExpression(inner_string_types,
- inner_expn_brace_counts,
- inner_quotes,
- inner_string_count,
- state,
- brace_counts,
- Quote);
- preferRE = true;
- // Skip one
- advance_char(i, ch, chNext, chNext2);
- } else {
- //todo: distinguish comments from pound chars
- // for now, handle as comment
- styler.ColourTo(i - 1, state);
- bool inEscape = false;
- while (++i < lengthDoc) {
- ch = styler.SafeGetCharAt(i);
- if (ch == '\\') {
- inEscape = true;
- } else if (isEOLChar(ch)) {
- // Comment inside a regex
- styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);
- break;
- } else if (inEscape) {
- inEscape = false; // don't look at char
- } else if (ch == Quote.Down) {
- // Have the regular handler deal with this
- // to get trailing modifiers.
- i--;
- ch = styler[i];
- break;
- }
- }
- chNext = styler.SafeGetCharAt(i + 1);
- chNext2 = styler.SafeGetCharAt(i + 2);
- }
- }
- // Quotes of all kinds...
- } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
- state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
- state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
- state == SCE_RB_BACKTICKS) {
- if (!Quote.Down && !isspacechar(ch)) {
- Quote.Open(ch);
- } else if (ch == '\\' && Quote.Up != '\\') {
- //Riddle me this: Is it safe to skip *every* escaped char?
- advance_char(i, ch, chNext, chNext2);
- } else if (ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0) {
- styler.ColourTo(i, state);
- state = SCE_RB_DEFAULT;
- preferRE = false;
- }
- } else if (ch == Quote.Up) {
- Quote.Count++;
- } else if (ch == '#' && chNext == '{'
- && inner_string_count < INNER_STRINGS_MAX_COUNT
- && state != SCE_RB_CHARACTER
- && state != SCE_RB_STRING_Q) {
- // process #{ ... }
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i + 1, SCE_RB_OPERATOR);
- enterInnerExpression(inner_string_types,
- inner_expn_brace_counts,
- inner_quotes,
- inner_string_count,
- state,
- brace_counts,
- Quote);
- preferRE = true;
- // Skip one
- advance_char(i, ch, chNext, chNext2);
- }
- }
-
- if (state == SCE_RB_ERROR) {
- break;
- }
- chPrev = ch;
- }
- if (state == SCE_RB_WORD) {
- // We've ended on a word, possibly at EOF, and need to
- // classify it.
- (void) ClassifyWordRb(styler.GetStartSegment(), lengthDoc - 1, keywords, styler, prevWord);
- } else {
- styler.ColourTo(lengthDoc - 1, state);
- }
-}
-
-// Helper functions for folding, disambiguation keywords
-// Assert that there are no high-bit chars
-
-static void getPrevWord(int pos,
- char *prevWord,
- Accessor &styler,
- int word_state)
-{
- int i;
- styler.Flush();
- for (i = pos - 1; i > 0; i--) {
- if (actual_style(styler.StyleAt(i)) != word_state) {
- i++;
- break;
- }
- }
- if (i < pos - MAX_KEYWORD_LENGTH) // overflow
- i = pos - MAX_KEYWORD_LENGTH;
- char *dst = prevWord;
- for (; i <= pos; i++) {
- *dst++ = styler[i];
- }
- *dst = 0;
-}
-
-static bool keywordIsAmbiguous(const char *prevWord)
-{
- // Order from most likely used to least likely
- // Lots of ways to do a loop in Ruby besides 'while/until'
- if (!strcmp(prevWord, "if")
- || !strcmp(prevWord, "do")
- || !strcmp(prevWord, "while")
- || !strcmp(prevWord, "unless")
- || !strcmp(prevWord, "until")) {
- return true;
- } else {
- return false;
- }
-}
-
-// Demote keywords in the following conditions:
-// if, while, unless, until modify a statement
-// do after a while or until, as a noise word (like then after if)
-
-static bool keywordIsModifier(const char *word,
- int pos,
- Accessor &styler)
-{
- if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
- return keywordDoStartsLoop(pos, styler);
- }
- char ch;
- int style = SCE_RB_DEFAULT;
- int lineStart = styler.GetLine(pos);
- int lineStartPosn = styler.LineStart(lineStart);
- styler.Flush();
- while (--pos >= lineStartPosn) {
- style = actual_style(styler.StyleAt(pos));
- if (style == SCE_RB_DEFAULT) {
- if (iswhitespace(ch = styler[pos])) {
- //continue
- } else if (ch == '\r' || ch == '\n') {
- // Scintilla's LineStart() and GetLine() routines aren't
- // platform-independent, so if we have text prepared with
- // a different system we can't rely on it.
- return false;
- }
- } else {
- break;
- }
- }
- if (pos < lineStartPosn) {
- return false; //XXX not quite right if the prev line is a continuation
- }
- // First things where the action is unambiguous
- switch (style) {
- case SCE_RB_DEFAULT:
- case SCE_RB_COMMENTLINE:
- case SCE_RB_POD:
- case SCE_RB_CLASSNAME:
- case SCE_RB_DEFNAME:
- case SCE_RB_MODULE_NAME:
- return false;
- case SCE_RB_OPERATOR:
- break;
- case SCE_RB_WORD:
- // Watch out for uses of 'else if'
- //XXX: Make a list of other keywords where 'if' isn't a modifier
- // and can appear legitimately
- // Formulate this to avoid warnings from most compilers
- if (strcmp(word, "if") == 0) {
- char prevWord[MAX_KEYWORD_LENGTH + 1];
- getPrevWord(pos, prevWord, styler, SCE_RB_WORD);
- return strcmp(prevWord, "else") != 0;
- }
- return true;
- default:
- return true;
- }
- // Assume that if the keyword follows an operator,
- // usually it's a block assignment, like
- // a << if x then y else z
-
- ch = styler[pos];
- switch (ch) {
- case ')':
- case ']':
- case '}':
- return true;
- default:
- return false;
- }
-}
-
-#define WHILE_BACKWARDS "elihw"
-#define UNTIL_BACKWARDS "litnu"
-
-// Nothing fancy -- look to see if we follow a while/until somewhere
-// on the current line
-
-static bool keywordDoStartsLoop(int pos,
- Accessor &styler)
-{
- char ch;
- int style;
- int lineStart = styler.GetLine(pos);
- int lineStartPosn = styler.LineStart(lineStart);
- styler.Flush();
- while (--pos >= lineStartPosn) {
- style = actual_style(styler.StyleAt(pos));
- if (style == SCE_RB_DEFAULT) {
- if ((ch = styler[pos]) == '\r' || ch == '\n') {
- // Scintilla's LineStart() and GetLine() routines aren't
- // platform-independent, so if we have text prepared with
- // a different system we can't rely on it.
- return false;
- }
- } else if (style == SCE_RB_WORD) {
- // Check for while or until, but write the word in backwards
- char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
- char *dst = prevWord;
- int wordLen = 0;
- int start_word;
- for (start_word = pos;
- start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD;
- start_word--) {
- if (++wordLen < MAX_KEYWORD_LENGTH) {
- *dst++ = styler[start_word];
- }
- }
- *dst = 0;
- // Did we see our keyword?
- if (!strcmp(prevWord, WHILE_BACKWARDS)
- || !strcmp(prevWord, UNTIL_BACKWARDS)) {
- return true;
- }
- // We can move pos to the beginning of the keyword, and then
- // accept another decrement, as we can never have two contiguous
- // keywords:
- // word1 word2
- // ^
- // <- move to start_word
- // ^
- // <- loop decrement
- // ^ # pointing to end of word1 is fine
- pos = start_word;
- }
- }
- return false;
-}
-
-/*
- * Folding Ruby
- *
- * The language is quite complex to analyze without a full parse.
- * For example, this line shouldn't affect fold level:
- *
- * print "hello" if feeling_friendly?
- *
- * Neither should this:
- *
- * print "hello" \
- * if feeling_friendly?
- *
- *
- * But this should:
- *
- * if feeling_friendly? #++
- * print "hello" \
- * print "goodbye"
- * end #--
- *
- * So we cheat, by actually looking at the existing indentation
- * levels for each line, and just echoing it back. Like Python.
- * Then if we get better at it, we'll take braces into consideration,
- * which always affect folding levels.
-
- * How the keywords should work:
- * No effect:
- * __FILE__ __LINE__ BEGIN END alias and
- * defined? false in nil not or self super then
- * true undef
-
- * Always increment:
- * begin class def do for module when {
- *
- * Always decrement:
- * end }
- *
- * Increment if these start a statement
- * if unless until while -- do nothing if they're modifiers
-
- * These end a block if there's no modifier, but don't bother
- * break next redo retry return yield
- *
- * These temporarily de-indent, but re-indent
- * case else elsif ensure rescue
- *
- * This means that the folder reflects indentation rather
- * than setting it. The language-service updates indentation
- * when users type return and finishes entering de-denters.
- *
- * Later offer to fold POD, here-docs, strings, and blocks of comments
- */
-
-static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-
- synchronizeDocStart(startPos, length, initStyle, styler, // ref args
- false);
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)
- & SC_FOLDLEVELNUMBERMASK
- & ~SC_FOLDLEVELBASE);
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1);
- bool buffer_ends_with_eol = false;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (style == SCE_RB_COMMENTLINE) {
- if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
- if (chNext == '{') {
- levelCurrent++;
- } else if (chNext == '}' && levelCurrent > 0) {
- levelCurrent--;
- }
- }
- } else if (style == SCE_RB_OPERATOR) {
- if (strchr("[{(", ch)) {
- levelCurrent++;
- } else if (strchr(")}]", ch)) {
- // Don't decrement below 0
- if (levelCurrent > 0)
- levelCurrent--;
- }
- } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {
- // Look at the keyword on the left and decide what to do
- char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
- prevWord[0] = 0;
- getPrevWord(i, prevWord, styler, SCE_RB_WORD);
- if (!strcmp(prevWord, "end")) {
- // Don't decrement below 0
- if (levelCurrent > 0)
- levelCurrent--;
- } else if ( !strcmp(prevWord, "if")
- || !strcmp(prevWord, "def")
- || !strcmp(prevWord, "class")
- || !strcmp(prevWord, "module")
- || !strcmp(prevWord, "begin")
- || !strcmp(prevWord, "case")
- || !strcmp(prevWord, "do")
- || !strcmp(prevWord, "while")
- || !strcmp(prevWord, "unless")
- || !strcmp(prevWord, "until")
- || !strcmp(prevWord, "for")
- ) {
- levelCurrent++;
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- buffer_ends_with_eol = true;
- } else if (!isspacechar(ch)) {
- visibleChars++;
- buffer_ends_with_eol = false;
- }
- stylePrev = style;
- }
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- if (!buffer_ends_with_eol) {
- lineCurrent++;
- int new_lev = levelCurrent;
- if (visibleChars == 0 && foldCompact)
- new_lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- new_lev |= SC_FOLDLEVELHEADERFLAG;
- levelCurrent = new_lev;
- }
- styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE);
-}
-
-static const char * const rubyWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexSML.cxx
- ** Lexer for SML.
- **/
-// Copyright 2009 by James Moffatt and Yuzhou Xin
-// Modified from LexCaml.cxx by Robert Roessler <robertr@rftp.com> Copyright 2005
-// The License.txt file describes the conditions under which this software may be distributed.
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-inline int issml(int c) {return isalnum(c) || c == '_';}
-inline int issmlf(int c) {return isalpha(c) || c == '_';}
-inline int issmld(int c) {return isdigit(c) || c == '_';}
-
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-void ColouriseSMLDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
-{
- StyleContext sc(startPos, length, initStyle, styler);
- int nesting = 0;
- if (sc.state < SCE_SML_STRING)
- sc.state = SCE_SML_DEFAULT;
- if (sc.state >= SCE_SML_COMMENT)
- nesting = (sc.state & 0x0f) - SCE_SML_COMMENT;
-
- int chBase = 0, chToken = 0, chLit = 0;
- WordList& keywords = *keywordlists[0];
- WordList& keywords2 = *keywordlists[1];
- WordList& keywords3 = *keywordlists[2];
- const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
-
- while (sc.More()) {
- int state2 = -1;
- int chColor = sc.currentPos - 1;
- bool advance = true;
-
- switch (sc.state & 0x0f) {
- case SCE_SML_DEFAULT:
- chToken = sc.currentPos;
- if (issmlf(sc.ch))
- state2 = SCE_SML_IDENTIFIER;
- else if (sc.Match('`') && issmlf(sc.chNext))
- state2 = SCE_SML_TAGNAME;
- else if (sc.Match('#')&&isdigit(sc.chNext))
- state2 = SCE_SML_LINENUM;
- else if (sc.Match('#','\"')){
- state2 = SCE_SML_CHAR,chLit = 0;
- sc.Forward();
-
- }
- else if (isdigit(sc.ch)) {
- state2 = SCE_SML_NUMBER, chBase = 10;
- if (sc.Match('0') && strchr("xX", sc.chNext))
- chBase = 16, sc.Forward();}
- else if (sc.Match('\"')&&sc.chPrev!='#')
- state2 = SCE_SML_STRING;
- else if (sc.Match('(', '*')){
- state2 = SCE_SML_COMMENT,
- sc.ch = ' ',
- sc.Forward();}
- else if (strchr("!~"
- "=<>@^+-*/"
- "()[];,:.#", sc.ch))
- state2 = SCE_SML_OPERATOR;
- break;
-
- case SCE_SML_IDENTIFIER:
- if (!(issml(sc.ch) || sc.Match('\''))) {
- const int n = sc.currentPos - chToken;
- if (n < 24) {
- char t[24];
- for (int i = -n; i < 0; i++)
- t[n + i] = static_cast<char>(sc.GetRelative(i));
- t[n] = '\0';
- if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
- sc.ChangeState(SCE_SML_KEYWORD);
- else if (keywords2.InList(t))
- sc.ChangeState(SCE_SML_KEYWORD2);
- else if (keywords3.InList(t))
- sc.ChangeState(SCE_SML_KEYWORD3);
- }
- state2 = SCE_SML_DEFAULT, advance = false;
- }
- break;
-
- case SCE_SML_TAGNAME:
- if (!(issml(sc.ch) || sc.Match('\'')))
- state2 = SCE_SML_DEFAULT, advance = false;
- break;
-
- case SCE_SML_LINENUM:
- if (!isdigit(sc.ch))
- state2 = SCE_SML_DEFAULT, advance = false;
- break;
-
- case SCE_SML_OPERATOR: {
- const char* o = 0;
- if (issml(sc.ch) || isspace(sc.ch)
- || (o = strchr(")]};,\'\"`#", sc.ch),o)
- || !strchr("!$%&*+-./:<=>?@^|~", sc.ch)) {
- if (o && strchr(")]};,", sc.ch)) {
- if ((sc.Match(')') && sc.chPrev == '(')
- || (sc.Match(']') && sc.chPrev == '['))
- sc.ChangeState(SCE_SML_KEYWORD);
- chColor++;
- } else
- advance = false;
- state2 = SCE_SML_DEFAULT;
- }
- break;
- }
-
- case SCE_SML_NUMBER:
- if (issmld(sc.ch) || IsADigit(sc.ch, chBase))
- break;
- if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
- && (issmld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))
- break;
- if (chBase == 10) {
- if (sc.Match('.') && issmld(sc.chPrev))
- break;
- if ((sc.Match('e') || sc.Match('E'))
- && (issmld(sc.chPrev) || sc.chPrev == '.'))
- break;
- if ((sc.Match('+') || sc.Match('-'))
- && (sc.chPrev == 'e' || sc.chPrev == 'E'))
- break;
- }
- state2 = SCE_SML_DEFAULT, advance = false;
- break;
-
- case SCE_SML_CHAR:
- if (sc.Match('\\')) {
- chLit = 1;
- if (sc.chPrev == '\\')
- sc.ch = ' ';
- } else if ((sc.Match('\"') && sc.chPrev != '\\') || sc.atLineEnd) {
- state2 = SCE_SML_DEFAULT;
- chLit = 1;
- if (sc.Match('\"'))
- chColor++;
- else
- sc.ChangeState(SCE_SML_IDENTIFIER);
- } else if (chLit < 1 && sc.currentPos - chToken >= 3)
- sc.ChangeState(SCE_SML_IDENTIFIER), advance = false;
- break;
-
- case SCE_SML_STRING:
- if (sc.Match('\\') && sc.chPrev == '\\')
- sc.ch = ' ';
- else if (sc.Match('\"') && sc.chPrev != '\\')
- state2 = SCE_SML_DEFAULT, chColor++;
- break;
-
- case SCE_SML_COMMENT:
- case SCE_SML_COMMENT1:
- case SCE_SML_COMMENT2:
- case SCE_SML_COMMENT3:
- if (sc.Match('(', '*'))
- state2 = sc.state + 1, chToken = sc.currentPos,
- sc.ch = ' ',
- sc.Forward(), nesting++;
- else if (sc.Match(')') && sc.chPrev == '*') {
- if (nesting)
- state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
- else
- state2 = SCE_SML_DEFAULT;
- chColor++;
- } else if (useMagic && sc.currentPos - chToken == 4
- && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
- sc.state |= 0x10;
- break;
- }
-
- if (state2 >= 0)
- styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
- if (advance)
- sc.Forward();
- }
-
- sc.Complete();
-}
-
-void FoldSMLDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
-{
- //supress "not used" warnings
- startPos || length || initStyle || keywordlists[0] || styler.Length();
-}
-
-static const char * const SMLWordListDesc[] = {
- "Keywords",
- "Keywords2",
- "Keywords3",
- 0
-};
-
-LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexSQL.cxx
- ** Lexer for SQL, including PL/SQL and SQL*Plus.
- **/
-// Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return (ch < 0x80) && (isalpha(ch) || ch == '_');
-}
-
-static inline bool IsADoxygenChar(int ch) {
- return (islower(ch) || ch == '$' || ch == '@' ||
- ch == '\\' || ch == '&' || ch == '<' ||
- ch == '>' || ch == '#' || ch == '{' ||
- ch == '}' || ch == '[' || ch == ']');
-}
-
-static inline bool IsANumberChar(int ch) {
- // Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- return (ch < 0x80) &&
- (isdigit(ch) || toupper(ch) == 'E' ||
- ch == '.' || ch == '-' || ch == '+');
-}
-
-static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords1 = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &kw_pldoc = *keywordlists[2];
- WordList &kw_sqlplus = *keywordlists[3];
- WordList &kw_user1 = *keywordlists[4];
- WordList &kw_user2 = *keywordlists[5];
- WordList &kw_user3 = *keywordlists[6];
- WordList &kw_user4 = *keywordlists[7];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- // property sql.backslash.escapes
- // Enables backslash as an escape character in SQL.
- bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
-
- bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
- int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
- for (; sc.More(); sc.Forward()) {
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_SQL_OPERATOR:
- sc.SetState(SCE_SQL_DEFAULT);
- break;
- case SCE_SQL_NUMBER:
- // We stop the number definition on non-numerical non-dot non-eE non-sign char
- if (!IsANumberChar(sc.ch)) {
- sc.SetState(SCE_SQL_DEFAULT);
- }
- break;
- case SCE_SQL_IDENTIFIER:
- if (!IsAWordChar(sc.ch)) {
- int nextState = SCE_SQL_DEFAULT;
- char s[1000];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords1.InList(s)) {
- sc.ChangeState(SCE_SQL_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_SQL_WORD2);
- } else if (kw_sqlplus.InListAbbreviated(s, '~')) {
- sc.ChangeState(SCE_SQL_SQLPLUS);
- if (strncmp(s, "rem", 3) == 0) {
- nextState = SCE_SQL_SQLPLUS_COMMENT;
- } else if (strncmp(s, "pro", 3) == 0) {
- nextState = SCE_SQL_SQLPLUS_PROMPT;
- }
- } else if (kw_user1.InList(s)) {
- sc.ChangeState(SCE_SQL_USER1);
- } else if (kw_user2.InList(s)) {
- sc.ChangeState(SCE_SQL_USER2);
- } else if (kw_user3.InList(s)) {
- sc.ChangeState(SCE_SQL_USER3);
- } else if (kw_user4.InList(s)) {
- sc.ChangeState(SCE_SQL_USER4);
- }
- sc.SetState(nextState);
- }
- break;
- case SCE_SQL_QUOTEDIDENTIFIER:
- if (sc.ch == 0x60) {
- if (sc.chNext == 0x60) {
- sc.Forward(); // Ignore it
- } else {
- sc.ForwardSetState(SCE_SQL_DEFAULT);
- }
- }
- break;
- case SCE_SQL_COMMENT:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_SQL_DEFAULT);
- }
- break;
- case SCE_SQL_COMMENTDOC:
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_SQL_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') { // Doxygen support
- // Verify that we have the conditions to mark a comment-doc-keyword
- if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
- styleBeforeDCKeyword = SCE_SQL_COMMENTDOC;
- sc.SetState(SCE_SQL_COMMENTDOCKEYWORD);
- }
- }
- break;
- case SCE_SQL_COMMENTLINE:
- case SCE_SQL_COMMENTLINEDOC:
- case SCE_SQL_SQLPLUS_COMMENT:
- case SCE_SQL_SQLPLUS_PROMPT:
- if (sc.atLineStart) {
- sc.SetState(SCE_SQL_DEFAULT);
- }
- break;
- case SCE_SQL_COMMENTDOCKEYWORD:
- if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {
- sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
- sc.Forward();
- sc.ForwardSetState(SCE_SQL_DEFAULT);
- } else if (!IsADoxygenChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {
- sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
- }
- sc.SetState(styleBeforeDCKeyword);
- }
- break;
- case SCE_SQL_CHARACTER:
- if (sqlBackslashEscapes && sc.ch == '\\') {
- sc.Forward();
- } else if (sc.ch == '\'') {
- if (sc.chNext == '\"') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_SQL_DEFAULT);
- }
- }
- break;
- case SCE_SQL_STRING:
- if (sc.ch == '\\') {
- // Escape sequence
- sc.Forward();
- } else if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
- sc.Forward();
- } else {
- sc.ForwardSetState(SCE_SQL_DEFAULT);
- }
- }
- break;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_SQL_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_SQL_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_SQL_IDENTIFIER);
- } else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
- sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
- } else if (sc.Match('/', '*')) {
- if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
- sc.SetState(SCE_SQL_COMMENTDOC);
- } else {
- sc.SetState(SCE_SQL_COMMENT);
- }
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('-', '-')) {
- // MySQL requires a space or control char after --
- // http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
- // Perhaps we should enforce that with proper property:
-//~ } else if (sc.Match("-- ")) {
- sc.SetState(SCE_SQL_COMMENTLINE);
- } else if (sc.ch == '#') {
- sc.SetState(SCE_SQL_COMMENTLINEDOC);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_SQL_CHARACTER);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_SQL_STRING);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_SQL_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_SQL_COMMENT ||
- style == SCE_SQL_COMMENTDOC ||
- style == SCE_SQL_COMMENTDOCKEYWORD ||
- style == SCE_SQL_COMMENTDOCKEYWORDERROR;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment.
-static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
-
- // property fold.sql.exists
- // Enables "EXISTS" to end a fold as is started by "IF" in "DROP TABLE IF EXISTS".
- bool foldSqlExists = styler.GetPropertyInt("fold.sql.exists", 1) != 0;
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0) {
- levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
- }
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- bool endFound = false;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelNext++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- }
- if (foldComment && (style == SCE_SQL_COMMENTLINE)) {
- // MySQL needs -- comments to be followed by space or control char
- if ((ch == '-') && (chNext == '-')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- char chNext3 = styler.SafeGetCharAt(i + 3);
- if (chNext2 == '{' || chNext3 == '{') {
- levelNext++;
- } else if (chNext2 == '}' || chNext3 == '}') {
- levelNext--;
- }
- }
- }
- if (style == SCE_SQL_OPERATOR) {
- if (ch == '(') {
- levelNext++;
- } else if (ch == ')') {
- levelNext--;
- }
- }
- // If new keyword (cannot trigger on elseif or nullif, does less tests)
- if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
- const int MAX_KW_LEN = 6; // Maximum length of folding keywords
- char s[MAX_KW_LEN + 2];
- unsigned int j = 0;
- for (; j < MAX_KW_LEN + 1; j++) {
- if (!iswordchar(styler[i + j])) {
- break;
- }
- s[j] = static_cast<char>(tolower(styler[i + j]));
- }
- if (j == MAX_KW_LEN + 1) {
- // Keyword too long, don't test it
- s[0] = '\0';
- } else {
- s[j] = '\0';
- }
- if ((!foldOnlyBegin) && (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0)) {
- if (endFound) {
- // ignore
- endFound = false;
- } else {
- levelNext++;
- }
- } else if (strcmp(s, "begin") == 0) {
- levelNext++;
- } else if ((strcmp(s, "end") == 0) ||
-// // DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
- (foldSqlExists && (strcmp(s, "exists") == 0)) ||
-// // SQL Anywhere permits IF ... ELSE ... ENDIF
-// // will only be active if "endif" appears in the
-// // keyword list.
- (strcmp(s, "endif") == 0)) {
- endFound = true;
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE) {
- levelNext = SC_FOLDLEVELBASE;
- }
- }
- }
- if (atEOL) {
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- visibleChars = 0;
- endFound = false;
- }
- if (!isspacechar(ch)) {
- visibleChars++;
- }
- }
-}
-
-static const char * const sqlWordListDesc[] = {
- "Keywords",
- "Database Objects",
- "PLDoc",
- "SQL*Plus",
- "User Keywords 1",
- "User Keywords 2",
- "User Keywords 3",
- "User Keywords 4",
- 0
-};
-
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", FoldSQLDoc, sqlWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexScriptol.cxx
- ** Lexer for Scriptol.
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
-{
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) != 0;
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++)
- {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
- }
- char chAttr = SCE_SCRIPTOL_IDENTIFIER;
- if (0 == strcmp(prevWord, "class")) chAttr = SCE_SCRIPTOL_CLASSNAME;
- else if (wordIsNumber) chAttr = SCE_SCRIPTOL_NUMBER;
- else if (keywords.InList(s)) chAttr = SCE_SCRIPTOL_KEYWORD;
- else for (unsigned int i = 0; i < end - start + 1; i++) // test dotted idents
- {
- if (styler[start + i] == '.')
- {
- styler.ColourTo(start + i - 1, chAttr);
- styler.ColourTo(start + i, SCE_SCRIPTOL_OPERATOR);
- }
- }
- styler.ColourTo(end, chAttr);
- strcpy(prevWord, s);
-}
-
-static bool IsSolComment(Accessor &styler, int pos, int len)
-{
- char c;
- if(len > 0)
- {
- c = styler[pos];
- if(c == '`') return true;
- if(len > 1)
- {
- if(c == '/')
- {
- c = styler[pos + 1];
- if(c == '/') return true;
- if(c == '*') return true;
- }
- }
- }
- return false;
-}
-
-static bool IsSolStringStart(char ch)
-{
- if (ch == '\'' || ch == '"') return true;
- return false;
-}
-
-static bool IsSolWordStart(char ch)
-{
- return (iswordchar(ch) && !IsSolStringStart(ch));
-}
-
-
-static int GetSolStringState(Accessor &styler, int i, int *nextIndex)
-{
- char ch = styler.SafeGetCharAt(i);
- char chNext = styler.SafeGetCharAt(i + 1);
-
- if (ch != '\"' && ch != '\'')
- {
- *nextIndex = i + 1;
- return SCE_SCRIPTOL_DEFAULT;
- }
- // ch is either single or double quotes in string
- // code below seem non-sense but is here for future extensions
- if (ch == chNext && ch == styler.SafeGetCharAt(i + 2))
- {
- *nextIndex = i + 3;
- if(ch == '\"') return SCE_SCRIPTOL_TRIPLE;
- if(ch == '\'') return SCE_SCRIPTOL_TRIPLE;
- return SCE_SCRIPTOL_STRING;
- }
- else
- {
- *nextIndex = i + 1;
- if (ch == '"') return SCE_SCRIPTOL_STRING;
- else return SCE_SCRIPTOL_STRING;
- }
-}
-
-
-static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler)
- {
-
- int lengthDoc = startPos + length;
- char stringType = '\"';
-
- if (startPos > 0)
- {
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0)
- {
- startPos = styler.LineStart(lineCurrent-1);
- if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT;
- else initStyle = styler.StyleAt(startPos-1);
- }
- }
-
- styler.StartAt(startPos, 127);
-
- WordList &keywords = *keywordlists[0];
-
- int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
- char prevWord[200];
- prevWord[0] = '\0';
- if (length == 0) return;
-
- int state = initStyle & 31;
-
- int nextIndex = 0;
- char chPrev = ' ';
- char chPrev2 = ' ';
- char chNext = styler[startPos];
- styler.StartSegment(startPos);
- bool atStartLine = true;
- int spaceFlags = 0;
- for (int i = startPos; i < lengthDoc; i++)
- {
-
- if (atStartLine)
- {
- char chBad = static_cast<char>(64);
- char chGood = static_cast<char>(0);
- char chFlags = chGood;
-
- if (whingeLevel == 1)
- {
- chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
- }
- else if (whingeLevel == 2)
- {
- chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
- }
- else if (whingeLevel == 3)
- {
- chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
- }
- else if (whingeLevel == 4)
- {
- chFlags = (spaceFlags & wsTab) ? chBad : chGood;
- }
- styler.SetFlags(chFlags, static_cast<char>(state));
- atStartLine = false;
- }
-
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
- {
- if ((state == SCE_SCRIPTOL_DEFAULT) ||
- (state == SCE_SCRIPTOL_TRIPLE) ||
- (state == SCE_SCRIPTOL_COMMENTBLOCK))
- {
- styler.ColourTo(i, state);
- }
- atStartLine = true;
- }
-
- if (styler.IsLeadByte(ch))
- {
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- chPrev2 = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_SCRIPTOL_STRINGEOL)
- {
- if (ch != '\r' && ch != '\n')
- {
- styler.ColourTo(i - 1, state);
- state = SCE_SCRIPTOL_DEFAULT;
- }
- }
-
- if (state == SCE_SCRIPTOL_DEFAULT)
- {
- if (IsSolWordStart(ch))
- {
- styler.ColourTo(i - 1, state);
- state = SCE_SCRIPTOL_KEYWORD;
- }
- else if (ch == '`')
- {
- styler.ColourTo(i - 1, state);
- state = SCE_SCRIPTOL_COMMENTLINE;
- }
- else if (ch == '/')
- {
- styler.ColourTo(i - 1, state);
- if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE;
- if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK;
- }
-
- else if (IsSolStringStart(ch))
- {
- styler.ColourTo(i - 1, state);
- state = GetSolStringState(styler, i, &nextIndex);
- if(state == SCE_SCRIPTOL_STRING)
- {
- stringType = ch;
- }
- if (nextIndex != i + 1)
- {
- i = nextIndex - 1;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- }
- }
- else if (isoperator(ch))
- {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
- }
- }
- else if (state == SCE_SCRIPTOL_KEYWORD)
- {
- if (!iswordchar(ch))
- {
- ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
- state = SCE_SCRIPTOL_DEFAULT;
- if (ch == '`')
- {
- state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE;
- }
- else if (IsSolStringStart(ch))
- {
- styler.ColourTo(i - 1, state);
- state = GetSolStringState(styler, i, &nextIndex);
- if (nextIndex != i + 1)
- {
- i = nextIndex - 1;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- }
- }
- else if (isoperator(ch))
- {
- styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR);
- }
- }
- }
- else
- {
- if (state == SCE_SCRIPTOL_COMMENTLINE ||
- state == SCE_SCRIPTOL_PERSISTENT ||
- state == SCE_SCRIPTOL_CSTYLE)
- {
- if (ch == '\r' || ch == '\n')
- {
- styler.ColourTo(i - 1, state);
- state = SCE_SCRIPTOL_DEFAULT;
- }
- }
- else if(state == SCE_SCRIPTOL_COMMENTBLOCK)
- {
- if(chPrev == '*' && ch == '/')
- {
- styler.ColourTo(i, state);
- state = SCE_SCRIPTOL_DEFAULT;
- }
- }
- else if ((state == SCE_SCRIPTOL_STRING) ||
- (state == SCE_SCRIPTOL_CHARACTER))
- {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\'))
- {
- styler.ColourTo(i - 1, state);
- state = SCE_SCRIPTOL_STRINGEOL;
- }
- else if (ch == '\\')
- {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\')
- {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- }
- else if ((ch == '\"') || (ch == '\''))
- {
- // must match the entered quote type
- if(ch == stringType)
- {
- styler.ColourTo(i, state);
- state = SCE_SCRIPTOL_DEFAULT;
- }
- }
- }
- else if (state == SCE_SCRIPTOL_TRIPLE)
- {
- if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') ||
- (ch == '\"' && chPrev == '\"' && chPrev2 == '\"'))
- {
- styler.ColourTo(i, state);
- state = SCE_SCRIPTOL_DEFAULT;
- }
- }
-
- }
- chPrev2 = chPrev;
- chPrev = ch;
- }
- if (state == SCE_SCRIPTOL_KEYWORD)
- {
- ClassifyWordSol(styler.GetStartSegment(),
- lengthDoc-1, keywords, styler, prevWord);
- }
- else
- {
- styler.ColourTo(lengthDoc-1, state);
- }
-}
-
-static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler)
- {
- int lengthDoc = startPos + length;
-
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0)
- {
- if (lineCurrent > 0)
- {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- if (startPos == 0)
- initStyle = SCE_SCRIPTOL_DEFAULT;
- else
- initStyle = styler.StyleAt(startPos-1);
- }
- }
- int state = initStyle & 31;
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
- if ((state == SCE_SCRIPTOL_TRIPLE))
- indentCurrent |= SC_FOLDLEVELWHITEFLAG;
- char chNext = styler[startPos];
- for (int i = startPos; i < lengthDoc; i++)
- {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int style = styler.StyleAt(i) & 31;
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc))
- {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment);
- if (style == SCE_SCRIPTOL_TRIPLE)
- indentNext |= SC_FOLDLEVELWHITEFLAG;
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
- {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
- {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- else if (indentNext & SC_FOLDLEVELWHITEFLAG)
- {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK))
- {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- }
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- }
- }
-}
-
-LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexSmalltalk.cxx
- ** Lexer for Smalltalk language.
- ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com
- **/
-// Copyright 1998-2002 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 <ctype.h>
-
-#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
-
-/*
-| lexTable classificationBlock charClasses |
-charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
-lexTable := ByteArray new: 128.
-classificationBlock := [ :charClass :chars |
- | flag |
- flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
- chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
-
-classificationBlock
- value: #DecDigit value: '0123456789';
- value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
- value: #Special value: '()[]{};.^:';
- value: #BinSel value: '~@%&*-+=|\/,<>?!';
- value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
-
-((String new: 500) streamContents: [ :stream |
- stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
- lexTable keysAndValuesDo: [ :index :value |
- ((index - 1) rem: 16) == 0 ifTrue: [
- stream crLf; tab]
- ifFalse: [
- stream space].
- stream print: value.
- index ~= 256 ifTrue: [
- stream nextPut: $,]].
- stream crLf; nextPutAll: '};'; crLf.
-
- charClasses keysAndValuesDo: [ :index :name |
- stream
- crLf;
- nextPutAll: (
- ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
- expandMacrosWith: name with: (1 bitShift: (index - 1)))
- ]]) edit
-*/
-
-// autogenerated {{{{
-
-static int ClassificationTable[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16,
- 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2,
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0,
-};
-
-static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}
-static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}
-static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}
-static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}
-static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}
-// autogenerated }}}}
-
-static inline bool isAlphaNumeric(int ch) {
- return isDecDigit(ch) || isLetter(ch);
-}
-
-static inline bool isDigitOfRadix(int ch, int radix)
-{
- if (isDecDigit(ch))
- return (ch - '0') < radix;
- else if (!isUpper(ch))
- return false;
- else
- return (ch - 'A' + 10) < radix;
-}
-
-static inline void skipComment(StyleContext& sc)
-{
- while (sc.More() && sc.ch != '\"')
- sc.Forward();
-}
-
-static inline void skipString(StyleContext& sc)
-{
- while (sc.More()) {
- if (sc.ch == '\'') {
- if (sc.chNext != '\'')
- return;
- sc.Forward();
- }
- sc.Forward();
- }
-}
-
-static void handleHash(StyleContext& sc)
-{
- if (isSpecial(sc.chNext)) {
- sc.SetState(SCE_ST_SPECIAL);
- return;
- }
-
- sc.SetState(SCE_ST_SYMBOL);
- sc.Forward();
- if (sc.ch == '\'') {
- sc.Forward();
- skipString(sc);
- }
- else {
- if (isLetter(sc.ch)) {
- while (isAlphaNumeric(sc.chNext) || sc.chNext == ':')
- sc.Forward();
- }
- else if (isBinSel(sc.ch)) {
- while (isBinSel(sc.chNext))
- sc.Forward();
- }
- }
-}
-
-static inline void handleSpecial(StyleContext& sc)
-{
- if (sc.ch == ':' && sc.chNext == '=') {
- sc.SetState(SCE_ST_ASSIGN);
- sc.Forward();
- }
- else {
- if (sc.ch == '^')
- sc.SetState(SCE_ST_RETURN);
- else
- sc.SetState(SCE_ST_SPECIAL);
- }
-}
-
-static inline void skipInt(StyleContext& sc, int radix)
-{
- while (isDigitOfRadix(sc.chNext, radix))
- sc.Forward();
-}
-
-static void handleNumeric(StyleContext& sc)
-{
- char num[256];
- int nl;
- int radix;
-
- sc.SetState(SCE_ST_NUMBER);
- num[0] = static_cast<char>(sc.ch);
- nl = 1;
- while (isDecDigit(sc.chNext)) {
- num[nl++] = static_cast<char>(sc.chNext);
- sc.Forward();
- if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check
- break;
- }
- if (sc.chNext == 'r') {
- num[nl] = 0;
- if (num[0] == '-')
- radix = atoi(num + 1);
- else
- radix = atoi(num);
- sc.Forward();
- if (sc.chNext == '-')
- sc.Forward();
- skipInt(sc, radix);
- }
- else
- radix = 10;
- if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix))
- return;
- sc.Forward();
- skipInt(sc, radix);
- if (sc.chNext == 's') {
- // ScaledDecimal
- sc.Forward();
- while (isDecDigit(sc.chNext))
- sc.Forward();
- return;
- }
- else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q')
- return;
- sc.Forward();
- if (sc.chNext == '+' || sc.chNext == '-')
- sc.Forward();
- skipInt(sc, radix);
-}
-
-static inline void handleBinSel(StyleContext& sc)
-{
- sc.SetState(SCE_ST_BINARY);
- while (isBinSel(sc.chNext))
- sc.Forward();
-}
-
-static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
-{
- char ident[256];
- int il;
- int state;
- bool doubleColonPresent;
-
- sc.SetState(SCE_ST_DEFAULT);
-
- ident[0] = static_cast<char>(sc.ch);
- il = 1;
- while (isAlphaNumeric(sc.chNext)) {
- ident[il++] = static_cast<char>(sc.chNext);
- sc.Forward();
- if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check
- break;
- }
-
- if (sc.chNext == ':') {
- doubleColonPresent = true;
- ident[il++] = ':';
- sc.Forward();
- }
- else
- doubleColonPresent = false;
- ident[il] = 0;
-
- if (specialSelectorList->InList(ident))
- state = SCE_ST_SPEC_SEL;
- else if (doubleColonPresent)
- state = SCE_ST_KWSEND;
- else if (isUpper(ident[0]))
- state = SCE_ST_GLOBAL;
- else {
- if (!strcmp(ident, "self"))
- state = SCE_ST_SELF;
- else if (!strcmp(ident, "super"))
- state = SCE_ST_SUPER;
- else if (!strcmp(ident, "nil"))
- state = SCE_ST_NIL;
- else if (!strcmp(ident, "true") || !strcmp(ident, "false"))
- state = SCE_ST_BOOL;
- else
- state = SCE_ST_DEFAULT;
- }
-
- sc.ChangeState(state);
-}
-
-static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *wordLists[], Accessor &styler)
-{
- StyleContext sc(startPos, length, initStyle, styler);
-
- if (initStyle == SCE_ST_COMMENT) {
- skipComment(sc);
- if (sc.More())
- sc.Forward();
- }
- else if (initStyle == SCE_ST_STRING) {
- skipString(sc);
- if (sc.More())
- sc.Forward();
- }
-
- for (; sc.More(); sc.Forward()) {
- int ch;
-
- ch = sc.ch;
- if (ch == '\"') {
- sc.SetState(SCE_ST_COMMENT);
- sc.Forward();
- skipComment(sc);
- }
- else if (ch == '\'') {
- sc.SetState(SCE_ST_STRING);
- sc.Forward();
- skipString(sc);
- }
- else if (ch == '#')
- handleHash(sc);
- else if (ch == '$') {
- sc.SetState(SCE_ST_CHARACTER);
- sc.Forward();
- }
- else if (isSpecial(ch))
- handleSpecial(sc);
- else if (isDecDigit(ch))
- handleNumeric(sc);
- else if (isLetter(ch))
- handleLetter(sc, wordLists[0]);
- else if (isBinSel(ch)) {
- if (ch == '-' && isDecDigit(sc.chNext))
- handleNumeric(sc);
- else
- handleBinSel(sc);
- }
- else
- sc.SetState(SCE_ST_DEFAULT);
- }
- sc.Complete();
-}
-
-static const char* const smalltalkWordListDesc[] = {
- "Special selectors",
- 0
-};
-
-LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexSorcus.cxx
-** Lexer for SORCUS installation files
-** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany
-** Based on the ASM Lexer by The Black Horus
-**/
-
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-
-//each character a..z and A..Z + '_' can be part of a keyword
-//additionally numbers that follow 'M' can be contained in a keyword
-static inline bool IsSWordStart(const int ch, const int prev_ch)
-{
- if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
- return true;
-
- return false;
-}
-
-
-//only digits that are not preceded by 'M' count as a number
-static inline bool IsSorcusNumber(const int ch, const int prev_ch)
-{
- if ((isdigit(ch)) && (prev_ch != 'M'))
- return true;
-
- return false;
-}
-
-
-//only = is a valid operator
-static inline bool IsSorcusOperator(const int ch)
-{
- if (ch == '=')
- return true;
-
- return false;
-}
-
-
-static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler)
-{
-
- WordList &Command = *keywordlists[0];
- WordList &Parameter = *keywordlists[1];
- WordList &Constant = *keywordlists[2];
-
- // Do not leak onto next line
- if (initStyle == SCE_SORCUS_STRINGEOL)
- initStyle = SCE_SORCUS_DEFAULT;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
-
- // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
- if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
- {
- sc.SetState(SCE_SORCUS_STRING);
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_SORCUS_OPERATOR)
- {
- if (!IsSorcusOperator(sc.ch))
- {
- sc.SetState(SCE_SORCUS_DEFAULT);
- }
- }
- else if(sc.state == SCE_SORCUS_NUMBER)
- {
- if(!IsSorcusNumber(sc.ch, sc.chPrev))
- {
- sc.SetState(SCE_SORCUS_DEFAULT);
- }
- }
- else if (sc.state == SCE_SORCUS_IDENTIFIER)
- {
- if (!IsSWordStart(sc.ch, sc.chPrev))
- {
- char s[100];
-
- sc.GetCurrent(s, sizeof(s));
-
- if (Command.InList(s))
- {
- sc.ChangeState(SCE_SORCUS_COMMAND);
- }
- else if (Parameter.InList(s))
- {
- sc.ChangeState(SCE_SORCUS_PARAMETER);
- }
- else if (Constant.InList(s))
- {
- sc.ChangeState(SCE_SORCUS_CONSTANT);
- }
-
- sc.SetState(SCE_SORCUS_DEFAULT);
- }
- }
- else if (sc.state == SCE_SORCUS_COMMENTLINE )
- {
- if (sc.atLineEnd)
- {
- sc.SetState(SCE_SORCUS_DEFAULT);
- }
- }
- else if (sc.state == SCE_SORCUS_STRING)
- {
- if (sc.ch == '\"')
- {
- sc.ForwardSetState(SCE_SORCUS_DEFAULT);
- }
- else if (sc.atLineEnd)
- {
- sc.ChangeState(SCE_SORCUS_STRINGEOL);
- sc.ForwardSetState(SCE_SORCUS_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_SORCUS_DEFAULT)
- {
- if ((sc.ch == ';') || (sc.ch == '\''))
- {
- sc.SetState(SCE_SORCUS_COMMENTLINE);
- }
- else if (IsSWordStart(sc.ch, sc.chPrev))
- {
- sc.SetState(SCE_SORCUS_IDENTIFIER);
- }
- else if (sc.ch == '\"')
- {
- sc.SetState(SCE_SORCUS_STRING);
- }
- else if (IsSorcusOperator(sc.ch))
- {
- sc.SetState(SCE_SORCUS_OPERATOR);
- }
- else if (IsSorcusNumber(sc.ch, sc.chPrev))
- {
- sc.SetState(SCE_SORCUS_NUMBER);
- }
- }
-
- }
- sc.Complete();
-}
-
-
-static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
-
-LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexSpecman.cxx
- ** Lexer for Specman E language.
- ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
-}
-
-static inline bool IsANumberChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\'');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '`');
-}
-
-static void ColouriseSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler, bool caseSensitive) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- // Do not leak onto next line
- if (initStyle == SCE_SN_STRINGEOL)
- initStyle = SCE_SN_CODE;
-
- int visibleChars = 0;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart && (sc.state == SCE_SN_STRING)) {
- // Prevent SCE_SN_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_SN_STRING);
- }
-
- // Handle line continuation generically.
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_SN_OPERATOR) {
- sc.SetState(SCE_SN_CODE);
- } else if (sc.state == SCE_SN_NUMBER) {
- if (!IsANumberChar(sc.ch)) {
- sc.SetState(SCE_SN_CODE);
- }
- } else if (sc.state == SCE_SN_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_SN_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_SN_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_SN_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_SN_USER);
- }
- sc.SetState(SCE_SN_CODE);
- }
- } else if (sc.state == SCE_SN_PREPROCESSOR) {
- if (IsASpace(sc.ch)) {
- sc.SetState(SCE_SN_CODE);
- }
- } else if (sc.state == SCE_SN_DEFAULT) {
- if (sc.Match('<', '\'')) {
- sc.Forward();
- sc.ForwardSetState(SCE_SN_CODE);
- }
- } else if (sc.state == SCE_SN_COMMENTLINE || sc.state == SCE_SN_COMMENTLINEBANG) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_SN_CODE);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_SN_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_SN_CODE);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_SN_STRINGEOL);
- sc.ForwardSetState(SCE_SN_CODE);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_SN_SIGNAL) {
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_SN_STRINGEOL);
- sc.ForwardSetState(SCE_SN_CODE);
- visibleChars = 0;
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_SN_CODE);
- }
- } else if (sc.state == SCE_SN_REGEXTAG) {
- if (!IsADigit(sc.ch)) {
- sc.SetState(SCE_SN_CODE);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_SN_CODE) {
- if (sc.ch == '$' && IsADigit(sc.chNext)) {
- sc.SetState(SCE_SN_REGEXTAG);
- sc.Forward();
- } else if (IsADigit(sc.ch)) {
- sc.SetState(SCE_SN_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_SN_IDENTIFIER);
- } else if (sc.Match('\'', '>')) {
- sc.SetState(SCE_SN_DEFAULT);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- if (sc.Match("//!")) // Nice to have a different comment style
- sc.SetState(SCE_SN_COMMENTLINEBANG);
- else
- sc.SetState(SCE_SN_COMMENTLINE);
- } else if (sc.Match('-', '-')) {
- if (sc.Match("--!")) // Nice to have a different comment style
- sc.SetState(SCE_SN_COMMENTLINEBANG);
- else
- sc.SetState(SCE_SN_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_SN_STRING);
- } else if (sc.ch == '\'') {
- sc.SetState(SCE_SN_SIGNAL);
- } else if (sc.ch == '#' && visibleChars == 0) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_SN_PREPROCESSOR);
- // Skip whitespace between # and preprocessor word
- do {
- sc.Forward();
- } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.atLineEnd) {
- sc.SetState(SCE_SN_CODE);
- }
- } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@') {
- sc.SetState(SCE_SN_OPERATOR);
- }
- }
-
- if (sc.atLineEnd) {
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- visibleChars = 0;
- }
- if (!IsASpace(sc.ch)) {
- visibleChars++;
- }
- }
- sc.Complete();
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldNoBoxSpecmanDoc(unsigned int startPos, int length, int,
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- //int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && (style == SCE_SN_COMMENTLINE)) {
- if (((ch == '/') && (chNext == '/')) ||
- ((ch == '-') && (chNext == '-'))) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelNext++;
- } else if (chNext2 == '}') {
- levelNext--;
- }
- }
- }
- if (style == SCE_SN_OPERATOR) {
- if (ch == '{') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- if (atEOL) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
-}
-
-static void FoldSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- FoldNoBoxSpecmanDoc(startPos, length, initStyle, styler);
-}
-
-static const char * const specmanWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Sequence keywords and identifiers",
- "User defined keywords and identifiers",
- "Unused",
- 0,
- };
-
-static void ColouriseSpecmanDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseSpecmanDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-
-LexerModule lmSpecman(SCLEX_SPECMAN, ColouriseSpecmanDocSensitive, "specman", FoldSpecmanDoc, specmanWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexSpice.cxx
- ** Lexer for Spice
- **/
-// Copyright 2006 by Fabien Proriol
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <string>
-
-#include "Platform.h"
-
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "PropSet.h"
-#include "KeyWords.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-/*
- * Interface
- */
-
-static void ColouriseDocument(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler);
-
-static const char * const spiceWordListDesc[] = {
- "Keywords", // SPICE command
- "Keywords2", // SPICE functions
- "Keywords3", // SPICE params
- 0
-};
-
-LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
-
-/*
- * Implementation
- */
-
-static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
-static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
-
-static inline bool IsDelimiterCharacter(int ch);
-static inline bool IsNumberStartCharacter(int ch);
-static inline bool IsNumberCharacter(int ch);
-static inline bool IsSeparatorOrDelimiterCharacter(int ch);
-static inline bool IsWordStartCharacter(int ch);
-static inline bool IsWordCharacter(int ch);
-
-static void ColouriseComment(StyleContext& sc, bool&) {
- sc.SetState(SCE_SPICE_COMMENTLINE);
- while (!sc.atLineEnd) {
- sc.Forward();
- }
-}
-
-static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = sc.Match (')');
- sc.SetState(SCE_SPICE_DELIMITER);
- sc.ForwardSetState(SCE_SPICE_DEFAULT);
-}
-
-static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = true;
- std::string number;
- sc.SetState(SCE_SPICE_NUMBER);
- // Get all characters up to a delimiter or a separator, including points, but excluding
- // double points (ranges).
- while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
- number += static_cast<char>(sc.ch);
- sc.Forward();
- }
- // Special case: exponent with sign
- if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
- (sc.ch == '+' || sc.ch == '-')) {
- number += static_cast<char>(sc.ch);
- sc.Forward ();
- while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
- number += static_cast<char>(sc.ch);
- sc.Forward();
- }
- }
- sc.SetState(SCE_SPICE_DEFAULT);
-}
-
-static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
- sc.SetState(SCE_SPICE_DEFAULT);
- sc.ForwardSetState(SCE_SPICE_DEFAULT);
-}
-
-static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
- apostropheStartsAttribute = true;
- sc.SetState(SCE_SPICE_IDENTIFIER);
- std::string word;
- while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
- word += static_cast<char>(tolower(sc.ch));
- sc.Forward();
- }
- if (keywords.InList(word.c_str())) {
- sc.ChangeState(SCE_SPICE_KEYWORD);
- if (word != "all") {
- apostropheStartsAttribute = false;
- }
- }
- else if (keywords2.InList(word.c_str())) {
- sc.ChangeState(SCE_SPICE_KEYWORD2);
- if (word != "all") {
- apostropheStartsAttribute = false;
- }
- }
- else if (keywords3.InList(word.c_str())) {
- sc.ChangeState(SCE_SPICE_KEYWORD3);
- if (word != "all") {
- apostropheStartsAttribute = false;
- }
- }
- sc.SetState(SCE_SPICE_DEFAULT);
-}
-
-//
-// ColouriseDocument
-//
-static void ColouriseDocument(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler) {
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- StyleContext sc(startPos, length, initStyle, styler);
- int lineCurrent = styler.GetLine(startPos);
- bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
- while (sc.More()) {
- if (sc.atLineEnd) {
- // Go to the next line
- sc.Forward();
- lineCurrent++;
- // Remember the line state for future incremental lexing
- styler.SetLineState(lineCurrent, apostropheStartsAttribute);
- // Don't continue any styles on the next line
- sc.SetState(SCE_SPICE_DEFAULT);
- }
- // Comments
- if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
- ColouriseComment(sc, apostropheStartsAttribute);
- // Whitespace
- } else if (IsASpace(sc.ch)) {
- ColouriseWhiteSpace(sc, apostropheStartsAttribute);
- // Delimiters
- } else if (IsDelimiterCharacter(sc.ch)) {
- ColouriseDelimiter(sc, apostropheStartsAttribute);
- // Numbers
- } else if (IsADigit(sc.ch) || sc.ch == '#') {
- ColouriseNumber(sc, apostropheStartsAttribute);
- // Keywords or identifiers
- } else {
- ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
- }
- }
- sc.Complete();
-}
-
-static inline bool IsDelimiterCharacter(int ch) {
- switch (ch) {
- case '&':
- case '\'':
- case '(':
- case ')':
- case '*':
- case '+':
- case ',':
- case '-':
- case '.':
- case '/':
- case ':':
- case ';':
- case '<':
- case '=':
- case '>':
- case '|':
- return true;
- default:
- return false;
- }
-}
-
-static inline bool IsNumberCharacter(int ch) {
- return IsNumberStartCharacter(ch) ||
- ch == '_' ||
- ch == '.' ||
- ch == '#' ||
- (ch >= 'a' && ch <= 'f') ||
- (ch >= 'A' && ch <= 'F');
-}
-
-static inline bool IsNumberStartCharacter(int ch) {
- return IsADigit(ch);
-}
-
-static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
- return IsASpace(ch) || IsDelimiterCharacter(ch);
-}
-
-static inline bool IsWordCharacter(int ch) {
- return IsWordStartCharacter(ch) || IsADigit(ch);
-}
-
-static inline bool IsWordStartCharacter(int ch) {
- return (isascii(ch) && isalpha(ch)) || ch == '_';
-}
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexTAL.cxx
- ** Lexer for TAL
- ** Based on LexPascal.cxx
- ** Written by Laurent le Tynevez
- ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
- ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
- ** Updated by Rod Falck, Aug 2006 Converted to TACL
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-inline bool isTACLoperator(char ch)
- {
- return ch == '\'' || isoperator(ch);
- }
-
-inline bool isTACLwordchar(char ch)
- {
- return ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch);
- }
-
-inline bool isTACLwordstart(char ch)
- {
- return ch == '#' || ch == '|' || ch == '_' || iswordstart(ch);
- }
-
-static void getRange(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- i++;
- }
- s[i] = '\0';
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_C_COMMENT ||
- style == SCE_C_COMMENTDOC ||
- style == SCE_C_COMMENTDOCKEYWORD ||
- style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
-
-static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
- if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
- styler.ColourTo(end, SCE_C_REGEX);
- } else
- styler.ColourTo(end, attr);
-}
-
-// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
-static int classifyWordTACL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
- int ret = 0;
-
- WordList& keywords = *keywordlists[0];
- WordList& builtins = *keywordlists[1];
- WordList& commands = *keywordlists[2];
-
- char s[100];
- getRange(start, end, styler, s, sizeof(s));
-
- char chAttr = SCE_C_IDENTIFIER;
- if (isdigit(s[0]) || (s[0] == '.')) {
- chAttr = SCE_C_NUMBER;
- }
- else {
- if (s[0] == '#' || keywords.InList(s)) {
- chAttr = SCE_C_WORD;
-
- if (strcmp(s, "asm") == 0) {
- ret = 2;
- }
- else if (strcmp(s, "end") == 0) {
- ret = -1;
- }
- }
- else if (s[0] == '|' || builtins.InList(s)) {
- chAttr = SCE_C_WORD2;
- }
- else if (commands.InList(s)) {
- chAttr = SCE_C_UUID;
- }
- else if (strcmp(s, "comment") == 0) {
- chAttr = SCE_C_COMMENTLINE;
- ret = 3;
- }
- }
- ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
- return ret;
-}
-
-static int classifyFoldPointTACL(const char* s) {
- int lev = 0;
- if (s[0] == '[')
- lev=1;
- else if (s[0] == ']')
- lev=-1;
- return lev;
-}
-
-static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- styler.StartAt(startPos);
-
- int state = initStyle;
- if (state == SCE_C_CHARACTER) // Does not leak onto next line
- state = SCE_C_DEFAULT;
- char chPrev = ' ';
- char chNext = styler[startPos];
- unsigned int lengthDoc = startPos + length;
-
- bool bInClassDefinition;
-
- int currentLine = styler.GetLine(startPos);
- if (currentLine > 0) {
- styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
- bInClassDefinition = (styler.GetLineState(currentLine) == 1);
- } else {
- styler.SetLineState(currentLine, 0);
- bInClassDefinition = false;
- }
-
- bool bInAsm = (state == SCE_C_REGEX);
- if (bInAsm)
- state = SCE_C_DEFAULT;
-
- styler.StartSegment(startPos);
- int visibleChars = 0;
- unsigned int i;
- for (i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
-
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
- // Avoid triggering two times on Dos/Win
- // End of line
- if (state == SCE_C_CHARACTER) {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- visibleChars = 0;
- currentLine++;
- styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
- }
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_C_DEFAULT) {
- if (isTACLwordstart(ch)) {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_IDENTIFIER;
- } else if (ch == '{') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENT;
- } else if (ch == '{' && chNext == '*') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENTDOC;
- } else if (ch == '=' && chNext == '=') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENTLINE;
- } else if (ch == '"') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_STRING;
- } else if (ch == '?' && visibleChars == 0) {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_PREPROCESSOR;
- } else if (isTACLoperator(ch)) {
- ColourTo(styler, i-1, state, bInAsm);
- ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
- }
- } else if (state == SCE_C_IDENTIFIER) {
- if (!isTACLwordchar(ch)) {
- int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
-
- if(lStateChange == 1) {
- styler.SetLineState(currentLine, 1);
- bInClassDefinition = true;
- } else if(lStateChange == 2) {
- bInAsm = true;
- } else if(lStateChange == -1) {
- styler.SetLineState(currentLine, 0);
- bInClassDefinition = false;
- bInAsm = false;
- }
-
- if (lStateChange == 3) {
- state = SCE_C_COMMENTLINE;
- }
- else {
- state = SCE_C_DEFAULT;
- chNext = styler.SafeGetCharAt(i + 1);
- if (ch == '{') {
- state = SCE_C_COMMENT;
- } else if (ch == '{' && chNext == '*') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENTDOC;
- } else if (ch == '=' && chNext == '=') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '"') {
- state = SCE_C_STRING;
- } else if (isTACLoperator(ch)) {
- ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
- }
- }
- }
- } else {
- if (state == SCE_C_PREPROCESSOR) {
- if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_COMMENT) {
- if (ch == '}' || (ch == '\r' || ch == '\n') ) {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_COMMENTDOC) {
- if (ch == '}' || (ch == '\r' || ch == '\n')) {
- if (((i > styler.GetStartSegment() + 2) || (
- (initStyle == SCE_C_COMMENTDOC) &&
- (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- }
- } else if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_STRING) {
- if (ch == '"' || ch == '\r' || ch == '\n') {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- }
- }
- if (!isspacechar(ch))
- visibleChars++;
- chPrev = ch;
- }
-
- // Process to end of document
- if (state == SCE_C_IDENTIFIER) {
- classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
- }
- else
- ColourTo(styler, lengthDoc - 1, state, bInAsm);
-}
-
-static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- bool section = false;
-
- int lastStart = 0;
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))
- {
- // Store last word start point.
- lastStart = i;
- }
-
- if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {
- if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {
- char s[100];
- getRange(lastStart, i, styler, s, sizeof(s));
- if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
- {
- section = true;
- levelCurrent = 1;
- levelPrev = 0;
- }
- else if (stylePrev == SCE_C_WORD)
- levelCurrent += classifyFoldPointTACL(s);
- }
- }
-
- if (style == SCE_C_OPERATOR) {
- if (ch == '[') {
- levelCurrent++;
- } else if (ch == ']') {
- levelCurrent--;
- }
- }
- if (foldComment && (style == SCE_C_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
-
- if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
- if (ch == '{' && chNext == '$') {
- unsigned int j=i+2; // skip {$
- while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- if (styler.Match(j, "region") || styler.Match(j, "if")) {
- levelCurrent++;
- } else if (styler.Match(j, "end")) {
- levelCurrent--;
- }
- }
- }
-
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelCurrent++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelCurrent--;
- }
- }
- if (atEOL) {
- int lev = levelPrev | SC_FOLDLEVELBASE;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- section = false;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const TACLWordListDesc[] = {
- "Builtins",
- "Labels",
- "Commands",
- 0
-};
-
-LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, "TACL", FoldTACLDoc, TACLWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexTADS3.cxx
- ** Lexer for TADS3.
- **/
-// Copyright 1998-2006 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-/*
- * TADS3 is a language designed by Michael J. Roberts for the writing of text
- * based games. TADS comes from Text Adventure Development System. It has good
- * support for the processing and outputting of formatted text and much of a
- * TADS program listing consists of strings.
- *
- * TADS has two types of strings, those enclosed in single quotes (') and those
- * enclosed in double quotes ("). These strings have different symantics and
- * can be given different highlighting if desired.
- *
- * There can be embedded within both types of strings html tags
- * ( <tag key=value> ), library directives ( <.directive> ), and message
- * parameters ( {The doctor's/his} ).
- *
- * Double quoted strings can also contain interpolated expressions
- * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions
- * may themselves contain single or double quoted strings, although the double
- * quoted strings may not contain interpolated expressions.
- *
- * These embedded constructs influence the output and formatting and are an
- * important part of a program and require highlighting.
- *
- * LINKS
- * http://www.tads.org/
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 int T3_SINGLE_QUOTE = 1;
-static const int T3_INT_EXPRESSION = 2;
-static const int T3_INT_EXPRESSION_IN_TAG = 4;
-static const int T3_HTML_SQUOTE = 8;
-
-static inline bool IsEOL(const int ch, const int chNext) {
- return (ch == '\r' && chNext != '\n') || (ch == '\n');
-}
-
-/*
- * Test the current character to see if it's the START of an EOL sequence;
- * if so, skip ahead to the last character of the sequence and return true,
- * and if not just return false. There are a few places where we want to
- * check to see if a newline sequence occurs at a particular point, but
- * where a caller expects a subroutine to stop only upon reaching the END
- * of a newline sequence (in particular, CR-LF on Windows). That's why
- * IsEOL() above only returns true on CR if the CR isn't followed by an LF
- * - it doesn't want to admit that there's a newline until reaching the END
- * of the sequence. We meet both needs by saying that there's a newline
- * when we see the CR in a CR-LF, but skipping the CR before returning so
- * that the caller's caller will see that we've stopped at the LF.
- */
-static inline bool IsEOLSkip(StyleContext &sc)
-{
- /* test for CR-LF */
- if (sc.ch == '\r' && sc.chNext == '\n')
- {
- /* got CR-LF - skip the CR and indicate that we're at a newline */
- sc.Forward();
- return true;
- }
-
- /*
- * in other cases, we have at most a 1-character newline, so do the
- * normal IsEOL test
- */
- return IsEOL(sc.ch, sc.chNext);
-}
-
-static inline bool IsASpaceOrTab(const int ch) {
- return ch == ' ' || ch == '\t';
-}
-
-static inline bool IsATADS3Operator(const int ch) {
- return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
- || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
- || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'
- || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'
- || ch == '@' || ch == '&' || ch == '~';
-}
-
-static inline bool IsAWordChar(const int ch) {
- return isalnum(ch) || ch == '_';
-}
-
-static inline bool IsAWordStart(const int ch) {
- return isalpha(ch) || ch == '_';
-}
-
-static inline bool IsAHexDigit(const int ch) {
- int lch = tolower(ch);
- return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c'
- || lch == 'd' || lch == 'e' || lch == 'f';
-}
-
-static inline bool IsAnHTMLChar(int ch) {
- return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';
-}
-
-static inline bool IsADirectiveChar(int ch) {
- return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/';
-}
-
-static inline bool IsANumberStart(StyleContext &sc) {
- return isdigit(sc.ch)
- || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext));
-}
-
-inline static void ColouriseTADS3Operator(StyleContext &sc) {
- int initState = sc.state;
- int c = sc.ch;
- sc.SetState(c == '{' || c == '}' ? SCE_T3_BRACE : SCE_T3_OPERATOR);
- sc.ForwardSetState(initState);
-}
-
-static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
- int endState = sc.state;
- int chQuote = sc.ch;
- int chString = (lineState & T3_SINGLE_QUOTE) ? '\'' : '"';
- if (endState == SCE_T3_HTML_STRING) {
- if (lineState&T3_SINGLE_QUOTE) {
- endState = SCE_T3_S_STRING;
- chString = '\'';
- } else if (lineState&T3_INT_EXPRESSION) {
- endState = SCE_T3_X_STRING;
- chString = '"';
- } else {
- endState = SCE_T3_HTML_DEFAULT;
- chString = '"';
- }
- chQuote = (lineState & T3_HTML_SQUOTE) ? '\'' : '"';
- } else {
- sc.SetState(SCE_T3_HTML_STRING);
- sc.Forward();
- }
- if (chQuote == '"')
- lineState &= ~T3_HTML_SQUOTE;
- else
- lineState |= T3_HTML_SQUOTE;
-
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.ch == chQuote) {
- sc.ForwardSetState(endState);
- return;
- }
- if (sc.Match('\\', static_cast<char>(chQuote))) {
- sc.Forward(2);
- sc.SetState(endState);
- return;
- }
- if (sc.ch == chString) {
- sc.SetState(SCE_T3_DEFAULT);
- return;
- }
-
- if (sc.Match('<', '<')) {
- lineState |= T3_INT_EXPRESSION | T3_INT_EXPRESSION_IN_TAG;
- sc.SetState(SCE_T3_X_DEFAULT);
- sc.Forward(2);
- return;
- }
-
- if (sc.Match('\\', static_cast<char>(chQuote))
- || sc.Match('\\', static_cast<char>(chString))
- || sc.Match('\\', '\\')) {
- sc.Forward(2);
- } else {
- sc.Forward();
- }
- }
-}
-
-static void ColouriseTADS3HTMLTagStart(StyleContext &sc) {
- sc.SetState(SCE_T3_HTML_TAG);
- sc.Forward();
- if (sc.ch == '/') {
- sc.Forward();
- }
- while (IsAnHTMLChar(sc.ch)) {
- sc.Forward();
- }
-}
-
-static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {
- int endState = sc.state;
- int chQuote = '"';
- int chString = '\'';
- switch (endState) {
- case SCE_T3_S_STRING:
- ColouriseTADS3HTMLTagStart(sc);
- sc.SetState(SCE_T3_HTML_DEFAULT);
- chQuote = '\'';
- chString = '"';
- break;
- case SCE_T3_D_STRING:
- case SCE_T3_X_STRING:
- ColouriseTADS3HTMLTagStart(sc);
- sc.SetState(SCE_T3_HTML_DEFAULT);
- break;
- case SCE_T3_HTML_DEFAULT:
- if (lineState&T3_SINGLE_QUOTE) {
- endState = SCE_T3_S_STRING;
- chQuote = '\'';
- chString = '"';
- } else if (lineState&T3_INT_EXPRESSION) {
- endState = SCE_T3_X_STRING;
- } else {
- endState = SCE_T3_D_STRING;
- }
- break;
- }
-
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.Match('/', '>')) {
- sc.SetState(SCE_T3_HTML_TAG);
- sc.Forward(2);
- sc.SetState(endState);
- return;
- }
- if (sc.ch == '>') {
- sc.SetState(SCE_T3_HTML_TAG);
- sc.ForwardSetState(endState);
- return;
- }
- if (sc.ch == chQuote) {
- sc.SetState(endState);
- return;
- }
- if (sc.Match('\\', static_cast<char>(chQuote))) {
- sc.Forward();
- ColouriseTADSHTMLString(sc, lineState);
- if (sc.state == SCE_T3_X_DEFAULT)
- break;
- } else if (sc.ch == chString) {
- ColouriseTADSHTMLString(sc, lineState);
- } else if (sc.ch == '=') {
- ColouriseTADS3Operator(sc);
- } else {
- sc.Forward();
- }
- }
-}
-
-static void ColouriseTADS3Keyword(StyleContext &sc,
- WordList *keywordlists[], unsigned int endPos) {
- char s[250];
- WordList &keywords = *keywordlists[0];
- WordList &userwords1 = *keywordlists[1];
- WordList &userwords2 = *keywordlists[2];
- WordList &userwords3 = *keywordlists[3];
- int initState = sc.state;
- sc.SetState(SCE_T3_IDENTIFIER);
- while (sc.More() && (IsAWordChar(sc.ch))) {
- sc.Forward();
- }
- sc.GetCurrent(s, sizeof(s));
- if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
- // have to find if "in" is next
- int n = 1;
- while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))
- n++;
- if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {
- sc.Forward(n+2);
- sc.ChangeState(SCE_T3_KEYWORD);
- }
- } else if (keywords.InList(s)) {
- sc.ChangeState(SCE_T3_KEYWORD);
- } else if (userwords3.InList(s)) {
- sc.ChangeState(SCE_T3_USER3);
- } else if (userwords2.InList(s)) {
- sc.ChangeState(SCE_T3_USER2);
- } else if (userwords1.InList(s)) {
- sc.ChangeState(SCE_T3_USER1);
- }
- sc.SetState(initState);
-}
-
-static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {
- int endState = sc.state;
- int chQuote = '"';
- switch (endState) {
- case SCE_T3_S_STRING:
- sc.SetState(SCE_T3_MSG_PARAM);
- sc.Forward();
- chQuote = '\'';
- break;
- case SCE_T3_D_STRING:
- case SCE_T3_X_STRING:
- sc.SetState(SCE_T3_MSG_PARAM);
- sc.Forward();
- break;
- case SCE_T3_MSG_PARAM:
- if (lineState&T3_SINGLE_QUOTE) {
- endState = SCE_T3_S_STRING;
- chQuote = '\'';
- } else if (lineState&T3_INT_EXPRESSION) {
- endState = SCE_T3_X_STRING;
- } else {
- endState = SCE_T3_D_STRING;
- }
- break;
- }
- while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.ch == '\\') {
- sc.Forward();
- }
- sc.Forward();
- }
- if (sc.ch == chQuote) {
- sc.SetState(endState);
- } else {
- sc.ForwardSetState(endState);
- }
-}
-
-static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {
- int initState = sc.state;
- int chQuote = '"';
- switch (initState) {
- case SCE_T3_S_STRING:
- sc.SetState(SCE_T3_LIB_DIRECTIVE);
- sc.Forward(2);
- chQuote = '\'';
- break;
- case SCE_T3_D_STRING:
- sc.SetState(SCE_T3_LIB_DIRECTIVE);
- sc.Forward(2);
- break;
- case SCE_T3_LIB_DIRECTIVE:
- if (lineState&T3_SINGLE_QUOTE) {
- initState = SCE_T3_S_STRING;
- chQuote = '\'';
- } else {
- initState = SCE_T3_D_STRING;
- }
- break;
- }
- while (sc.More() && IsADirectiveChar(sc.ch)) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- sc.Forward();
- };
- if (sc.ch == '>' || !sc.More()) {
- sc.ForwardSetState(initState);
- } else if (sc.ch == chQuote) {
- sc.SetState(initState);
- } else {
- sc.ChangeState(initState);
- sc.Forward();
- }
-}
-
-static void ColouriseTADS3String(StyleContext &sc, int &lineState) {
- int chQuote = sc.ch;
- int endState = sc.state;
- switch (sc.state) {
- case SCE_T3_DEFAULT:
- case SCE_T3_X_DEFAULT:
- if (chQuote == '"') {
- if (sc.state == SCE_T3_DEFAULT) {
- sc.SetState(SCE_T3_D_STRING);
- } else {
- sc.SetState(SCE_T3_X_STRING);
- }
- lineState &= ~T3_SINGLE_QUOTE;
- } else {
- sc.SetState(SCE_T3_S_STRING);
- lineState |= T3_SINGLE_QUOTE;
- }
- sc.Forward();
- break;
- case SCE_T3_S_STRING:
- chQuote = '\'';
- endState = lineState&T3_INT_EXPRESSION ?
- SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;
- break;
- case SCE_T3_D_STRING:
- chQuote = '"';
- endState = SCE_T3_DEFAULT;
- break;
- case SCE_T3_X_STRING:
- chQuote = '"';
- endState = SCE_T3_X_DEFAULT;
- break;
- }
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.ch == chQuote) {
- sc.ForwardSetState(endState);
- return;
- }
- if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
- lineState |= T3_INT_EXPRESSION;
- sc.SetState(SCE_T3_X_DEFAULT);
- sc.Forward(2);
- return;
- }
- if (sc.Match('\\', static_cast<char>(chQuote))
- || sc.Match('\\', '\\')) {
- sc.Forward(2);
- } else if (sc.ch == '{') {
- ColouriseTADS3MsgParam(sc, lineState);
- } else if (sc.Match('<', '.')) {
- ColouriseTADS3LibDirective(sc, lineState);
- } else if (sc.ch == '<') {
- ColouriseTADS3HTMLTag(sc, lineState);
- if (sc.state == SCE_T3_X_DEFAULT)
- return;
- } else {
- sc.Forward();
- }
- }
-}
-
-static void ColouriseTADS3Comment(StyleContext &sc, int endState) {
- sc.SetState(SCE_T3_BLOCK_COMMENT);
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.Match('*', '/')) {
- sc.Forward(2);
- sc.SetState(endState);
- return;
- }
- sc.Forward();
- }
-}
-
-static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
- sc.SetState(initState);
- while (sc.More()) {
- if (sc.ch == '\\') {
- sc.Forward();
- if (IsEOLSkip(sc)) {
- return;
- }
- }
- if (IsEOL(sc.ch, sc.chNext)) {
- sc.SetState(endState);
- return;
- }
- sc.Forward();
- }
-}
-
-static void ColouriseTADS3Number(StyleContext &sc) {
- int endState = sc.state;
- bool inHexNumber = false;
- bool seenE = false;
- bool seenDot = sc.ch == '.';
- sc.SetState(SCE_T3_NUMBER);
- if (sc.More()) {
- sc.Forward();
- }
- if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {
- inHexNumber = true;
- sc.Forward();
- }
- while (sc.More()) {
- if (inHexNumber) {
- if (!IsAHexDigit(sc.ch)) {
- break;
- }
- } else if (!isdigit(sc.ch)) {
- if (!seenE && tolower(sc.ch) == 'e') {
- seenE = true;
- seenDot = true;
- if (sc.chNext == '+' || sc.chNext == '-') {
- sc.Forward();
- }
- } else if (!seenDot && sc.ch == '.') {
- seenDot = true;
- } else {
- break;
- }
- }
- sc.Forward();
- }
- sc.SetState(endState);
-}
-
-static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- int visibleChars = 0;
- int bracketLevel = 0;
- int lineState = 0;
- unsigned int endPos = startPos + length;
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0) {
- lineState = styler.GetLineState(lineCurrent-1);
- }
- StyleContext sc(startPos, length, initStyle, styler);
-
- while (sc.More()) {
-
- if (IsEOL(sc.ch, sc.chNext)) {
- styler.SetLineState(lineCurrent, lineState);
- lineCurrent++;
- visibleChars = 0;
- sc.Forward();
- if (sc.ch == '\n') {
- sc.Forward();
- }
- }
-
- switch(sc.state) {
- case SCE_T3_PREPROCESSOR:
- case SCE_T3_LINE_COMMENT:
- ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
- SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
- break;
- case SCE_T3_S_STRING:
- case SCE_T3_D_STRING:
- case SCE_T3_X_STRING:
- ColouriseTADS3String(sc, lineState);
- visibleChars++;
- break;
- case SCE_T3_MSG_PARAM:
- ColouriseTADS3MsgParam(sc, lineState);
- break;
- case SCE_T3_LIB_DIRECTIVE:
- ColouriseTADS3LibDirective(sc, lineState);
- break;
- case SCE_T3_HTML_DEFAULT:
- ColouriseTADS3HTMLTag(sc, lineState);
- break;
- case SCE_T3_HTML_STRING:
- ColouriseTADSHTMLString(sc, lineState);
- break;
- case SCE_T3_BLOCK_COMMENT:
- ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
- SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
- break;
- case SCE_T3_DEFAULT:
- case SCE_T3_X_DEFAULT:
- if (IsASpaceOrTab(sc.ch)) {
- sc.Forward();
- } else if (sc.ch == '#' && visibleChars == 0) {
- ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
- } else if (sc.Match('/', '*')) {
- ColouriseTADS3Comment(sc, sc.state);
- visibleChars++;
- } else if (sc.Match('/', '/')) {
- ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
- } else if (sc.ch == '"') {
- bracketLevel = 0;
- ColouriseTADS3String(sc, lineState);
- visibleChars++;
- } else if (sc.ch == '\'') {
- ColouriseTADS3String(sc, lineState);
- visibleChars++;
- } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
- && sc.Match('>', '>')) {
- sc.Forward(2);
- sc.SetState(SCE_T3_D_STRING);
- if (lineState & T3_INT_EXPRESSION_IN_TAG)
- sc.SetState(SCE_T3_HTML_STRING);
- lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION
- |T3_INT_EXPRESSION_IN_TAG);
- } else if (IsATADS3Operator(sc.ch)) {
- if (sc.state == SCE_T3_X_DEFAULT) {
- if (sc.ch == '(') {
- bracketLevel++;
- } else if (sc.ch == ')' && bracketLevel > 0) {
- bracketLevel--;
- }
- }
- ColouriseTADS3Operator(sc);
- visibleChars++;
- } else if (IsANumberStart(sc)) {
- ColouriseTADS3Number(sc);
- visibleChars++;
- } else if (IsAWordStart(sc.ch)) {
- ColouriseTADS3Keyword(sc, keywordlists, endPos);
- visibleChars++;
- } else if (sc.Match("...")) {
- sc.SetState(SCE_T3_IDENTIFIER);
- sc.Forward(3);
- sc.SetState(SCE_T3_DEFAULT);
- } else {
- sc.Forward();
- visibleChars++;
- }
- break;
- default:
- sc.SetState(SCE_T3_DEFAULT);
- sc.Forward();
- }
- }
- sc.Complete();
-}
-
-/*
- TADS3 has two styles of top level block (TLB). Eg
-
- // default style
- silverKey : Key 'small silver key' 'small silver key'
- "A small key glints in the sunlight. "
- ;
-
- and
-
- silverKey : Key {
- 'small silver key'
- 'small silver key'
- "A small key glints in the sunlight. "
- }
-
- Some constructs mandate one or the other, but usually the author has may choose
- either.
-
- T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
- seen and is also used to match the closing ';' of the default style.
-
- T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
- what characters may be seen without incrementing the block level. The general
- pattern is identifier <punc> identifier, acceptable punctuation characters
- are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
- characters are syntactically correct, eg parentheses match. A ')' always
- signifies the start of a block. We just need to check if it is followed by a
- '{', in which case we let the brace handling code handle the folding level.
-
- expectingIdentifier == false && expectingIdentifier == false
- Before the start of a TLB.
-
- expectingIdentifier == true && expectingIdentifier == true
- Currently in an identifier. Will accept identifier or punctuation.
-
- expectingIdentifier == true && expectingIdentifier == false
- Just seen a punctuation character & now waiting for an identifier to start.
-
- expectingIdentifier == false && expectingIdentifier == truee
- We were in an identifier and have seen space. Now waiting to see a punctuation
- character
-
- Space, comments & preprocessor directives are always acceptable and are
- equivalent.
-*/
-
-static const int T3_SEENSTART = 1 << 12;
-static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
-static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
-
-static inline bool IsStringTransition(int s1, int s2) {
- return s1 != s2
- && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
- || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT))
- && s2 != SCE_T3_LIB_DIRECTIVE
- && s2 != SCE_T3_MSG_PARAM
- && s2 != SCE_T3_HTML_TAG
- && s2 != SCE_T3_HTML_STRING;
-}
-
-static inline bool IsATADS3Punctuation(const int ch) {
- return ch == ':' || ch == ',' || ch == '(' || ch == ')';
-}
-
-static inline bool IsAnIdentifier(const int style) {
- return style == SCE_T3_IDENTIFIER
- || style == SCE_T3_USER1
- || style == SCE_T3_USER2
- || style == SCE_T3_USER3;
-}
-
-static inline bool IsAnOperator(const int style) {
- return style == SCE_T3_OPERATOR || SCE_T3_BRACE;
-}
-
-static inline bool IsSpaceEquivalent(const int ch, const int style) {
- return isspace(ch)
- || style == SCE_T3_BLOCK_COMMENT
- || style == SCE_T3_LINE_COMMENT
- || style == SCE_T3_PREPROCESSOR;
-}
-
-static char peekAhead(unsigned int startPos, unsigned int endPos,
- Accessor &styler) {
- for (unsigned int i = startPos; i < endPos; i++) {
- int style = styler.StyleAt(i);
- char ch = styler[i];
- if (!IsSpaceEquivalent(ch, style)) {
- if (IsAnIdentifier(style)) {
- return 'a';
- }
- if (IsATADS3Punctuation(ch)) {
- return ':';
- }
- if (ch == '{') {
- return '{';
- }
- return '*';
- }
- }
- return ' ';
-}
-
-static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- unsigned int endPos = startPos + length;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int seenStart = levelCurrent & T3_SEENSTART;
- int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;
- int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;
- levelCurrent &= SC_FOLDLEVELNUMBERMASK;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- char ch = chNext;
- int stylePrev = style;
- bool redo = false;
- for (unsigned int i = startPos; i < endPos; i++) {
- if (redo) {
- redo = false;
- i--;
- } else {
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- }
- bool atEOL = IsEOL(ch, chNext);
-
- if (levelNext == SC_FOLDLEVELBASE) {
- if (IsSpaceEquivalent(ch, style)) {
- if (expectingPunctuation) {
- expectingIdentifier = 0;
- }
- if (style == SCE_T3_BLOCK_COMMENT) {
- levelNext++;
- }
- } else if (ch == '{') {
- levelNext++;
- seenStart = 0;
- } else if (ch == '\'' || ch == '"' || ch == '[') {
- levelNext++;
- if (seenStart) {
- redo = true;
- }
- } else if (ch == ';') {
- seenStart = 0;
- expectingIdentifier = 0;
- expectingPunctuation = 0;
- } else if (expectingIdentifier && expectingPunctuation) {
- if (IsATADS3Punctuation(ch)) {
- if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
- levelNext++;
- } else {
- expectingPunctuation = 0;
- }
- } else if (!IsAnIdentifier(style)) {
- levelNext++;
- }
- } else if (expectingIdentifier && !expectingPunctuation) {
- if (!IsAnIdentifier(style)) {
- levelNext++;
- } else {
- expectingPunctuation = T3_EXPECTINGPUNCTUATION;
- }
- } else if (!expectingIdentifier && expectingPunctuation) {
- if (!IsATADS3Punctuation(ch)) {
- levelNext++;
- } else {
- if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
- levelNext++;
- } else {
- expectingIdentifier = T3_EXPECTINGIDENTIFIER;
- expectingPunctuation = 0;
- }
- }
- } else if (!expectingIdentifier && !expectingPunctuation) {
- if (IsAnIdentifier(style)) {
- seenStart = T3_SEENSTART;
- expectingIdentifier = T3_EXPECTINGIDENTIFIER;
- expectingPunctuation = T3_EXPECTINGPUNCTUATION;
- }
- }
-
- if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {
- expectingIdentifier = 0;
- expectingPunctuation = 0;
- }
-
- } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart
- && ch == ';' && IsAnOperator(style)) {
- levelNext--;
- seenStart = 0;
- } else if (style == SCE_T3_BLOCK_COMMENT) {
- if (stylePrev != SCE_T3_BLOCK_COMMENT) {
- levelNext++;
- } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- } else if (ch == '\'' || ch == '"') {
- if (IsStringTransition(style, stylePrev)) {
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (IsStringTransition(style, styleNext)) {
- levelNext--;
- }
- } else if (IsAnOperator(style)) {
- if (ch == '{' || ch == '[') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}' || ch == ']') {
- levelNext--;
- }
- }
-
- if (atEOL) {
- if (seenStart && levelNext == SC_FOLDLEVELBASE) {
- switch (peekAhead(i+1, endPos, styler)) {
- case ' ':
- case '{':
- break;
- case '*':
- levelNext++;
- break;
- case 'a':
- if (expectingPunctuation) {
- levelNext++;
- }
- break;
- case ':':
- if (expectingIdentifier) {
- levelNext++;
- }
- break;
- }
- if (levelNext != SC_FOLDLEVELBASE) {
- expectingIdentifier = 0;
- expectingPunctuation = 0;
- }
- }
- int lev = levelMinCurrent | (levelNext | expectingIdentifier
- | expectingPunctuation | seenStart) << 16;
- if (levelMinCurrent < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- }
- }
-}
-
-static const char * const tads3WordList[] = {
- "TADS3 Keywords",
- "User defined 1",
- "User defined 2",
- "User defined 3",
- 0
-};
-
-LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexTAL.cxx
- ** Lexer for TAL
- ** Based on LexPascal.cxx
- ** Written by Laurent le Tynevez
- ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
- ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
- ** Updated by Rod Falck, Aug 2006 Converted to TAL
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-inline bool isTALoperator(char ch)
- {
- return ch == '\'' || ch == '@' || ch == '#' || isoperator(ch);
- }
-
-inline bool isTALwordchar(char ch)
- {
- return ch == '$' || ch == '^' || iswordchar(ch);
- }
-
-inline bool isTALwordstart(char ch)
- {
- return ch == '$' || ch == '^' || iswordstart(ch);
- }
-
-static void getRange(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- i++;
- }
- s[i] = '\0';
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_C_COMMENT ||
- style == SCE_C_COMMENTDOC ||
- style == SCE_C_COMMENTDOCKEYWORD ||
- style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
-
-static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
- if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
- styler.ColourTo(end, SCE_C_REGEX);
- } else
- styler.ColourTo(end, attr);
-}
-
-// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
-static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
- int ret = 0;
-
- WordList& keywords = *keywordlists[0];
- WordList& builtins = *keywordlists[1];
- WordList& nonreserved_keywords = *keywordlists[2];
-
- char s[100];
- getRange(start, end, styler, s, sizeof(s));
-
- char chAttr = SCE_C_IDENTIFIER;
- if (isdigit(s[0]) || (s[0] == '.')) {
- chAttr = SCE_C_NUMBER;
- }
- else {
- if (keywords.InList(s)) {
- chAttr = SCE_C_WORD;
-
- if (strcmp(s, "asm") == 0) {
- ret = 2;
- }
- else if (strcmp(s, "end") == 0) {
- ret = -1;
- }
- }
- else if (s[0] == '$' || builtins.InList(s)) {
- chAttr = SCE_C_WORD2;
- }
- else if (nonreserved_keywords.InList(s)) {
- chAttr = SCE_C_UUID;
- }
- }
- ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
- return ret;
-}
-
-static int classifyFoldPointTAL(const char* s) {
- int lev = 0;
- if (!(isdigit(s[0]) || (s[0] == '.'))) {
- if (strcmp(s, "begin") == 0 ||
- strcmp(s, "block") == 0) {
- lev=1;
- } else if (strcmp(s, "end") == 0) {
- lev=-1;
- }
- }
- return lev;
-}
-
-static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- styler.StartAt(startPos);
-
- int state = initStyle;
- if (state == SCE_C_CHARACTER) // Does not leak onto next line
- state = SCE_C_DEFAULT;
- char chPrev = ' ';
- char chNext = styler[startPos];
- unsigned int lengthDoc = startPos + length;
-
- bool bInClassDefinition;
-
- int currentLine = styler.GetLine(startPos);
- if (currentLine > 0) {
- styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
- bInClassDefinition = (styler.GetLineState(currentLine) == 1);
- } else {
- styler.SetLineState(currentLine, 0);
- bInClassDefinition = false;
- }
-
- bool bInAsm = (state == SCE_C_REGEX);
- if (bInAsm)
- state = SCE_C_DEFAULT;
-
- styler.StartSegment(startPos);
- int visibleChars = 0;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
-
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
- // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
- // Avoid triggering two times on Dos/Win
- // End of line
- if (state == SCE_C_CHARACTER) {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- visibleChars = 0;
- currentLine++;
- styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
- }
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
- chPrev = ' ';
- i += 1;
- continue;
- }
-
- if (state == SCE_C_DEFAULT) {
- if (isTALwordstart(ch)) {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_IDENTIFIER;
- } else if (ch == '!' && chNext != '*') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENT;
- } else if (ch == '!' && chNext == '*') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENTDOC;
- } else if (ch == '-' && chNext == '-') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENTLINE;
- } else if (ch == '"') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_STRING;
- } else if (ch == '?' && visibleChars == 0) {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_PREPROCESSOR;
- } else if (isTALoperator(ch)) {
- ColourTo(styler, i-1, state, bInAsm);
- ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
- }
- } else if (state == SCE_C_IDENTIFIER) {
- if (!isTALwordchar(ch)) {
- int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
-
- if(lStateChange == 1) {
- styler.SetLineState(currentLine, 1);
- bInClassDefinition = true;
- } else if(lStateChange == 2) {
- bInAsm = true;
- } else if(lStateChange == -1) {
- styler.SetLineState(currentLine, 0);
- bInClassDefinition = false;
- bInAsm = false;
- }
-
- state = SCE_C_DEFAULT;
- chNext = styler.SafeGetCharAt(i + 1);
- if (ch == '!' && chNext != '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '!' && chNext == '*') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_COMMENTDOC;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '"') {
- state = SCE_C_STRING;
- } else if (isTALoperator(ch)) {
- ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
- }
- }
- } else {
- if (state == SCE_C_PREPROCESSOR) {
- if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_COMMENT) {
- if (ch == '!' || (ch == '\r' || ch == '\n') ) {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_COMMENTDOC) {
- if (ch == '!' || (ch == '\r' || ch == '\n')) {
- if (((i > styler.GetStartSegment() + 2) || (
- (initStyle == SCE_C_COMMENTDOC) &&
- (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- }
- } else if (state == SCE_C_COMMENTLINE) {
- if (ch == '\r' || ch == '\n') {
- ColourTo(styler, i-1, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- } else if (state == SCE_C_STRING) {
- if (ch == '"') {
- ColourTo(styler, i, state, bInAsm);
- state = SCE_C_DEFAULT;
- }
- }
- }
- if (!isspacechar(ch))
- visibleChars++;
- chPrev = ch;
- }
- ColourTo(styler, lengthDoc - 1, state, bInAsm);
-}
-
-static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- bool was_end = false;
- bool section = false;
-
- int lastStart = 0;
-
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR))
- {
- // Store last word start point.
- lastStart = i;
- }
-
- if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) {
- if(isTALwordchar(ch) && !isTALwordchar(chNext)) {
- char s[100];
- getRange(lastStart, i, styler, s, sizeof(s));
- if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
- {
- section = true;
- levelCurrent = 1;
- levelPrev = 0;
- }
- else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID)
- {
- if (strcmp(s, "block") == 0)
- {
- // block keyword is ignored immediately after end keyword
- if (!was_end)
- levelCurrent++;
- }
- else
- levelCurrent += classifyFoldPointTAL(s);
- if (strcmp(s, "end") == 0)
- {
- was_end = true;
- }
- else
- {
- was_end = false;
- }
- }
- }
- }
-
- if (foldComment && (style == SCE_C_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
-
- if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
- if (ch == '{' && chNext == '$') {
- unsigned int j=i+2; // skip {$
- while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- if (styler.Match(j, "region") || styler.Match(j, "if")) {
- levelCurrent++;
- } else if (styler.Match(j, "end")) {
- levelCurrent--;
- }
- }
- }
-
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelCurrent++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelCurrent--;
- }
- }
-
- if (atEOL) {
- int lev = levelPrev | SC_FOLDLEVELBASE;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- section = false;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-static const char * const TALWordListDesc[] = {
- "Keywords",
- "Builtins",
- 0
-};
-
-LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, "TAL", FoldTALDoc, TALWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexTCL.cxx
- ** Lexer for TCL language.
- **/
-// Copyright 1998-2001 by Andre Arpin <arpin@kingston.net>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#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
-
-// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
- return ch >= 0x80 ||
- (isalnum(ch) || ch == '_' || ch ==':' || ch=='.'); // : name space separator
-}
-
-static inline bool IsAWordStart(int ch) {
- return ch >= 0x80 || (ch ==':' || isalpha(ch) || ch == '_');
-}
-
-static inline bool IsANumberChar(int ch) {
- // Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- return (ch < 0x80) &&
- (IsADigit(ch, 0x10) || toupper(ch) == 'E' ||
- ch == '.' || ch == '-' || ch == '+');
-}
-
-static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *keywordlists[], Accessor &styler) {
-#define isComment(s) (s==SCE_TCL_COMMENT || s==SCE_TCL_COMMENTLINE || s==SCE_TCL_COMMENT_BOX || s==SCE_TCL_BLOCK_COMMENT)
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool commentLevel = false;
- bool subBrace = false; // substitution begin with a brace ${.....}
- enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf,
- LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32 } lineState = LS_DEFAULT;
- bool prevSlash = false;
- int currentLevel = 0;
- bool expected = 0;
- bool subParen = 0;
-
- int currentLine = styler.GetLine(startPos);
- if (currentLine > 0)
- currentLine--;
- length += startPos - styler.LineStart(currentLine);
- // make sure lines overlap
- startPos = styler.LineStart(currentLine);
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
- WordList &keywords8 = *keywordlists[7];
- WordList &keywords9 = *keywordlists[8];
-
- if (currentLine > 0) {
- int ls = styler.GetLineState(currentLine - 1);
- lineState = tLineState(ls & LS_MASK_STATE);
- expected = LS_COMMAND_EXPECTED == tLineState(ls & LS_COMMAND_EXPECTED);
- subBrace = LS_BRACE_ONLY == tLineState(ls & LS_BRACE_ONLY);
- currentLevel = styler.LevelAt(currentLine - 1) >> 17;
- commentLevel = (styler.LevelAt(currentLine - 1) >> 16) & 1;
- } else
- styler.SetLevel(0, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG);
- bool visibleChars = false;
-
- int previousLevel = currentLevel;
- StyleContext sc(startPos, length, SCE_TCL_DEFAULT, styler);
- for (; ; sc.Forward()) {
-next:
- if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac
- continue;
- bool atEnd = !sc.More(); // make sure we coloured the last word
- if (lineState != LS_DEFAULT) {
- sc.SetState(SCE_TCL_DEFAULT);
- if (lineState == LS_OPEN_COMMENT)
- sc.SetState(SCE_TCL_COMMENTLINE);
- else if (lineState == LS_OPEN_DOUBLE_QUOTE)
- sc.SetState(SCE_TCL_IN_QUOTE);
- else if (lineState == LS_COMMENT_BOX && (sc.ch == '#' || (sc.ch == ' ' && sc.chNext=='#')))
- sc.SetState(SCE_TCL_COMMENT_BOX);
- lineState = LS_DEFAULT;
- }
- if (subBrace) { // ${ overrides every thing even \ except }
- if (sc.ch == '}') {
- subBrace = false;
- sc.SetState(SCE_TCL_OPERATOR);
- sc.ForwardSetState(SCE_TCL_DEFAULT);
- goto next;
- }
- else
- sc.SetState(SCE_TCL_SUB_BRACE);
- if (!sc.atLineEnd)
- continue;
- } else if (sc.state == SCE_TCL_DEFAULT || sc.state ==SCE_TCL_OPERATOR) {
- expected &= isspacechar(static_cast<unsigned char>(sc.ch)) || IsAWordStart(sc.ch) || sc.ch =='#';
- } else if (sc.state == SCE_TCL_SUBSTITUTION) {
- switch(sc.ch) {
- case '(':
- subParen=true;
- sc.SetState(SCE_TCL_OPERATOR);
- sc.ForwardSetState(SCE_TCL_SUBSTITUTION);
- continue;
- case ')':
- sc.SetState(SCE_TCL_OPERATOR);
- subParen=false;
- continue;
- case '$':
- continue;
- case ',':
- sc.SetState(SCE_TCL_OPERATOR);
- if (subParen)
- sc.ForwardSetState(SCE_TCL_SUBSTITUTION);
- continue;
- default :
- // maybe spaces should be allowed ???
- if (!IsAWordChar(sc.ch)) { // probably the code is wrong
- sc.SetState(SCE_TCL_DEFAULT);
- subParen = 0;
- }
- break;
- }
- } else if (isComment(sc.state)) {
- } else if (!IsAWordChar(sc.ch)) {
- if ((sc.state == SCE_TCL_IDENTIFIER && expected) || sc.state == SCE_TCL_MODIFIER) {
- char w[100];
- char *s=w;
- sc.GetCurrent(w, sizeof(w));
- if (w[strlen(w)-1]=='\r')
- w[strlen(w)-1]=0;
- while(*s == ':') // ignore leading : like in ::set a 10
- ++s;
- bool quote = sc.state == SCE_TCL_IN_QUOTE;
- if (commentLevel || expected) {
- if (keywords.InList(s)) {
- sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD4);
- } else if (sc.GetRelative(-static_cast<int>(strlen(s))-1) == '{' &&
- keywords5.InList(s) && sc.ch == '}') { // {keyword} exactly no spaces
- sc.ChangeState(SCE_TCL_EXPAND);
- }
- if (keywords6.InList(s)) {
- sc.ChangeState(SCE_TCL_WORD5);
- } else if (keywords7.InList(s)) {
- sc.ChangeState(SCE_TCL_WORD6);
- } else if (keywords8.InList(s)) {
- sc.ChangeState(SCE_TCL_WORD7);
- } else if (keywords9.InList(s)) {
- sc.ChangeState(SCE_TCL_WORD8);
- }
- }
- expected = false;
- sc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT);
- } else if (sc.state == SCE_TCL_MODIFIER || sc.state == SCE_TCL_IDENTIFIER) {
- sc.SetState(SCE_TCL_DEFAULT);
- }
- }
- if (atEnd)
- break;
- if (sc.atLineEnd) {
- lineState = LS_DEFAULT;
- currentLine = styler.GetLine(sc.currentPos);
- if (foldComment && sc.state!=SCE_TCL_COMMENT && isComment(sc.state)) {
- if (currentLevel == 0) {
- ++currentLevel;
- commentLevel = true;
- }
- } else {
- if (visibleChars && commentLevel) {
- --currentLevel;
- --previousLevel;
- commentLevel = false;
- }
- }
- int flag = 0;
- if (!visibleChars)
- flag = SC_FOLDLEVELWHITEFLAG;
- if (currentLevel > previousLevel)
- flag = SC_FOLDLEVELHEADERFLAG;
- styler.SetLevel(currentLine, flag + previousLevel + SC_FOLDLEVELBASE + (currentLevel << 17) + (commentLevel << 16));
-
- // Update the line state, so it can be seen by next line
- if (sc.state == SCE_TCL_IN_QUOTE)
- lineState = LS_OPEN_DOUBLE_QUOTE;
- else {
- if (prevSlash) {
- if (isComment(sc.state))
- lineState = LS_OPEN_COMMENT;
- } else if (sc.state == SCE_TCL_COMMENT_BOX)
- lineState = LS_COMMENT_BOX;
- }
- styler.SetLineState(currentLine,
- (subBrace ? LS_BRACE_ONLY : 0) |
- (expected ? LS_COMMAND_EXPECTED : 0) | lineState);
- if (lineState == LS_COMMENT_BOX)
- sc.ForwardSetState(SCE_TCL_COMMENT_BOX);
- else if (lineState == LS_OPEN_DOUBLE_QUOTE)
- sc.ForwardSetState(SCE_TCL_IN_QUOTE);
- else
- sc.ForwardSetState(SCE_TCL_DEFAULT);
- prevSlash = false;
- previousLevel = currentLevel;
- goto next;
- }
-
- if (prevSlash) {
- prevSlash = false;
- if (sc.ch == '#' && IsANumberChar(sc.chNext))
- sc.ForwardSetState(SCE_TCL_NUMBER);
- continue;
- }
- prevSlash = sc.ch == '\\';
- if (isComment(sc.state))
- continue;
- if (sc.atLineStart) {
- visibleChars = false;
- if (sc.state!=SCE_TCL_IN_QUOTE && !isComment(sc.state))
- {
- sc.SetState(SCE_TCL_DEFAULT);
- expected = IsAWordStart(sc.ch)|| isspacechar(static_cast<unsigned char>(sc.ch));
- }
- }
-
- switch (sc.state) {
- case SCE_TCL_NUMBER:
- if (!IsANumberChar(sc.ch))
- sc.SetState(SCE_TCL_DEFAULT);
- break;
- case SCE_TCL_IN_QUOTE:
- if (sc.ch == '"') {
- sc.ForwardSetState(SCE_TCL_DEFAULT);
- visibleChars = true; // necessary if a " is the first and only character on a line
- goto next;
- } else if (sc.ch == '[' || sc.ch == ']' || sc.ch == '$') {
- sc.SetState(SCE_TCL_OPERATOR);
- expected = sc.ch == '[';
- sc.ForwardSetState(SCE_TCL_IN_QUOTE);
- goto next;
- }
- continue;
- case SCE_TCL_OPERATOR:
- sc.SetState(SCE_TCL_DEFAULT);
- break;
- }
-
- if (sc.ch == '#') {
- if (visibleChars) {
- if (sc.state != SCE_TCL_IN_QUOTE && expected)
- sc.SetState(SCE_TCL_COMMENT);
- } else {
- sc.SetState(SCE_TCL_COMMENTLINE);
- if (sc.chNext == '~')
- sc.SetState(SCE_TCL_BLOCK_COMMENT);
- if (sc.atLineStart && (sc.chNext == '#' || sc.chNext == '-'))
- sc.SetState(SCE_TCL_COMMENT_BOX);
- }
- }
-
- if (!isspacechar(static_cast<unsigned char>(sc.ch))) {
- visibleChars = true;
- }
-
- if (sc.ch == '\\') {
- prevSlash = true;
- continue;
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_TCL_DEFAULT) {
- if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_TCL_IDENTIFIER);
- } else if (IsADigit(sc.ch) && !IsAWordChar(sc.chPrev)) {
- sc.SetState(SCE_TCL_NUMBER);
- } else {
- switch (sc.ch) {
- case '\"':
- sc.SetState(SCE_TCL_IN_QUOTE);
- break;
- case '{':
- sc.SetState(SCE_TCL_OPERATOR);
- expected = true;
- ++currentLevel;
- break;
- case '}':
- sc.SetState(SCE_TCL_OPERATOR);
- --currentLevel;
- break;
- case '[':
- expected = true;
- case ']':
- case '(':
- case ')':
- sc.SetState(SCE_TCL_OPERATOR);
- break;
- case ';':
- expected = true;
- break;
- case '$':
- subParen = 0;
- if (sc.chNext != '{') {
- sc.SetState(SCE_TCL_SUBSTITUTION);
- }
- else {
- sc.SetState(SCE_TCL_OPERATOR); // $
- sc.Forward(); // {
- sc.ForwardSetState(SCE_TCL_SUB_BRACE);
- subBrace = true;
- }
- break;
- case '#':
- if ((isspacechar(static_cast<unsigned char>(sc.chPrev))||
- isoperator(static_cast<char>(sc.chPrev))) && IsADigit(sc.chNext,0x10))
- sc.SetState(SCE_TCL_NUMBER);
- break;
- case '-':
- sc.SetState(IsADigit(sc.chNext)? SCE_TCL_NUMBER: SCE_TCL_MODIFIER);
- break;
- default:
- if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_TCL_OPERATOR);
- }
- }
- }
- }
- }
- sc.Complete();
-}
-
-static const char * const tclWordListDesc[] = {
- "TCL Keywords",
- "TK Keywords",
- "iTCL Keywords",
- "tkCommands",
- "expand"
- "user1",
- "user2",
- "user3",
- "user4",
- 0
- };
-
-// this code supports folding in the colourizer
-LexerModule lmTCL(SCLEX_TCL, ColouriseTCLDoc, "tcl", 0, tclWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-
-// File: LexTeX.cxx - general context conformant tex coloring scheme
-// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
-// Version: September 28, 2003
-
-// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-// This lexer is derived from the one written for the texwork environment (1999++) which in
-// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).
-
-// If you run into strange boundary cases, just tell me and I'll look into it.
-
-
-// TeX Folding code added by instanton (soft_share@126.com) with borrowed code from VisualTeX source by Alex Romanenko.
-// Version: June 22, 2007
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-// val SCE_TEX_DEFAULT = 0
-// val SCE_TEX_SPECIAL = 1
-// val SCE_TEX_GROUP = 2
-// val SCE_TEX_SYMBOL = 3
-// val SCE_TEX_COMMAND = 4
-// val SCE_TEX_TEXT = 5
-
-// Definitions in SciTEGlobal.properties:
-//
-// TeX Highlighting
-//
-// # Default
-// style.tex.0=fore:#7F7F00
-// # Special
-// style.tex.1=fore:#007F7F
-// # Group
-// style.tex.2=fore:#880000
-// # Symbol
-// style.tex.3=fore:#7F7F00
-// # Command
-// style.tex.4=fore:#008800
-// # Text
-// style.tex.5=fore:#000000
-
-// lexer.tex.interface.default=0
-// lexer.tex.comment.process=0
-
-// todo: lexer.tex.auto.if
-
-// Auxiliary functions:
-
-static inline bool endOfLine(Accessor &styler, unsigned int i) {
- return
- (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
-}
-
-static inline bool isTeXzero(int ch) {
- return
- (ch == '%') ;
-}
-
-static inline bool isTeXone(int ch) {
- return
- (ch == '[') || (ch == ']') || (ch == '=') || (ch == '#') ||
- (ch == '(') || (ch == ')') || (ch == '<') || (ch == '>') ||
- (ch == '"') ;
-}
-
-static inline bool isTeXtwo(int ch) {
- return
- (ch == '{') || (ch == '}') || (ch == '$') ;
-}
-
-static inline bool isTeXthree(int ch) {
- return
- (ch == '~') || (ch == '^') || (ch == '_') || (ch == '&') ||
- (ch == '-') || (ch == '+') || (ch == '\"') || (ch == '`') ||
- (ch == '/') || (ch == '|') || (ch == '%') ;
-}
-
-static inline bool isTeXfour(int ch) {
- return
- (ch == '\\') ;
-}
-
-static inline bool isTeXfive(int ch) {
- return
- ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
- (ch == '@') || (ch == '!') || (ch == '?') ;
-}
-
-static inline bool isTeXsix(int ch) {
- return
- (ch == ' ') ;
-}
-
-static inline bool isTeXseven(int ch) {
- return
- (ch == '^') ;
-}
-
-// Interface determination
-
-static int CheckTeXInterface(
- unsigned int startPos,
- int length,
- Accessor &styler,
- int defaultInterface) {
-
- char lineBuffer[1024] ;
- unsigned int linePos = 0 ;
-
- // some day we can make something lexer.tex.mapping=(all,0)(nl,1)(en,2)...
-
- if (styler.SafeGetCharAt(0) == '%') {
- for (unsigned int i = 0; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
- if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
- lineBuffer[linePos] = '\0';
- if (strstr(lineBuffer, "interface=all")) {
- return 0 ;
- } else if (strstr(lineBuffer, "interface=tex")) {
- return 1 ;
- } else if (strstr(lineBuffer, "interface=nl")) {
- return 2 ;
- } else if (strstr(lineBuffer, "interface=en")) {
- return 3 ;
- } else if (strstr(lineBuffer, "interface=de")) {
- return 4 ;
- } else if (strstr(lineBuffer, "interface=cz")) {
- return 5 ;
- } else if (strstr(lineBuffer, "interface=it")) {
- return 6 ;
- } else if (strstr(lineBuffer, "interface=ro")) {
- return 7 ;
- } else if (strstr(lineBuffer, "interface=latex")) {
- // we will move latex cum suis up to 91+ when more keyword lists are supported
- return 8 ;
- } else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) {
- // better would be to limit the search to just one line
- return 3 ;
- } else {
- return defaultInterface ;
- }
- }
- }
- }
-
- return defaultInterface ;
-}
-
-static void ColouriseTeXDoc(
- unsigned int startPos,
- int length,
- int,
- WordList *keywordlists[],
- Accessor &styler) {
-
- styler.StartAt(startPos) ;
- styler.StartSegment(startPos) ;
-
- bool processComment = styler.GetPropertyInt("lexer.tex.comment.process", 0) == 1 ;
- bool useKeywords = styler.GetPropertyInt("lexer.tex.use.keywords", 1) == 1 ;
- bool autoIf = styler.GetPropertyInt("lexer.tex.auto.if", 1) == 1 ;
- int defaultInterface = styler.GetPropertyInt("lexer.tex.interface.default", 1) ;
-
- char key[100] ;
- int k ;
- bool newifDone = false ;
- bool inComment = false ;
-
- int currentInterface = CheckTeXInterface(startPos,length,styler,defaultInterface) ;
-
- if (currentInterface == 0) {
- useKeywords = false ;
- currentInterface = 1 ;
- }
-
- WordList &keywords = *keywordlists[currentInterface-1] ;
-
- StyleContext sc(startPos, length, SCE_TEX_TEXT, styler);
-
- bool going = sc.More() ; // needed because of a fuzzy end of file state
-
- for (; going; sc.Forward()) {
-
- if (! sc.More()) { going = false ; } // we need to go one behind the end of text
-
- if (inComment) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_TEX_TEXT) ;
- newifDone = false ;
- inComment = false ;
- }
- } else {
- if (! isTeXfive(sc.ch)) {
- if (sc.state == SCE_TEX_COMMAND) {
- if (sc.LengthCurrent() == 1) { // \<noncstoken>
- if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {
- sc.Forward(2) ; // \^^ and \^^<token>
- }
- sc.ForwardSetState(SCE_TEX_TEXT) ;
- } else {
- sc.GetCurrent(key, sizeof(key)-1) ;
- k = strlen(key) ;
- memmove(key,key+1,k) ; // shift left over escape token
- key[k] = '\0' ;
- k-- ;
- if (! keywords || ! useKeywords) {
- sc.SetState(SCE_TEX_COMMAND) ;
- newifDone = false ;
- } else if (k == 1) { //\<cstoken>
- sc.SetState(SCE_TEX_COMMAND) ;
- newifDone = false ;
- } else if (keywords.InList(key)) {
- sc.SetState(SCE_TEX_COMMAND) ;
- newifDone = autoIf && (strcmp(key,"newif") == 0) ;
- } else if (autoIf && ! newifDone && (key[0] == 'i') && (key[1] == 'f') && keywords.InList("if")) {
- sc.SetState(SCE_TEX_COMMAND) ;
- } else {
- sc.ChangeState(SCE_TEX_TEXT) ;
- sc.SetState(SCE_TEX_TEXT) ;
- newifDone = false ;
- }
- }
- }
- if (isTeXzero(sc.ch)) {
- sc.SetState(SCE_TEX_SYMBOL);
-
- if (!endOfLine(styler,sc.currentPos + 1))
- sc.ForwardSetState(SCE_TEX_DEFAULT) ;
-
- inComment = ! processComment ;
- newifDone = false ;
- } else if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {
- sc.SetState(SCE_TEX_TEXT) ;
- sc.ForwardSetState(SCE_TEX_TEXT) ;
- } else if (isTeXone(sc.ch)) {
- sc.SetState(SCE_TEX_SPECIAL) ;
- newifDone = false ;
- } else if (isTeXtwo(sc.ch)) {
- sc.SetState(SCE_TEX_GROUP) ;
- newifDone = false ;
- } else if (isTeXthree(sc.ch)) {
- sc.SetState(SCE_TEX_SYMBOL) ;
- newifDone = false ;
- } else if (isTeXfour(sc.ch)) {
- sc.SetState(SCE_TEX_COMMAND) ;
- } else if (isTeXsix(sc.ch)) {
- sc.SetState(SCE_TEX_TEXT) ;
- } else if (sc.atLineEnd) {
- sc.SetState(SCE_TEX_TEXT) ;
- newifDone = false ;
- inComment = false ;
- } else {
- sc.SetState(SCE_TEX_TEXT) ;
- }
- } else if (sc.state != SCE_TEX_COMMAND) {
- sc.SetState(SCE_TEX_TEXT) ;
- }
- }
- }
- sc.ChangeState(SCE_TEX_TEXT) ;
- sc.Complete();
-
-}
-
-
-static inline bool isNumber(int ch) {
- return
- (ch == '0') || (ch == '1') || (ch == '2') ||
- (ch == '3') || (ch == '4') || (ch == '5') ||
- (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9');
-}
-
-static inline bool isWordChar(int ch) {
- return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'));
-}
-
-static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command)
-{
- int length=0;
- char ch=styler.SafeGetCharAt(pos+1);
-
- if(ch==',' || ch==':' || ch==';' || ch=='%'){
- command[0]=ch;
- command[1]=0;
- return 1;
- }
-
- // find end
- while(isWordChar(ch) && !isNumber(ch) && ch!='_' && ch!='.' && length<100){
- command[length]=ch;
- length++;
- ch=styler.SafeGetCharAt(pos+length+1);
- }
-
- command[length]='\0';
- if(!length) return 0;
- return length+1;
-}
-
-static int classifyFoldPointTeXPaired(const char* s) {
- int lev=0;
- if (!(isdigit(s[0]) || (s[0] == '.'))){
- if (strcmp(s, "begin")==0||strcmp(s,"FoldStart")==0||
- strcmp(s,"abstract")==0||strcmp(s,"unprotect")==0||
- strcmp(s,"title")==0||strncmp(s,"start",5)==0||strncmp(s,"Start",5)==0||
- strcmp(s,"documentclass")==0||strncmp(s,"if",2)==0
- )
- lev=1;
- if (strcmp(s, "end")==0||strcmp(s,"FoldStop")==0||
- strcmp(s,"maketitle")==0||strcmp(s,"protect")==0||
- strncmp(s,"stop",4)==0||strncmp(s,"Stop",4)==0||
- strcmp(s,"fi")==0
- )
- lev=-1;
- }
- return lev;
-}
-
-static int classifyFoldPointTeXUnpaired(const char* s) {
- int lev=0;
- if (!(isdigit(s[0]) || (s[0] == '.'))){
- if (strcmp(s,"part")==0||
- strcmp(s,"chapter")==0||
- strcmp(s,"section")==0||
- strcmp(s,"subsection")==0||
- strcmp(s,"subsubsection")==0||
- strcmp(s,"CJKfamily")==0||
- strcmp(s,"appendix")==0||
- strcmp(s,"Topic")==0||strcmp(s,"topic")==0||
- strcmp(s,"subject")==0||strcmp(s,"subsubject")==0||
- strcmp(s,"def")==0||strcmp(s,"gdef")==0||strcmp(s,"edef")==0||
- strcmp(s,"xdef")==0||strcmp(s,"framed")==0||
- strcmp(s,"frame")==0||
- strcmp(s,"foilhead")==0||strcmp(s,"overlays")==0||strcmp(s,"slide")==0
- ){
- lev=1;
- }
- }
- return lev;
-}
-
-static bool IsTeXCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
-
- int startpos = pos;
-
- while (startpos<eol_pos){
- char ch = styler[startpos];
- if (ch!='%' && ch!=' ') return false;
- else if (ch=='%') return true;
- startpos++;
- }
-
- return false;
-}
-
-// FoldTeXDoc: borrowed from VisualTeX with modifications
-
-static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
-{
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- unsigned int endPos = startPos+length;
- int visibleChars=0;
- int lineCurrent=styler.GetLine(startPos);
- int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
- int levelCurrent=levelPrev;
- char chNext=styler[startPos];
- char buffer[100]="";
-
- for (unsigned int i=startPos; i < endPos; i++) {
- char ch=chNext;
- chNext=styler.SafeGetCharAt(i+1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if(ch=='\\') {
- ParseTeXCommand(i, styler, buffer);
- levelCurrent += classifyFoldPointTeXPaired(buffer)+classifyFoldPointTeXUnpaired(buffer);
- }
-
- if (levelCurrent > SC_FOLDLEVELBASE && ((ch == '\r' || ch=='\n') && (chNext == '\\'))) {
- ParseTeXCommand(i+1, styler, buffer);
- levelCurrent -= classifyFoldPointTeXUnpaired(buffer);
- }
-
- char chNext2;
- char chNext3;
- char chNext4;
- char chNext5;
- chNext2=styler.SafeGetCharAt(i+2);
- chNext3=styler.SafeGetCharAt(i+3);
- chNext4=styler.SafeGetCharAt(i+4);
- chNext5=styler.SafeGetCharAt(i+5);
-
- bool atEOfold = (ch == '%') &&
- (chNext == '%') && (chNext2=='}') &&
- (chNext3=='}')&& (chNext4=='-')&& (chNext5=='-');
-
- bool atBOfold = (ch == '%') &&
- (chNext == '%') && (chNext2=='-') &&
- (chNext3=='-')&& (chNext4=='{')&& (chNext5=='{');
-
- if(atBOfold){
- levelCurrent+=1;
- }
-
- if(atEOfold){
- levelCurrent-=1;
- }
-
- if(ch=='\\' && chNext=='['){
- levelCurrent+=1;
- }
-
- if(ch=='\\' && chNext==']'){
- levelCurrent-=1;
- }
-
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-
- if (foldComment && atEOL && IsTeXCommentLine(lineCurrent, styler))
- {
- if (lineCurrent==0 && IsTeXCommentLine(lineCurrent + 1, styler)
- )
- levelCurrent++;
- else if (lineCurrent!=0 && !IsTeXCommentLine(lineCurrent - 1, styler)
- && IsTeXCommentLine(lineCurrent + 1, styler)
- )
- levelCurrent++;
- else if (lineCurrent!=0 && IsTeXCommentLine(lineCurrent - 1, styler) &&
- !IsTeXCommentLine(lineCurrent+1, styler))
- levelCurrent--;
- }
-
-//---------------------------------------------------------------------------------------------
-
- if (atEOL) {
- int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
-
- if (!isspacechar(ch))
- visibleChars++;
- }
-
- // Fill in the real level of the next line, keeping the current flags as they will be filled in later
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-}
-
-
-
-
-static const char * const texWordListDesc[] = {
- "TeX, eTeX, pdfTeX, Omega",
- "ConTeXt Dutch",
- "ConTeXt English",
- "ConTeXt German",
- "ConTeXt Czech",
- "ConTeXt Italian",
- "ConTeXt Romanian",
- 0,
-} ;
-
-LexerModule lmTeX(SCLEX_TEX, ColouriseTeXDoc, "tex", FoldTexDoc, texWordListDesc);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexVB.cxx
- ** Lexer for Visual Basic and VBScript.
- **/
-// Copyright 1998-2005 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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
-
-// Internal state, highlighted as number
-#define SCE_B_FILENUMBER SCE_B_DEFAULT+100
-
-
-static bool IsVBComment(Accessor &styler, int pos, int len) {
- return len > 0 && styler[pos] == '\'';
-}
-
-static inline bool IsTypeCharacter(int ch) {
- return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
-}
-
-// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
- return ch >= 0x80 ||
- (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return ch >= 0x80 ||
- (isalpha(ch) || ch == '_');
-}
-
-static inline bool IsANumberChar(int ch) {
- // Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- return (ch < 0x80) &&
- (isdigit(ch) || toupper(ch) == 'E' ||
- ch == '.' || ch == '-' || ch == '+');
-}
-
-static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler, bool vbScriptSyntax) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- styler.StartAt(startPos);
-
- int visibleChars = 0;
- int fileNbDigits = 0;
-
- // Do not leak onto next line
- if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
- initStyle = SCE_B_DEFAULT;
- }
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.state == SCE_B_OPERATOR) {
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.state == SCE_B_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- // In Basic (except VBScript), a variable name or a function name
- // can end with a special character indicating the type of the value
- // held or returned.
- bool skipType = false;
- if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
- sc.Forward(); // Skip it
- skipType = true;
- }
- if (sc.ch == ']') {
- sc.Forward();
- }
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (skipType) {
- s[strlen(s) - 1] = '\0';
- }
- if (strcmp(s, "rem") == 0) {
- sc.ChangeState(SCE_B_COMMENT);
- } else {
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD4);
- } // Else, it is really an identifier...
- sc.SetState(SCE_B_DEFAULT);
- }
- }
- } else if (sc.state == SCE_B_NUMBER) {
- // We stop the number definition on non-numerical non-dot non-eE non-sign char
- // Also accepts A-F for hex. numbers
- if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
- sc.SetState(SCE_B_DEFAULT);
- }
- } else if (sc.state == SCE_B_STRING) {
- // VB doubles quotes to preserve them, so just end this string
- // state now as a following quote will start again
- if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
- sc.Forward();
- } else {
- if (tolower(sc.chNext) == 'c') {
- sc.Forward();
- }
- sc.ForwardSetState(SCE_B_DEFAULT);
- }
- } else if (sc.atLineEnd) {
- visibleChars = 0;
- sc.ChangeState(SCE_B_STRINGEOL);
- sc.ForwardSetState(SCE_B_DEFAULT);
- }
- } else if (sc.state == SCE_B_COMMENT) {
- if (sc.atLineEnd) {
- visibleChars = 0;
- sc.ForwardSetState(SCE_B_DEFAULT);
- }
- } else if (sc.state == SCE_B_PREPROCESSOR) {
- if (sc.atLineEnd) {
- visibleChars = 0;
- sc.ForwardSetState(SCE_B_DEFAULT);
- }
- } else if (sc.state == SCE_B_FILENUMBER) {
- if (IsADigit(sc.ch)) {
- fileNbDigits++;
- if (fileNbDigits > 3) {
- sc.ChangeState(SCE_B_DATE);
- }
- } else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
- // Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
- // Too bad if date is format #27, Oct, 2003# or something like that...
- // Use regular number state
- sc.ChangeState(SCE_B_NUMBER);
- sc.SetState(SCE_B_DEFAULT);
- } else if (sc.ch == '#') {
- sc.ChangeState(SCE_B_DATE);
- sc.ForwardSetState(SCE_B_DEFAULT);
- } else {
- sc.ChangeState(SCE_B_DATE);
- }
- if (sc.state != SCE_B_FILENUMBER) {
- fileNbDigits = 0;
- }
- } else if (sc.state == SCE_B_DATE) {
- if (sc.atLineEnd) {
- visibleChars = 0;
- sc.ChangeState(SCE_B_STRINGEOL);
- sc.ForwardSetState(SCE_B_DEFAULT);
- } else if (sc.ch == '#') {
- sc.ForwardSetState(SCE_B_DEFAULT);
- }
- }
-
- if (sc.state == SCE_B_DEFAULT) {
- if (sc.ch == '\'') {
- sc.SetState(SCE_B_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_B_STRING);
- } else if (sc.ch == '#' && visibleChars == 0) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_B_PREPROCESSOR);
- } else if (sc.ch == '#') {
- // It can be a date literal, ending with #, or a file number, from 1 to 511
- // The date literal depends on the locale, so anything can go between #'s.
- // Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
- // So we set the FILENUMBER state, and switch to DATE if it isn't a file number
- sc.SetState(SCE_B_FILENUMBER);
- } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
- // Hexadecimal number
- sc.SetState(SCE_B_NUMBER);
- sc.Forward();
- } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
- // Octal number
- sc.SetState(SCE_B_NUMBER);
- sc.Forward();
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_B_NUMBER);
- } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
- sc.SetState(SCE_B_IDENTIFIER);
- } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division
- sc.SetState(SCE_B_OPERATOR);
- }
- }
-
- if (sc.atLineEnd) {
- visibleChars = 0;
- }
- if (!IsASpace(sc.ch)) {
- visibleChars++;
- }
- }
-
- if (sc.state == SCE_B_IDENTIFIER && !IsAWordChar(sc.ch)) {
- // In Basic (except VBScript), a variable name or a function name
- // can end with a special character indicating the type of the value
- // held or returned.
- bool skipType = false;
- if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
- sc.Forward(); // Skip it
- skipType = true;
- }
- if (sc.ch == ']') {
- sc.Forward();
- }
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (skipType) {
- s[strlen(s) - 1] = '\0';
- }
- if (strcmp(s, "rem") == 0) {
- sc.ChangeState(SCE_B_COMMENT);
- } else {
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_B_KEYWORD4);
- } // Else, it is really an identifier...
- sc.SetState(SCE_B_DEFAULT);
- }
- }
-
- sc.Complete();
-}
-
-static void FoldVBDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- int endPos = startPos + length;
-
- // Backtrack to previous line in case need to fix its fold status
- int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);
- char chNext = styler[startPos];
- for (int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
- }
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- }
- }
-}
-
-static void ColouriseVBNetDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, false);
-}
-
-static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-static const char * const vbWordListDesc[] = {
- "Keywords",
- "user1",
- "user2",
- "user3",
- 0
-};
-
-LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
-LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexVHDL.cxx
- ** Lexer for VHDL
- ** Written by Phil Reid,
- ** Based on:
- ** - The Verilog Lexer by Avi Yegudin
- ** - The Fortran Lexer by Chuan-jian Shen
- ** - The C++ lexer by Neil Hodgson
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 void ColouriseVHDLDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler);
-
-
-/***************************************/
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' );
-}
-
-/***************************************/
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
-/***************************************/
-inline bool IsABlank(unsigned int ch) {
- return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
-}
-
-/***************************************/
-static void ColouriseVHDLDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
-{
- WordList &Keywords = *keywordlists[0];
- WordList &Operators = *keywordlists[1];
- WordList &Attributes = *keywordlists[2];
- WordList &Functions = *keywordlists[3];
- WordList &Packages = *keywordlists[4];
- WordList &Types = *keywordlists[5];
- WordList &User = *keywordlists[6];
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward())
- {
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_VHDL_OPERATOR) {
- sc.SetState(SCE_VHDL_DEFAULT);
- } else if (sc.state == SCE_VHDL_NUMBER) {
- if (!IsAWordChar(sc.ch) && (sc.ch != '#')) {
- sc.SetState(SCE_VHDL_DEFAULT);
- }
- } else if (sc.state == SCE_VHDL_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (Keywords.InList(s)) {
- sc.ChangeState(SCE_VHDL_KEYWORD);
- } else if (Operators.InList(s)) {
- sc.ChangeState(SCE_VHDL_STDOPERATOR);
- } else if (Attributes.InList(s)) {
- sc.ChangeState(SCE_VHDL_ATTRIBUTE);
- } else if (Functions.InList(s)) {
- sc.ChangeState(SCE_VHDL_STDFUNCTION);
- } else if (Packages.InList(s)) {
- sc.ChangeState(SCE_VHDL_STDPACKAGE);
- } else if (Types.InList(s)) {
- sc.ChangeState(SCE_VHDL_STDTYPE);
- } else if (User.InList(s)) {
- sc.ChangeState(SCE_VHDL_USERWORD);
- }
- sc.SetState(SCE_VHDL_DEFAULT);
- }
- } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_V_COMMENTLINEBANG) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_VHDL_DEFAULT);
- }
- } else if (sc.state == SCE_VHDL_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_VHDL_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_V_STRINGEOL);
- sc.ForwardSetState(SCE_VHDL_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_VHDL_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_VHDL_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_VHDL_IDENTIFIER);
- } else if (sc.Match('-', '-')) {
- sc.SetState(SCE_VHDL_COMMENT);
- sc.Forward();
- } else if (sc.Match('-', '-')) {
- if (sc.Match("--!")) // Nice to have a different comment style
- sc.SetState(SCE_VHDL_COMMENTLINEBANG);
- else
- sc.SetState(SCE_VHDL_COMMENT);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_VHDL_STRING);
- } else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_VHDL_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-//=============================================================================
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eol_pos; i++) {
- char ch = styler[i];
- char chNext = styler[i+1];
- if ((ch == '-') && (chNext == '-'))
- return true;
- else if (ch != ' ' && ch != '\t')
- return false;
- }
- return false;
-}
-
-//=============================================================================
-// Folding the code
-static void FoldNoBoxVHDLDoc(
- unsigned int startPos,
- int length,
- int initStyle,
- Accessor &styler)
-{
- // Decided it would be smarter to have the lexer have all keywords included. Therefore I
- // don't check if the style for the keywords that I use to adjust the levels.
- char words[] =
- "architecture begin case component else elsif end entity generate loop package process record then "
- "procedure function when";
- WordList keywords;
- keywords.Set(words);
-
- bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 1) != 0;
- bool foldAtBegin = styler.GetPropertyInt("fold.at.Begin", 1) != 0;
- bool foldAtParenthese = styler.GetPropertyInt("fold.at.Parenthese", 1) != 0;
- //bool foldAtWhen = styler.GetPropertyInt("fold.at.When", 1) != 0; //< fold at when in case statements
-
- int visibleChars = 0;
- unsigned int endPos = startPos + length;
-
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if(lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- //int levelMinCurrent = levelCurrent;
- int levelMinCurrentElse = levelCurrent; //< Used for folding at 'else'
- int levelMinCurrentBegin = levelCurrent; //< Used for folding at 'begin'
- int levelNext = levelCurrent;
-
- /***************************************/
- int lastStart = 0;
- char prevWord[32] = "";
-
- /***************************************/
- // Find prev word
- // The logic for going up or down a level depends on a the previous keyword
- // This code could be cleaned up.
- int end = 0;
- unsigned int j;
- for(j = startPos; j>0; j--)
- {
- char ch = styler.SafeGetCharAt(j);
- char chPrev = styler.SafeGetCharAt(j-1);
- int style = styler.StyleAt(j);
- int stylePrev = styler.StyleAt(j-1);
- if ((stylePrev != SCE_VHDL_COMMENT) && (stylePrev != SCE_VHDL_STRING))
- {
- if(IsAWordChar(chPrev) && !IsAWordChar(ch))
- {
- end = j-1;
- }
- }
- if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
- {
- if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0))
- {
- char s[32];
- unsigned int k;
- for(k=0; (k<31 ) && (k<end-j+1 ); k++) {
- s[k] = static_cast<char>(tolower(styler[j+k]));
- }
- s[k] = '\0';
-
- if(keywords.InList(s)) {
- strcpy(prevWord, s);
- break;
- }
- }
- }
- }
- for(j=j+strlen(prevWord); j<endPos; j++)
- {
- char ch = styler.SafeGetCharAt(j);
- int style = styler.StyleAt(j);
- if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
- {
- if((ch == ';') && (strcmp(prevWord, "end") == 0))
- {
- strcpy(prevWord, ";");
- }
- }
- }
-
- char chNext = styler[startPos];
- char chPrev = '\0';
- char chNextNonBlank;
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- //Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent);
-
- /***************************************/
- for (unsigned int i = startPos; i < endPos; i++)
- {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- chPrev = styler.SafeGetCharAt(i - 1);
- chNextNonBlank = chNext;
- unsigned int j = i+1;
- while(IsABlank(chNextNonBlank) && j<endPos)
- {
- j ++ ;
- chNextNonBlank = styler.SafeGetCharAt(j);
- }
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
- if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
- {
- if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler))
- {
- levelNext++;
- }
- else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler))
- {
- levelNext--;
- }
- }
-
- if ((style == SCE_VHDL_OPERATOR) && foldAtParenthese)
- {
- if(ch == '(') {
- levelNext++;
- } else if (ch == ')') {
- levelNext--;
- }
- }
-
- if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
- {
- if((ch == ';') && (strcmp(prevWord, "end") == 0))
- {
- strcpy(prevWord, ";");
- }
-
- if(!IsAWordChar(chPrev) && IsAWordStart(ch))
- {
- lastStart = i;
- }
-
- if(iswordchar(ch) && !iswordchar(chNext)) {
- char s[32];
- unsigned int k;
- for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
- s[k] = static_cast<char>(tolower(styler[lastStart+k]));
- }
- s[k] = '\0';
-
- if(keywords.InList(s))
- {
- if (
- strcmp(s, "architecture") == 0 ||
- strcmp(s, "case") == 0 ||
- strcmp(s, "component") == 0 ||
- strcmp(s, "entity") == 0 ||
- strcmp(s, "generate") == 0 ||
- strcmp(s, "loop") == 0 ||
- strcmp(s, "package") ==0 ||
- strcmp(s, "process") == 0 ||
- strcmp(s, "record") == 0 ||
- strcmp(s, "then") == 0)
- {
- if (strcmp(prevWord, "end") != 0)
- {
- if (levelMinCurrentElse > levelNext) {
- levelMinCurrentElse = levelNext;
- }
- levelNext++;
- }
- } else if (
- strcmp(s, "procedure") == 0 ||
- strcmp(s, "function") == 0)
- {
- if (strcmp(prevWord, "end") != 0) // check for "end procedure" etc.
- { // This code checks to see if the procedure / function is a definition within a "package"
- // rather than the actual code in the body.
- int BracketLevel = 0;
- for(int j=i+1; j<styler.Length(); j++)
- {
- int LocalStyle = styler.StyleAt(j);
- char LocalCh = styler.SafeGetCharAt(j);
- if(LocalCh == '(') BracketLevel++;
- if(LocalCh == ')') BracketLevel--;
- if(
- (BracketLevel == 0) &&
- (LocalStyle != SCE_VHDL_COMMENT) &&
- (LocalStyle != SCE_VHDL_STRING) &&
- !iswordchar(styler.SafeGetCharAt(j-1)) &&
- styler.Match(j, "is") &&
- !iswordchar(styler.SafeGetCharAt(j+2)))
- {
- if (levelMinCurrentElse > levelNext) {
- levelMinCurrentElse = levelNext;
- }
- levelNext++;
- break;
- }
- if((BracketLevel == 0) && (LocalCh == ';'))
- {
- break;
- }
- }
- }
-
- } else if (strcmp(s, "end") == 0) {
- levelNext--;
- } else if(strcmp(s, "elsif") == 0) { // elsif is followed by then so folding occurs correctly
- levelNext--;
- } else if (strcmp(s, "else") == 0) {
- if(strcmp(prevWord, "when") != 0) // ignore a <= x when y else z;
- {
- levelMinCurrentElse = levelNext - 1; // VHDL else is all on its own so just dec. the min level
- }
- } else if(
- ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "architecture") == 0)) ||
- ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) ||
- ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0)))
- {
- levelMinCurrentBegin = levelNext - 1;
- }
- //Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent);
- strcpy(prevWord, s);
- }
- }
- }
- if (atEOL) {
- int levelUse = levelCurrent;
-
- if (foldAtElse && (levelMinCurrentElse < levelUse)) {
- levelUse = levelMinCurrentElse;
- }
- if (foldAtBegin && (levelMinCurrentBegin < levelUse)) {
- levelUse = levelMinCurrentBegin;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
-
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- //Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent);
- lineCurrent++;
- levelCurrent = levelNext;
- //levelMinCurrent = levelCurrent;
- levelMinCurrentElse = levelCurrent;
- levelMinCurrentBegin = levelCurrent;
- visibleChars = 0;
- }
- /***************************************/
- if (!isspacechar(ch)) visibleChars++;
- }
-
- /***************************************/
-// Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent);
-}
-
-//=============================================================================
-static void FoldVHDLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- FoldNoBoxVHDLDoc(startPos, length, initStyle, styler);
-}
-
-//=============================================================================
-static const char * const VHDLWordLists[] = {
- "Keywords",
- "Operators",
- "Attributes",
- "Standard Functions",
- "Standard Packages",
- "Standard Types",
- "User Words",
- 0,
- };
-
-
-LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, "vhdl", FoldVHDLDoc, VHDLWordLists);
-
-
-// Keyword:
-// access after alias all architecture array assert attribute begin block body buffer bus case component
-// configuration constant disconnect downto else elsif end entity exit file for function generate generic
-// group guarded if impure in inertial inout is label library linkage literal loop map new next null of
-// on open others out package port postponed procedure process pure range record register reject report
-// return select severity shared signal subtype then to transport type unaffected units until use variable
-// wait when while with
-//
-// Operators:
-// abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor
-//
-// Attributes:
-// left right low high ascending image value pos val succ pred leftof rightof base range reverse_range
-// length delayed stable quiet transaction event active last_event last_active last_value driving
-// driving_value simple_name path_name instance_name
-//
-// Std Functions:
-// now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector
-// to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left
-// rotate_right resize to_integer to_unsigned to_signed std_match to_01
-//
-// Std Packages:
-// std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed
-// std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives
-// vital_timing
-//
-// Std Types:
-// boolean bit character severity_level integer real time delay_length natural positive string bit_vector
-// file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic
-// std_logic_vector X01 X01Z UX01 UX01Z unsigned signed
-//
-
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexVerilog.cxx
- ** Lexer for Verilog.
- ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson
- **/
-// Copyright 1998-2002 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 <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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 inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
-}
-
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '$');
-}
-
-static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
-
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
-
- // Do not leak onto next line
- if (initStyle == SCE_V_STRINGEOL)
- initStyle = SCE_V_DEFAULT;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- for (; sc.More(); sc.Forward()) {
-
- if (sc.atLineStart && (sc.state == SCE_V_STRING)) {
- // Prevent SCE_V_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_V_STRING);
- }
-
- // Handle line continuation generically.
- if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- continue;
- }
- }
-
- // Determine if the current state should terminate.
- if (sc.state == SCE_V_OPERATOR) {
- sc.SetState(SCE_V_DEFAULT);
- } else if (sc.state == SCE_V_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_V_DEFAULT);
- }
- } else if (sc.state == SCE_V_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_V_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_V_WORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_V_WORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_V_USER);
- }
- sc.SetState(SCE_V_DEFAULT);
- }
- } else if (sc.state == SCE_V_PREPROCESSOR) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_V_DEFAULT);
- }
- } else if (sc.state == SCE_V_COMMENT) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_V_DEFAULT);
- }
- } else if (sc.state == SCE_V_COMMENTLINE || sc.state == SCE_V_COMMENTLINEBANG) {
- if (sc.atLineStart) {
- sc.SetState(SCE_V_DEFAULT);
- }
- } else if (sc.state == SCE_V_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
- sc.Forward();
- }
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_V_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_V_STRINGEOL);
- sc.ForwardSetState(SCE_V_DEFAULT);
- }
- }
-
- // Determine if a new state should be entered.
- if (sc.state == SCE_V_DEFAULT) {
- if (IsADigit(sc.ch) || (sc.ch == '\'') || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_V_NUMBER);
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_V_IDENTIFIER);
- } else if (sc.Match('/', '*')) {
- sc.SetState(SCE_V_COMMENT);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- } else if (sc.Match('/', '/')) {
- if (sc.Match("//!")) // Nice to have a different comment style
- sc.SetState(SCE_V_COMMENTLINEBANG);
- else
- sc.SetState(SCE_V_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_V_STRING);
- } else if (sc.ch == '`') {
- sc.SetState(SCE_V_PREPROCESSOR);
- // Skip whitespace between ` and preprocessor word
- do {
- sc.Forward();
- } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.atLineEnd) {
- sc.SetState(SCE_V_DEFAULT);
- }
- } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') {
- sc.SetState(SCE_V_OPERATOR);
- }
- }
- }
- sc.Complete();
-}
-
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_V_COMMENT;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment
-// and to make it possible to fiddle the current level for "} else {".
-static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle,
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
- // Verilog specific folding options:
- // fold_at_module -
- // Generally used methodology in verilog code is
- // one module per file, so folding at module definition is useless.
- // fold_at_brace/parenthese -
- // Folding of long port lists can be convenient.
- bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0;
- bool foldAtBrace = 1;
- bool foldAtParenthese = 1;
-
- unsigned int endPos = startPos + length;
- int visibleChars = 0;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- for (unsigned int i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- int stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev)) {
- levelNext++;
- } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- }
- if (foldComment && (style == SCE_V_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelNext++;
- } else if (chNext2 == '}') {
- levelNext--;
- }
- }
- }
- if (foldPreprocessor && (style == SCE_V_PREPROCESSOR)) {
- if (ch == '`') {
- unsigned int j = i + 1;
- while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- if (styler.Match(j, "if")) {
- levelNext++;
- } else if (styler.Match(j, "end")) {
- levelNext--;
- }
- }
- }
- if (style == SCE_V_OPERATOR) {
- if (foldAtParenthese) {
- if (ch == '(') {
- levelNext++;
- } else if (ch == ')') {
- levelNext--;
- }
- }
- }
- if (style == SCE_V_OPERATOR) {
- if (foldAtBrace) {
- if (ch == '{') {
- levelNext++;
- } else if (ch == '}') {
- levelNext--;
- }
- }
- }
- if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) {
- unsigned int j = i;
- if (styler.Match(j, "case") ||
- styler.Match(j, "casex") ||
- styler.Match(j, "casez") ||
- styler.Match(j, "function") ||
- styler.Match(j, "fork") ||
- styler.Match(j, "table") ||
- styler.Match(j, "task") ||
- styler.Match(j, "generate") ||
- styler.Match(j, "specify") ||
- styler.Match(j, "primitive") ||
- (styler.Match(j, "module") && foldAtModule) ||
- styler.Match(j, "begin")) {
- levelNext++;
- } else if (styler.Match(j, "endcase") ||
- styler.Match(j, "endfunction") ||
- styler.Match(j, "join") ||
- styler.Match(j, "endtask") ||
- styler.Match(j, "endgenerate") ||
- styler.Match(j, "endtable") ||
- styler.Match(j, "endspecify") ||
- styler.Match(j, "endprimitive") ||
- (styler.Match(j, "endmodule") && foldAtModule) ||
- (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
- levelNext--;
- }
- }
- if (atEOL) {
- int levelUse = levelCurrent;
- if (foldAtElse) {
- levelUse = levelMinCurrent;
- }
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
-}
-
-static void FoldVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *[],
- Accessor &styler) {
- FoldNoBoxVerilogDoc(startPos, length, initStyle, styler);
-}
-
-static const char * const verilogWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "System Tasks",
- "User defined tasks and identifiers",
- "Unused",
- 0,
- };
-
-
-LexerModule lmVerilog(SCLEX_VERILOG, ColouriseVerilogDoc, "verilog", FoldVerilogDoc, verilogWordLists);
+++ /dev/null
-// Scintilla source code edit control
-/** @file LexYAML.cxx
- ** Lexer for YAML.
- **/
-// Copyright 2003- by Sean O'Dell <sean@celsoft.com>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#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));
- const int comment_continue = (comment && prevComment);
- if (!comment)
- indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
- if (indentNext & SC_FOLDLEVELWHITEFLAG)
- indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
-
- if (comment_start) {
- // Place fold point at start of a block of comments
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (comment_continue) {
- // Add level to rest of lines in the block
- lev = lev + 1;
- }
-
- // Skip past any blank lines for next indent level info; we skip also
- // comments (all comments, not just those starting in column 0)
- // which effectively folds them into surrounding code rather
- // than screwing up folding.
-
- while ((lineNext < docLines) &&
- ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
- (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
-
- lineNext++;
- indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
- }
-
- const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
- const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
-
- // Now set all the indent levels on the lines we skipped
- // Do this from end to start. Once we encounter one line
- // which is indented more than the line after the end of
- // the comment-block, use the level of the block before
-
- int skipLine = lineNext;
- int skipLevel = levelAfterComments;
-
- while (--skipLine > lineCurrent) {
- int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
-
- if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
- skipLevel = levelBeforeComments;
-
- int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
-
- styler.SetLevel(skipLine, skipLevel | whiteFlag);
- }
-
- // Set fold header on non-comment line
- if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
-
- // Keep track of block comment state of previous line
- prevComment = comment_start || comment_continue;
-
- // Set fold level for this line and move to next line
- styler.SetLevel(lineCurrent, lev);
- indentCurrent = indentNext;
- lineCurrent = lineNext;
- }
-
- // NOTE: Cannot set level of last line here because indentCurrent doesn't have
- // header flag set; the loop above is crafted to take care of this case!
- //styler.SetLevel(lineCurrent, indentCurrent);
-}
-
-LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, "yaml", FoldYAMLDoc, yamlWordListDesc);
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "Scintilla.h"
using namespace Scintilla;
#endif
-void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
- pal.WantFind(fore, want);
- pal.WantFind(back, want);
- if (pxpm) {
- pxpm->RefreshColourPalette(pal, want);
- }
-}
-
void LineMarker::SetXPM(const char *textForm) {
delete pxpm;
pxpm = new XPM(textForm);
markType = SC_MARK_PIXMAP;
}
-void LineMarker::SetXPM(const char * const *linesForm) {
+void LineMarker::SetXPM(const char *const *linesForm) {
delete pxpm;
pxpm = new XPM(linesForm);
markType = SC_MARK_PIXMAP;
}
-static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
+void LineMarker::SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage) {
+ delete image;
+ image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, pixelsRGBAImage);
+ markType = SC_MARK_RGBAIMAGE;
+}
+
+static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) {
PRectangle rc;
rc.left = centreX - armSize;
rc.top = centreY - armSize;
surface->RectangleDraw(rc, back, fore);
}
-static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
+static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) {
PRectangle rcCircle;
rcCircle.left = centreX - armSize;
rcCircle.top = centreY - armSize;
surface->Ellipse(rcCircle, back, fore);
}
-static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
+static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) {
PRectangle rcV(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1);
surface->FillRectangle(rcV, fore);
PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
surface->FillRectangle(rcH, fore);
}
-static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
+static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) {
PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
surface->FillRectangle(rcH, fore);
}
-void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
+void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) {
+ ColourDesired head = back;
+ ColourDesired body = back;
+ ColourDesired tail = back;
+
+ switch (tFold) {
+ case LineMarker::head :
+ case LineMarker::headWithTail :
+ head = backSelected;
+ tail = backSelected;
+ break;
+ case LineMarker::body :
+ head = backSelected;
+ body = backSelected;
+ break;
+ case LineMarker::tail :
+ body = backSelected;
+ tail = backSelected;
+ break;
+ default :
+ // LineMarker::undefined
+ break;
+ }
+
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole);
return;
}
+ if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
+ // Make rectangle just large enough to fit image centred on centre of rcWhole
+ PRectangle rcImage;
+ rcImage.top = static_cast<int>(((rcWhole.top + rcWhole.bottom) - image->GetHeight()) / 2);
+ rcImage.bottom = rcImage.top + image->GetHeight();
+ rcImage.left = static_cast<int>(((rcWhole.left + rcWhole.right) - image->GetWidth()) / 2);
+ rcImage.right = rcImage.left + image->GetWidth();
+ surface->DrawRGBAImage(rcImage, image->GetWidth(), image->GetHeight(), image->Pixels());
+ return;
+ }
// Restrict most shapes a bit
PRectangle rc = rcWhole;
rc.top++;
int dimOn4 = minDim / 4;
int blobSize = dimOn2-1;
int armSize = dimOn2-2;
- if (rc.Width() > (rc.Height() * 2)) {
- // Wide column is line number so move to left to try to avoid overlapping number
+ if (marginStyle == SC_MARGIN_NUMBER || marginStyle == SC_MARGIN_TEXT || marginStyle == SC_MARGIN_RTEXT) {
+ // On textual margins move marker to the left to try to avoid overlapping the text
centreX = rc.left + dimOn2 + 1;
}
if (markType == SC_MARK_ROUNDRECT) {
PRectangle rcRounded = rc;
rcRounded.left = rc.left + 1;
rcRounded.right = rc.right - 1;
- surface->RoundedRectangle(rcRounded, fore.allocated, back.allocated);
+ surface->RoundedRectangle(rcRounded, fore, back);
} else if (markType == SC_MARK_CIRCLE) {
PRectangle rcCircle;
rcCircle.left = centreX - dimOn2;
rcCircle.top = centreY - dimOn2;
rcCircle.right = centreX + dimOn2;
rcCircle.bottom = centreY + dimOn2;
- surface->Ellipse(rcCircle, fore.allocated, back.allocated);
+ surface->Ellipse(rcCircle, fore, back);
} else if (markType == SC_MARK_ARROW) {
Point pts[] = {
Point(centreX - dimOn4, centreY - dimOn2),
Point(centreX + dimOn2 - dimOn4, centreY),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- fore.allocated, back.allocated);
+ fore, back);
} else if (markType == SC_MARK_ARROWDOWN) {
Point pts[] = {
Point(centreX, centreY + dimOn2 - dimOn4),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- fore.allocated, back.allocated);
+ fore, back);
} else if (markType == SC_MARK_PLUS) {
Point pts[] = {
Point(centreX - armSize, centreY + 1),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- fore.allocated, back.allocated);
+ fore, back);
} else if (markType == SC_MARK_MINUS) {
Point pts[] = {
Point(centreX - armSize, centreY + 1),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- fore.allocated, back.allocated);
+ fore, back);
} else if (markType == SC_MARK_SMALLRECT) {
PRectangle rcSmall;
rcSmall.top = rc.top + 2;
rcSmall.right = rc.right - 1;
rcSmall.bottom = rc.bottom - 2;
- surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
+ surface->RectangleDraw(rcSmall, fore, back);
- } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
+ } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
// An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) {
- surface->PenColour(back.allocated);
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
- surface->PenColour(back.allocated);
+ surface->PenColour(tail);
surface->MoveTo(centreX, rcWhole.top);
- surface->LineTo(centreX, rc.top + dimOn2);
- surface->LineTo(rc.right - 2, rc.top + dimOn2);
+ surface->LineTo(centreX, centreY);
+ surface->LineTo(rc.right - 1, centreY);
} else if (markType == SC_MARK_TCORNER) {
- surface->PenColour(back.allocated);
+ surface->PenColour(tail);
+ surface->MoveTo(centreX, centreY);
+ surface->LineTo(rc.right - 1, centreY);
+
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
+ surface->LineTo(centreX, centreY + 1);
+
+ surface->PenColour(head);
surface->LineTo(centreX, rcWhole.bottom);
- surface->MoveTo(centreX, rc.top + dimOn2);
- surface->LineTo(rc.right - 2, rc.top + dimOn2);
} else if (markType == SC_MARK_LCORNERCURVE) {
- surface->PenColour(back.allocated);
+ surface->PenColour(tail);
surface->MoveTo(centreX, rcWhole.top);
- surface->LineTo(centreX, rc.top + dimOn2-3);
- surface->LineTo(centreX+3, rc.top + dimOn2);
- surface->LineTo(rc.right - 1, rc.top + dimOn2);
+ surface->LineTo(centreX, centreY-3);
+ surface->LineTo(centreX+3, centreY);
+ surface->LineTo(rc.right - 1, centreY);
} else if (markType == SC_MARK_TCORNERCURVE) {
- surface->PenColour(back.allocated);
+ surface->PenColour(tail);
+ surface->MoveTo(centreX, centreY-3);
+ surface->LineTo(centreX+3, centreY);
+ surface->LineTo(rc.right - 1, centreY);
+
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
- surface->LineTo(centreX, rcWhole.bottom);
+ surface->LineTo(centreX, centreY-2);
- surface->MoveTo(centreX, rc.top + dimOn2-3);
- surface->LineTo(centreX+3, rc.top + dimOn2);
- surface->LineTo(rc.right - 1, rc.top + dimOn2);
+ surface->PenColour(head);
+ surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXPLUS) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawBox(surface, centreX, centreY, blobSize, fore, head);
+ DrawPlus(surface, centreX, centreY, blobSize, tail);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-
+ if (tFold == LineMarker::headWithTail)
+ surface->PenColour(tail);
+ else
+ surface->PenColour(body);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
+ DrawBox(surface, centreX, centreY, blobSize, fore, head);
+ DrawPlus(surface, centreX, centreY, blobSize, tail);
+
+ if (tFold == LineMarker::body) {
+ surface->PenColour(tail);
+ surface->MoveTo(centreX + 1, centreY + blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
+
+ surface->MoveTo(centreX + blobSize, centreY + blobSize);
+ surface->LineTo(centreX + blobSize, centreY - blobSize);
+
+ surface->MoveTo(centreX + 1, centreY - blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
+ }
} else if (markType == SC_MARK_BOXMINUS) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawBox(surface, centreX, centreY, blobSize, fore, head);
+ DrawMinus(surface, centreX, centreY, blobSize, tail);
+ surface->PenColour(head);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawBox(surface, centreX, centreY, blobSize, fore, head);
+ DrawMinus(surface, centreX, centreY, blobSize, tail);
+ surface->PenColour(head);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
+ if (tFold == LineMarker::body) {
+ surface->PenColour(tail);
+ surface->MoveTo(centreX + 1, centreY + blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
+
+ surface->MoveTo(centreX + blobSize, centreY + blobSize);
+ surface->LineTo(centreX + blobSize, centreY - blobSize);
+
+ surface->MoveTo(centreX + 1, centreY - blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
+ }
} else if (markType == SC_MARK_CIRCLEPLUS) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawCircle(surface, centreX, centreY, blobSize, fore, head);
+ DrawPlus(surface, centreX, centreY, blobSize, tail);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-
+ if (tFold == LineMarker::headWithTail)
+ surface->PenColour(tail);
+ else
+ surface->PenColour(body);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
+ DrawCircle(surface, centreX, centreY, blobSize, fore, head);
+ DrawPlus(surface, centreX, centreY, blobSize, tail);
+
} else if (markType == SC_MARK_CIRCLEMINUS) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawCircle(surface, centreX, centreY, blobSize, fore, head);
+ DrawMinus(surface, centreX, centreY, blobSize, tail);
+ surface->PenColour(head);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawCircle(surface, centreX, centreY, blobSize, fore, head);
+ DrawMinus(surface, centreX, centreY, blobSize, tail);
+ surface->PenColour(head);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType >= SC_MARK_CHARACTER) {
char character[1];
character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
- int width = surface->WidthText(fontForCharacter, character, 1);
+ XYPOSITION width = surface->WidthText(fontForCharacter, character, 1);
rc.left += (rc.Width() - width) / 2;
rc.right = rc.left + width;
surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
- character, 1, fore.allocated, back.allocated);
+ character, 1, fore, back);
} else if (markType == SC_MARK_DOTDOTDOT) {
int right = centreX - 6;
for (int b=0; b<3; b++) {
PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
- surface->FillRectangle(rcBlob, fore.allocated);
+ surface->FillRectangle(rcBlob, fore);
right += 5;
}
} else if (markType == SC_MARK_ARROWS) {
- surface->PenColour(fore.allocated);
+ surface->PenColour(fore);
int right = centreX - 2;
for (int b=0; b<3; b++) {
surface->MoveTo(right - 4, centreY - 4);
Point(centreX, centreY + dimOn2),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
- fore.allocated, back.allocated);
+ fore, back);
} else if (markType == SC_MARK_LEFTRECT) {
PRectangle rcLeft = rcWhole;
rcLeft.right = rcLeft.left + 4;
- surface->FillRectangle(rcLeft, back.allocated);
+ surface->FillRectangle(rcLeft, back);
} else { // SC_MARK_FULLRECT
- surface->FillRectangle(rcWhole, back.allocated);
+ surface->FillRectangle(rcWhole, back);
}
}
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
namespace Scintilla {
#endif
+
/**
*/
class LineMarker {
public:
+ enum typeOfFold { undefined, head, body, tail, headWithTail };
+
int markType;
- ColourPair fore;
- ColourPair back;
+ ColourDesired fore;
+ ColourDesired back;
+ ColourDesired backSelected;
int alpha;
XPM *pxpm;
+ RGBAImage *image;
LineMarker() {
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
+ backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
+ image = NULL;
}
LineMarker(const LineMarker &) {
- // Defined to avoid pxpm being blindly copied, not as real copy constructor
+ // Defined to avoid pxpm being blindly copied, not as a complete copy constructor
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
+ backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
+ image = NULL;
}
~LineMarker() {
delete pxpm;
+ delete image;
}
- LineMarker &operator=(const LineMarker &) {
- // Defined to avoid pxpm being blindly copied, not as real assignment operator
- markType = SC_MARK_CIRCLE;
- fore = ColourDesired(0,0,0);
- back = ColourDesired(0xff,0xff,0xff);
- alpha = SC_ALPHA_NOALPHA;
- delete pxpm;
- pxpm = NULL;
+ LineMarker &operator=(const LineMarker &other) {
+ // Defined to avoid pxpm being blindly copied, not as a complete assignment operator
+ if (this != &other) {
+ markType = SC_MARK_CIRCLE;
+ fore = ColourDesired(0,0,0);
+ back = ColourDesired(0xff,0xff,0xff);
+ backSelected = ColourDesired(0xff,0x00,0x00);
+ alpha = SC_ALPHA_NOALPHA;
+ delete pxpm;
+ pxpm = NULL;
+ delete image;
+ image = NULL;
+ }
return *this;
}
- void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm);
- void SetXPM(const char * const *linesForm);
- void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
+ void SetXPM(const char *const *linesForm);
+ void SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage);
+ void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold, int marginStyle);
};
#ifdef SCI_NAMESPACE
#ifndef PARTITIONING_H
#define PARTITIONING_H
-/// A split vector of integers with a method for adding a value to all elements
+/// A split vector of integers with a method for adding a value to all elements
/// in a range.
/// Used by the Partitioning class.
/// Divide an interval into multiple partitions.
/// Useful for breaking a document down into sections such as lines.
+/// A 0 length interval has a single 0 length partition, numbered 0
+/// If interval not 0 length then each partition non-zero length
+/// When needed, positions after the interval are considered part of the last partition
+/// but the end of the last partition can be found with PositionFromPartition(last+1).
class Partitioning {
private:
return pos;
}
+ /// Return value in range [0 .. Partitions() - 1] even for arguments outside interval
int PartitionFromPosition(int pos) const {
if (body->Length() <= 1)
return 0;
}
}
-bool MarkerHandleSet::RemoveNumber(int markerNum) {
+bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) {
bool performedDeletion = false;
MarkerHandleNumber **pmhn = &root;
while (*pmhn) {
*pmhn = mhn->next;
delete mhn;
performedDeletion = true;
+ if (!all)
+ break;
} else {
pmhn = &((*pmhn)->next);
}
return 0;
}
+int LineMarkers::MarkerNext(int lineStart, int mask) const {
+ if (lineStart < 0)
+ lineStart = 0;
+ int length = markers.Length();
+ for (int iLine = lineStart; iLine < length; iLine++) {
+ MarkerHandleSet *onLine = markers[iLine];
+ if (onLine && ((onLine->MarkValue() & mask) != 0))
+ //if ((pdoc->GetMark(iLine) & lParam) != 0)
+ return iLine;
+ }
+ return -1;
+}
+
int LineMarkers::AddMark(int line, int markerNum, int lines) {
handleCurrent++;
if (!markers.Length()) {
return handleCurrent;
}
-void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+bool LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+ bool someChanges = false;
if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
if (markerNum == -1) {
+ someChanges = true;
delete markers[line];
markers[line] = NULL;
} else {
- bool performedDeletion = markers[line]->RemoveNumber(markerNum);
- while (all && performedDeletion) {
- performedDeletion = markers[line]->RemoveNumber(markerNum);
- }
+ someChanges = markers[line]->RemoveNumber(markerNum, all);
if (markers[line]->Length() == 0) {
delete markers[line];
markers[line] = NULL;
}
}
}
+ return someChanges;
}
void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
void LineLevels::InsertLine(int line) {
if (levels.Length()) {
- int level = SC_FOLDLEVELBASE;
- if ((line > 0) && (line < levels.Length())) {
- level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
- }
+ int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE;
levels.InsertValue(line, 1, level);
}
}
void LineState::InsertLine(int line) {
if (lineStates.Length()) {
lineStates.EnsureLength(line);
- lineStates.Insert(line, 0);
+ int val = (line < lineStates.Length()) ? lineStates[line] : 0;
+ lineStates.Insert(line, val);
}
}
}
int LineState::GetLineState(int line) {
+ if (line < 0)
+ return 0;
lineStates.EnsureLength(line + 1);
return lineStates[line];
}
}
bool LineAnnotation::MultipleStyles(int line) const {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line])
return reinterpret_cast<AnnotationHeader *>(annotations[line])->style == IndividualStyles;
else
return 0;
}
int LineAnnotation::Style(int line) {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line])
return reinterpret_cast<AnnotationHeader *>(annotations[line])->style;
else
return 0;
}
const char *LineAnnotation::Text(int line) const {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line])
return annotations[line]+sizeof(AnnotationHeader);
else
return 0;
}
const unsigned char *LineAnnotation::Styles(int line) const {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line] && MultipleStyles(line))
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line] && MultipleStyles(line))
return reinterpret_cast<unsigned char *>(annotations[line] + sizeof(AnnotationHeader) + Length(line));
else
return 0;
}
void LineAnnotation::SetText(int line, const char *text) {
- if (text) {
+ if (text && (line >= 0)) {
annotations.EnsureLength(line+1);
int style = Style(line);
if (annotations[line]) {
delete []annotations[line];
}
- annotations[line] = AllocateAnnotation(strlen(text), style);
- AnnotationHeader *pah = reinterpret_cast<AnnotationHeader*>(annotations[line]);
+ annotations[line] = AllocateAnnotation(static_cast<int>(strlen(text)), style);
+ AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
pah->style = static_cast<short>(style);
- pah->length = strlen(text);
+ pah->length = static_cast<int>(strlen(text));
pah->lines = static_cast<short>(NumberLines(text));
memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
} else {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line]) {
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) {
delete []annotations[line];
annotations[line] = 0;
}
}
void LineAnnotation::SetStyles(int line, const unsigned char *styles) {
- annotations.EnsureLength(line+1);
- if (!annotations[line]) {
- annotations[line] = AllocateAnnotation(0, IndividualStyles);
- } else {
- AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]);
- if (pahSource->style != IndividualStyles) {
- char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles);
- AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation);
- pahAlloc->length = pahSource->length;
- pahAlloc->lines = pahSource->lines;
- memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length);
- delete []annotations[line];
- annotations[line] = allocation;
+ if (line >= 0) {
+ annotations.EnsureLength(line+1);
+ if (!annotations[line]) {
+ annotations[line] = AllocateAnnotation(0, IndividualStyles);
+ } else {
+ AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+ if (pahSource->style != IndividualStyles) {
+ char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles);
+ AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation);
+ pahAlloc->length = pahSource->length;
+ pahAlloc->lines = pahSource->lines;
+ memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length);
+ delete []annotations[line];
+ annotations[line] = allocation;
+ }
}
+ AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+ pah->style = IndividualStyles;
+ memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length);
}
- AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
- pah->style = IndividualStyles;
- memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length);
}
int LineAnnotation::Length(int line) const {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line])
return reinterpret_cast<AnnotationHeader *>(annotations[line])->length;
else
return 0;
}
int LineAnnotation::Lines(int line) const {
- if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+ if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line])
return reinterpret_cast<AnnotationHeader *>(annotations[line])->lines;
else
return 0;
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
-
+
/**
* This holds the marker identifier and the marker type to display.
* MarkerHandleNumbers are members of lists.
bool Contains(int handle) const;
bool InsertHandle(int handle, int markerNum);
void RemoveHandle(int handle);
- bool RemoveNumber(int markerNum);
+ bool RemoveNumber(int markerNum, bool all);
void CombineWith(MarkerHandleSet *other);
};
virtual void RemoveLine(int line);
int MarkValue(int line);
+ int MarkerNext(int lineStart, int mask) const;
int AddMark(int line, int marker, int lines);
void MergeMarkers(int pos);
- void DeleteMark(int line, int markerNum, bool all);
+ bool DeleteMark(int line, int markerNum, bool all);
void DeleteMarkFromHandle(int markerHandle);
int LineFromHandle(int markerHandle);
};
#include <stdio.h>
#include <ctype.h>
+#include <string>
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "Scintilla.h"
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Decoration.h"
+#include "ILexer.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
widthLine(wrapWidthInfinite),
lines(1),
wrapIndent(0) {
+ bracePreviousStyles[0] = 0;
+ bracePreviousStyles[1] = 0;
Resize(maxLineLength_);
}
indicators = new char[maxLineLength_ + 1];
// Extra position allocated as sometimes the Windows
// GetTextExtentExPoint API writes an extra element.
- positions = new int[maxLineLength_ + 1 + 1];
+ positions = new XYPOSITION[maxLineLength_ + 1 + 1];
maxLineLength = maxLineLength_;
}
}
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
- char bracesMatchStyle, int xHighlight) {
- if (rangeLine.ContainsCharacter(braces[0])) {
+ char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[0] = styles[braceOffset];
styles[braceOffset] = bracesMatchStyle;
}
}
- if (rangeLine.ContainsCharacter(braces[1])) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[1] = styles[braceOffset];
}
}
-void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
- if (rangeLine.ContainsCharacter(braces[0])) {
+void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[0];
}
}
- if (rangeLine.ContainsCharacter(braces[1])) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[1];
xHighlightGuide = 0;
}
-int LineLayout::FindBefore(int x, int lower, int upper) const {
+int LineLayout::FindBefore(XYPOSITION x, int lower, int upper) const {
do {
int middle = (upper + lower + 1) / 2; // Round high
- int posMiddle = positions[middle];
+ XYPOSITION posMiddle = positions[middle];
if (x < posMiddle) {
upper = middle - 1;
} else {
for (unsigned int j = 0; j<saeLen; j++) {
if (val == selAndEdge[j]) {
return;
- } if (val < selAndEdge[j]) {
+ }
+ if (val < selAndEdge[j]) {
for (unsigned int k = saeLen; k>j; k--) {
selAndEdge[k] = selAndEdge[k-1];
}
return -1;
}
-BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
+BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
+ int xStart, bool breakForSelection, Document *pdoc_) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
posLineStart(posLineStart_),
- utf8(utf8_),
nextBreak(lineStart_),
saeSize(0),
saeLen(0),
saeCurrentPos(0),
saeNext(0),
- subBreak(-1) {
+ subBreak(-1),
+ pdoc(pdoc_) {
saeSize = 8;
selAndEdge = new int[saeSize];
for (unsigned int j=0; j < saeSize; j++) {
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
- if (utf8) {
+ if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
int trailBytes=0;
for (int pos = -1;;) {
pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
delete []selAndEdge;
}
-int BreakFinder::First() {
+int BreakFinder::First() const {
return nextBreak;
}
-static bool IsTrailByte(int ch) {
- return (ch >= 0x80) && (ch < (0x80 + 0x40));
-}
-
int BreakFinder::Next() {
if (subBreak == -1) {
int prev = nextBreak;
subBreak = -1;
return nextBreak;
} else {
- int lastGoodBreak = -1;
- int lastOKBreak = -1;
- int lastUTF8Break = -1;
- int j;
- for (j = subBreak + 1; j <= nextBreak; j++) {
- if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
- lastGoodBreak = j;
- }
- if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
- lastOKBreak = j;
- }
- if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
- lastUTF8Break = j;
- }
- if (((j - subBreak) >= lengthEachSubdivision) &&
- ((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
- break;
- }
- }
- if (lastGoodBreak >= 0) {
- subBreak = lastGoodBreak;
- } else if (lastOKBreak >= 0) {
- subBreak = lastOKBreak;
- } else if (lastUTF8Break >= 0) {
- subBreak = lastUTF8Break;
- } else {
- subBreak = nextBreak;
- }
+ subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
if (subBreak >= nextBreak) {
subBreak = -1;
return nextBreak;
}
void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_,
- unsigned int len_, int *positions_, unsigned int clock_) {
+ unsigned int len_, XYPOSITION *positions_, unsigned int clock_) {
Clear();
styleNumber = styleNumber_;
len = len_;
clock = clock_;
if (s_ && positions_) {
- positions = new short[len + (len + 1) / 2];
- for (unsigned int i=0;i<len;i++) {
- positions[i] = static_cast<short>(positions_[i]);
+ positions = new XYPOSITION[len + (len + 1) / 2];
+ for (unsigned int i=0; i<len; i++) {
+ positions[i] = static_cast<XYPOSITION>(positions_[i]);
}
memcpy(reinterpret_cast<char *>(positions + len), s_, len);
}
}
bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
- unsigned int len_, int *positions_) const {
+ unsigned int len_, XYPOSITION *positions_) const {
if ((styleNumber == styleNumber_) && (len == len_) &&
(memcmp(reinterpret_cast<char *>(positions + len), s_, len)== 0)) {
- for (unsigned int i=0;i<len;i++) {
+ for (unsigned int i=0; i<len; i++) {
positions_[i] = positions[i];
}
return true;
}
}
-int PositionCacheEntry::Hash(unsigned int styleNumber, const char *s, unsigned int len) {
+int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) {
unsigned int ret = s[0] << 7;
- for (unsigned int i=0; i<len; i++) {
+ for (unsigned int i=0; i<len_; i++) {
ret *= 1000003;
ret ^= s[i];
}
ret *= 1000003;
- ret ^= len;
+ ret ^= len_;
ret *= 1000003;
- ret ^= styleNumber;
+ ret ^= styleNumber_;
return ret;
}
-bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) {
+bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const {
return clock > other.clock;
}
void PositionCache::Clear() {
if (!allClear) {
- for (size_t i=0;i<size;i++) {
+ for (size_t i=0; i<size; i++) {
pces[i].Clear();
}
}
}
void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
- const char *s, unsigned int len, int *positions) {
+ const char *s, unsigned int len, XYPOSITION *positions, Document *pdoc) {
+
allClear = false;
int probe = -1;
if ((size > 0) && (len < 30)) {
// Two way associative: try two probe positions.
int hashValue = PositionCacheEntry::Hash(styleNumber, s, len);
- probe = hashValue % size;
+ probe = static_cast<int>(hashValue % size);
if (pces[probe].Retrieve(styleNumber, s, len, positions)) {
return;
}
- int probe2 = (hashValue * 37) % size;
+ int probe2 = static_cast<int>((hashValue * 37) % size);
if (pces[probe2].Retrieve(styleNumber, s, len, positions)) {
return;
}
probe = probe2;
}
}
- surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
+ if (len > BreakFinder::lengthStartSubdivision) {
+ // Break up into segments
+ unsigned int startSegment = 0;
+ XYPOSITION xStartSegment = 0;
+ while (startSegment < len) {
+ unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
+ surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
+ for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
+ positions[startSegment + inSeg] += xStartSegment;
+ }
+ xStartSegment = positions[startSegment + lenSegment - 1];
+ startSegment += lenSegment;
+ }
+ } else {
+ surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
+ }
if (probe >= 0) {
clock++;
if (clock > 60000) {
// Since there are only 16 bits for the clock, wrap it round and
// reset all cache entries so none get stuck with a high clock.
- for (size_t i=0;i<size;i++) {
+ for (size_t i=0; i<size; i++) {
pces[i].ResetClock();
}
clock = 2;
unsigned char *styles;
int styleBitsSet;
char *indicators;
- int *positions;
+ XYPOSITION *positions;
char bracePreviousStyles[2];
// Hotspot support
// Wrapped line support
int widthLine;
int lines;
- int wrapIndent; // In pixels
+ XYPOSITION wrapIndent; // In pixels
LineLayout(int maxLineLength_);
virtual ~LineLayout();
bool InLine(int offset, int line) const;
void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[],
- char bracesMatchStyle, int xHighlight);
- void RestoreBracesHighlight(Range rangeLine, Position braces[]);
- int FindBefore(int x, int lower, int upper) const;
+ char bracesMatchStyle, int xHighlight, bool ignoreStyle);
+ void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
+ int FindBefore(XYPOSITION x, int lower, int upper) const;
int EndLineStyle() const;
};
};
void Invalidate(LineLayout::validLevel validity_);
void SetLevel(int level_);
- int GetLevel() { return level; }
+ int GetLevel() const { return level; }
LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_,
int linesOnScreen, int linesInDoc);
void Dispose(LineLayout *ll);
unsigned int styleNumber:8;
unsigned int len:8;
unsigned int clock:16;
- short *positions;
+ XYPOSITION *positions;
public:
PositionCacheEntry();
~PositionCacheEntry();
- void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_, unsigned int clock);
+ void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_, unsigned int clock);
void Clear();
- bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const;
- static int Hash(unsigned int styleNumber, const char *s, unsigned int len);
- bool NewerThan(const PositionCacheEntry &other);
+ bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const;
+ static int Hash(unsigned int styleNumber_, const char *s, unsigned int len);
+ bool NewerThan(const PositionCacheEntry &other) const;
void ResetClock();
};
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
- // If a whole run is longer than lengthStartSubdivision then subdivide
- // into smaller runs at spaces or punctuation.
- enum { lengthStartSubdivision = 300 };
- // Try to make each subdivided run lengthEachSubdivision or shorter.
- enum { lengthEachSubdivision = 100 };
LineLayout *ll;
int lineStart;
int lineEnd;
int posLineStart;
- bool utf8;
int nextBreak;
int *selAndEdge;
unsigned int saeSize;
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
+ Document *pdoc;
void Insert(int val);
public:
- BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
+ // If a whole run is longer than lengthStartSubdivision then subdivide
+ // into smaller runs at spaces or punctuation.
+ enum { lengthStartSubdivision = 300 };
+ // Try to make each subdivided run lengthEachSubdivision or shorter.
+ enum { lengthEachSubdivision = 100 };
+ BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
+ int xStart, bool breakForSelection, Document *pdoc_);
~BreakFinder();
- int First();
+ int First() const;
int Next();
};
~PositionCache();
void Clear();
void SetSize(size_t size_);
- int GetSize() { return size; }
+ size_t GetSize() const { return size; }
void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
- const char *s, unsigned int len, int *positions);
+ const char *s, unsigned int len, XYPOSITION *positions, Document *pdoc);
};
inline bool IsSpaceOrTab(int ch) {
+++ /dev/null
-// SciTE - Scintilla based Text Editor
-/** @file PropSet.cxx
- ** A Java style properties file module.
- **/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-// Maintain a dictionary of properties
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifdef _MSC_VER
-// Visual C++ doesn't like unreachable code or long decorated names in its own headers.
-#pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702 4786)
-#endif
-
-#include <string>
-#include <map>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "PropSetSimple.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-typedef std::map<std::string, std::string> mapss;
-
-PropSetSimple::PropSetSimple() {
- mapss *props = new mapss;
- impl = static_cast<void *>(props);
-}
-
-PropSetSimple::~PropSetSimple() {
- mapss *props = static_cast<mapss *>(impl);
- delete props;
- impl = 0;
-}
-
-void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
- mapss *props = static_cast<mapss *>(impl);
- if (!*key) // Empty keys are not supported
- return;
- if (lenKey == -1)
- lenKey = static_cast<int>(strlen(key));
- if (lenVal == -1)
- lenVal = static_cast<int>(strlen(val));
- (*props)[std::string(key, lenKey)] = std::string(val, lenVal);
-}
-
-static bool IsASpaceCharacter(unsigned int ch) {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
-void PropSetSimple::Set(const char *keyVal) {
- while (IsASpaceCharacter(*keyVal))
- keyVal++;
- const char *endVal = keyVal;
- while (*endVal && (*endVal != '\n'))
- endVal++;
- const char *eqAt = strchr(keyVal, '=');
- if (eqAt) {
- Set(keyVal, eqAt + 1, eqAt-keyVal, endVal - eqAt - 1);
- } else if (*keyVal) { // No '=' so assume '=1'
- Set(keyVal, "1", endVal-keyVal, 1);
- }
-}
-
-void PropSetSimple::SetMultiple(const char *s) {
- const char *eol = strchr(s, '\n');
- while (eol) {
- Set(s);
- s = eol + 1;
- eol = strchr(s, '\n');
- }
- Set(s);
-}
-
-const char *PropSetSimple::Get(const char *key) const {
- mapss *props = static_cast<mapss *>(impl);
- mapss::const_iterator keyPos = props->find(std::string(key));
- if (keyPos != props->end()) {
- return keyPos->second.c_str();
- } else {
- return "";
- }
-}
-
-// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)").
-// A solution is to keep a stack of variables that have been expanded, so that
-// recursive expansions can be skipped. For now I'll just use the C++ stack
-// for that, through a recursive function and a simple chain of pointers.
-
-struct VarChain {
- VarChain(const char*var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
-
- bool contains(const char *testVar) const {
- return (var && (0 == strcmp(var, testVar)))
- || (link && link->contains(testVar));
- }
-
- const char *var;
- const VarChain *link;
-};
-
-static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
- size_t varStart = withVars.find("$(");
- while ((varStart != std::string::npos) && (maxExpands > 0)) {
- size_t varEnd = withVars.find(")", varStart+2);
- if (varEnd == std::string::npos) {
- break;
- }
-
- // For consistency, when we see '$(ab$(cde))', expand the inner variable first,
- // regardless whether there is actually a degenerate variable named 'ab$(cde'.
- size_t innerVarStart = withVars.find("$(", varStart+2);
- while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
- varStart = innerVarStart;
- innerVarStart = withVars.find("$(", varStart+2);
- }
-
- std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
- std::string val = props.Get(var.c_str());
-
- if (blankVars.contains(var.c_str())) {
- val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
- }
-
- if (--maxExpands >= 0) {
- maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
- }
-
- withVars.erase(varStart, varEnd-varStart+1);
- withVars.insert(varStart, val.c_str(), val.length());
-
- varStart = withVars.find("$(");
- }
-
- return maxExpands;
-}
-
-char *PropSetSimple::Expanded(const char *key) const {
- std::string val = Get(key);
- ExpandAllInPlace(*this, val, 100, VarChain(key));
- char *ret = new char [val.size() + 1];
- strcpy(ret, val.c_str());
- return ret;
-}
-
-char *PropSetSimple::ToString() const {
- mapss *props = static_cast<mapss *>(impl);
- std::string sval;
- for (mapss::const_iterator it=props->begin(); it != props->end(); it++) {
- sval += it->first;
- sval += "=";
- sval += it->second;
- sval += "\n";
- }
- char *ret = new char [sval.size() + 1];
- strcpy(ret, sval.c_str());
- return ret;
-}
-
-int PropSetSimple::GetInt(const char *key, int defaultValue) const {
- char *val = Expanded(key);
- if (val) {
- int retVal = val[0] ? atoi(val) : defaultValue;
- delete []val;
- return retVal;
- }
- return defaultValue;
-}
+++ /dev/null
-// Scintilla source code edit control
-/** @file PropSetSimple.h
- ** A basic string to string map.
- **/
-// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-#ifndef PROPSETSIMPLE_H
-#define PROPSETSIMPLE_H
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-class PropSetSimple : public PropertyGet {
- void *impl;
- void Set(const char *keyVal);
-public:
- PropSetSimple();
- virtual ~PropSetSimple();
- void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
- void SetMultiple(const char *);
- const char *Get(const char *key) const;
- char *Expanded(const char *key) const;
- char *ToString() const;
- int GetInt(const char *key, int defaultValue=0) const;
-};
-
-#ifdef SCI_NAMESPACE
-}
-#endif
-
-#endif
* Put all global/static variables into an object so this code can be
* used from multiple threads, etc.
* Some extensions by Philippe Lhoste PhiLho(a)GMX.net
+ * '?' extensions by Michael Mullin masmullin@gmail.com
*
* These routines are the PUBLIC DOMAIN equivalents of regex
* routines as found in 4.nBSD UN*X, with minor extensions.
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
- * character (metachar): . \ [ ] * + ^ $
+ * character (metachar): . \ [ ] * + ? ^ $
* and ( ) if posix option.
*
* [2] . matches any character.
* regex searches are made line per line
* (stripped of end-of-line chars).
* - if not in posix mode, when followed by a
- * left or right round bracket (see [7]);
- * - when followed by a digit 1 to 9 (see [8]);
+ * left or right round bracket (see [8]);
+ * - when followed by a digit 1 to 9 (see [9]);
* - when followed by a left or right angle bracket
- * (see [9]);
- * - when followed by d, D, s, S, w or W (see [10]);
- * - when followed by x and two hexa digits (see [11].
+ * (see [10]);
+ * - when followed by d, D, s, S, w or W (see [11]);
+ * - when followed by x and two hexa digits (see [12].
* Backslash is used as an escape character for all
* other meta-characters, and itself.
*
* [a-zA-Z] any alpha
*
* [5] * any regular expression form [1] to [4]
- * (except [7], [8] and [9] forms of [3]),
+ * (except [8], [9] and [10] forms of [3]),
* followed by closure char (*)
* matches zero or more matches of that form.
*
* [6] + same as [5], except it matches one or more.
- * Both [5] and [6] are greedy (they match as much as possible).
*
- * [7] a regular expression in the form [1] to [12], enclosed
+ * [5-6] Both [5] and [6] are greedy (they match as much as possible).
+ * Unless they are followed by the 'lazy' quantifier (?)
+ * In which case both [5] and [6] try to match as little as possible
+ *
+ * [7] ? same as [5] except it matches zero or one.
+ *
+ * [8] a regular expression in the form [1] to [13], enclosed
* as \(form\) (or (form) with posix flag) matches what
* form matches. The enclosure creates a set of tags,
- * used for [8] and for pattern substitution.
+ * used for [9] and for pattern substitution.
* The tagged forms are numbered starting from 1.
*
- * [8] a \ followed by a digit 1 to 9 matches whatever a
- * previously tagged regular expression ([7]) matched.
+ * [9] a \ followed by a digit 1 to 9 matches whatever a
+ * previously tagged regular expression ([8]) matched.
*
- * [9] \< a regular expression starting with a \< construct
+ * [10] \< a regular expression starting with a \< construct
* \> and/or ending with a \> construct, restricts the
* pattern matching to the beginning of a word, and/or
* the end of a word. A word is defined to be a character
* by user setting. The word must also be preceded and/or
* followed by any character outside those mentioned.
*
- * [10] \l a backslash followed by d, D, s, S, w or W,
+ * [11] \l a backslash followed by d, D, s, S, w or W,
* becomes a character class (both inside and
* outside sets []).
* d: decimal digits
* w: alphanumeric & underscore (changed by user setting)
* W: any char except alphanumeric & underscore (see above)
*
- * [11] \xHH a backslash followed by x and two hexa digits,
+ * [12] \xHH a backslash followed by x and two hexa digits,
* becomes the character whose Ascii code is equal
* to these digits. If not followed by two digits,
* it is 'x' char itself.
*
- * [12] a composite regular expression xy where x and y
- * are in the form [1] to [11] matches the longest
+ * [13] a composite regular expression xy where x and y
+ * are in the form [1] to [12] matches the longest
* match of x followed by a match for y.
*
- * [13] ^ a regular expression starting with a ^ character
+ * [14] ^ a regular expression starting with a ^ character
* $ and/or ending with a $ character, restricts the
* pattern matching to the beginning of the line,
* or the end of line. [anchors] Elsewhere in the
#define EOW 9
#define REF 10
#define CLO 11
+#define CLQ 12 /* 0 to 1 closure */
+#define LCLO 13 /* lazy closure */
#define END 0
*/
RESearch::RESearch(CharClassify *charClassTable) {
+ failure = 0;
charClass = charClassTable;
Init();
}
}
}
-const unsigned char escapeValue(unsigned char ch) {
+unsigned char escapeValue(unsigned char ch) {
switch (ch) {
case 'a': return '\a';
case 'b': return '\b';
* or -1 for a char class. In this case, bittab is changed.
*/
int RESearch::GetBackslashExpression(
- const char *pattern,
- int &incr) {
+ const char *pattern,
+ int &incr) {
// Since error reporting is primitive and messages are not used anyway,
// I choose to interpret unexpected syntax in a logical way instead
// of reporting errors. Otherwise, we can stick on, eg., PCRE behavior.
if (*(p+1) != ']') {
c1 = prevChar + 1;
i++;
- c2 = *++p;
+ c2 = static_cast<unsigned char>(*++p);
if (c2 == '\\') {
if (!*(p+1)) // End of RE
return badpat("Missing ]");
prevChar = -1;
}
} else {
- prevChar = *p;
+ prevChar = static_cast<unsigned char>(*p);
ChSetWithCase(*p, caseSensitive);
}
i++;
case '*': /* match 0 or more... */
case '+': /* match 1 or more... */
+ case '?':
if (p == pattern)
return badpat("Empty closure");
lp = sp; /* previous opcode */
- if (*lp == CLO) /* equivalence... */
+ if (*lp == CLO || *lp == LCLO) /* equivalence... */
break;
switch (*lp) {
*mp++ = END;
*mp++ = END;
sp = mp;
+
while (--mp > lp)
*mp = mp[-1];
- *mp = CLO;
+ if (*p == '?') *mp = CLQ;
+ else if (*(p+1) == '?') *mp = LCLO;
+ else *mp = CLO;
+
mp = sp;
break;
int bp; /* beginning of subpat... */
int ep; /* ending of subpat... */
int are; /* to save the line ptr. */
+ int llp; /* lazy lp for LCLO */
while ((op = *ap++) != END)
switch (op) {
return NOTFOUND;
break;
case BOT:
- bopat[*ap++] = lp;
+ bopat[static_cast<int>(*ap++)] = lp;
break;
case EOT:
- eopat[*ap++] = lp;
+ eopat[static_cast<int>(*ap++)] = lp;
break;
- case BOW:
+ case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))
return NOTFOUND;
break;
if (ci.CharAt(bp++) != ci.CharAt(lp++))
return NOTFOUND;
break;
+ case LCLO:
+ case CLQ:
case CLO:
are = lp;
switch (*ap) {
case ANY:
- while (lp < endp)
+ if (op == CLO || op == LCLO)
+ while (lp < endp)
+ lp++;
+ else if (lp < endp)
lp++;
+
n = ANYSKIP;
break;
case CHR:
c = *(ap+1);
- while ((lp < endp) && (c == ci.CharAt(lp)))
+ if (op == CLO || op == LCLO)
+ while ((lp < endp) && (c == ci.CharAt(lp)))
+ lp++;
+ else if ((lp < endp) && (c == ci.CharAt(lp)))
lp++;
n = CHRSKIP;
break;
//re_fail("closure: bad nfa.", *ap);
return NOTFOUND;
}
-
ap += n;
- while (lp >= are) {
- if ((e = PMatch(ci, lp, endp, ap)) != NOTFOUND)
- return e;
- --lp;
+ llp = lp;
+ e = NOTFOUND;
+ while (llp >= are) {
+ int q;
+ if ((q = PMatch(ci, llp, endp, ap)) != NOTFOUND) {
+ e = q;
+ lp = llp;
+ if (op != LCLO) return e;
+ }
+ if (*ap == END) return e;
+ --llp;
}
- return NOTFOUND;
+ if (*ap == EOT)
+ PMatch(ci, lp, endp, ap);
+ return e;
default:
//re_fail("RESearch::Execute: bad nfa.", static_cast<char>(op));
return NOTFOUND;
#endif
// Find the first run at a position
-int RunStyles::RunFromPosition(int position) {
+int RunStyles::RunFromPosition(int position) const {
int run = starts->PartitionFromPosition(position);
// Go to first element with this position
while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {
runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart);
+ runEnd = RunFromPosition(end);
+ RemoveRunIfEmpty(runEnd);
+ return true;
+ } else {
+ return false;
}
- return true;
}
void RunStyles::SetValueAt(int position, int value) {
}
}
+int RunStyles::Runs() const {
+ return starts->Partitions();
+}
+
+bool RunStyles::AllSame() const {
+ for (int run = 1; run < starts->Partitions(); run++) {
+ if (styles->ValueAt(run) != styles->ValueAt(run - 1))
+ return false;
+ }
+ return true;
+}
+
+bool RunStyles::AllSameAs(int value) const {
+ return AllSame() && (styles->ValueAt(0) == value);
+}
+
+int RunStyles::Find(int value, int start) const {
+ if (start < Length()) {
+ int run = start ? RunFromPosition(start) : 0;
+ if (styles->ValueAt(run) == value)
+ return start;
+ run++;
+ while (run < starts->Partitions()) {
+ if (styles->ValueAt(run) == value)
+ return starts->PositionFromPartition(run);
+ run++;
+ }
+ }
+ return -1;
+}
#endif
class RunStyles {
-public:
+private:
Partitioning *starts;
SplitVector<int> *styles;
- int RunFromPosition(int position);
+ int RunFromPosition(int position) const;
int SplitRun(int position);
void RemoveRun(int run);
void RemoveRunIfEmpty(int run);
void InsertSpace(int position, int insertLength);
void DeleteAll();
void DeleteRange(int position, int deleteLength);
+ int Runs() const;
+ bool AllSame() const;
+ bool AllSameAs(int value) const;
+ int Find(int value, int start) const;
};
#ifdef SCI_NAMESPACE
*/
class SVector {
enum { allocSize = 4000 };
-
+
int *v; ///< The vector
unsigned int size; ///< Number of elements allocated
unsigned int len; ///< Number of elements used in vector
-
+
/** Internally allocate more elements than the user wants
* to avoid thrashing the memory allocator. */
void SizeTo(int newSize) {
if (newSize < allocSize)
newSize += allocSize;
- else
+ else
newSize = (newSize * 3) / 2;
- int* newv = new int[newSize];
+ int *newv = new int[newSize];
size = newSize;
unsigned int i=0;
for (; i<len; i++) {
delete []v;
v = newv;
}
-
+
public:
SVector() {
v = 0;
size = 0;
if (other.Length() > 0) {
SizeTo(other.Length());
- for (int i=0;i<other.Length();i++)
+ for (int i=0; i<other.Length(); i++)
v[i] = other.v[i];
len = other.Length();
}
size = 0;
if (other.Length() > 0) {
SizeTo(other.Length());
- for (int i=0;i<other.Length();i++)
+ for (int i=0; i<other.Length(); i++)
v[i] = other.v[i];
len = other.Length();
}
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
+
+#include <string>
+#include <vector>
+#include <map>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
-#include "PropSet.h"
+
#include "PropSetSimple.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+#include "LexerModule.h"
+#include "Catalogue.h"
#endif
#include "SplitVector.h"
#include "Partitioning.h"
displayPopupMenu = true;
listType = 0;
maxListWidth = 0;
-#ifdef SCI_LEXER
- lexLanguage = SCLEX_CONTAINER;
- performingStyle = false;
- lexCurrent = 0;
- for (int wl = 0;wl < numWordLists;wl++)
- keyWordLists[wl] = new WordList;
- keyWordLists[numWordLists] = 0;
-#endif
}
ScintillaBase::~ScintillaBase() {
-#ifdef SCI_LEXER
- for (int wl = 0;wl < numWordLists;wl++)
- delete keyWordLists[wl];
-#endif
}
void ScintillaBase::Finalise() {
popup.Destroy();
}
-void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) {
- Editor::RefreshColourPalette(pal, want);
- ct.RefreshColourPalette(pal, want);
-}
-
void ScintillaBase::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
bool isFillUp = ac.Active() && ac.IsFillUpChar(*s);
if (!isFillUp) {
AutoCompleteMove(1);
return 0;
case SCI_LINEUP:
- AutoCompleteMove( -1);
+ AutoCompleteMove(-1);
return 0;
case SCI_PAGEDOWN:
- AutoCompleteMove(5);
+ AutoCompleteMove(ac.lb->GetVisibleRows());
return 0;
case SCI_PAGEUP:
- AutoCompleteMove( -5);
+ AutoCompleteMove(-ac.lb->GetVisibleRows());
return 0;
case SCI_VCHOME:
- AutoCompleteMove( -5000);
+ AutoCompleteMove(-5000);
return 0;
case SCI_LINEEND:
AutoCompleteMove(5000);
return Editor::KeyCommand(iMessage);
}
-void ScintillaBase::AutoCompleteDoubleClick(void* p) {
- ScintillaBase* sci = reinterpret_cast<ScintillaBase*>(p);
+void ScintillaBase::AutoCompleteDoubleClick(void *p) {
+ ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
sci->AutoCompleteCompleted();
}
if (ac.chooseSingle && (listType == 0)) {
if (list && !strchr(list, ac.GetSeparator())) {
const char *typeSep = strchr(list, ac.GetTypesep());
- size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
+ int lenInsert = typeSep ?
+ static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
if (ac.ignoreCase) {
SetEmptySelection(sel.MainCaret() - lenEntered);
pdoc->DeleteChars(sel.MainCaret(), lenEntered);
pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert - lenEntered);
SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered);
}
+ ac.Cancel();
return;
}
}
ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
- lenEntered, vs.lineHeight, IsUnicodeMode());
+ lenEntered, vs.lineHeight, IsUnicodeMode(), technology);
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
}
void ScintillaBase::AutoCompleteMoveToCurrentWord() {
- char wordCurrent[1000];
- int i;
- int startWord = ac.posStart - ac.startLen;
- for (i = startWord; i < sel.MainCaret() && i - startWord < 1000; i++)
- wordCurrent[i - startWord] = pdoc->CharAt(i);
- wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0';
- ac.Select(wordCurrent);
+ std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
+ ac.Select(wordCurrent.c_str());
}
void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
}
void ScintillaBase::AutoCompleteCompleted() {
- int item = ac.lb->GetSelection();
- char selected[1000];
- selected[0] = '\0';
- if (item != -1) {
- ac.lb->GetValue(item, selected, sizeof(selected));
- } else {
+ int item = ac.GetSelection();
+ if (item == -1) {
AutoCompleteCancel();
return;
}
+ const std::string selected = ac.GetValue(item);
ac.Show(false);
scn.wParam = listType;
scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen;
+ scn.position = firstPos;
scn.lParam = firstPos;
- scn.text = selected;
+ scn.text = selected.c_str();
NotifyParent(scn);
if (!ac.Active())
}
SetEmptySelection(ac.posStart);
if (item != -1) {
- pdoc->InsertCString(firstPos, selected);
- SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
+ pdoc->InsertCString(firstPos, selected.c_str());
+ SetEmptySelection(firstPos + static_cast<int>(selected.length()));
}
+ SetLastXChosen();
}
int ScintillaBase::AutoCompleteGetCurrent() {
if (!ac.Active())
return -1;
- return ac.lb->GetSelection();
+ return ac.GetSelection();
}
int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
if (ac.Active()) {
- int item = ac.lb->GetSelection();
- char selected[1000];
- selected[0] = '\0';
+ int item = ac.GetSelection();
if (item != -1) {
- ac.lb->GetValue(item, selected, sizeof(selected));
+ const std::string selected = ac.GetValue(item);
if (buffer != NULL)
- strcpy(buffer, selected);
- return strlen(selected);
+ strcpy(buffer, selected.c_str());
+ return static_cast<int>(selected.length());
}
}
if (buffer != NULL)
void ScintillaBase::CallTipShow(Point pt, const char *defn) {
ac.Cancel();
- pt.y += vs.lineHeight;
// If container knows about STYLE_CALLTIP then use it in place of the
// STYLE_DEFAULT for the face name, size and character set. Also use it
// for the foreground and background colour.
ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
}
PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
+ vs.lineHeight,
defn,
vs.styles[ctStyle].fontName,
vs.styles[ctStyle].sizeZoomed,
CodePage(),
vs.styles[ctStyle].characterSet,
+ vs.technology,
wMain);
// If the call-tip window would be out of the client
- // space, adjust so it displays above the text.
+ // space
PRectangle rcClient = GetClientRectangle();
+ int offset = vs.lineHeight + rc.Height();
+ // adjust so it displays below the text.
+ if (rc.top < rcClient.top) {
+ rc.top += offset;
+ rc.bottom += offset;
+ }
+ // adjust so it displays above the text.
if (rc.bottom > rcClient.bottom) {
- int offset = vs.lineHeight + rc.Height();
rc.top -= offset;
rc.bottom -= offset;
}
}
#ifdef SCI_LEXER
-void ScintillaBase::SetLexer(uptr_t wParam) {
- lexLanguage = wParam;
- lexCurrent = LexerModule::Find(lexLanguage);
- if (!lexCurrent)
- lexCurrent = LexerModule::Find(SCLEX_NULL);
- int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
- vs.EnsureStyle((1 << bits) - 1);
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexState : public LexInterface {
+ const LexerModule *lexCurrent;
+ void SetLexerModule(const LexerModule *lex);
+ PropSetSimple props;
+public:
+ int lexLanguage;
+
+ LexState(Document *pdoc_);
+ virtual ~LexState();
+ void SetLexer(uptr_t wParam);
+ void SetLexerLanguage(const char *languageName);
+ const char *DescribeWordListSets();
+ void SetWordList(int n, const char *wl);
+ int GetStyleBitsNeeded() const;
+ const char *GetName() const;
+ void *PrivateCall(int operation, void *pointer);
+ const char *PropertyNames();
+ int PropertyType(const char *name);
+ const char *DescribeProperty(const char *name);
+ void PropSet(const char *key, const char *val);
+ const char *PropGet(const char *key) const;
+ int PropGetInt(const char *key, int defaultValue=0) const;
+ int PropGetExpanded(const char *key, char *result) const;
+};
+
+#ifdef SCI_NAMESPACE
}
+#endif
-void ScintillaBase::SetLexerLanguage(const char *languageName) {
+LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
+ lexCurrent = 0;
+ performingStyle = false;
lexLanguage = SCLEX_CONTAINER;
- lexCurrent = LexerModule::Find(languageName);
- if (!lexCurrent)
- lexCurrent = LexerModule::Find(SCLEX_NULL);
- if (lexCurrent)
- lexLanguage = lexCurrent->GetLanguage();
- int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
- vs.EnsureStyle((1 << bits) - 1);
}
-void ScintillaBase::Colourise(int start, int end) {
- if (!performingStyle) {
- // Protect against reentrance, which may occur, for example, when
- // fold points are discovered while performing styling and the folding
- // code looks for child lines which may trigger styling.
- performingStyle = true;
+LexState::~LexState() {
+ if (instance) {
+ instance->Release();
+ instance = 0;
+ }
+}
+
+LexState *ScintillaBase::DocumentLexState() {
+ if (!pdoc->pli) {
+ pdoc->pli = new LexState(pdoc);
+ }
+ return static_cast<LexState *>(pdoc->pli);
+}
- int lengthDoc = pdoc->Length();
- if (end == -1)
- end = lengthDoc;
- int len = end - start;
+void LexState::SetLexerModule(const LexerModule *lex) {
+ if (lex != lexCurrent) {
+ if (instance) {
+ instance->Release();
+ instance = 0;
+ }
+ lexCurrent = lex;
+ if (lexCurrent)
+ instance = lexCurrent->Create();
+ pdoc->LexerChanged();
+ }
+}
- PLATFORM_ASSERT(len >= 0);
- PLATFORM_ASSERT(start + len <= lengthDoc);
+void LexState::SetLexer(uptr_t wParam) {
+ lexLanguage = wParam;
+ if (lexLanguage == SCLEX_CONTAINER) {
+ SetLexerModule(0);
+ } else {
+ const LexerModule *lex = Catalogue::Find(lexLanguage);
+ if (!lex)
+ lex = Catalogue::Find(SCLEX_NULL);
+ SetLexerModule(lex);
+ }
+}
- //WindowAccessor styler(wMain.GetID(), props);
- DocumentAccessor styler(pdoc, props, wMain.GetID());
+void LexState::SetLexerLanguage(const char *languageName) {
+ const LexerModule *lex = Catalogue::Find(languageName);
+ if (!lex)
+ lex = Catalogue::Find(SCLEX_NULL);
+ if (lex)
+ lexLanguage = lex->GetLanguage();
+ SetLexerModule(lex);
+}
- int styleStart = 0;
- if (start > 0)
- styleStart = styler.StyleAt(start - 1) & pdoc->stylingBitsMask;
- styler.SetCodePage(pdoc->dbcsCodePage);
+const char *LexState::DescribeWordListSets() {
+ if (instance) {
+ return instance->DescribeWordListSets();
+ } else {
+ return 0;
+ }
+}
- if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
- lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- if (styler.GetPropertyInt("fold")) {
- lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- }
+void LexState::SetWordList(int n, const char *wl) {
+ if (instance) {
+ int firstModification = instance->WordListSet(n, wl);
+ if (firstModification >= 0) {
+ pdoc->ModifiedAt(firstModification);
}
+ }
+}
- performingStyle = false;
+int LexState::GetStyleBitsNeeded() const {
+ return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+}
+
+const char *LexState::GetName() const {
+ return lexCurrent ? lexCurrent->languageName : "";
+}
+
+void *LexState::PrivateCall(int operation, void *pointer) {
+ if (pdoc && instance) {
+ return instance->PrivateCall(operation, pointer);
+ } else {
+ return 0;
+ }
+}
+
+const char *LexState::PropertyNames() {
+ if (instance) {
+ return instance->PropertyNames();
+ } else {
+ return 0;
+ }
+}
+
+int LexState::PropertyType(const char *name) {
+ if (instance) {
+ return instance->PropertyType(name);
+ } else {
+ return SC_TYPE_BOOLEAN;
+ }
+}
+
+const char *LexState::DescribeProperty(const char *name) {
+ if (instance) {
+ return instance->DescribeProperty(name);
+ } else {
+ return 0;
+ }
+}
+
+void LexState::PropSet(const char *key, const char *val) {
+ props.Set(key, val);
+ if (instance) {
+ int firstModification = instance->PropertySet(key, val);
+ if (firstModification >= 0) {
+ pdoc->ModifiedAt(firstModification);
+ }
}
}
+
+const char *LexState::PropGet(const char *key) const {
+ return props.Get(key);
+}
+
+int LexState::PropGetInt(const char *key, int defaultValue) const {
+ return props.GetInt(key, defaultValue);
+}
+
+int LexState::PropGetExpanded(const char *key, char *result) const {
+ return props.GetExpanded(key, result);
+}
+
#endif
void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
#ifdef SCI_LEXER
- if (lexLanguage != SCLEX_CONTAINER) {
- int endStyled = WndProc(SCI_GETENDSTYLED, 0, 0);
- int lineEndStyled = WndProc(SCI_LINEFROMPOSITION, endStyled, 0);
- endStyled = WndProc(SCI_POSITIONFROMLINE, lineEndStyled, 0);
- Colourise(endStyled, endStyleNeeded);
+ if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
+ int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
+ int endStyled = pdoc->LineStart(lineEndStyled);
+ DocumentLexState()->Colourise(endStyled, endStyleNeeded);
return;
}
#endif
Editor::NotifyStyleToNeeded(endStyleNeeded);
}
+void ScintillaBase::NotifyLexerChanged(Document *, void *) {
+#ifdef SCI_LEXER
+ int bits = DocumentLexState()->GetStyleBitsNeeded();
+ vs.EnsureStyle((1 << bits) - 1);
+#endif
+}
+
sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
switch (iMessage) {
case SCI_AUTOCSHOW:
case SCI_AUTOCGETIGNORECASE:
return ac.ignoreCase;
+ case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR:
+ ac.ignoreCaseBehaviour = wParam;
+ break;
+
+ case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR:
+ return ac.ignoreCaseBehaviour;
+
case SCI_USERLISTSHOW:
listType = wParam;
AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break;
+ case SCI_REGISTERRGBAIMAGE:
+ ac.lb->RegisterRGBAImage(wParam, sizeRGBAImage.x, sizeRGBAImage.y, reinterpret_cast<unsigned char *>(lParam));
+ break;
+
case SCI_CLEARREGISTEREDIMAGES:
ac.lb->ClearRegisteredImages();
break;
InvalidateStyleRedraw();
break;
+ case SCI_CALLTIPSETPOSITION:
+ ct.SetPosition(wParam != 0);
+ InvalidateStyleRedraw();
+ break;
+
case SCI_USEPOPUP:
displayPopupMenu = wParam != 0;
break;
#ifdef SCI_LEXER
case SCI_SETLEXER:
- SetLexer(wParam);
- lexLanguage = wParam;
+ DocumentLexState()->SetLexer(wParam);
break;
case SCI_GETLEXER:
- return lexLanguage;
+ return DocumentLexState()->lexLanguage;
case SCI_COLOURISE:
- if (lexLanguage == SCLEX_CONTAINER) {
+ if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
pdoc->ModifiedAt(wParam);
NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
} else {
- Colourise(wParam, lParam);
+ DocumentLexState()->Colourise(wParam, lParam);
}
Redraw();
break;
case SCI_SETPROPERTY:
- props.Set(reinterpret_cast<const char *>(wParam),
+ DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
reinterpret_cast<const char *>(lParam));
break;
case SCI_GETPROPERTY:
- return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
-
- case SCI_GETPROPERTYEXPANDED: {
- char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
- const int n = strlen(val);
- if (lParam != 0) {
- char *ptr = reinterpret_cast<char *>(lParam);
- strcpy(ptr, val);
- }
- delete []val;
- return n; // Not including NUL
- }
+ return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
+
+ case SCI_GETPROPERTYEXPANDED:
+ return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
+ reinterpret_cast<char *>(lParam));
case SCI_GETPROPERTYINT:
- return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
+ return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), lParam);
case SCI_SETKEYWORDS:
- if (wParam < numWordLists) {
- keyWordLists[wParam]->Clear();
- keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
- }
+ DocumentLexState()->SetWordList(wParam, reinterpret_cast<const char *>(lParam));
break;
case SCI_SETLEXERLANGUAGE:
- SetLexerLanguage(reinterpret_cast<const char *>(lParam));
+ DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
break;
case SCI_GETLEXERLANGUAGE:
- return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
+ return StringResult(lParam, DocumentLexState()->GetName());
+
+ case SCI_PRIVATELEXERCALL:
+ return reinterpret_cast<sptr_t>(
+ DocumentLexState()->PrivateCall(wParam, reinterpret_cast<void *>(lParam)));
case SCI_GETSTYLEBITSNEEDED:
- return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+ return DocumentLexState()->GetStyleBitsNeeded();
+
+ case SCI_PROPERTYNAMES:
+ return StringResult(lParam, DocumentLexState()->PropertyNames());
+
+ case SCI_PROPERTYTYPE:
+ return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
+
+ case SCI_DESCRIBEPROPERTY:
+ return StringResult(lParam, DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
+
+ case SCI_DESCRIBEKEYWORDSETS:
+ return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
#endif
namespace Scintilla {
#endif
+#ifdef SCI_LEXER
+class LexState;
+#endif
+
/**
*/
class ScintillaBase : public Editor {
int maxListWidth; /// Maximum width of list, in average character widths
#ifdef SCI_LEXER
- bool performingStyle; ///< Prevent reentrance
- int lexLanguage;
- const LexerModule *lexCurrent;
- PropSetSimple props;
- enum {numWordLists=KEYWORDSET_MAX+1};
- WordList *keyWordLists[numWordLists+1];
+ LexState *DocumentLexState();
void SetLexer(uptr_t wParam);
void SetLexerLanguage(const char *languageName);
void Colourise(int start, int end);
virtual void Initialise() = 0;
virtual void Finalise() = 0;
- virtual void RefreshColourPalette(Palette &pal, bool want);
-
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
void Command(int cmdId);
virtual void CancelModes();
void AutoCompleteCharacterDeleted();
void AutoCompleteCompleted();
void AutoCompleteMoveToCurrentWord();
- static void AutoCompleteDoubleClick(void* p);
+ static void AutoCompleteDoubleClick(void *p);
void CallTipClick();
void CallTipShow(Point pt, const char *defn);
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
- virtual void NotifyStyleToNeeded(int endStyleNeeded);
+ void NotifyStyleToNeeded(int endStyleNeeded);
+ void NotifyLexerChanged(Document *doc, void *userData);
+
public:
// Public so scintilla_send_message can use it
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
#endif
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
+ if (position == startChange) {
+ virtualSpace = 0;
+ }
if (insertion) {
if (position > startChange) {
position += length;
position -= length;
} else {
position = startChange;
+ virtualSpace = 0;
}
}
}
} else if (start <= startRange) {
// Trim end
end = startRange;
- } else { //
+ } else { //
PLATFORM_ASSERT(end >= endRange);
// Trim start
start = endRange;
for (size_t i=0; i<ranges.size();) {
if ((i != mainRange) && (ranges[i].Trim(range))) {
// Trimmed to empty so remove
- for (size_t j=i;j<ranges.size()-1;j++) {
+ for (size_t j=i; j<ranges.size()-1; j++) {
ranges[j] = ranges[j+1];
if (j == mainRange-1)
mainRange--;
mainRange = ranges.size() - 1;
}
+void Selection::AddSelectionWithoutTrim(SelectionRange range) {
+ ranges.push_back(range);
+ mainRange = ranges.size() - 1;
+}
+
void Selection::TentativeSelection(SelectionRange range) {
if (!tentativeMain) {
rangesSaved = ranges;
};
// Ordered range to make drawing simpler
-struct SelectionSegment {
+struct SelectionSegment {
SelectionPosition start;
SelectionPosition end;
- SelectionSegment() {
+ SelectionSegment() : start(), end() {
}
SelectionSegment(SelectionPosition a, SelectionPosition b) {
if (a < b) {
SelectionPosition caret;
SelectionPosition anchor;
- SelectionRange() {
+ SelectionRange() : caret(), anchor() {
}
SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
}
void MinimizeVirtualSpace();
};
-
-#include "wx/vector.h"
-
class Selection {
- wxVector<SelectionRange> ranges;
- wxVector<SelectionRange> rangesSaved;
+ std::vector<SelectionRange> ranges;
+ std::vector<SelectionRange> rangesSaved;
SelectionRange rangeRectangular;
size_t mainRange;
bool moveExtends;
int MainAnchor() const;
SelectionRange &Rectangular();
SelectionSegment Limits() const;
- // This is for when you want to move the caret in response to a
+ // This is for when you want to move the caret in response to a
// user direction command - for rectangular selections, use the range
// that covers all selected text otherwise return the main selection.
SelectionSegment LimitsForRectangularElseMain() const;
void TrimSelection(SelectionRange range);
void SetSelection(SelectionRange range);
void AddSelection(SelectionRange range);
+ void AddSelectionWithoutTrim(SelectionRange range);
void TentativeSelection(SelectionRange range);
void CommitTentative();
int CharacterInSelection(int posCharacter) const;
void RemoveDuplicates();
void RotateMain();
bool Tentative() const { return tentativeMain; }
- wxVector<SelectionRange> RangesCopy() const {
+ std::vector<SelectionRange> RangesCopy() const {
return ranges;
}
};
// Scintilla source code edit control
/** @file SplitVector.h
- ** Main data structure for holding arrays that handle insertions
+ ** Main data structure for holding arrays that handle insertions
** and deletions efficiently.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
/// Retrieve the character at a particular position.
/// Retrieving positions outside the range of the buffer returns 0.
- /// The assertions here are disabled since calling code can be
+ /// The assertions here are disabled since calling code can be
/// simpler if out of range access works and returns 0.
T ValueAt(int position) const {
if (position < part1Length) {
}
}
- T& operator[](int position) const {
+ T &operator[](int position) const {
PLATFORM_ASSERT(position >= 0 && position < lengthBody);
if (position < part1Length) {
return body[position];
}
}
- /// Ensure at least length elements allocated,
+ /// Ensure at least length elements allocated,
/// appending zero valued elements if needed.
void EnsureLength(int wantedLength) {
if (Length() < wantedLength) {
InsertValue(Length(), wantedLength - Length(), 0);
}
}
-
+
/// Insert text into the buffer from an array.
void InsertFromArray(int positionToInsert, const T s[], int positionFrom, int insertLength) {
PLATFORM_ASSERT((positionToInsert >= 0) && (positionToInsert <= lengthBody));
DeleteRange(0, lengthBody);
}
- T* BufferPointer() {
+ // Retrieve a range of elements into an array
+ void GetRange(T *buffer, int position, int retrieveLength) const {
+ // Split into up to 2 ranges, before and after the split then use memcpy on each.
+ int range1Length = 0;
+ if (position < part1Length) {
+ int part1AfterPosition = part1Length - position;
+ range1Length = retrieveLength;
+ if (range1Length > part1AfterPosition)
+ range1Length = part1AfterPosition;
+ }
+ memcpy(buffer, body + position, range1Length * sizeof(T));
+ buffer += range1Length;
+ position = position + range1Length + gapLength;
+ int range2Length = retrieveLength - range1Length;
+ memcpy(buffer, body + position, range2Length * sizeof(T));
+ }
+
+ T *BufferPointer() {
RoomFor(1);
GapTo(lengthBody);
body[lengthBody] = 0;
return body;
}
+
+ T *RangePointer(int position, int rangeLength) {
+ if (position < part1Length) {
+ if ((position + rangeLength) > part1Length) {
+ // Range overlaps gap, so move gap to start of range.
+ GapTo(position);
+ return body + position + gapLength;
+ } else {
+ return body + position ;
+ }
+ } else {
+ return body + position + gapLength;
+ }
+ }
+
+ int GapPosition() const {
+ return part1Length;
+ }
};
#endif
using namespace Scintilla;
#endif
-Style::Style() {
- aliasOfDefaultFont = true;
+FontAlias::FontAlias() {
+}
+
+FontAlias::~FontAlias() {
+ SetID(0);
+ // ~Font will not release the actual font resource sine it is now 0
+}
+
+void FontAlias::MakeAlias(Font &fontOrigin) {
+ SetID(fontOrigin.GetID());
+}
+
+void FontAlias::ClearFont() {
+ SetID(0);
+}
+
+bool FontSpecification::EqualTo(const FontSpecification &other) const {
+ return weight == other.weight &&
+ italic == other.italic &&
+ size == other.size &&
+ characterSet == other.characterSet &&
+ fontName == other.fontName;
+}
+
+FontMeasurements::FontMeasurements() {
+ Clear();
+}
+
+void FontMeasurements::Clear() {
+ ascent = 1;
+ descent = 1;
+ aveCharWidth = 1;
+ spaceWidth = 1;
+ sizeZoomed = 2;
+}
+
+Style::Style() : FontSpecification() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
- Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
- false, false, false, false, caseMixed, true, true, false);
+ Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, 0, SC_CHARSET_DEFAULT,
+ SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false);
}
-Style::Style(const Style &source) {
+Style::Style(const Style &source) : FontSpecification(), FontMeasurements() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, 0,
- false, false, false, false, caseMixed, true, true, false);
- fore.desired = source.fore.desired;
- back.desired = source.back.desired;
+ SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false);
+ fore = source.fore;
+ back = source.back;
characterSet = source.characterSet;
- bold = source.bold;
+ weight = source.weight;
italic = source.italic;
size = source.size;
eolFilled = source.eolFilled;
}
Style::~Style() {
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- aliasOfDefaultFont = false;
}
Style &Style::operator=(const Style &source) {
return * this;
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, SC_CHARSET_DEFAULT,
- false, false, false, false, caseMixed, true, true, false);
- fore.desired = source.fore.desired;
- back.desired = source.back.desired;
+ SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false);
+ fore = source.fore;
+ back = source.back;
characterSet = source.characterSet;
- bold = source.bold;
+ weight = source.weight;
italic = source.italic;
size = source.size;
eolFilled = source.eolFilled;
}
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
- const char *fontName_, int characterSet_,
- bool bold_, bool italic_, bool eolFilled_,
- bool underline_, ecaseForced caseForce_,
- bool visible_, bool changeable_, bool hotspot_) {
- fore.desired = fore_;
- back.desired = back_;
+ const char *fontName_, int characterSet_,
+ int weight_, bool italic_, bool eolFilled_,
+ bool underline_, ecaseForced caseForce_,
+ bool visible_, bool changeable_, bool hotspot_) {
+ fore = fore_;
+ back = back_;
characterSet = characterSet_;
- bold = bold_;
+ weight = weight_;
italic = italic_;
size = size_;
fontName = fontName_;
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- aliasOfDefaultFont = false;
+ font.ClearFont();
+ FontMeasurements::Clear();
}
void Style::ClearTo(const Style &source) {
Clear(
- source.fore.desired,
- source.back.desired,
- source.size,
- source.fontName,
- source.characterSet,
- source.bold,
- source.italic,
- source.eolFilled,
- source.underline,
- source.caseForce,
- source.visible,
- source.changeable,
- source.hotspot);
-}
-
-bool Style::EquivalentFontTo(const Style *other) const {
- if (bold != other->bold ||
- italic != other->italic ||
- size != other->size ||
- characterSet != other->characterSet)
- return false;
- if (fontName == other->fontName)
- return true;
- if (!fontName)
- return false;
- if (!other->fontName)
- return false;
- return strcmp(fontName, other->fontName) == 0;
+ source.fore,
+ source.back,
+ source.size,
+ source.fontName,
+ source.characterSet,
+ source.weight,
+ source.italic,
+ source.eolFilled,
+ source.underline,
+ source.caseForce,
+ source.visible,
+ source.changeable,
+ source.hotspot);
}
-void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
- sizeZoomed = size + zoomLevel;
- if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
- sizeZoomed = 2;
-
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
- aliasOfDefaultFont = defaultStyle &&
- (EquivalentFontTo(defaultStyle) || !fontName);
- if (aliasOfDefaultFont) {
- font.SetID(defaultStyle->font.GetID());
- } else if (fontName) {
- font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
- } else {
- font.SetID(0);
- }
-
- ascent = surface.Ascent(font);
- descent = surface.Descent(font);
- // Probably more typographically correct to include leading
- // but that means more complex drawing as leading must be erased
- //lineHeight = surface.ExternalLeading() + surface.Height();
- externalLeading = surface.ExternalLeading(font);
- lineHeight = surface.Height(font);
- aveCharWidth = surface.AverageCharWidth(font);
- spaceWidth = surface.WidthChar(font, ' ');
+void Style::Copy(Font &font_, const FontMeasurements &fm_) {
+ font.MakeAlias(font_);
+#if PLAT_WX
+ font.SetAscent(fm_.ascent);
+#endif
+ (FontMeasurements &)(*this) = fm_;
}
namespace Scintilla {
#endif
-/**
- */
-class Style {
-public:
- ColourPair fore;
- ColourPair back;
- bool aliasOfDefaultFont;
- bool bold;
+struct FontSpecification {
+ const char *fontName;
+ int weight;
bool italic;
int size;
- const char *fontName;
int characterSet;
+ int extraFontFlag;
+ FontSpecification() :
+ fontName(0),
+ weight(SC_WEIGHT_NORMAL),
+ italic(false),
+ size(10 * SC_FONT_SIZE_MULTIPLIER),
+ characterSet(0),
+ extraFontFlag(0) {
+ }
+ bool EqualTo(const FontSpecification &other) const;
+};
+
+// Just like Font but only has a copy of the FontID so should not delete it
+class FontAlias : public Font {
+ // Private so FontAlias objects can not be copied
+ FontAlias(const FontAlias &);
+ FontAlias &operator=(const FontAlias &);
+public:
+ FontAlias();
+ virtual ~FontAlias();
+ void MakeAlias(Font &fontOrigin);
+ void ClearFont();
+};
+
+struct FontMeasurements {
+ unsigned int ascent;
+ unsigned int descent;
+ XYPOSITION aveCharWidth;
+ XYPOSITION spaceWidth;
+ int sizeZoomed;
+ FontMeasurements();
+ void Clear();
+};
+
+/**
+ */
+class Style : public FontSpecification, public FontMeasurements {
+public:
+ ColourDesired fore;
+ ColourDesired back;
bool eolFilled;
bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower};
bool changeable;
bool hotspot;
- Font font;
- int sizeZoomed;
- unsigned int lineHeight;
- unsigned int ascent;
- unsigned int descent;
- unsigned int externalLeading;
- unsigned int aveCharWidth;
- unsigned int spaceWidth;
+ FontAlias font;
Style();
Style(const Style &source);
void Clear(ColourDesired fore_, ColourDesired back_,
int size_,
const char *fontName_, int characterSet_,
- bool bold_, bool italic_, bool eolFilled_,
+ int weight_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source);
- bool EquivalentFontTo(const Style *other) const;
- void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
- bool IsProtected() const { return !(changeable && visible);};
+ void Copy(Font &font_, const FontMeasurements &fm_);
+ bool IsProtected() const { return !(changeable && visible);}
};
#ifdef SCI_NAMESPACE
+++ /dev/null
-// Scintilla source code edit control
-/** @file StyleContext.cxx
- ** Lexer infrastructure.
- **/
-// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
-// This file is in the public domain.
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static void getRange(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = styler[start + i];
- i++;
- }
- s[i] = '\0';
-}
-
-void StyleContext::GetCurrent(char *s, unsigned int len) {
- getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len);
-}
-
-static void getRangeLowered(unsigned int start,
- unsigned int end,
- Accessor &styler,
- char *s,
- unsigned int len) {
- unsigned int i = 0;
- while ((i < end - start + 1) && (i < len-1)) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- i++;
- }
- s[i] = '\0';
-}
-
-void StyleContext::GetCurrentLowered(char *s, unsigned int len) {
- getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
-}
+++ /dev/null
-// Scintilla source code edit control
-/** @file StyleContext.cxx
- ** Lexer infrastructure.
- **/
-// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
-// This file is in the public domain.
-
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-// All languages handled so far can treat all characters >= 0x80 as one class
-// which just continues the current token or starts an identifier if in default.
-// DBCS treated specially as the second character can be < 0x80 and hence
-// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
-class StyleContext {
- Accessor &styler;
- unsigned int endPos;
- StyleContext& operator=(const StyleContext&);
- void GetNextChar(unsigned int pos) {
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
- }
- // End of line?
- // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
- // or on LF alone (Unix). Avoid triggering two times on Dos/Win.
- atLineEnd = (ch == '\r' && chNext != '\n') ||
- (ch == '\n') ||
- (currentPos >= endPos);
- }
-
-public:
- unsigned int currentPos;
- bool atLineStart;
- bool atLineEnd;
- int state;
- int chPrev;
- int ch;
- int chNext;
-
- StyleContext(unsigned int startPos, unsigned int length,
- int initStyle, Accessor &styler_, char chMask=31) :
- styler(styler_),
- endPos(startPos + length),
- currentPos(startPos),
- atLineStart(true),
- atLineEnd(false),
- state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
- chPrev(0),
- ch(0),
- chNext(0) {
- styler.StartAt(startPos, chMask);
- styler.StartSegment(startPos);
- unsigned int pos = currentPos;
- ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
- if (styler.IsLeadByte(static_cast<char>(ch))) {
- pos++;
- ch = ch << 8;
- ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
- }
- GetNextChar(pos);
- }
- void Complete() {
- styler.ColourTo(currentPos - 1, state);
- }
- bool More() {
- return currentPos < endPos;
- }
- void Forward() {
- if (currentPos < endPos) {
- atLineStart = atLineEnd;
- chPrev = ch;
- currentPos++;
- if (ch >= 0x100)
- currentPos++;
- ch = chNext;
- GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
- } else {
- atLineStart = false;
- chPrev = ' ';
- ch = ' ';
- chNext = ' ';
- atLineEnd = true;
- }
- }
- void Forward(int nb) {
- for (int i = 0; i < nb; i++) {
- Forward();
- }
- }
- void ChangeState(int state_) {
- state = state_;
- }
- void SetState(int state_) {
- styler.ColourTo(currentPos - 1, state);
- state = state_;
- }
- void ForwardSetState(int state_) {
- Forward();
- styler.ColourTo(currentPos - 1, state);
- state = state_;
- }
- int LengthCurrent() {
- return currentPos - styler.GetStartSegment();
- }
- int GetRelative(int n) {
- return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
- }
- bool Match(char ch0) {
- return ch == static_cast<unsigned char>(ch0);
- }
- bool Match(char ch0, char ch1) {
- return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
- }
- bool Match(const char *s) {
- if (ch != static_cast<unsigned char>(*s))
- return false;
- s++;
- if (!*s)
- return true;
- if (chNext != static_cast<unsigned char>(*s))
- return false;
- s++;
- for (int n=2; *s; n++) {
- if (*s != styler.SafeGetCharAt(currentPos+n))
- return false;
- s++;
- }
- return true;
- }
- bool MatchIgnoreCase(const char *s) {
- if (tolower(ch) != static_cast<unsigned char>(*s))
- return false;
- s++;
- if (tolower(chNext) != static_cast<unsigned char>(*s))
- return false;
- s++;
- for (int n=2; *s; n++) {
- if (static_cast<unsigned char>(*s) !=
- tolower(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
- return false;
- s++;
- }
- return true;
- }
- // Non-inline
- void GetCurrent(char *s, unsigned int len);
- void GetCurrentLowered(char *s, unsigned int len);
-};
-
-#ifdef SCI_NAMESPACE
-}
-#endif
-
-inline bool IsASpace(unsigned int ch) {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
-inline bool IsASpaceOrTab(unsigned int ch) {
- return (ch == ' ') || (ch == '\t');
-}
-
-inline bool IsADigit(unsigned int ch) {
- return (ch >= '0') && (ch <= '9');
-}
-
-inline bool IsADigit(unsigned int ch, unsigned int base) {
- if (base <= 10) {
- return (ch >= '0') && (ch < '0' + base);
- } else {
- return ((ch >= '0') && (ch <= '9')) ||
- ((ch >= 'A') && (ch < 'A' + base - 10)) ||
- ((ch >= 'a') && (ch < 'a' + base - 10));
- }
-}
// Scintilla source code edit control
/** @file UniConversion.cxx
- ** Functions to handle UFT-8 and UCS-2 strings.
+ ** Functions to handle UTF-8 and UTF-16 strings.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
putf[len] = '\0';
}
+unsigned int UTF8CharLength(unsigned char ch) {
+ if (ch < 0x80) {
+ return 1;
+ } else if (ch < 0x80 + 0x40 + 0x20) {
+ return 2;
+ } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
+ return 3;
+ } else {
+ return 4;
+ }
+}
+
unsigned int UTF16Length(const char *s, unsigned int len) {
unsigned int ulen = 0;
unsigned int charLen;
- for (unsigned int i=0;i<len;) {
+ for (unsigned int i=0; i<len;) {
unsigned char ch = static_cast<unsigned char>(s[i]);
if (ch < 0x80) {
charLen = 1;
}
return ui;
}
+
+int UTF8BytesOfLead[256];
+static bool initialisedBytesOfLead = false;
+
+static int BytesFromLead(int leadByte) {
+ if (leadByte < 0xC2) {
+ // Single byte or invalid
+ return 1;
+ } else if (leadByte < 0xE0) {
+ return 2;
+ } else if (leadByte < 0xF0) {
+ return 3;
+ } else if (leadByte < 0xF5) {
+ return 4;
+ } else {
+ // Characters longer than 4 bytes not possible in current UTF-8
+ return 1;
+ }
+}
+
+void UTF8BytesOfLeadInitialise() {
+ if (!initialisedBytesOfLead) {
+ for (int i=0;i<256;i++) {
+ UTF8BytesOfLead[i] = BytesFromLead(i);
+ }
+ initialisedBytesOfLead = true;
+ }
+}
+
+// Return both the width of the first character in the string and a status
+// saying whether it is valid or invalid.
+// Most invalid sequences return a width of 1 so are treated as isolated bytes but
+// the non-characters *FFFE, *FFFF and FDD0 .. FDEF return 3 or 4 as they can be
+// reasonably treated as code points in some circumstances. They will, however,
+// not have associated glyphs.
+int UTF8Classify(const unsigned char *us, int len) {
+ // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ if (*us < 0x80) {
+ // Single bytes easy
+ return 1;
+ } else if (*us > 0xf4) {
+ // Characters longer than 4 bytes not possible in current UTF-8
+ return UTF8MaskInvalid | 1;
+ } else if (*us >= 0xf0) {
+ // 4 bytes
+ if (len < 4)
+ return UTF8MaskInvalid | 1;
+ if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2]) && UTF8IsTrailByte(us[3])) {
+ if (((us[1] & 0xf) == 0xf) && (us[2] == 0xbf) && ((us[3] == 0xbe) || (us[3] == 0xbf))) {
+ // *FFFE or *FFFF non-character
+ return UTF8MaskInvalid | 4;
+ }
+ if (*us == 0xf4) {
+ // Check if encoding a value beyond the last Unicode character 10FFFF
+ if (us[1] > 0x8f) {
+ return UTF8MaskInvalid | 1;
+ } else if (us[1] == 0x8f) {
+ if (us[2] > 0xbf) {
+ return UTF8MaskInvalid | 1;
+ } else if (us[2] == 0xbf) {
+ if (us[3] > 0xbf) {
+ return UTF8MaskInvalid | 1;
+ }
+ }
+ }
+ } else if ((*us == 0xf0) && ((us[1] & 0xf0) == 0x80)) {
+ // Overlong
+ return UTF8MaskInvalid | 1;
+ }
+ return 4;
+ } else {
+ return UTF8MaskInvalid | 1;
+ }
+ } else if (*us >= 0xe0) {
+ // 3 bytes
+ if (len < 3)
+ return UTF8MaskInvalid | 1;
+ if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2])) {
+ if ((*us == 0xe0) && ((us[1] & 0xe0) == 0x80)) {
+ // Overlong
+ return UTF8MaskInvalid | 1;
+ }
+ if ((*us == 0xed) && ((us[1] & 0xe0) == 0xa0)) {
+ // Surrogate
+ return UTF8MaskInvalid | 1;
+ }
+ if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbe)) {
+ // U+FFFE non-character - 3 bytes long
+ return UTF8MaskInvalid | 3;
+ }
+ if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbf)) {
+ // U+FFFF non-character - 3 bytes long
+ return UTF8MaskInvalid | 3;
+ }
+ if ((*us == 0xef) && (us[1] == 0xb7) && (((us[2] & 0xf0) == 0x90) || ((us[2] & 0xf0) == 0xa0))) {
+ // U+FDD0 .. U+FDEF
+ return UTF8MaskInvalid | 3;
+ }
+ return 3;
+ } else {
+ return UTF8MaskInvalid | 1;
+ }
+ } else if (*us >= 0xc2) {
+ // 2 bytes
+ if (len < 2)
+ return UTF8MaskInvalid | 1;
+ if (UTF8IsTrailByte(us[1])) {
+ return 2;
+ } else {
+ return UTF8MaskInvalid | 1;
+ }
+ } else {
+ // 0xc0 .. 0xc1 is overlong encoding
+ // 0x80 .. 0xbf is trail byte
+ return UTF8MaskInvalid | 1;
+ }
+}
// Scintilla source code edit control
/** @file UniConversion.h
- ** Functions to handle UFT-8 and UCS-2 strings.
+ ** Functions to handle UTF-8 and UTF-16 strings.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+const int UTF8MaxBytes = 4;
+
unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen);
void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len);
+unsigned int UTF8CharLength(unsigned char ch);
unsigned int UTF16Length(const char *s, unsigned int len);
unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen);
+extern int UTF8BytesOfLead[256];
+void UTF8BytesOfLeadInitialise();
+
+inline bool UTF8IsTrailByte(int ch) {
+ return (ch >= 0x80) && (ch < 0xc0);
+}
+
+inline bool UTF8IsAscii(int ch) {
+ return ch < 0x80;
+}
+
+enum { UTF8MaskWidth=0x7, UTF8MaskInvalid=0x8 };
+int UTF8Classify(const unsigned char *us, int len);
#include <string.h>
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "Scintilla.h"
#endif
MarginStyle::MarginStyle() :
- style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false) {
+ style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
}
// A list of the fontnames - avoids wasting space in each style
}
void FontNames::Clear() {
- for (int i=0;i<max;i++) {
+ for (int i=0; i<max; i++) {
delete []names[i];
}
max = 0;
const char *FontNames::Save(const char *name) {
if (!name)
return 0;
- for (int i=0;i<max;i++) {
+ for (int i=0; i<max; i++) {
if (strcmp(names[i], name) == 0) {
return names[i];
}
// Grow array
int sizeNew = size * 2;
char **namesNew = new char *[sizeNew];
- for (int j=0;j<max;j++) {
+ for (int j=0; j<max; j++) {
namesNew[j] = names[j];
}
delete []names;
return names[max-1];
}
+FontRealised::FontRealised(const FontSpecification &fs) {
+ frNext = NULL;
+ (FontSpecification &)(*this) = fs;
+}
+
+FontRealised::~FontRealised() {
+ font.Release();
+ delete frNext;
+ frNext = 0;
+}
+
+void FontRealised::Realise(Surface &surface, int zoomLevel, int technology) {
+ PLATFORM_ASSERT(fontName);
+ sizeZoomed = size + zoomLevel * SC_FONT_SIZE_MULTIPLIER;
+ if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1
+ sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER;
+
+ float deviceHeight = surface.DeviceHeightFont(sizeZoomed);
+ FontParameters fp(fontName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, weight, italic, extraFontFlag, technology, characterSet);
+ font.Create(fp);
+
+ ascent = surface.Ascent(font);
+ descent = surface.Descent(font);
+ aveCharWidth = surface.AverageCharWidth(font);
+ spaceWidth = surface.WidthChar(font, ' ');
+ if (frNext) {
+ frNext->Realise(surface, zoomLevel, technology);
+ }
+}
+
+FontRealised *FontRealised::Find(const FontSpecification &fs) {
+ if (!fs.fontName)
+ return this;
+ FontRealised *fr = this;
+ while (fr) {
+ if (fr->EqualTo(fs))
+ return fr;
+ fr = fr->frNext;
+ }
+ return 0;
+}
+
+void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
+ FontRealised *fr = this;
+ while (fr) {
+ if (maxAscent < fr->ascent)
+ maxAscent = fr->ascent;
+ if (maxDescent < fr->descent)
+ maxDescent = fr->descent;
+ fr = fr->frNext;
+ }
+}
+
ViewStyle::ViewStyle() {
Init();
}
ViewStyle::ViewStyle(const ViewStyle &source) {
+ frFirst = NULL;
Init(source.stylesSize);
- for (unsigned int sty=0;sty<source.stylesSize;sty++) {
+ for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty];
// Can't just copy fontname as its lifetime is relative to its owning ViewStyle
styles[sty].fontName = fontNames.Save(source.styles[sty].fontName);
}
- for (int mrk=0;mrk<=MARKER_MAX;mrk++) {
+ for (int mrk=0; mrk<=MARKER_MAX; mrk++) {
markers[mrk] = source.markers[mrk];
}
- for (int ind=0;ind<=INDIC_MAX;ind++) {
+ CalcLargestMarkerHeight();
+ for (int ind=0; ind<=INDIC_MAX; ind++) {
indicators[ind] = source.indicators[ind];
}
selforeset = source.selforeset;
- selforeground.desired = source.selforeground.desired;
- selAdditionalForeground.desired = source.selAdditionalForeground.desired;
+ selforeground = source.selforeground;
+ selAdditionalForeground = source.selAdditionalForeground;
selbackset = source.selbackset;
- selbackground.desired = source.selbackground.desired;
- selAdditionalBackground.desired = source.selAdditionalBackground.desired;
- selbackground2.desired = source.selbackground2.desired;
+ selbackground = source.selbackground;
+ selAdditionalBackground = source.selAdditionalBackground;
+ selbackground2 = source.selbackground2;
selAlpha = source.selAlpha;
selAdditionalAlpha = source.selAdditionalAlpha;
selEOLFilled = source.selEOLFilled;
foldmarginColourSet = source.foldmarginColourSet;
- foldmarginColour.desired = source.foldmarginColour.desired;
+ foldmarginColour = source.foldmarginColour;
foldmarginHighlightColourSet = source.foldmarginHighlightColourSet;
- foldmarginHighlightColour.desired = source.foldmarginHighlightColour.desired;
+ foldmarginHighlightColour = source.foldmarginHighlightColour;
hotspotForegroundSet = source.hotspotForegroundSet;
- hotspotForeground.desired = source.hotspotForeground.desired;
+ hotspotForeground = source.hotspotForeground;
hotspotBackgroundSet = source.hotspotBackgroundSet;
- hotspotBackground.desired = source.hotspotBackground.desired;
+ hotspotBackground = source.hotspotBackground;
hotspotUnderline = source.hotspotUnderline;
hotspotSingleLine = source.hotspotSingleLine;
whitespaceForegroundSet = source.whitespaceForegroundSet;
- whitespaceForeground.desired = source.whitespaceForeground.desired;
+ whitespaceForeground = source.whitespaceForeground;
whitespaceBackgroundSet = source.whitespaceBackgroundSet;
- whitespaceBackground.desired = source.whitespaceBackground.desired;
- selbar.desired = source.selbar.desired;
- selbarlight.desired = source.selbarlight.desired;
- caretcolour.desired = source.caretcolour.desired;
- additionalCaretColour.desired = source.additionalCaretColour.desired;
+ whitespaceBackground = source.whitespaceBackground;
+ selbar = source.selbar;
+ selbarlight = source.selbarlight;
+ caretcolour = source.caretcolour;
+ additionalCaretColour = source.additionalCaretColour;
showCaretLineBackground = source.showCaretLineBackground;
- caretLineBackground.desired = source.caretLineBackground.desired;
+ caretLineBackground = source.caretLineBackground;
caretLineAlpha = source.caretLineAlpha;
- edgecolour.desired = source.edgecolour.desired;
+ edgecolour = source.edgecolour;
edgeState = source.edgeState;
caretStyle = source.caretStyle;
caretWidth = source.caretWidth;
someStylesProtected = false;
+ someStylesForceCase = false;
leftMarginWidth = source.leftMarginWidth;
rightMarginWidth = source.rightMarginWidth;
- for (int i=0;i < margins; i++) {
+ for (int i=0; i < margins; i++) {
ms[i] = source.ms[i];
}
- symbolMargin = source.symbolMargin;
maskInLine = source.maskInLine;
fixedColumnWidth = source.fixedColumnWidth;
zoomLevel = source.zoomLevel;
whitespaceSize = source.whitespaceSize;
viewIndentationGuides = source.viewIndentationGuides;
viewEOL = source.viewEOL;
- showMarkedLines = source.showMarkedLines;
extraFontFlag = source.extraFontFlag;
extraAscent = source.extraAscent;
extraDescent = source.extraDescent;
marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset;
+ braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
+ braceHighlightIndicator = source.braceHighlightIndicator;
+ braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
+ braceBadLightIndicator = source.braceBadLightIndicator;
}
ViewStyle::~ViewStyle() {
delete []styles;
styles = NULL;
+ delete frFirst;
+ frFirst = NULL;
}
void ViewStyle::Init(size_t stylesSize_) {
+ frFirst = NULL;
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
fontNames.Clear();
ResetDefaultStyle();
+ // There are no image markers by default, so no need for calling CalcLargestMarkerHeight()
+ largestMarkerHeight = 0;
+
indicators[0].style = INDIC_SQUIGGLE;
indicators[0].under = false;
indicators[0].fore = ColourDesired(0, 0x7f, 0);
indicators[2].under = false;
indicators[2].fore = ColourDesired(0xff, 0, 0);
+ technology = SC_TECHNOLOGY_DEFAULT;
lineHeight = 1;
maxAscent = 1;
maxDescent = 1;
spaceWidth = 8;
selforeset = false;
- selforeground.desired = ColourDesired(0xff, 0, 0);
- selAdditionalForeground.desired = ColourDesired(0xff, 0, 0);
+ selforeground = ColourDesired(0xff, 0, 0);
+ selAdditionalForeground = ColourDesired(0xff, 0, 0);
selbackset = true;
- selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0);
- selAdditionalBackground.desired = ColourDesired(0xd7, 0xd7, 0xd7);
- selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0);
+ selbackground = ColourDesired(0xc0, 0xc0, 0xc0);
+ selAdditionalBackground = ColourDesired(0xd7, 0xd7, 0xd7);
+ selbackground2 = ColourDesired(0xb0, 0xb0, 0xb0);
selAlpha = SC_ALPHA_NOALPHA;
selAdditionalAlpha = SC_ALPHA_NOALPHA;
selEOLFilled = false;
foldmarginColourSet = false;
- foldmarginColour.desired = ColourDesired(0xff, 0, 0);
+ foldmarginColour = ColourDesired(0xff, 0, 0);
foldmarginHighlightColourSet = false;
- foldmarginHighlightColour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+ foldmarginHighlightColour = ColourDesired(0xc0, 0xc0, 0xc0);
whitespaceForegroundSet = false;
- whitespaceForeground.desired = ColourDesired(0, 0, 0);
+ whitespaceForeground = ColourDesired(0, 0, 0);
whitespaceBackgroundSet = false;
- whitespaceBackground.desired = ColourDesired(0xff, 0xff, 0xff);
- selbar.desired = Platform::Chrome();
- selbarlight.desired = Platform::ChromeHighlight();
- styles[STYLE_LINENUMBER].fore.desired = ColourDesired(0, 0, 0);
- styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
- caretcolour.desired = ColourDesired(0, 0, 0);
- additionalCaretColour.desired = ColourDesired(0x7f, 0x7f, 0x7f);
+ whitespaceBackground = ColourDesired(0xff, 0xff, 0xff);
+ selbar = Platform::Chrome();
+ selbarlight = Platform::ChromeHighlight();
+ styles[STYLE_LINENUMBER].fore = ColourDesired(0, 0, 0);
+ styles[STYLE_LINENUMBER].back = Platform::Chrome();
+ caretcolour = ColourDesired(0, 0, 0);
+ additionalCaretColour = ColourDesired(0x7f, 0x7f, 0x7f);
showCaretLineBackground = false;
- caretLineBackground.desired = ColourDesired(0xff, 0xff, 0);
+ caretLineBackground = ColourDesired(0xff, 0xff, 0);
caretLineAlpha = SC_ALPHA_NOALPHA;
- edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+ edgecolour = ColourDesired(0xc0, 0xc0, 0xc0);
edgeState = EDGE_NONE;
caretStyle = CARETSTYLE_LINE;
caretWidth = 1;
someStylesProtected = false;
+ someStylesForceCase = false;
hotspotForegroundSet = false;
- hotspotForeground.desired = ColourDesired(0, 0, 0xff);
+ hotspotForeground = ColourDesired(0, 0, 0xff);
hotspotBackgroundSet = false;
- hotspotBackground.desired = ColourDesired(0xff, 0xff, 0xff);
+ hotspotBackground = ColourDesired(0xff, 0xff, 0xff);
hotspotUnderline = true;
hotspotSingleLine = true;
ms[2].width = 0;
ms[2].mask = 0;
fixedColumnWidth = leftMarginWidth;
- symbolMargin = false;
maskInLine = 0xffffffff;
for (int margin=0; margin < margins; margin++) {
fixedColumnWidth += ms[margin].width;
- symbolMargin = symbolMargin || (ms[margin].style != SC_MARGIN_NUMBER);
if (ms[margin].width > 0)
maskInLine &= ~ms[margin].mask;
}
whitespaceSize = 1;
viewIndentationGuides = ivNone;
viewEOL = false;
- showMarkedLines = true;
extraFontFlag = 0;
extraAscent = 0;
extraDescent = 0;
marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0;
+ braceHighlightIndicatorSet = false;
+ braceHighlightIndicator = 0;
+ braceBadLightIndicatorSet = false;
+ braceBadLightIndicator = 0;
}
-void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
- unsigned int i;
- for (i=0;i<stylesSize;i++) {
- pal.WantFind(styles[i].fore, want);
- pal.WantFind(styles[i].back, want);
- }
- for (i=0;i<(sizeof(indicators)/sizeof(indicators[0]));i++) {
- pal.WantFind(indicators[i].fore, want);
- }
- for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) {
- markers[i].RefreshColourPalette(pal, want);
+void ViewStyle::CreateFont(const FontSpecification &fs) {
+ if (fs.fontName) {
+ for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
+ if (cur->EqualTo(fs))
+ return;
+ if (!cur->frNext) {
+ cur->frNext = new FontRealised(fs);
+ return;
+ }
+ }
+ frFirst = new FontRealised(fs);
}
- pal.WantFind(selforeground, want);
- pal.WantFind(selAdditionalForeground, want);
- pal.WantFind(selbackground, want);
- pal.WantFind(selAdditionalBackground, want);
- pal.WantFind(selbackground2, want);
-
- pal.WantFind(foldmarginColour, want);
- pal.WantFind(foldmarginHighlightColour, want);
-
- pal.WantFind(whitespaceForeground, want);
- pal.WantFind(whitespaceBackground, want);
- pal.WantFind(selbar, want);
- pal.WantFind(selbarlight, want);
- pal.WantFind(caretcolour, want);
- pal.WantFind(additionalCaretColour, want);
- pal.WantFind(caretLineBackground, want);
- pal.WantFind(edgecolour, want);
- pal.WantFind(hotspotForeground, want);
- pal.WantFind(hotspotBackground, want);
}
void ViewStyle::Refresh(Surface &surface) {
- selbar.desired = Platform::Chrome();
- selbarlight.desired = Platform::ChromeHighlight();
- styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
- maxAscent = styles[STYLE_DEFAULT].ascent;
- maxDescent = styles[STYLE_DEFAULT].descent;
- someStylesProtected = false;
+ delete frFirst;
+ frFirst = NULL;
+ selbar = Platform::Chrome();
+ selbarlight = Platform::ChromeHighlight();
+
for (unsigned int i=0; i<stylesSize; i++) {
- if (i != STYLE_DEFAULT) {
- styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
- if (maxAscent < styles[i].ascent)
- maxAscent = styles[i].ascent;
- if (maxDescent < styles[i].descent)
- maxDescent = styles[i].descent;
- }
- if (styles[i].IsProtected()) {
- someStylesProtected = true;
- }
+ styles[i].extraFontFlag = extraFontFlag;
}
+
+ CreateFont(styles[STYLE_DEFAULT]);
+ for (unsigned int j=0; j<stylesSize; j++) {
+ CreateFont(styles[j]);
+ }
+
+ frFirst->Realise(surface, zoomLevel, technology);
+
+ for (unsigned int k=0; k<stylesSize; k++) {
+ FontRealised *fr = frFirst->Find(styles[k]);
+ styles[k].Copy(fr->font, *fr);
+ }
+ maxAscent = 1;
+ maxDescent = 1;
+ frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
maxAscent += extraAscent;
maxDescent += extraDescent;
-
lineHeight = maxAscent + maxDescent;
+
+ someStylesProtected = false;
+ someStylesForceCase = false;
+ for (unsigned int l=0; l<stylesSize; l++) {
+ if (styles[l].IsProtected()) {
+ someStylesProtected = true;
+ }
+ if (styles[l].caseForce != Style::caseMixed) {
+ someStylesForceCase = true;
+ }
+ }
+
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
fixedColumnWidth = leftMarginWidth;
- symbolMargin = false;
maskInLine = 0xffffffff;
for (int margin=0; margin < margins; margin++) {
fixedColumnWidth += ms[margin].width;
- symbolMargin = symbolMargin || (ms[margin].style != SC_MARGIN_NUMBER);
if (ms[margin].width > 0)
maskInLine &= ~ms[margin].mask;
}
void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
- ColourDesired(0xff,0xff,0xff),
- Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
- SC_CHARSET_DEFAULT,
- false, false, false, false, Style::caseMixed, true, true, false);
+ ColourDesired(0xff,0xff,0xff),
+ Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, fontNames.Save(Platform::DefaultFont()),
+ SC_CHARSET_DEFAULT,
+ SC_WEIGHT_NORMAL, false, false, false, Style::caseMixed, true, true, false);
}
void ViewStyle::ClearStyles() {
styles[i].ClearTo(styles[STYLE_DEFAULT]);
}
}
- styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
+ styles[STYLE_LINENUMBER].back = Platform::Chrome();
// Set call tip fore/back to match the values previously set for call tips
- styles[STYLE_CALLTIP].back.desired = ColourDesired(0xff, 0xff, 0xff);
- styles[STYLE_CALLTIP].fore.desired = ColourDesired(0x80, 0x80, 0x80);
+ styles[STYLE_CALLTIP].back = ColourDesired(0xff, 0xff, 0xff);
+ styles[STYLE_CALLTIP].fore = ColourDesired(0x80, 0x80, 0x80);
}
void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
return styleIndex < stylesSize;
}
+void ViewStyle::CalcLargestMarkerHeight() {
+ largestMarkerHeight = 0;
+ for (int m = 0; m <= MARKER_MAX; ++m) {
+ switch (markers[m].markType) {
+ case SC_MARK_PIXMAP:
+ if (markers[m].pxpm->GetHeight() > largestMarkerHeight)
+ largestMarkerHeight = markers[m].pxpm->GetHeight();
+ break;
+ case SC_MARK_RGBAIMAGE:
+ if (markers[m].image->GetHeight() > largestMarkerHeight)
+ largestMarkerHeight = markers[m].image->GetHeight();
+ break;
+ }
+ }
+}
+
int width;
int mask;
bool sensitive;
+ int cursor;
MarginStyle();
};
const char *Save(const char *name);
};
+class FontRealised : public FontSpecification, public FontMeasurements {
+ // Private so FontRealised objects can not be copied
+ FontRealised(const FontRealised &);
+ FontRealised &operator=(const FontRealised &);
+public:
+ Font font;
+ FontRealised *frNext;
+ FontRealised(const FontSpecification &fs);
+ virtual ~FontRealised();
+ void Realise(Surface &surface, int zoomLevel, int technology);
+ FontRealised *Find(const FontSpecification &fs);
+ void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
+};
+
enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
class ViewStyle {
public:
FontNames fontNames;
+ FontRealised *frFirst;
size_t stylesSize;
Style *styles;
LineMarker markers[MARKER_MAX + 1];
+ int largestMarkerHeight;
Indicator indicators[INDIC_MAX + 1];
+ int technology;
int lineHeight;
unsigned int maxAscent;
unsigned int maxDescent;
- unsigned int aveCharWidth;
- unsigned int spaceWidth;
+ XYPOSITION aveCharWidth;
+ XYPOSITION spaceWidth;
bool selforeset;
- ColourPair selforeground;
- ColourPair selAdditionalForeground;
+ ColourDesired selforeground;
+ ColourDesired selAdditionalForeground;
bool selbackset;
- ColourPair selbackground;
- ColourPair selAdditionalBackground;
- ColourPair selbackground2;
+ ColourDesired selbackground;
+ ColourDesired selAdditionalBackground;
+ ColourDesired selbackground2;
int selAlpha;
int selAdditionalAlpha;
bool selEOLFilled;
bool whitespaceForegroundSet;
- ColourPair whitespaceForeground;
+ ColourDesired whitespaceForeground;
bool whitespaceBackgroundSet;
- ColourPair whitespaceBackground;
- ColourPair selbar;
- ColourPair selbarlight;
+ ColourDesired whitespaceBackground;
+ ColourDesired selbar;
+ ColourDesired selbarlight;
bool foldmarginColourSet;
- ColourPair foldmarginColour;
+ ColourDesired foldmarginColour;
bool foldmarginHighlightColourSet;
- ColourPair foldmarginHighlightColour;
+ ColourDesired foldmarginHighlightColour;
bool hotspotForegroundSet;
- ColourPair hotspotForeground;
+ ColourDesired hotspotForeground;
bool hotspotBackgroundSet;
- ColourPair hotspotBackground;
+ ColourDesired hotspotBackground;
bool hotspotUnderline;
bool hotspotSingleLine;
/// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin
enum { margins=5 };
int leftMarginWidth; ///< Spacing margin on left of text
- int rightMarginWidth; ///< Spacing margin on left of text
- bool symbolMargin;
+ int rightMarginWidth; ///< Spacing margin on right of text
int maskInLine; ///< Mask for markers to be put into text because there is nowhere for them to go in margin
MarginStyle ms[margins];
int fixedColumnWidth;
int whitespaceSize;
IndentView viewIndentationGuides;
bool viewEOL;
- bool showMarkedLines;
- ColourPair caretcolour;
- ColourPair additionalCaretColour;
+ ColourDesired caretcolour;
+ ColourDesired additionalCaretColour;
bool showCaretLineBackground;
- ColourPair caretLineBackground;
+ ColourDesired caretLineBackground;
int caretLineAlpha;
- ColourPair edgecolour;
+ ColourDesired edgecolour;
int edgeState;
int caretStyle;
int caretWidth;
bool someStylesProtected;
+ bool someStylesForceCase;
int extraFontFlag;
int extraAscent;
int extraDescent;
int marginStyleOffset;
int annotationVisible;
int annotationStyleOffset;
+ bool braceHighlightIndicatorSet;
+ int braceHighlightIndicator;
+ bool braceBadLightIndicatorSet;
+ int braceBadLightIndicator;
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void Init(size_t stylesSize_=64);
- void RefreshColourPalette(Palette &pal, bool want);
+ void CreateFont(const FontSpecification &fs);
void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew);
void EnsureStyle(size_t index);
void SetStyleFontName(int styleIndex, const char *name);
bool ProtectionActive() const;
bool ValidStyle(size_t styleIndex) const;
+ void CalcLargestMarkerHeight();
};
#ifdef SCI_NAMESPACE
+++ /dev/null
-// Scintilla source code edit control
-/** @file WindowAccessor.cxx
- ** Rapid easy access to contents of a Scintilla.
- **/
-// 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 <ctype.h>
-#include <stdio.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "WindowAccessor.h"
-#include "Scintilla.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-WindowAccessor::~WindowAccessor() {
-}
-
-bool WindowAccessor::InternalIsLeadByte(char ch) {
- if (SC_CP_UTF8 == codePage)
- // For lexing, all characters >= 0x80 are treated the
- // same so none is considered a lead byte.
- return false;
- else
- return Platform::IsDBCSLeadByte(codePage, ch);
-}
-
-void WindowAccessor::Fill(int position) {
- if (lenDoc == -1)
- lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0);
- startPos = position - slopSize;
- if (startPos + bufferSize > lenDoc)
- startPos = lenDoc - bufferSize;
- if (startPos < 0)
- startPos = 0;
- endPos = startPos + bufferSize;
- if (endPos > lenDoc)
- endPos = lenDoc;
-
- Sci_TextRange tr = {{startPos, endPos}, buf};
- Platform::SendScintillaPointer(id, SCI_GETTEXTRANGE, 0, &tr);
-}
-
-bool WindowAccessor::Match(int pos, const char *s) {
- for (int i=0; *s; i++) {
- if (*s != SafeGetCharAt(pos+i))
- return false;
- s++;
- }
- return true;
-}
-
-char WindowAccessor::StyleAt(int position) {
- return static_cast<char>(Platform::SendScintilla(
- id, SCI_GETSTYLEAT, position, 0));
-}
-
-int WindowAccessor::GetLine(int position) {
- return Platform::SendScintilla(id, SCI_LINEFROMPOSITION, position, 0);
-}
-
-int WindowAccessor::LineStart(int line) {
- return Platform::SendScintilla(id, SCI_POSITIONFROMLINE, line, 0);
-}
-
-int WindowAccessor::LevelAt(int line) {
- return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0);
-}
-
-int WindowAccessor::Length() {
- if (lenDoc == -1)
- lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0);
- return lenDoc;
-}
-
-int WindowAccessor::GetLineState(int line) {
- return Platform::SendScintilla(id, SCI_GETLINESTATE, line);
-}
-
-int WindowAccessor::SetLineState(int line, int state) {
- return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state);
-}
-
-void WindowAccessor::StartAt(unsigned int start, char chMask) {
- Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask);
-}
-
-void WindowAccessor::StartSegment(unsigned int pos) {
- startSeg = pos;
-}
-
-void WindowAccessor::ColourTo(unsigned int pos, int chAttr) {
- // Only perform styling if non empty range
- if (pos != startSeg - 1) {
- if (pos < startSeg) {
- Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos);
- }
-
- if (validLen + (pos - startSeg + 1) >= bufferSize)
- Flush();
- if (validLen + (pos - startSeg + 1) >= bufferSize) {
- // Too big for buffer so send directly
- Platform::SendScintilla(id, SCI_SETSTYLING, pos - startSeg + 1, chAttr);
- } else {
- if (chAttr != chWhile)
- chFlags = 0;
- chAttr |= chFlags;
- for (unsigned int i = startSeg; i <= pos; i++) {
- styleBuf[validLen++] = static_cast<char>(chAttr);
- }
- }
- }
- startSeg = pos+1;
-}
-
-void WindowAccessor::SetLevel(int line, int level) {
- Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level);
-}
-
-void WindowAccessor::Flush() {
- startPos = extremePosition;
- lenDoc = -1;
- if (validLen > 0) {
- Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
- styleBuf);
- validLen = 0;
- }
-}
-
-int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
- int end = Length();
- int spaceFlags = 0;
-
- // Determines the indentation level of the current line and also checks for consistent
- // indentation compared to the previous line.
- // Indentation is judged consistent when the indentation whitespace of each line lines
- // the same or the indentation of one line is a prefix of the other.
-
- int pos = LineStart(line);
- char ch = (*this)[pos];
- int indent = 0;
- bool inPrevPrefix = line > 0;
- int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
- while ((ch == ' ' || ch == '\t') && (pos < end)) {
- if (inPrevPrefix) {
- char chPrev = (*this)[posPrev++];
- if (chPrev == ' ' || chPrev == '\t') {
- if (chPrev != ch)
- spaceFlags |= wsInconsistent;
- } else {
- inPrevPrefix = false;
- }
- }
- if (ch == ' ') {
- spaceFlags |= wsSpace;
- indent++;
- } else { // Tab
- spaceFlags |= wsTab;
- if (spaceFlags & wsSpace)
- spaceFlags |= wsSpaceTab;
- indent = (indent / 8 + 1) * 8;
- }
- ch = (*this)[++pos];
- }
-
- *flags = spaceFlags;
- indent += SC_FOLDLEVELBASE;
- // if completely empty line or the start of a comment...
- if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
- return indent | SC_FOLDLEVELWHITEFLAG;
- else
- return indent;
-}
-
-void WindowAccessor::IndicatorFill(int start, int end, int indicator, int value) {
- Platform::SendScintilla(id, SCI_SETINDICATORCURRENT, indicator);
- if (value) {
- Platform::SendScintilla(id, SCI_SETINDICATORVALUE, value);
- Platform::SendScintilla(id, SCI_INDICATORFILLRANGE, start, end - start);
- } else {
- Platform::SendScintilla(id, SCI_INDICATORCLEARRANGE, start, end - start);
- }
-}
#include <string.h>
#include <stdlib.h>
+#include <vector>
+#include <map>
+
#include "Platform.h"
#include "XPM.h"
return i;
}
-ColourAllocated XPM::ColourFromCode(int ch) {
- return colourCodeTable[ch]->allocated;
-#ifdef SLOW
- for (int i=0; i<nColours; i++) {
- if (codes[i] == ch) {
- return colours[i].allocated;
- }
- }
- return colours[0].allocated;
-#endif
+ColourDesired XPM::ColourDesiredFromCode(int ch) const {
+ return *colourCodeTable[ch];
+}
+
+ColourDesired XPM::ColourFromCode(int ch) const {
+ return *colourCodeTable[ch];
}
void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
Init(textForm);
}
-XPM::XPM(const char * const *linesForm) :
+XPM::XPM(const char *const *linesForm) :
data(0), codes(0), colours(0), lines(0) {
Init(linesForm);
}
}
}
-void XPM::Init(const char * const *linesForm) {
+void XPM::Init(const char *const *linesForm) {
Clear();
height = 1;
width = 1;
return;
}
codes = new char[nColours];
- colours = new ColourPair[nColours];
+ colours = new ColourDesired[nColours];
int strings = 1+height+nColours;
lines = new char *[strings];
codes[c] = colourDef[0];
colourDef += 4;
if (*colourDef == '#') {
- colours[c].desired.Set(colourDef);
+ colours[c].Set(colourDef);
} else {
- colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
+ colours[c] = ColourDesired(0xff, 0xff, 0xff);
codeTransparent = codes[c];
}
colourCodeTable[static_cast<unsigned char>(codes[c])] = &(colours[c]);
lines = 0;
}
-void XPM::RefreshColourPalette(Palette &pal, bool want) {
- if (!data || !codes || !colours || !lines) {
- return;
- }
- for (int i=0; i<nColours; i++) {
- pal.WantFind(colours[i], want);
- }
-}
-
-void XPM::CopyDesiredColours() {
- if (!data || !codes || !colours || !lines) {
- return;
- }
- for (int i=0; i<nColours; i++) {
- colours[i].Copy();
- }
-}
-
void XPM::Draw(Surface *surface, PRectangle &rc) {
if (!data || !codes || !colours || !lines) {
return;
// Centre the pixmap
int startY = rc.top + (rc.Height() - height) / 2;
int startX = rc.left + (rc.Width() - width) / 2;
- for (int y=0;y<height;y++) {
+ for (int y=0; y<height; y++) {
int prevCode = 0;
int xStartRun = 0;
for (int x=0; x<width; x++) {
}
}
+void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const {
+ if (!data || !codes || !colours || !lines || (x<0) || (x >= width) || (y<0) || (y >= height)) {
+ colour = 0;
+ transparent = true;
+ return;
+ }
+ int code = lines[y+nColours+1][x];
+ transparent = code == codeTransparent;
+ if (transparent) {
+ colour = 0;
+ } else {
+ colour = ColourDesiredFromCode(code).AsLong();
+ }
+}
+
const char **XPM::LinesFormFromTextForm(const char *textForm) {
// Build the lines form out of the text form
const char **linesForm = 0;
width = -1;
}
-void XPMSet::Add(int id, const char *textForm) {
+void XPMSet::Add(int ident, const char *textForm) {
// Invalidate cached dimensions
height = -1;
width = -1;
// Replace if this id already present
for (int i = 0; i < len; i++) {
- if (set[i]->GetId() == id) {
+ if (set[i]->GetId() == ident) {
set[i]->Init(textForm);
- set[i]->CopyDesiredColours();
return;
}
}
// Not present, so add to end
XPM *pxpm = new XPM(textForm);
if (pxpm) {
- pxpm->SetId(id);
- pxpm->CopyDesiredColours();
+ pxpm->SetId(ident);
if (len == maximum) {
maximum += 64;
XPM **setNew = new XPM *[maximum];
}
}
-XPM *XPMSet::Get(int id) {
+XPM *XPMSet::Get(int ident) {
for (int i = 0; i < len; i++) {
- if (set[i]->GetId() == id) {
+ if (set[i]->GetId() == ident) {
return set[i];
}
}
}
return (width > 0) ? width : 0;
}
+
+RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
+ height(height_), width(width_) {
+ if (pixels_) {
+ pixelBytes.assign(pixels_, pixels_ + CountBytes());
+ } else {
+ pixelBytes.resize(CountBytes());
+ }
+}
+
+RGBAImage::RGBAImage(const XPM &xpm) {
+ height = xpm.GetHeight();
+ width = xpm.GetWidth();
+ pixelBytes.resize(CountBytes());
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ ColourDesired colour;
+ bool transparent = false;
+ xpm.PixelAt(x, y, colour, transparent);
+ SetPixel(x, y, colour, transparent ? 0 : 255);
+ }
+ }
+}
+
+RGBAImage::~RGBAImage() {
+}
+
+int RGBAImage::CountBytes() const {
+ return width * height * 4;
+}
+
+const unsigned char *RGBAImage::Pixels() const {
+ return &pixelBytes[0];
+}
+
+void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
+ unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4;
+ // RGBA
+ pixel[0] = colour.GetRed();
+ pixel[1] = colour.GetGreen();
+ pixel[2] = colour.GetBlue();
+ pixel[3] = alpha;
+}
+
+RGBAImageSet::RGBAImageSet() : height(-1), width(-1){
+}
+
+RGBAImageSet::~RGBAImageSet() {
+ Clear();
+}
+
+/// Remove all images.
+void RGBAImageSet::Clear() {
+ for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) {
+ delete it->second;
+ it->second = 0;
+ }
+ images.clear();
+ height = -1;
+ width = -1;
+}
+
+/// Add an image.
+void RGBAImageSet::Add(int ident, RGBAImage *image) {
+ ImageMap::iterator it=images.find(ident);
+ if (it == images.end()) {
+ images[ident] = image;
+ } else {
+ delete it->second;
+ it->second = image;
+ }
+ height = -1;
+ width = -1;
+}
+
+/// Get image by id.
+RGBAImage *RGBAImageSet::Get(int ident) {
+ ImageMap::iterator it = images.find(ident);
+ if (it != images.end()) {
+ return it->second;
+ }
+ return NULL;
+}
+
+/// Give the largest height of the set.
+int RGBAImageSet::GetHeight() const {
+ if (height < 0) {
+ for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
+ if (height < it->second->GetHeight()) {
+ height = it->second->GetHeight();
+ }
+ }
+ }
+ return (height > 0) ? height : 0;
+}
+
+/// Give the largest width of the set.
+int RGBAImageSet::GetWidth() const {
+ if (width < 0) {
+ for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
+ if (width < it->second->GetWidth()) {
+ width = it->second->GetWidth();
+ }
+ }
+ }
+ return (width > 0) ? width : 0;
+}
char *data;
char codeTransparent;
char *codes;
- ColourPair *colours;
- ColourAllocated ColourFromCode(int ch);
+ ColourDesired *colours;
+ ColourDesired ColourDesiredFromCode(int ch) const;
+ ColourDesired ColourFromCode(int ch) const;
void FillRun(Surface *surface, int code, int startX, int y, int x);
char **lines;
- ColourPair *colourCodeTable[256];
+ ColourDesired *colourCodeTable[256];
public:
XPM(const char *textForm);
- XPM(const char * const *linesForm);
+ XPM(const char *const *linesForm);
~XPM();
void Init(const char *textForm);
- void Init(const char * const *linesForm);
+ void Init(const char *const *linesForm);
void Clear();
- /// Similar to same named method in ViewStyle:
- void RefreshColourPalette(Palette &pal, bool want);
- /// No palette used, so just copy the desired colours to the allocated colours
- void CopyDesiredColours();
/// Decompose image into runs and use FillRectangle for each run
void Draw(Surface *surface, PRectangle &rc);
char **InLinesForm() { return lines; }
void SetId(int pid_) { pid = pid_; }
- int GetId() { return pid; }
- int GetHeight() { return height; }
- int GetWidth() { return width; }
+ int GetId() const { return pid; }
+ int GetHeight() const { return height; }
+ int GetWidth() const { return width; }
+ void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const;
static const char **LinesFormFromTextForm(const char *textForm);
};
/// Remove all XPMs.
void Clear();
/// Add a XPM.
- void Add(int id, const char *textForm);
+ void Add(int ident, const char *textForm);
/// Get XPM by id.
- XPM *Get(int id);
+ XPM *Get(int ident);
/// Give the largest height of the set.
int GetHeight();
/// Give the largest width of the set.
int GetWidth();
};
+/**
+ * An translucent image stoed as a sequence of RGBA bytes.
+ */
+class RGBAImage {
+ // Private so RGBAImage objects can not be copied
+ RGBAImage(const RGBAImage &);
+ RGBAImage &operator=(const RGBAImage &);
+ int height;
+ int width;
+ std::vector<unsigned char> pixelBytes;
+public:
+ RGBAImage(int width_, int height_, const unsigned char *pixels_);
+ RGBAImage(const XPM &xpm);
+ virtual ~RGBAImage();
+ int GetHeight() const { return height; }
+ int GetWidth() const { return width; }
+ int CountBytes() const;
+ const unsigned char *Pixels() const;
+ void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff);
+};
+
+/**
+ * A collection of RGBAImage pixmaps indexed by integer id.
+ */
+class RGBAImageSet {
+ typedef std::map<int, RGBAImage*> ImageMap;
+ ImageMap images;
+ mutable int height; ///< Memorize largest height of the set.
+ mutable int width; ///< Memorize largest width of the set.
+public:
+ RGBAImageSet();
+ ~RGBAImageSet();
+ /// Remove all images.
+ void Clear();
+ /// Add an image.
+ void Add(int ident, RGBAImage *image);
+ /// Get image by id.
+ RGBAImage *Get(int ident);
+ /// Give the largest height of the set.
+ int GetHeight() const;
+ /// Give the largest width of the set.
+ int GetWidth() const;
+};
+
#ifdef SCI_NAMESPACE
}
#endif
+++ /dev/null
-#*****************************************************************************
-# *
-# Make file for VMS *
-# Author : J.Jansen (joukj@hrem.nano.tudelft.nl) *
-# Date : 27 September 2011 *
-# *
-#*****************************************************************************
-
-.first
- define wx [----.include.wx]
-
-.suffixes : .cpp
-
-.ifdef __WXMOTIF__
-CXX_DEFINE = /define=(__WX__=1,__WXMOTIF__=1,__USE_STD_IOSTREAM=1)/name=(as_is,short)\
- /assume=(nostdnew,noglobal_array_new)/include=([],[-.src],[-.include])
-CC_DEFINE = /define=(__WX__=1,__WXMOTIF__=1)/name=(as_is,short)\
- /include=([],[-.src],[-.include])
-.else
-.ifdef __WXGTK__
-CXX_DEFINE = /define=(__WX__=1,__WXGTK__=1,__USE_STD_IOSTREAM=1)/float=ieee/name=(as_is,short)/ieee=denorm\
- /assume=(nostdnew,noglobal_array_new)/include=([],[-.src],[-.include])
-CC_DEFINE = /define=(__WX__=1,__WXGTK__=1)/float=ieee/name=(as_is,short)/ieee=denorm\
- /include=([],[-.src],[-.include])
-.else
-.ifdef __WXGTK2__
-CXX_DEFINE = /define=(__WX__=1,__WXGTK__=1,VMS_GTK2=1,__USE_STD_IOSTREAM=1)/float=ieee/name=(as_is,short)/ieee=denorm\
- /assume=(nostdnew,noglobal_array_new)/include=([],[-.src],[-.include])
-CC_DEFINE = /define=(__WX__=1,__WXGTK__=1,VMS_GTK2=1)/float=ieee/name=(as_is,short)\
- /ieee=denorm/include=([],[-.src],[-.include])
-.else
-.ifdef __WXX11__
-CXX_DEFINE = /define=(__WX__=1,__WXX11__=1,__WXUNIVERSAL__==1,__USE_STD_IOSTREAM=1)/float=ieee\
- /name=(as_is,short)/assume=(nostdnew,noglobal_array_new)\
- /include=([],[-.src],[-.include])
-CC_DEFINE = /define=(__WX__=1,__WXX11__=1,__WXUNIVERSAL__==1)/float=ieee\
- /name=(as_is,short)/include=([],[-.src],[-.include])
-.else
-CXX_DEFINE =
-CC_DEFINE =
-.endif
-.endif
-.endif
-.endif
-
-.cxx.obj :
- cxx $(CXXFLAGS)$(CXX_DEFINE) $(MMS$TARGET_NAME).cxx
-.cpp.obj :
- cxx $(CXXFLAGS)$(CXX_DEFINE) $(MMS$TARGET_NAME).cpp
-.c.obj :
- cc $(CFLAGS)$(CC_DEFINE) $(MMS$TARGET_NAME).c
-
-OBJECTS=AutoComplete.obj,CallTip.obj,CellBuffer.obj,CharClassify.obj,\
- ContractionState.obj,Decoration.obj,Document.obj,DocumentAccessor.obj,\
- Editor.obj,ExternalLexer.obj,Indicator.obj,KeyMap.obj,KeyWords.obj,\
- LexAbaqus.obj,LexAda.obj,LexAPDL.obj,LexAsm.obj,LexAsn1.obj,\
- LexASY.obj,LexAU3.obj,LexAVE.obj,LexBaan.obj,LexBash.obj,LexBasic.obj,\
- LexBullant.obj,LexCaml.obj,LexCLW.obj,LexCmake.obj,LexConf.obj,\
- LexCPP.obj,LexCrontab.obj,LexCsound.obj,LexCSS.obj,LexD.obj,\
- LexEiffel.obj,LexErlang.obj,LexEScript.obj,LexFlagship.obj,\
- LexForth.obj,LexFortran.obj,LexGAP.obj,LexGui4Cli.obj,LexHaskell.obj
-
-OBJECTS1=LexHTML.obj,LexInno.obj,LexKix.obj,LexLisp.obj,LexLout.obj,LexLua.obj,\
- LexMatlab.obj,LexMetapost.obj,LexMMIXAL.obj,LexMPT.obj,LexMSSQL.obj,\
- LexNsis.obj,LexOpal.obj,LexOthers.obj,LexPascal.obj,LexPB.obj,\
- LexPerl.obj,LexPLM.obj,LexPOV.obj,LexProgress.obj,LexPS.obj,\
- LexPython.obj,LexR.obj,LexRebol.obj,LexRuby.obj,LexScriptol.obj,\
- LexSmalltalk.obj,LexSpecman.obj,LexSpice.obj,LexSQL.obj,LexTADS3.obj,\
- LexTCL.obj,LexTeX.obj,LexVB.obj,LexVerilog.obj,LexVHDL.obj,\
- LexYAML.obj,LineMarker.obj,PositionCache.obj,PropSet.obj,RESearch.obj,\
- RunStyles.obj,ScintillaBase.obj,Style.obj,StyleContext.obj,\
- UniConversion.obj,ViewStyle.obj,WindowAccessor.obj,XPM.obj,\
- PerLine.obj,Selection.obj,LexPowerPro.obj,LexCOBOL.obj,\
- LexMagik.obj,LexMarkdown.obj,LexMySQL.obj,LexNimrod.obj,\
- LexPowerShell.obj,LexSML.obj,LexSorcus.obj,LexTACL.obj,LexTAL.obj
-
-SOURCES=AutoComplete.cxx,CallTip.cxx,CellBuffer.cxx,CharClassify.cxx,\
- ContractionState.cxx,Decoration.cxx,Document.cxx,DocumentAccessor.cxx,\
- Editor.cxx,ExternalLexer.cxx,Indicator.cxx,KeyMap.cxx,KeyWords.cxx,\
- LexAbaqus.cxx,LexAda.cxx,LexAPDL.cxx,LexAsm.cxx,LexAsn1.cxx,\
- LexASY.cxx,LexAU3.cxx,LexAVE.cxx,LexBaan.cxx,LexBash.cxx,LexBasic.cxx,\
- LexBullant.cxx,LexCaml.cxx,LexCLW.cxx,LexCmake.cxx,LexConf.cxx,\
- LexCPP.cxx,LexCrontab.cxx,LexCsound.cxx,LexCSS.cxx,LexD.cxx,\
- LexEiffel.cxx,LexErlang.cxx,LexEScript.cxx,LexFlagship.cxx,\
- LexForth.cxx,LexFortran.cxx,LexGAP.cxx,LexGui4Cli.cxx,LexHaskell.cxx,\
- LexHTML.cxx,LexInno.cxx,LexKix.cxx,LexLisp.cxx,LexLout.cxx,LexLua.cxx,\
- LexMatlab.cxx,LexMetapost.cxx,LexMMIXAL.cxx,LexMPT.cxx,LexMSSQL.cxx,\
- LexNsis.cxx,LexOpal.cxx,LexOthers.cxx,LexPascal.cxx,LexPB.cxx,\
- LexPerl.cxx,LexPLM.cxx,LexPOV.cxx,LexProgress.cxx,LexPS.cxx,\
- LexPython.cxx,LexR.cxx,LexRebol.cxx,LexRuby.cxx,LexScriptol.cxx,\
- LexSmalltalk.cxx,LexSpecman.cxx,LexSpice.cxx,LexSQL.cxx,LexTADS3.cxx,\
- LexTCL.cxx,LexTeX.cxx,LexVB.cxx,LexVerilog.cxx,LexVHDL.cxx,\
- LexYAML.cxx,LineMarker.cxx,PositionCache.cxx,PropSet.cxx,RESearch.cxx,\
- RunStyles.cxx,ScintillaBase.cxx,Style.cxx,StyleContext.cxx,\
- UniConversion.cxx,ViewStyle.cxx,WindowAccessor.cxx,XPM.cxx,\
- PerLine.cxx,Selection.cxx,LexPowerPro.cxx,LexCOBOL.cxx,\
- LexMagik.cxx,LexMarkdown.cxx,LexMySQL.cxx,LexNimrod.cxx,\
- LexPowerShell.cxx,LexSML.cxx,LexSorcus.cxx,LexTACL.cxx,LexTAL.cxx
-
-all : $(SOURCES)
- $(MMS)$(MMSQUALIFIERS) $(OBJECTS)
- $(MMS)$(MMSQUALIFIERS) $(OBJECTS1)
-.ifdef __WXMOTIF__
- library [----.lib]libwx_motif.olb $(OBJECTS)
- library [----.lib]libwx_motif.olb $(OBJECTS1)
- If f$getsyi("HW_MODEL") .le. 2048 then library [----.lib]libwx_motif.olb [.CXX_REPOSITORY]*.obj
-.else
-.ifdef __WXGTK__
- library [----.lib]libwx_gtk.olb $(OBJECTS)
- library [----.lib]libwx_gtk.olb $(OBJECTS1)
- If f$getsyi("HW_MODEL") .le. 2048 then library [----.lib]libwx_gtk.olb [.CXX_REPOSITORY]*.obj
-.else
-.ifdef __WXGTK2__
- library [----.lib]libwx_gtk2.olb $(OBJECTS)
- library [----.lib]libwx_gtk2.olb $(OBJECTS1)
- If f$getsyi("HW_MODEL") .le. 2048 then library [----.lib]libwx_gtk2.olb [.CXX_REPOSITORY]*.obj
-.else
-.ifdef __WXX11__
- library [----.lib]libwx_x11_univ.olb $(OBJECTS)
- library [----.lib]libwx_x11_univ.olb $(OBJECTS1)
- If f$getsyi("HW_MODEL") .le. 2048 then library [----.lib]libwx_x11_univ.olb [.CXX_REPOSITORY]*.obj
-.endif
-.endif
-.endif
-.endif
-
-$(OBJECTS) : [----.include.wx]setup.h
-$(OBJECTS1) : [----.include.wx]setup.h
-
-AutoComplete.obj : AutoComplete.cxx
-CallTip.obj : CallTip.cxx
-CellBuffer.obj : CellBuffer.cxx
-CharClassify.obj : CharClassify.cxx
-ContractionState.obj : ContractionState.cxx
-Decoration.obj : Decoration.cxx
-Document.obj : Document.cxx
-DocumentAccessor.obj : DocumentAccessor.cxx
-Editor.obj : Editor.cxx
- cxx $(CXXFLAGS)$(CXX_DEFINE)/nowarn Editor.cxx
-ExternalLexer.obj : ExternalLexer.cxx
-Indicator.obj : Indicator.cxx
-KeyMap.obj : KeyMap.cxx
-KeyWords.obj : KeyWords.cxx
-LexAbaqus.obj : LexAbaqus.cxx
-LexAda.obj : LexAda.cxx
-LexAPDL.obj : LexAPDL.cxx
-LexAsm.obj : LexAsm.cxx
-LexAsn1.obj : LexAsn1.cxx
-LexASY.obj : LexASY.cxx
-LexAU3.obj : LexAU3.cxx
-LexAVE.obj : LexAVE.cxx
-LexBaan.obj : LexBaan.cxx
-LexBash.obj : LexBash.cxx
-LexBasic.obj : LexBasic.cxx
-LexBullant.obj : LexBullant.cxx
-LexCaml.obj : LexCaml.cxx
-LexCLW.obj : LexCLW.cxx
-LexCmake.obj : LexCmake.cxx
-LexConf.obj : LexConf.cxx
-LexCPP.obj : LexCPP.cxx
-LexCrontab.obj : LexCrontab.cxx
-LexCsound.obj : LexCsound.cxx
-LexCSS.obj : LexCSS.cxx
-LexD.obj : LexD.cxx
- cxx $(CXXFLAGS)$(CXX_DEFINE)/nowarn LexD.cxx
-LexEiffel.obj : LexEiffel.cxx
-LexErlang.obj : LexErlang.cxx
-LexEScript.obj : LexEScript.cxx
-LexFlagship.obj : LexFlagship.cxx
-LexForth.obj : LexForth.cxx
-LexFortran.obj : LexFortran.cxx
-LexGAP.obj : LexGAP.cxx
-LexGui4Cli.obj : LexGui4Cli.cxx
-LexHaskell.obj : LexHaskell.cxx
-LexHTML.obj : LexHTML.cxx
-LexInno.obj : LexInno.cxx
-LexKix.obj : LexKix.cxx
-LexLisp.obj : LexLisp.cxx
-LexLout.obj : LexLout.cxx
-LexLua.obj : LexLua.cxx
-LexMatlab.obj : LexMatlab.cxx
-LexMetapost.obj : LexMetapost.cxx
-LexMMIXAL.obj : LexMMIXAL.cxx
-LexMPT.obj : LexMPT.cxx
-LexMSSQL.obj : LexMSSQL.cxx
-LexNsis.obj : LexNsis.cxx
-LexOpal.obj : LexOpal.cxx
-LexOthers.obj : LexOthers.cxx
-LexPascal.obj : LexPascal.cxx
-LexPB.obj : LexPB.cxx
-LexPerl.obj : LexPerl.cxx
-LexPLM.obj : LexPLM.cxx
-LexPOV.obj : LexPOV.cxx
-LexProgress.obj : LexProgress.cxx
-LexPS.obj : LexPS.cxx
-LexPython.obj : LexPython.cxx
-LexR.obj : LexR.cxx
-LexRebol.obj : LexRebol.cxx
-LexRuby.obj : LexRuby.cxx
-LexScriptol.obj : LexScriptol.cxx
-LexSmalltalk.obj : LexSmalltalk.cxx
-LexSpecman.obj : LexSpecman.cxx
-LexSpice.obj : LexSpice.cxx
-LexSQL.obj : LexSQL.cxx
-LexTADS3.obj : LexTADS3.cxx
-LexTCL.obj : LexTCL.cxx
-LexTeX.obj : LexTeX.cxx
-LexVB.obj : LexVB.cxx
-LexVerilog.obj : LexVerilog.cxx
-LexVHDL.obj : LexVHDL.cxx
-LexYAML.obj : LexYAML.cxx
-LineMarker.obj : LineMarker.cxx
-PositionCache.obj : PositionCache.cxx
-PropSet.obj : PropSet.cxx
-RESearch.obj : RESearch.cxx
-RunStyles.obj : RunStyles.cxx
-ScintillaBase.obj : ScintillaBase.cxx
-Style.obj : Style.cxx
-StyleContext.obj : StyleContext.cxx
-UniConversion.obj : UniConversion.cxx
-ViewStyle.obj : ViewStyle.cxx
-WindowAccessor.obj : WindowAccessor.cxx
-XPM.obj : XPM.cxx
-PerLine.obj : PerLine.cxx
-Selection.obj : Selection.cxx
-LexPowerPro.obj : LexPowerPro.cxx
-LexCOBOL.obj : LexCOBOL.cxx
-LexMagik.obj : LexMagik.cxx
-LexMarkdown.obj : LexMarkdown.cxx
-LexMySQL.obj : LexMySQL.cxx
-LexNimrod.obj : LexNimrod.cxx
-LexPowerShell.obj : LexPowerShell.cxx
-LexSML.obj : LexSML.cxx
-LexSorcus.obj : LexSorcus.cxx
-LexTACL.obj : LexTACL.cxx
-LexTAL.obj : LexTAL.cxx