Initial copy of Scintilla 3.21 code

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72331 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2012-08-14 05:14:09 +00:00
parent 0c3140ca44
commit 1dcf666dc7
179 changed files with 18961 additions and 7629 deletions

View File

@@ -1,79 +0,0 @@
// 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;
};

View File

@@ -0,0 +1,77 @@
// 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

View File

@@ -1,113 +0,0 @@
// 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;
}

View File

@@ -16,9 +16,11 @@
#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)
@@ -29,6 +31,10 @@
#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
@@ -38,6 +44,11 @@
#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
@@ -53,6 +64,10 @@
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
@@ -70,10 +85,10 @@ typedef void *IdlerID;
*/
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
@@ -88,12 +103,12 @@ public:
*/
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_) {
}
@@ -115,31 +130,19 @@ public:
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.
*/
@@ -204,83 +207,40 @@ public:
}
};
/**
* 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.
*/
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());
}
};
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.
*/
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 Font {
protected:
FontID fid;
@@ -288,19 +248,21 @@ protected:
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;
};
@@ -314,9 +276,9 @@ private:
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;
@@ -324,35 +286,35 @@ public:
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 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 int SetPalette(Palette *pal, bool inBackGround)=0;
virtual void SetClip(PRectangle rc)=0;
virtual void FlushCachedState()=0;
@@ -411,8 +373,8 @@ public:
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;
@@ -429,7 +391,7 @@ public:
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;
@@ -443,6 +405,7 @@ public:
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;
@@ -474,7 +437,7 @@ public:
*/
class DynamicLibrary {
public:
virtual ~DynamicLibrary() {};
virtual ~DynamicLibrary() {}
/// @return Pointer to function "name", or NULL on failure.
virtual Function FindFunction(const char *name) = 0;
@@ -553,4 +516,10 @@ public:
#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

View File

@@ -1,26 +0,0 @@
// 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

View File

@@ -1,289 +0,0 @@
// 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

View File

@@ -111,6 +111,15 @@
#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
@@ -148,6 +157,10 @@
#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
@@ -339,6 +352,16 @@
#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
@@ -403,6 +426,14 @@
#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
@@ -423,6 +454,7 @@
#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
@@ -453,6 +485,17 @@
#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
@@ -600,6 +643,7 @@
#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
@@ -637,6 +681,8 @@
#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
@@ -1081,11 +1127,19 @@
#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
@@ -1266,6 +1320,9 @@
#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
@@ -1376,6 +1433,180 @@
#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

View File

@@ -11,18 +11,14 @@
#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();
@@ -55,6 +51,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -95,9 +92,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -129,6 +124,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -141,6 +137,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -164,6 +162,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -221,6 +221,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -238,6 +246,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -248,6 +257,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -311,6 +325,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -324,13 +339,13 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -403,6 +418,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -417,6 +433,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -445,6 +462,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -486,6 +504,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -552,7 +575,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -590,7 +615,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -658,9 +685,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -668,6 +702,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -696,10 +733,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -714,6 +755,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -782,6 +827,27 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -797,6 +863,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -816,7 +890,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -845,6 +924,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -871,6 +951,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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
@@ -901,23 +982,28 @@ struct Sci_TextToFind {
#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
@@ -931,11 +1017,22 @@ struct Sci_NotifyHeader {
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 */
@@ -949,11 +1046,20 @@ struct SCNotification {
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

View File

@@ -101,6 +101,9 @@ fun void InsertText=2003(position pos, string text)
# 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(,)
@@ -224,17 +227,10 @@ get int GetTabWidth=2121(,)
# 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
@@ -262,7 +258,7 @@ val SC_MARK_CIRCLEPLUSCONNECTED=19
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
@@ -271,6 +267,7 @@ val SC_MARK_FULLRECT=26
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
@@ -290,10 +287,16 @@ val SC_MASK_FOLDERS=0xFE000000
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)
@@ -307,7 +310,8 @@ fun void MarkerDeleteAll=2045(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.
@@ -320,7 +324,7 @@ fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
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
@@ -354,6 +358,12 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive)
# 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_
@@ -393,7 +403,7 @@ val SC_CHARSET_THAI=222
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)
@@ -444,7 +454,7 @@ get int StyleGetSize=2485(int style,)
# 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,)
@@ -455,7 +465,7 @@ get bool StyleGetUnderline=2488(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.
@@ -471,6 +481,25 @@ get bool StyleGetHotSpot=2493(int style,)
# 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)
@@ -523,6 +552,10 @@ set void SetCaretPeriod=2076(int periodMilliseconds,)
# 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(,)
@@ -540,6 +573,11 @@ val INDIC_STRIKE=4
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
@@ -732,9 +770,11 @@ get position GetLineIndentPosition=2128(int line,)
# 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(,)
@@ -758,7 +798,7 @@ set void SetHighlightGuide=2134(int column,)
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(,)
@@ -766,9 +806,6 @@ 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(,)
@@ -787,6 +824,9 @@ set void SetSelectionEnd=2144(position pos,)
# 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,)
@@ -1008,6 +1048,9 @@ set void CallTipSetForeHlt=2207(colour fore,)
# 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,)
@@ -1046,6 +1089,9 @@ fun void HideLines=2227(int lineStart, int lineEnd)
# 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)
@@ -1066,7 +1112,7 @@ val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010
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.
@@ -1113,6 +1159,7 @@ enu WrapVisualFlag=SC_WRAPVISUALFLAG_
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,)
@@ -1198,7 +1245,7 @@ get bool GetVScrollBar=2281(,)
# 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
@@ -1223,6 +1270,19 @@ get int GetFontQuality=2612(,)
# 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(,)
@@ -1423,9 +1483,15 @@ fun int LineLength=2350(int line,)
# 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,)
@@ -1529,7 +1595,9 @@ get bool GetMouseDownCaptures=2385(,)
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.
@@ -1565,7 +1633,7 @@ fun void DelLineLeft=2395(,)
# 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(,)
@@ -1599,7 +1667,7 @@ val CARET_JUMPS=0x10
# 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)
@@ -1736,15 +1804,35 @@ fun void WordRightEndExtend=2442(,)
# 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,)
@@ -1767,10 +1855,15 @@ fun int EncodedFromUTF8=2449(string utf8, stringresult encoded)
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(,)
@@ -1814,7 +1907,7 @@ get int GetIndicatorCurrent=2501(,)
# 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.
@@ -1848,6 +1941,15 @@ fun void CopyAllowLine=2519(,)
# 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,)
@@ -1860,6 +1962,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
# 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,)
@@ -1902,6 +2010,16 @@ set void MarginSetStyleOffset=2537(int style,)
# 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)
@@ -1986,10 +2104,10 @@ get int GetSelections=2570(,)
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,)
@@ -2013,7 +2131,7 @@ set void SetSelectionNStart=2584(int selection, position pos)
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,)
@@ -2071,6 +2189,70 @@ fun void RotateSelection=2606(,)
# 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(,)
@@ -2102,11 +2284,11 @@ set void SetLexerLanguage=4006(, string language)
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.
@@ -2119,11 +2301,31 @@ get int GetStyleBitsNeeded=4011(,)
# 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
@@ -2143,7 +2345,14 @@ val SC_MOD_CHANGELINESTATE=0x8000
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.
@@ -2185,6 +2394,7 @@ val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCMOD_SUPER=8
val SCMOD_META=16
################################################
# For SciLexer.h
@@ -2286,6 +2496,15 @@ val SCLEX_POWERPRO=95
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.
@@ -2332,6 +2551,10 @@ val SCE_C_WORD2=16
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
@@ -2382,10 +2605,10 @@ val SCE_TCL_WORD8=19
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
@@ -2546,6 +2769,16 @@ val SCE_PL_POD_VERB=31
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
@@ -2620,6 +2853,14 @@ val SCE_L_COMMAND=1
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
@@ -2642,6 +2883,7 @@ val SCE_LUA_WORD5=16
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
@@ -2676,6 +2918,19 @@ val SCE_BAT_HIDE=4
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
@@ -2851,6 +3106,7 @@ val SCE_ASM_COMMENTBLOCK=11
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_
@@ -2893,6 +3149,8 @@ val SCE_CSS_PSEUDOELEMENT=18
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
@@ -3375,7 +3633,7 @@ val SCE_ST_ASSIGN=14
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
@@ -3395,11 +3653,19 @@ val SCE_FS_IDENTIFIER=15
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
@@ -3606,6 +3872,9 @@ val SCE_POWERSHELL_IDENTIFIER=7
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
@@ -3730,6 +3999,196 @@ val SCE_MARKDOWN_LINK=18
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
@@ -3740,23 +4199,39 @@ evt void SavePointLeft=2003(void)
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,)

View File

@@ -9,13 +9,13 @@
#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 ())
@@ -34,21 +34,13 @@ struct _ScintillaClass {
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
}

View File

@@ -1,67 +0,0 @@
// 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

View File

@@ -0,0 +1,318 @@
// 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 &registers = *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);

View File

@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -4,19 +4,20 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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;

View File

@@ -52,19 +52,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -238,7 +241,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
if (IsAWordChar(sc.ch) || sc.ch == '}')
{
strcpy(s_save,s);
int tp = strlen(s_save);
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';

View File

@@ -9,19 +9,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -42,7 +45,7 @@ inline bool IsAWordStart(const int ch) {
}
inline bool isAveOperator(char ch) {
if (isalnum(ch))
if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||

View File

@@ -0,0 +1,293 @@
// 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);

View File

@@ -10,19 +10,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -6,19 +6,24 @@
// 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 <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#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 "PropSet.h"
#include "KeyWords.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;

View File

@@ -0,0 +1,460 @@
// 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 = &registers;
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);

View File

@@ -5,21 +5,24 @@
// 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 <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -2,25 +2,26 @@
/** @file LexBash.cxx
** Lexer for Bash.
**/
// Copyright 2004-2008 by Neil Hodgson <neilh@scintilla.org>
// 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 <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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;
@@ -40,6 +41,14 @@ using namespace Scintilla;
#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';
@@ -80,11 +89,15 @@ 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 setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@");
CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
@@ -144,46 +157,115 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
int numBase = 0;
int digit;
unsigned int endPos = startPos + length;
int cmdState = BASH_CMD_START;
int testExprType = 0;
// 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--;
// 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[1000];
char s[500];
char s2[10];
sc.GetCurrent(s, sizeof(s));
if (s[0] != '-' && // for file operators
!keywords.InList(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);
@@ -248,14 +330,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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);
if (sc.atLineEnd && sc.chPrev != '\\') {
sc.SetState(SCE_SH_DEFAULT);
}
break;
case SCE_SH_HERE_DELIM:
@@ -294,24 +370,15 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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
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 == '\\' && 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;
@@ -339,8 +406,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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)) {
if ((prefixws == 0) || // indentation rule
(prefixws > 0 && HereDoc.Indent)) {
sc.SetState(SCE_SH_DEFAULT);
break;
}
@@ -358,7 +425,6 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_SH_STRING: // delimited styles
case SCE_SH_CHARACTER:
case SCE_SH_BACKTICKS:
case SCE_SH_PARAM:
if (sc.ch == '\\' && Quote.Up != '\\') {
@@ -372,6 +438,14 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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
@@ -391,10 +465,17 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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 == '\\') { // escaped character
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;
@@ -424,19 +505,20 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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_CHARACTER);
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);
if (sc.chNext == '(') { // $(( is lexed as operator
sc.ChangeState(SCE_SH_OPERATOR);
}
} else {
continue; // scalar has no delimiter pair
}
@@ -453,9 +535,66 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
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();
}
@@ -507,6 +646,14 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
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)

View File

@@ -1,6 +1,7 @@
// 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.
@@ -19,18 +20,24 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include <string>
#include <map>
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#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
@@ -86,8 +93,213 @@ static int LowerCase(int c)
return c;
}
static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, char comment_char) {
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);
@@ -111,7 +323,7 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
};
sc.GetCurrentLowered(s, sizeof(s));
for (int i = 0; i < 4; i++) {
if (keywordlists[i]->InList(s)) {
if (keywordlists[i].InList(s)) {
sc.ChangeState(kstates[i]);
}
}
@@ -202,66 +414,30 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
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;
}
void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
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;
}
if (!options.fold)
return;
LexAccessor styler(pAccess);
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;
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 (i = startPos; i < endPos; i++) {
int c = styler.SafeGetCharAt(i);
if (!done && !go) {
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
@@ -291,8 +467,27 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
}
if (c == '\n') { // line end
if (!done && wordlen == 0 && foldCompact) // line was only space
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);
@@ -308,66 +503,8 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
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);
LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);

View File

@@ -3,24 +3,29 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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';
@@ -111,7 +116,7 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
}
blockChange=0;
*/ }
if (!isspace(ch))
if (!(isascii(ch) && isspace(ch)))
visibleChars++;
if (styler.IsLeadByte(ch)) {

View File

@@ -10,17 +10,20 @@
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;
@@ -90,11 +93,11 @@ static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &k
getRange(start, end, styler, s, sizeof(s));
char chAttr = SCE_C_IDENTIFIER;
if (isdigit(s[0]) || (s[0] == '.')) {
if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {
chAttr = SCE_C_NUMBER;
char *p = s + 1;
while (*p) {
if (!isdigit(*p) && isCOBOLwordchar(*p)) {
if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
chAttr = SCE_C_IDENTIFIER;
break;
}
@@ -202,9 +205,17 @@ static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle,
}
if (state == SCE_C_DEFAULT) {
if (isCOBOLwordstart(ch) || (ch == '$' && isalpha(chNext))) {
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;

File diff suppressed because it is too large Load Diff

View File

@@ -3,25 +3,34 @@
** 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 <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -48,6 +57,22 @@ inline bool IsCssOperator(const int ch) {
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];
@@ -62,11 +87,47 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
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 && sc.Match('*', '/')) {
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
@@ -90,8 +151,12 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
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)
@@ -105,7 +170,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
i--;
if ((sc.currentPos - i) % 2 == 1)
continue;
sc.ForwardSetState(SCE_CSS_VALUE);
sc.ForwardSetState(lastStateS);
}
if (sc.state == SCE_CSS_OPERATOR) {
@@ -121,7 +186,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
}
switch (op) {
case '@':
if (lastState == SCE_CSS_DEFAULT)
if (lastState == SCE_CSS_DEFAULT || hasNesting)
sc.SetState(SCE_CSS_DIRECTIVE);
break;
case '>':
@@ -140,16 +205,34 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
sc.SetState(SCE_CSS_TAG);
break;
case '{':
if (lastState == SCE_CSS_DIRECTIVE)
nestingLevel++;
switch (lastState) {
case SCE_CSS_MEDIA:
sc.SetState(SCE_CSS_DEFAULT);
else if (lastState == SCE_CSS_TAG)
break;
case SCE_CSS_TAG:
case SCE_CSS_DIRECTIVE:
sc.SetState(SCE_CSS_IDENTIFIER);
break;
}
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)
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);
@@ -163,14 +246,28 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
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)
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);
else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 ||
lastState == SCE_CSS_IDENTIFIER3 || lastState == SCE_CSS_EXTENDED_IDENTIFIER ||
lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
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 ||
@@ -189,10 +286,40 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
sc.SetState(SCE_CSS_DEFAULT);
break;
case ';':
if (lastState == SCE_CSS_DIRECTIVE)
switch (lastState) {
case SCE_CSS_DIRECTIVE:
if (hasNesting) {
sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT);
} else {
sc.SetState(SCE_CSS_DEFAULT);
else if (lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT)
}
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)
@@ -201,13 +328,76 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
}
}
if (IsAWordChar(sc.ch)) {
if (sc.state == SCE_CSS_DEFAULT)
if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
sc.SetState(SCE_CSS_TAG);
continue;
}
if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
// 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;
}
@@ -219,7 +409,8 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
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_IMPORTANT ||
sc.state == SCE_CSS_DIRECTIVE
)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
@@ -263,6 +454,10 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
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;
}
}
@@ -278,14 +473,23 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
if (sc.Match('/', '*')) {
lastStateC = sc.state;
comment_mode = eCommentBlock;
sc.SetState(SCE_CSS_COMMENT);
sc.Forward();
} else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
} 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.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;

View File

@@ -20,20 +20,23 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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 == '_';}
@@ -51,9 +54,13 @@ using namespace Scintilla;
/*
(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
@@ -430,13 +437,11 @@ void ColouriseCamlDoc(
static
#endif /* BUILD_AS_EXTERNAL_LEXER */
void FoldCamlDoc(
unsigned int startPos, int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler)
unsigned int, int,
int,
WordList *[],
Accessor &)
{
// below useless evaluation(s) to supress "not used" warnings
startPos || length || initStyle || keywordlists[0] || styler.Length();
}
static const char * const camlWordListDesc[] = {

View File

@@ -5,21 +5,25 @@
// 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 <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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

View File

@@ -0,0 +1,571 @@
// 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);

View File

@@ -2,7 +2,7 @@
/** @file LexConf.cxx
** Lexer for Apache Configuration Files.
**
** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
** 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...
**/
@@ -11,18 +11,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -70,17 +74,17 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
} else if( ch == '"') {
state = SCE_CONF_STRING;
styler.ColourTo(i,SCE_CONF_STRING);
} else if( ispunct(ch) ) {
} 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( isalpha(ch) ) {
} 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( isdigit(ch) ) {
} else if( isascii(ch) && isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
@@ -107,7 +111,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
// 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 == '_') ||
if( (isascii(ch) && isalnum(ch)) || (ch == '_') ||
(ch == '-') || (ch == '$') ||
(ch == '/') || (ch == '.') || (ch == '*') )
{
@@ -129,7 +133,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
case SCE_CONF_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
buffer[bufferCount++] = static_cast<char>(tolower(ch));
} else {
state = SCE_CONF_DEFAULT;
@@ -154,7 +158,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
case SCE_CONF_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
if( isdigit(ch) || ch == '.') {
if( (isascii(ch) && isdigit(ch)) || ch == '.') {
buffer[bufferCount++] = ch;
} else {
state = SCE_CONF_DEFAULT;

View File

@@ -9,18 +9,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -94,12 +98,12 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
// signals an asterisk
// no state jump necessary for this simple case...
styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
} else if( isalpha(ch) || ch == '<' ) {
} else if( (isascii(ch) && isalpha(ch)) || ch == '<' ) {
// signals the start of an identifier
bufferCount = 0;
buffer[bufferCount++] = ch;
state = SCE_NNCRONTAB_IDENTIFIER;
} else if( isdigit(ch) ) {
} else if( isascii(ch) && isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
@@ -167,7 +171,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
case SCE_NNCRONTAB_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') ||
if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||
(ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
(ch == '@') ) {
buffer[bufferCount++] = ch;
@@ -196,7 +200,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
case SCE_NNCRONTAB_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
if( isdigit(ch) /* || ch == '.' */ ) {
if( isascii(ch) && isdigit(ch) /* || ch == '.' */ ) {
buffer[bufferCount++] = ch;
} else {
state = SCE_NNCRONTAB_DEFAULT;

View File

@@ -8,18 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include <assert.h>
#include <ctype.h>
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -35,7 +39,7 @@ static inline bool IsAWordStart(const int ch) {
}
static inline bool IsCsoundOperator(char ch) {
if (isalnum(ch))
if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||

View File

@@ -2,25 +2,32 @@
** 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 <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include <string>
#include <map>
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#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
@@ -55,17 +62,187 @@ 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;
}
static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
// An individual named option for use in an OptionSet
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];
// 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;
@@ -290,24 +467,17 @@ static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
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;
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);
@@ -319,6 +489,8 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
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);
@@ -326,7 +498,7 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment && IsStreamCommentStyle(style)) {
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -334,7 +506,25 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
levelNext--;
}
}
if (style == SCE_D_OPERATOR) {
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 {"
@@ -346,19 +536,19 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
levelNext--;
}
}
if (atEOL) {
if (foldComment) { // Handle nested comments
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 (foldAtElse) {
if (options.foldSyntaxBased && foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
@@ -375,25 +565,4 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
}
}
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);
LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);

View File

@@ -1,8 +1,8 @@
// Scintilla source code edit control
/** @file LexCPP.cxx
** Lexer for C++, C, Java, and JavaScript.
/** @file LexECL.cxx
** Lexer for ECL.
**/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// 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>
@@ -10,82 +10,76 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.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 "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#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_C_COMMENTDOC) ||
// including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
(state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
(state == SCE_C_COMMENTDOCKEYWORDERROR);
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);
}
// 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 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");
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, "$@\\&<>#{}[]");
bool stylingWithinPreprocessor = false;
CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,");
CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]");
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('$');
}
CharacterSet setQualified(CharacterSet::setNone, "uUxX");
int chPrevNonWhite = ' ';
int visibleChars = 0;
bool lastWordWasUUID = false;
int styleBeforeDCKeyword = SCE_C_DEFAULT;
int styleBeforeDCKeyword = SCE_ECL_DEFAULT;
bool continuationLine = false;
bool isIncludePreprocessor = false;
if (initStyle == SCE_C_PREPROCESSOR) {
if (initStyle == SCE_ECL_PREPROCESSOR) {
// Set continuationLine if last character of previous line is '\'
int lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0) {
@@ -106,7 +100,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
int back = startPos;
while (--back && IsSpaceEquiv(styler.StyleAt(back)))
;
if (styler.StyleAt(back) == SCE_C_OPERATOR) {
if (styler.StyleAt(back) == SCE_ECL_OPERATOR) {
chPrevNonWhite = styler.SafeGetCharAt(back);
}
}
@@ -114,18 +108,16 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
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
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_C_STRING);
sc.SetState(SCE_ECL_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.
@@ -142,134 +134,145 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT);
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_C_NUMBER:
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_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
}
break;
case SCE_C_IDENTIFIER:
case SCE_ECL_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)) {
if (keywords0.InList(s)) {
lastWordWasUUID = strcmp(s, "uuid") == 0;
sc.ChangeState(SCE_C_WORD);
sc.ChangeState(SCE_ECL_WORD0);
} else if (keywords1.InList(s)) {
sc.ChangeState(SCE_ECL_WORD1);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_C_WORD2);
sc.ChangeState(SCE_ECL_WORD2);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_C_GLOBALCLASS);
sc.ChangeState(SCE_ECL_WORD4);
} else if (keywords5.InList(s)) {
sc.ChangeState(SCE_ECL_WORD5);
}
sc.SetState(SCE_C_DEFAULT);
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_C_PREPROCESSOR:
case SCE_ECL_PREPROCESSOR:
if (sc.atLineStart && !continuationLine) {
sc.SetState(SCE_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
} else if (stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
sc.SetState(SCE_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
}
} else {
if (sc.Match('/', '*') || sc.Match('/', '/')) {
sc.SetState(SCE_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
}
}
break;
case SCE_C_COMMENT:
case SCE_ECL_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT);
sc.ForwardSetState(SCE_ECL_DEFAULT);
}
break;
case SCE_C_COMMENTDOC:
case SCE_ECL_COMMENTDOC:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT);
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_C_COMMENTDOC;
sc.SetState(SCE_C_COMMENTDOCKEYWORD);
styleBeforeDCKeyword = SCE_ECL_COMMENTDOC;
sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
}
}
break;
case SCE_C_COMMENTLINE:
case SCE_ECL_COMMENTLINE:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
}
break;
case SCE_C_COMMENTLINEDOC:
case SCE_ECL_COMMENTLINEDOC:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
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_C_COMMENTLINEDOC;
sc.SetState(SCE_C_COMMENTDOCKEYWORD);
styleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC;
sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
}
}
break;
case SCE_C_COMMENTDOCKEYWORD:
if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
case SCE_ECL_COMMENTDOCKEYWORD:
if ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) {
sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT);
sc.ForwardSetState(SCE_ECL_DEFAULT);
} else if (!setDoxygen.Contains(sc.ch)) {
char s[100];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
} else {
char s[1000];
sc.GetCurrentLowered(s, sizeof(s));
}
if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
if (!IsASpace(sc.ch) || !keywords6.InList(s+1)) {
sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
}
sc.SetState(styleBeforeDCKeyword);
}
break;
case SCE_C_STRING:
case SCE_ECL_STRING:
if (sc.atLineEnd) {
sc.ChangeState(SCE_C_STRINGEOL);
} else if (isIncludePreprocessor) {
if (sc.ch == '>') {
sc.ForwardSetState(SCE_C_DEFAULT);
isIncludePreprocessor = false;
}
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_C_DEFAULT);
sc.ForwardSetState(SCE_ECL_DEFAULT);
}
break;
case SCE_C_CHARACTER:
case SCE_ECL_CHARACTER:
if (sc.atLineEnd) {
sc.ChangeState(SCE_C_STRINGEOL);
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_C_DEFAULT);
sc.ForwardSetState(SCE_ECL_DEFAULT);
}
break;
case SCE_C_REGEX:
case SCE_ECL_REGEX:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
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_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
} else if (sc.ch == '\\') {
// Gobble up the quoted character
if (sc.chNext == '\\' || sc.chNext == '/') {
@@ -277,82 +280,85 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
}
break;
case SCE_C_STRINGEOL:
case SCE_ECL_STRINGEOL:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
}
break;
case SCE_C_VERBATIM:
case SCE_ECL_VERBATIM:
if (sc.ch == '\"') {
if (sc.chNext == '\"') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_C_DEFAULT);
sc.ForwardSetState(SCE_ECL_DEFAULT);
}
}
break;
case SCE_C_UUID:
case SCE_ECL_UUID:
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
sc.SetState(SCE_C_DEFAULT);
sc.SetState(SCE_ECL_DEFAULT);
}
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM);
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_C_UUID);
sc.SetState(SCE_ECL_UUID);
lastWordWasUUID = false;
} else {
sc.SetState(SCE_C_NUMBER);
sc.SetState(SCE_ECL_NUMBER);
}
} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
if (lastWordWasUUID) {
sc.SetState(SCE_C_UUID);
sc.SetState(SCE_ECL_UUID);
lastWordWasUUID = false;
} else {
sc.SetState(SCE_C_IDENTIFIER);
sc.SetState(SCE_ECL_IDENTIFIER);
}
} else if (sc.Match('/', '*')) {
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
sc.SetState(SCE_C_COMMENTDOC);
sc.SetState(SCE_ECL_COMMENTDOC);
} else {
sc.SetState(SCE_C_COMMENT);
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_C_COMMENTLINEDOC);
sc.SetState(SCE_ECL_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);
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_C_CHARACTER);
sc.SetState(SCE_ECL_CHARACTER);
} else if (sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
sc.SetState(SCE_C_PREPROCESSOR);
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_C_DEFAULT);
} else if (sc.Match("include")) {
isIncludePreprocessor = true;
sc.SetState(SCE_ECL_DEFAULT);
}
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_C_OPERATOR);
sc.SetState(SCE_ECL_OPERATOR);
}
}
@@ -363,38 +369,39 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
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;
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 FoldCppDoc(unsigned int startPos, int length, int initStyle,
static void FoldEclDoc(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;
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);
@@ -414,14 +421,14 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
} 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_C_COMMENTLINE)) {
if (foldComment && (style == SCE_ECL_COMMENTLINE)) {
if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
if (chNext2 == '{') {
@@ -431,20 +438,20 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
}
}
}
if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
if (foldPreprocessor && (style == SCE_ECL_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")) {
if (MatchNoCase(styler, j, "region") || MatchNoCase(styler, j, "if")) {
levelNext++;
} else if (styler.Match(j, "end")) {
} else if (MatchNoCase(styler, j, "endregion") || MatchNoCase(styler, j, "end")) {
levelNext--;
}
}
}
if (style == SCE_C_OPERATOR) {
if (style == SCE_ECL_OPERATOR) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
@@ -456,8 +463,15 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
levelNext--;
}
}
if (!IsASpace(ch))
visibleChars++;
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) {
@@ -480,27 +494,19 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
}
visibleChars = 0;
}
if (!IsASpace(ch))
visibleChars++;
}
}
static const char * const cppWordLists[] = {
"Primary keywords and identifiers",
"Secondary keywords and identifiers",
"Documentation comment keywords",
"Unused",
"Global classes and typedefs",
0,
};
static const char * const EclWordListDesc[] = {
"Keywords",
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);
LexerModule lmECL(
SCLEX_ECL,
ColouriseEclDoc,
"ecl",
FoldEclDoc,
EclWordListDesc);

View File

@@ -9,16 +9,19 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -10,18 +10,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -0,0 +1,354 @@
// 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);

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -8,18 +8,23 @@
/***************************************/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
/***************************************/
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -82,7 +87,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
/***********************************************/
// Handle the fix format generically
int toLineStart = sc.currentPos - posLineStart;
if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
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$") ||
@@ -94,7 +99,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
}
while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
} else if (toLineStart > 72) {
} else if (toLineStart >= 72) {
sc.SetState(SCE_F_COMMENT);
while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
} else if (toLineStart < 5) {
@@ -103,8 +108,10 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
else
sc.SetState(SCE_F_DEFAULT);
} else if (toLineStart == 5) {
if (!IsASpace(sc.ch) && sc.ch != '0') {
//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);
@@ -112,8 +119,16 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
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 == '&') {
if (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) {
char chTemp = ' ';
int j = 1;
while (IsABlank(chTemp) && j<132) {
@@ -247,7 +262,8 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|| 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, "type") == 0 && chNextNonBlank != '(')
|| strcmp(s, "critical") == 0){
if (strcmp(prevWord, "end") == 0)
lev = 0;
else
@@ -260,11 +276,13 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|| 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
|| 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;
}
@@ -307,7 +325,7 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
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)) {
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;
}

View File

@@ -8,25 +8,28 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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 (isalnum(ch)) return false;
if (isascii(ch) && isalnum(ch)) return false;
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
ch == '=' || ch == '<' || ch == '>' || ch == '(' ||

View File

@@ -23,19 +23,22 @@ val SCE_GC_OPERATOR=9
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -7,19 +7,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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;
@@ -54,15 +56,8 @@ inline bool IsOperator(int ch) {
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;
unsigned int i = 0;
for (; (i < end - start + 1) && (i < len-1); i++) {
s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
}
@@ -71,7 +66,7 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
size_t i = 0;
unsigned int i = 0;
for (; i < sLen-1; i++) {
char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
if ((i == 0) && !IsAWordStart(ch))
@@ -266,28 +261,29 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
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];
char withSpace[30 + 2] = " ";
const char *s = withSpace + 1;
// Copy after the '<'
unsigned int i = 0;
unsigned int i = 1;
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));
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...
s[i] = ' ';
s[i+1] = '\0';
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("meta link img area br hr input ", s));
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
s[i] = '\0';
withSpace[i] = '\0';
// No keywords -> all are known
char chAttr = SCE_H_TAGUNKNOWN;
@@ -323,18 +319,18 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
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))
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));
@@ -361,7 +357,7 @@ static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keyw
return SCE_HB_DEFAULT;
}
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType) {
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;
@@ -378,6 +374,8 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
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);
}
@@ -499,6 +497,9 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
(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 == '}';
@@ -507,6 +508,18 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
}
}
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) ||
@@ -575,20 +588,22 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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';
int makoComment = 0;
char djangoBlockType[2];
djangoBlockType[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 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)))) {
startPos--;
length++;
int backLineStart = styler.LineStart(styler.GetLine(startPos-1));
length += startPos - backLineStart;
startPos = backLineStart;
}
state = SCE_H_DEFAULT;
}
@@ -607,7 +622,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int lineCurrent = styler.GetLine(startPos);
int lineState;
if (lineCurrent > 0) {
lineState = styler.GetLineState(lineCurrent);
lineState = styler.GetLineState(lineCurrent-1);
} else {
// Default client and ASP scripting language is JavaScript
lineState = eScriptJS << 8;
@@ -630,6 +645,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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.
@@ -668,6 +684,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// 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);
@@ -732,15 +752,25 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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;
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) {
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')) {
@@ -785,8 +815,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
visibleChars = 0;
levelPrev = levelCurrent;
}
lineCurrent++;
lineStartVisibleChars = 0;
styler.SetLineState(lineCurrent,
((inScriptType & 0x03) << 0) |
((tagOpened & 0x01) << 2) |
@@ -794,6 +822,20 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
((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
@@ -857,10 +899,12 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
else if ((state != SCE_H_ASPAT) &&
!isPHPStringState(state) &&
(state != SCE_HPHP_COMMENT) &&
(state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') &&
(chNext == '?') &&
!IsScriptCommentState(state) ) {
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
!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;
@@ -888,9 +932,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// 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 == '%')
if (ch == '%' || ch == '/')
strcpy(makoBlockType, "%");
else if (ch == '$')
strcpy(makoBlockType, "{");
@@ -915,12 +960,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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 (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
@@ -931,8 +974,62 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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 && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
else if (!isMako && !isDjango && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
@@ -977,7 +1074,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') &&
(StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint)) ) {
(!IsScriptCommentState(StateToPrint))) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
@@ -992,7 +1089,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_H_SGML_COMMAND; // wait for a pending command
}
// fold whole tag (-- when closing the tag)
if (foldHTMLPreprocessor || (state == SCE_H_COMMENT))
if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA)
levelCurrent++;
continue;
}
@@ -1007,7 +1104,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript);
}
if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else {
styler.ColourTo(i - 1, StateToPrint);
}
@@ -1015,7 +1112,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%")) {
else if (0 == strcmp(makoBlockType, "%") && ch == '/') {
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%") || ch == '/') {
styler.ColourTo(i, SCE_H_ASP);
}
state = beforePreProc;
@@ -1023,15 +1124,38 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
levelCurrent--;
}
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 && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
(((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
@@ -1048,7 +1172,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
break;
case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
break;
case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
@@ -1081,7 +1205,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
}
scriptLanguage = eScriptNone;
scriptLanguage = beforeLanguage;
continue;
}
/////////////////////////////////////
@@ -1461,6 +1585,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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;
@@ -1564,8 +1692,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
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)) {
@@ -1708,7 +1838,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
break;
case SCE_HP_WORD:
if (!IsAWordChar(ch)) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
state = SCE_HP_DEFAULT;
if (ch == '#') {
state = SCE_HP_COMMENTLINE;
@@ -1859,7 +1989,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_DEFAULT;
} else if (isLineEnd(chPrev)) {
const int psdLength = strlen(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) ||
@@ -1882,7 +2012,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HPHP_DEFAULT;
}
} else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
const int psdLength = strlen(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) ||
@@ -1997,13 +2127,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
break;
case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
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;
}

View File

@@ -0,0 +1,368 @@
/******************************************************************
* 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");

View File

@@ -7,20 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -34,7 +36,6 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
char *buffer = new char[length];
int bufferCount = 0;
bool isBOL, isEOL, isWS, isBOLWS = 0;
bool isCode = false;
bool isCStyleComment = false;
WordList &sectionKeywords = *keywordLists[0];
@@ -44,6 +45,10 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
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);
@@ -64,6 +69,12 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
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) {

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;
@@ -44,7 +47,7 @@ static inline bool isLispwordstart(char ch) {
static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
PLATFORM_ASSERT(end >= start);
assert(end >= start);
char s[100];
unsigned int i;
bool digit_flag = true;
@@ -139,7 +142,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
}
}
} else if (state == SCE_LISP_MACRO_DISPATCH) {
if (!isdigit(ch)) {
if (!(isascii(ch) && isdigit(ch))) {
if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
state = SCE_LISP_DEFAULT;
} else {

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -9,19 +9,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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;
@@ -57,10 +59,11 @@ static void ColouriseLuaDoc(
// Accepts accented characters
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 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");
// 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, "\"'\\");
@@ -68,12 +71,16 @@ static void ColouriseLuaDoc(
// 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;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
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 >> 8;
nestLevel = lineState >> 9;
sepCount = lineState & 0xFF;
stringWs = lineState & 0x100;
}
// Do not leak onto next line
@@ -93,8 +100,10 @@ static void ColouriseLuaDoc(
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);
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
@@ -121,21 +130,91 @@ static void ColouriseLuaDoc(
// 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-eE non-sign non-hexdigit char
// 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 (sc.chPrev != 'E' && sc.chPrev != 'e')
if (!setExponent.Contains(sc.chPrev))
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_IDENTIFIER) {
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
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)) {
@@ -158,24 +237,38 @@ static void ColouriseLuaDoc(
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 (sc.atLineEnd) {
} 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 (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
@@ -212,8 +305,10 @@ static void ColouriseLuaDoc(
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) {
@@ -244,7 +339,7 @@ static void ColouriseLuaDoc(
}
}
if (setWord.Contains(sc.chPrev)) {
if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {

View File

@@ -9,19 +9,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -32,10 +35,10 @@ static inline bool IsAWordChar(const int ch) {
}
inline bool isMMIXALOperator(char ch) {
if (isalnum(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 == ')' ||

View File

@@ -7,21 +7,26 @@
// 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 <stdlib.h>
#include <string>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -32,7 +37,7 @@ static int GetLotLineState(std::string &line) {
// 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]))
if (!(isascii(line[i]) && isspace(line[i])))
break;
}

View File

@@ -7,18 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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

View File

@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -230,7 +233,7 @@ static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
}
if(characters.InList(keyword)) {
sc.Forward(strlen(keyword));
sc.Forward(static_cast<int>(strlen(keyword)));
} else {
sc.Forward();
}

View File

@@ -36,19 +36,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -100,9 +102,9 @@ static void SetStateAndZoom(const int state, const int length, const int token,
static bool HasPrevLineContent(StyleContext &sc) {
int i = 0;
// Go back to the previous newline
while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
;
while (--i + sc.currentPos) {
while ((--i + (int)sc.currentPos) >= 0) {
if (IsNewline(sc.GetRelative(i)))
break;
if (!IsASpaceOrTab(sc.GetRelative(i)))
@@ -111,6 +113,10 @@ static bool HasPrevLineContent(StyleContext &sc) {
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;
@@ -371,36 +377,39 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
}
}
// Code - also a special case for alternate inside spacing
if (sc.Match("``") && sc.GetRelative(3) != ' ') {
if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE2);
sc.Forward();
}
else if (sc.ch == '`' && sc.chNext != ' ') {
else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE);
}
// Strong
else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG1);
sc.Forward();
}
else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG2);
sc.Forward();
}
// Emphasis
else if (sc.ch == '*' && sc.chNext != ' ')
else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM1);
else if (sc.ch == '_' && sc.chNext != ' ')
}
else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM2);
}
// Strikeout
else if (sc.Match("~~") && sc.GetRelative(2) != ' ') {
else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRIKEOUT);
sc.Forward();
}
// Beginning of line
else if (IsNewline(sc.ch))
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();

View File

@@ -12,19 +12,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -103,13 +106,13 @@ static void ColouriseMatlabOctaveDoc(
transpose = true;
}
} else if (sc.state == SCE_MATLAB_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
if (sc.ch == '\'') {
if (sc.chNext == '\'') {
sc.Forward();
}
} else if (sc.ch == '\'') {
} else {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
}
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {

View File

@@ -14,18 +14,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;

View File

@@ -0,0 +1,743 @@
// -*- 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);

View File

@@ -12,19 +12,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -321,9 +324,9 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
bool endFound = false;
bool whenFound = false;
bool elseFound = false;
bool endPending = false;
bool whenPending = false;
bool elseIfPending = false;
char nextChar = styler.SafeGetCharAt(startPos);
for (unsigned int i = startPos; length > 0; i++, length--)
@@ -374,18 +377,42 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
}
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:
@@ -394,91 +421,81 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
// 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");
// 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 (!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
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
if (ifFound)
elseFound = 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"))
whenFound = true;
else
{
if (beginFound)
levelNext++;
else
if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
{
if (endFound)
endFound = false;
else
levelNext++;
whenPending = true;
}
else
if (MatchIgnoreCase(styler, i, "end"))
{
// Multiple "end" in a row are counted multiple times!
if (endFound)
}
}
}
}
// 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;
}
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;
}
// 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)
@@ -491,8 +508,6 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
lineCurrent++;
levelCurrent = levelNext;
visibleChars = 0;
endFound = false;
whenFound = false;
}
if (!isspacechar(currentChar))

View File

@@ -9,19 +9,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -378,7 +381,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
const int levelBeforeComments =
Platform::Maximum(indentCurrentLevel,levelAfterComments);
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

View File

@@ -5,21 +5,25 @@
// 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 <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -138,6 +142,7 @@ static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel
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 ] );

View File

@@ -0,0 +1,548 @@
// 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);

View File

@@ -6,18 +6,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;
@@ -292,7 +295,7 @@ inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Access
}
ch = styler.SafeGetCharAt( cur );
if( !isdigit( ch ) )
if( !( isascii( ch ) && isdigit( ch ) ) )
{
styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
styler.StartSegment( cur );
@@ -311,7 +314,7 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
{
ch = styler.SafeGetCharAt( cur );
if( ( ch != '_' ) && ( ch != '-' ) &&
!islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;
!( isascii( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;
cur++;
if( cur >= one_too_much )
@@ -487,13 +490,13 @@ static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle,
default:
{
// Integer
if( isdigit( ch ) )
if( isascii( ch ) && isdigit( ch ) )
{
if( !HandleInteger( cur, one_too_much, styler ) ) return;
}
// Keyword
else if( islower( ch ) || isupper( ch ) )
else if( isascii( ch ) && ( islower( ch ) || isupper( ch ) ) )
{
if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;

View File

@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -37,6 +40,10 @@ 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'));
@@ -51,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators
static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') ||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
(ch == '\"') || (ch == '\'') || (ch == '/');
}
static void ColouriseBatchLine(
@@ -101,7 +108,7 @@ static void ColouriseBatchLine(
}
return;
// Check for Drive Change (Drive Change is internal command) - return if found
} else if ((isalpha(lineBuffer[offset])) &&
} else if ((IsAlphabetic(lineBuffer[offset])) &&
(lineBuffer[offset + 1] == ':') &&
((isspacechar(lineBuffer[offset + 2])) ||
(((lineBuffer[offset + 2] == '\\')) &&
@@ -493,6 +500,10 @@ static void ColouriseBatchDoc(
}
}
#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
@@ -502,7 +513,7 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
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)) {
} 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);
@@ -549,20 +560,27 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
}
static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024];
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++) {
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';
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);
}
}
@@ -847,14 +865,18 @@ static void ColouriseMakeLine(
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) {
@@ -922,8 +944,8 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
// 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;
// Diff removal.
return SCE_ERR_DIFF_DELETION;
} else if (lineBuffer[0] == '!') {
return SCE_ERR_DIFF_CHANGED;
} else if (lineBuffer[0] == '+') {
@@ -961,17 +983,17 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
} else if (strstart(lineBuffer, "Warning ")) {
// Borland warning message
return SCE_ERR_BORLAND;
} else if (strstr(lineBuffer, "at line " ) &&
(strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
} 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)) &&
} else if (strstr(lineBuffer, " at ") &&
(strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, " line ") &&
(strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
(strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
(strstr(lineBuffer, " at ") < (strstr(lineBuffer, " line ")))) {
// perl error message
return SCE_ERR_PERL;
} else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
@@ -1004,7 +1026,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
bool initialTab = (lineBuffer[0] == '\t');
bool initialColonPart = false;
enum { stInitial,
stGccStart, stGccDigit, stGcc,
stGccStart, stGccDigit, stGccColumn, stGcc,
stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
stUnrecognized
@@ -1036,12 +1058,18 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
state = Is1To9(ch) ? stGccDigit : stUnrecognized;
} else if (state == stGccDigit) { // <filename>:<line>
if (ch == ':') {
state = stGcc; // :9.*: is GCC
state = stGccColumn; // :9.*: is GCC
startValue = i + 1;
break;
} 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>
@@ -1065,7 +1093,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
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++)
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") ||
@@ -1151,21 +1179,71 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
}
}
static int isSpecial(char s) {
return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') ||
(s == '\"') || (s == '`') || (s == '^') || (s == '~');
static bool latexIsSpecial(int ch) {
return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
(ch == '{') || (ch == '}') || (ch == ' ');
}
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];
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++;
e = styler[start + i] != '{';
}
s[i] = '\0';
return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
return (strcmp(s, needle) == 0);
}
static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
@@ -1174,39 +1252,51 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.StartAt(startPos);
int state = initStyle;
char chNext = styler[startPos];
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)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
chNext = styler.SafeGetCharAt(i + 1);
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);
if (latexIsSpecial(chNext)) {
state = SCE_L_SPECIAL;
} else {
if (isTag(i + 1, styler))
state = SCE_L_TAG;
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);
}
@@ -1217,29 +1307,124 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
break;
}
break;
case SCE_L_COMMAND :
if (chNext == '[' || chNext == '{' || chNext == '}' ||
chNext == ' ' || chNext == '\r' || chNext == '\n') {
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;
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
break;
case SCE_L_TAG :
if (ch == '}') {
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 :
@@ -1247,18 +1432,55 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
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[] = {
static const char *const batchWordListDesc[] = {
"Internal Commands",
"External Commands",
0
};
static const char * const emptyWordListDesc[] = {
static const char *const emptyWordListDesc[] = {
0
};

View File

@@ -35,19 +35,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -4,18 +4,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;

View File

@@ -16,19 +16,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -54,6 +54,8 @@ 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
@@ -109,19 +111,21 @@ contains requires
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;
@@ -481,6 +485,24 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
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++;
}

View File

@@ -12,33 +12,36 @@
// 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
// 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
// passsing to functions that require positive values like isspacechar()
// 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 <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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;
@@ -48,65 +51,81 @@ 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 nsPos = styler.LineStart(szLine);
int nePos = styler.LineStart(szLine + 1) - 2;
while (nsPos < nePos)
int startPos = styler.LineStart(szLine);
int endPos = styler.LineStart(szLine + 1) - 2;
while (startPos < endPos)
{
int stylech = styler.StyleAt(nsPos);
char stylech = styler.StyleAt(startPos);
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;
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 == '+');
}
}
nePos--; // skip to next char
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(unsigned int szLine, Accessor &styler)
static int GetStyleFirstWord(int szLine, Accessor &styler)
{
int nsPos = styler.LineStart(szLine);
int nePos = styler.LineStart(szLine+1) - 1;
char ch = styler.SafeGetCharAt(nsPos);
int startPos = styler.LineStart(szLine);
int endPos = styler.LineStart(szLine + 1) - 1;
char ch = styler.SafeGetCharAt(startPos);
while (ch > 0 && isspacechar(ch) && nsPos < nePos)
while (ch > 0 && isspacechar(ch) && startPos < endPos)
{
nsPos++; // skip to next char
ch = styler.SafeGetCharAt(nsPos);
startPos++; // skip to next char
ch = styler.SafeGetCharAt(startPos);
}
return styler.StyleAt(nsPos);
return styler.StyleAt(startPos);
}
//returns true if there is a function to highlight
//used to highlight <name> in 'function <name>'
static bool HasFunction(Accessor &styler, unsigned int currentPos) {
//note:
// sample line (without quotes): "\tfunction asdf()
// currentPos will be the position of 'a'
static bool IsFunction(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
);
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[],
@@ -124,9 +143,11 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
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));
@@ -134,14 +155,12 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
if ((sc.ch > 0) && setWord.Contains(sc.ch))
{
strcpy(s_save,s);
int tp = strlen(s_save);
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) {
@@ -173,6 +192,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
if (keywords.InList(s)) {
sc.ChangeState(SCE_POWERPRO_WORD);
} else if (keywords2.InList(s)) {
@@ -258,7 +278,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
break;
case SCE_POWERPRO_FUNCTION:
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
if (isspacechar(sc.ch) || sc.ch == '(') {
sc.SetState(SCE_POWERPRO_DEFAULT);
}
break;
@@ -276,9 +296,9 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
sc.SetState(SCE_POWERPRO_ALTQUOTE);
sc.Forward();
}
} else if (HasFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
} else if (IsFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
sc.SetState(SCE_POWERPRO_FUNCTION);
} else if (sc.ch == '@' && sc.atLineStart) { //alternate function definition [label]
} 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);
@@ -289,7 +309,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
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
} 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);
@@ -301,6 +321,15 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
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;
}
//*************************************
@@ -337,7 +366,9 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
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)
//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
@@ -360,31 +391,32 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
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))) {
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;
// 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 DoFoundLast = false;
bool isDoLastWord = false;
// var for indentlevel
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0) {
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
}
int levelNext = levelCurrent;
int visibleChars = 0;
@@ -400,52 +432,52 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if ((ch > 0) && setWord.Contains(ch)) {
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;
// 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';
}
else if (szKeywordlen < KEYWORD_MAX - 1) {
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
szKeyword[szKeywordlen] = '\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';
}
}
// 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) {
//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 ) {
DoFoundLast = true;
}
}
else if (szDolen < 2) {
if (strcmp(szDo, "do") == 0)
isDoLastWord = true;
} else if (szDolen < 2) {
szDo[szDolen++] = static_cast<char>(tolower(ch));
szDo[szDolen] = '\0';
}
@@ -453,7 +485,9 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
}
// End of Line found so process the information
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
if ((ch == '\r' && chNext != '\n') // \r\n
|| ch == '\n' // \n
|| i == endPos) { // end of selection
// **************************
// Folding logic for Keywords
@@ -461,24 +495,23 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
// 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)) ) {
if (firstWordLen > 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) {
if (strcmp(szFirstWord, "if") == 0 && isDoLastWord)
levelNext++;
}
// create new fold for these words
if (strcmp(szKeyword,"for") == 0) {
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(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) {
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) {
@@ -494,14 +527,15 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
}
// end the fold for these words before the current line
if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) {
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(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) {
if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 )
levelCurrent--;
}
}
// Preprocessor and Comment folding
int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
@@ -510,20 +544,19 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
// Folding logic for Comment blocks
// *********************************
if (foldComment && IsStreamCommentStyle(style)) {
// Start of a comment block
if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) {
levelNext++;
}
// fold till the last line for normal comment lines
} // fold till the last line for normal comment lines
else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_POWERPRO_COMMENTLINE)
&& styleNext != SCE_POWERPRO_COMMENTLINE
&& stylePrev == SCE_POWERPRO_COMMENTLINE
&& style == SCE_POWERPRO_COMMENTLINE) {
levelNext--;
}
// fold till the one but last line for Blockcomment lines
} // fold till the one but last line for Blockcomment lines
else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_POWERPRO_COMMENTBLOCK)
&& styleNext != SCE_POWERPRO_COMMENTBLOCK
&& style == SCE_POWERPRO_COMMENTBLOCK) {
levelNext--;
levelCurrent--;
@@ -534,12 +567,10 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext) {
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
}
// reset values for the next line
lineCurrent++;
@@ -549,18 +580,16 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
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;
if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') {
firstWordLen = 0;
szDolen = 0;
FirstWordStart = false;
FirstWordEnd = false;
DoFoundLast = false;
//blank out keyword
for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
szKeyword[i] = '\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';
}
}
@@ -569,7 +598,6 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
chPrevPrevPrev = chPrevPrev;
chPrevPrev = chPrev;
chPrev = ch;
visibleChars++;
}
}
@@ -598,3 +626,5 @@ static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int i
}
LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);

View File

@@ -7,26 +7,29 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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 == '-';
return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
}
static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
@@ -35,6 +38,8 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
styler.StartAt(startPos);
@@ -46,6 +51,10 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
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 == '\"') {
@@ -79,6 +88,10 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
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);
}
@@ -88,6 +101,8 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
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 == '\'') {
@@ -109,8 +124,9 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
// 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,
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;
@@ -123,10 +139,12 @@ static void FoldPowerShellDoc(unsigned int startPos, int length, int,
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 style = styleNext;
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_POWERSHELL_OPERATOR) {
@@ -140,6 +158,12 @@ static void FoldPowerShellDoc(unsigned int startPos, int length, int,
} 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++;
@@ -168,6 +192,8 @@ static const char * const powershellWordLists[] = {
"Commands",
"Cmdlets",
"Aliases",
"Functions",
"User1",
0
};

View File

@@ -13,19 +13,22 @@ Support more than 6 comments levels
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -7,25 +7,28 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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 };
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
static const int indicatorWhitespace = 1;
@@ -162,6 +165,11 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
// 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;
@@ -243,7 +251,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
} else if (kwLast == kwCDef) {
} else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') {
@@ -261,7 +269,16 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
}
}
} 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);
@@ -274,11 +291,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
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)
else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther;
} else if (kwLast != kwCDef) {
} else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther;
}
}
@@ -334,8 +353,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true;
}
// One cdef line, clear kwLast only at end of line
if (kwLast == kwCDef && sc.atLineEnd) {
// One cdef or cpdef line, clear kwLast only at end of line
if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther;
}
@@ -409,12 +428,8 @@ static bool IsQuoteLine(int line, Accessor &styler) {
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;
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.
@@ -445,14 +460,11 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
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)) {
//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;
@@ -462,16 +474,13 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
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;
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);
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)
if (!quote || !prevQuote)
indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
if (quote)
indentNext = indentCurrentLevel;
@@ -484,12 +493,6 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
} 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
@@ -507,7 +510,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
}
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
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
@@ -537,18 +540,17 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
}
}
// Set fold header on non-quote/non-comment line
if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
// 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 and block comment state of previous line
// Keep track of triple quote 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);
styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
indentCurrent = indentNext;
lineCurrent = lineNext;
}
@@ -558,7 +560,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
//styler.SetLevel(lineCurrent, indentCurrent);
}
static const char * const pythonWordListDesc[] = {
static const char *const pythonWordListDesc[] = {
"Keywords",
"Highlighted identifiers",
0

View File

@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -77,9 +80,9 @@ static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, Word
sc.SetState(SCE_R_DEFAULT);
}
} else if (sc.state == SCE_R_IDENTIFIER) {
if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_R_KWORD);
} else if (keywords2.InList(s)) {

View File

@@ -13,18 +13,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;

View File

@@ -7,18 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -784,13 +788,13 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
state = SCE_RB_COMMENTLINE;
} else if (ch == '=') {
// =begin indicates the start of a comment (doc) block
if (i == 0 || (isEOLChar(chPrev)
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)))) {
&& !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) {
styler.ColourTo(i - 1, state);
state = SCE_RB_POD;
} else {
@@ -973,6 +977,15 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
} 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
@@ -1124,6 +1137,10 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
}
} 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 {
@@ -1175,7 +1192,6 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
state = SCE_RB_DEFAULT;
i--;
chNext = ch;
chNext2 = chNext;
preferRE = false;
} else if (HereDoc.Quoted) {
if (ch == HereDoc.Quote) { // closing quote => end of delimiter
@@ -1332,7 +1348,6 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
}
}
chNext = styler.SafeGetCharAt(i + 1);
chNext2 = styler.SafeGetCharAt(i + 2);
}
}
// Quotes of all kinds...
@@ -1439,10 +1454,32 @@ static bool keywordIsModifier(const char *word,
if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
return keywordDoStartsLoop(pos, styler);
}
char ch;
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));
@@ -1453,14 +1490,27 @@ static bool keywordIsModifier(const char *word,
// 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; //XXX not quite right if the prev line is a continuation
return false;
}
// First things where the action is unambiguous
switch (style) {
@@ -1676,6 +1726,12 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
) {
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;
@@ -1712,4 +1768,4 @@ static const char * const rubyWordListDesc[] = {
0
};
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);

View File

@@ -6,22 +6,24 @@
// 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 <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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 == '_';}
@@ -203,13 +205,11 @@ void ColouriseSMLDoc(
}
void FoldSMLDoc(
unsigned int startPos, int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler)
unsigned int, int,
int,
WordList *[],
Accessor &)
{
//supress "not used" warnings
startPos || length || initStyle || keywordlists[0] || styler.Length();
}
static const char * const SMLWordListDesc[] = {

View File

@@ -0,0 +1,834 @@
//-*- 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);

View File

@@ -5,18 +5,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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
@@ -48,10 +52,9 @@ static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keyw
static bool IsSolComment(Accessor &styler, int pos, int len)
{
char c;
if(len > 0)
{
c = styler[pos];
char c = styler[pos];
if(c == '`') return true;
if(len > 1)
{
@@ -365,7 +368,7 @@ static void FoldSolDoc(unsigned int startPos, int length, int initStyle,
int state = initStyle & 31;
int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment);
if ((state == SCE_SCRIPTOL_TRIPLE))
if (state == SCE_SCRIPTOL_TRIPLE)
indentCurrent |= SC_FOLDLEVELWHITEFLAG;
char chNext = styler[startPos];
for (int i = startPos; i < lengthDoc; i++)

View File

@@ -8,17 +8,22 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -9,19 +9,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -11,16 +11,19 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -6,19 +6,24 @@
// 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 <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#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 "PropSet.h"
#include "KeyWords.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;

View File

@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;

View File

@@ -33,19 +33,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -89,10 +92,6 @@ static inline bool IsEOLSkip(StyleContext &sc)
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 == ';'
@@ -698,7 +697,7 @@ static inline bool IsAnIdentifier(const int style) {
}
static inline bool IsAnOperator(const int style) {
return style == SCE_T3_OPERATOR || SCE_T3_BRACE;
return style == SCE_T3_OPERATOR || style == SCE_T3_BRACE;
}
static inline bool IsSpaceEquivalent(const int ch, const int style) {

View File

@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -306,6 +309,7 @@ next:
break;
case '}':
sc.SetState(SCE_TCL_OPERATOR);
expected = true;
--currentLevel;
break;
case '[':

View File

@@ -0,0 +1,511 @@
// 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);

View File

@@ -18,18 +18,21 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.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;
@@ -219,7 +222,7 @@ static void ColouriseTeXDoc(
sc.ForwardSetState(SCE_TEX_TEXT) ;
} else {
sc.GetCurrent(key, sizeof(key)-1) ;
k = strlen(key) ;
k = static_cast<int>(strlen(key)) ;
memmove(key,key+1,k) ; // shift left over escape token
key[k] = '\0' ;
k-- ;

View File

@@ -0,0 +1,480 @@
/******************************************************************
* 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");

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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

View File

@@ -15,16 +15,19 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -101,7 +104,7 @@ static void ColouriseVHDLDoc(
}
sc.SetState(SCE_VHDL_DEFAULT);
}
} else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_V_COMMENTLINEBANG) {
} else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_VHDL_COMMENTLINEBANG) {
if (sc.atLineEnd) {
sc.SetState(SCE_VHDL_DEFAULT);
}
@@ -113,7 +116,7 @@ static void ColouriseVHDLDoc(
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_VHDL_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_V_STRINGEOL);
sc.ChangeState(SCE_VHDL_STRINGEOL);
sc.ForwardSetState(SCE_VHDL_DEFAULT);
}
}
@@ -124,9 +127,6 @@ static void ColouriseVHDLDoc(
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);
@@ -161,7 +161,7 @@ static bool IsCommentLine(int line, Accessor &styler) {
static void FoldNoBoxVHDLDoc(
unsigned int startPos,
int length,
int initStyle,
int,
Accessor &styler)
{
// Decided it would be smarter to have the lexer have all keywords included. Therefore I
@@ -232,7 +232,7 @@ static void FoldNoBoxVHDLDoc(
}
}
}
for(j=j+strlen(prevWord); j<endPos; j++)
for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++)
{
char ch = styler.SafeGetCharAt(j);
int style = styler.StyleAt(j);
@@ -249,7 +249,6 @@ static void FoldNoBoxVHDLDoc(
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);
/***************************************/
@@ -265,7 +264,7 @@ static void FoldNoBoxVHDLDoc(
j ++ ;
chNextNonBlank = styler.SafeGetCharAt(j);
}
style = styleNext;
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');

View File

@@ -8,25 +8,28 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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 == '\'');
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$');
}
static inline bool IsAWordStart(const int ch) {
@@ -150,6 +153,22 @@ 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 {".
@@ -195,6 +214,15 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
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);
@@ -241,24 +269,36 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
if (styler.Match(j, "case") ||
styler.Match(j, "casex") ||
styler.Match(j, "casez") ||
styler.Match(j, "class") ||
styler.Match(j, "function") ||
styler.Match(j, "fork") ||
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, "generate") ||
styler.Match(j, "specify") ||
styler.Match(j, "primitive") ||
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, "join") ||
styler.Match(j, "endtask") ||
styler.Match(j, "endgenerate") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endspecify") ||
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--;

View File

@@ -0,0 +1,470 @@
// 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);

View File

@@ -7,19 +7,22 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.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
@@ -270,7 +273,7 @@ static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unu
}
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
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

View File

@@ -0,0 +1,79 @@
// 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;
}

View File

@@ -0,0 +1,35 @@
// 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

Some files were not shown because too many files have changed in this diff Show More