Update scintilla to 3.21.1
This commit is contained in:
parent
0a33da8058
commit
6c3b0f66f3
223 changed files with 21171 additions and 9779 deletions
|
|
@ -2,19 +2,19 @@ License for Scintilla and SciTE
|
|||
|
||||
Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
|
||||
|
||||
All Rights Reserved
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation.
|
||||
|
||||
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||
OR PERFORMANCE OF THIS SOFTWARE.
|
||||
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||
OR PERFORMANCE OF THIS SOFTWARE.
|
||||
70
src/stc/scintilla/include/Compat.h
Normal file
70
src/stc/scintilla/include/Compat.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// c++11 compatibility with some c++14 features and higher.
|
||||
// This helps minimize changes from the default branch.
|
||||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace Sci {
|
||||
|
||||
// std::clamp
|
||||
template <typename T>
|
||||
inline constexpr T clamp(T val, T minVal, T maxVal) {
|
||||
return (val > maxVal) ? maxVal : ((val < minVal) ? minVal : val);
|
||||
}
|
||||
|
||||
// std::round (not present on older MacOSX SDKs)
|
||||
template<class T>
|
||||
T round(T arg) {
|
||||
return ::round(arg);
|
||||
}
|
||||
|
||||
// std::lround (not present on older MacOSX SDKs)
|
||||
template<class T>
|
||||
long lround(T arg) {
|
||||
return ::lround(arg);
|
||||
}
|
||||
|
||||
// std::make_unique
|
||||
template<class T> struct _Unique_if {
|
||||
typedef std::unique_ptr<T> _Single_object;
|
||||
};
|
||||
template<class T> struct _Unique_if<T[]> {
|
||||
typedef std::unique_ptr<T[]> _Unknown_bound;
|
||||
};
|
||||
template<class T, size_t N> struct _Unique_if<T[N]> {
|
||||
typedef void _Known_bound;
|
||||
};
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Single_object
|
||||
make_unique(Args&&... args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
template<class T>
|
||||
typename _Unique_if<T>::_Unknown_bound
|
||||
make_unique(size_t n) {
|
||||
typedef typename std::remove_extent<T>::type U;
|
||||
return std::unique_ptr<T>(new U[n]());
|
||||
}
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Known_bound
|
||||
make_unique(Args&&...) = delete;
|
||||
|
||||
// std::size
|
||||
template <typename T, size_t N>
|
||||
constexpr size_t size(const T (&)[N]) noexcept {
|
||||
return N;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -10,15 +10,7 @@
|
|||
|
||||
#include "Sci_Position.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
namespace Scintilla {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SCI_METHOD __stdcall
|
||||
#else
|
||||
#define SCI_METHOD
|
||||
#endif
|
||||
|
||||
enum { dvOriginal=0, dvLineEnd=1 };
|
||||
|
||||
|
|
@ -54,7 +46,7 @@ public:
|
|||
virtual int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const = 0;
|
||||
};
|
||||
|
||||
enum { lvOriginal=0, lvSubStyles=1 };
|
||||
enum { lvOriginal=0, lvSubStyles=1, lvMetaData=2, lvIdentity=3 };
|
||||
|
||||
class ILexer {
|
||||
public:
|
||||
|
|
@ -85,16 +77,21 @@ public:
|
|||
virtual const char * SCI_METHOD GetSubStyleBases() = 0;
|
||||
};
|
||||
|
||||
class ILoader {
|
||||
class ILexerWithMetaData : public ILexerWithSubStyles {
|
||||
public:
|
||||
virtual int SCI_METHOD Release() = 0;
|
||||
// Returns a status code from SC_STATUS_*
|
||||
virtual int SCI_METHOD AddData(char *data, Sci_Position length) = 0;
|
||||
virtual void * SCI_METHOD ConvertToDocument() = 0;
|
||||
virtual int SCI_METHOD NamedStyles() = 0;
|
||||
virtual const char * SCI_METHOD NameOfStyle(int style) = 0;
|
||||
virtual const char * SCI_METHOD TagsOfStyle(int style) = 0;
|
||||
virtual const char * SCI_METHOD DescriptionOfStyle(int style) = 0;
|
||||
};
|
||||
|
||||
class ILexerWithIdentity : public ILexerWithMetaData {
|
||||
public:
|
||||
virtual const char * SCI_METHOD GetName() = 0;
|
||||
virtual int SCI_METHOD GetIdentifier() = 0;
|
||||
virtual const char * SCI_METHOD PropertyGet(const char *key) = 0;
|
||||
};
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
21
src/stc/scintilla/include/ILoader.h
Normal file
21
src/stc/scintilla/include/ILoader.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file ILoader.h
|
||||
** Interface for loading into a Scintilla document from a background thread.
|
||||
**/
|
||||
// Copyright 1998-2017 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef ILOADER_H
|
||||
#define ILOADER_H
|
||||
|
||||
#include "Sci_Position.h"
|
||||
|
||||
class ILoader {
|
||||
public:
|
||||
virtual int SCI_METHOD Release() = 0;
|
||||
// Returns a status code from SC_STATUS_*
|
||||
virtual int SCI_METHOD AddData(const char *data, Sci_Position length) = 0;
|
||||
virtual void * SCI_METHOD ConvertToDocument() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#define PLAT_FOX 0
|
||||
#define PLAT_CURSES 0
|
||||
#define PLAT_TK 0
|
||||
#define PLAT_HAIKU 0
|
||||
|
||||
#if defined(FOX)
|
||||
#undef PLAT_FOX
|
||||
|
|
@ -38,6 +39,10 @@
|
|||
#undef PLAT_CURSES
|
||||
#define PLAT_CURSES 1
|
||||
|
||||
#elif defined(__HAIKU__)
|
||||
#undef PLAT_HAIKU
|
||||
#define PLAT_HAIKU 1
|
||||
|
||||
#elif defined(SCINTILLA_QT)
|
||||
#undef PLAT_QT
|
||||
#define PLAT_QT 1
|
||||
|
|
@ -71,15 +76,10 @@
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
namespace Scintilla {
|
||||
#endif
|
||||
|
||||
typedef float XYPOSITION;
|
||||
typedef double XYACCUMULATOR;
|
||||
inline int RoundXYPosition(XYPOSITION xyPos) {
|
||||
return int(xyPos + 0.5);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
@ -101,21 +101,31 @@ public:
|
|||
XYPOSITION x;
|
||||
XYPOSITION y;
|
||||
|
||||
explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) {
|
||||
constexpr explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) noexcept : x(x_), y(y_) {
|
||||
}
|
||||
|
||||
static Point FromInts(int x_, int y_) {
|
||||
static constexpr Point FromInts(int x_, int y_) noexcept {
|
||||
return Point(static_cast<XYPOSITION>(x_), static_cast<XYPOSITION>(y_));
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
constexpr bool operator!=(Point other) const noexcept {
|
||||
return (x != other.x) || (y != other.y);
|
||||
}
|
||||
|
||||
static Point FromLong(long lpoint);
|
||||
constexpr Point operator+(Point other) const noexcept {
|
||||
return Point(x + other.x, y + other.y);
|
||||
}
|
||||
|
||||
constexpr Point operator-(Point other) const noexcept {
|
||||
return Point(x - other.x, y - other.y);
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
};
|
||||
|
||||
/**
|
||||
* A geometric rectangle class.
|
||||
* PRectangle is similar to the Win32 RECT.
|
||||
* PRectangle is similar to Win32 RECT.
|
||||
* PRectangles contain their top and left sides, but not their right and bottom sides.
|
||||
*/
|
||||
class PRectangle {
|
||||
|
|
@ -125,113 +135,147 @@ public:
|
|||
XYPOSITION right;
|
||||
XYPOSITION bottom;
|
||||
|
||||
explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) :
|
||||
constexpr explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) noexcept :
|
||||
left(left_), top(top_), right(right_), bottom(bottom_) {
|
||||
}
|
||||
|
||||
static PRectangle FromInts(int left_, int top_, int right_, int bottom_) {
|
||||
static constexpr PRectangle FromInts(int left_, int top_, int right_, int bottom_) noexcept {
|
||||
return PRectangle(static_cast<XYPOSITION>(left_), static_cast<XYPOSITION>(top_),
|
||||
static_cast<XYPOSITION>(right_), static_cast<XYPOSITION>(bottom_));
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
|
||||
bool operator==(PRectangle &rc) const {
|
||||
constexpr bool operator==(const PRectangle &rc) const noexcept {
|
||||
return (rc.left == left) && (rc.right == right) &&
|
||||
(rc.top == top) && (rc.bottom == bottom);
|
||||
}
|
||||
bool Contains(Point pt) const {
|
||||
constexpr bool Contains(Point pt) const noexcept {
|
||||
return (pt.x >= left) && (pt.x <= right) &&
|
||||
(pt.y >= top) && (pt.y <= bottom);
|
||||
}
|
||||
bool ContainsWholePixel(Point pt) const {
|
||||
constexpr bool ContainsWholePixel(Point pt) const noexcept {
|
||||
// Does the rectangle contain all of the pixel to left/below the point
|
||||
return (pt.x >= left) && ((pt.x+1) <= right) &&
|
||||
(pt.y >= top) && ((pt.y+1) <= bottom);
|
||||
}
|
||||
bool Contains(PRectangle rc) const {
|
||||
constexpr bool Contains(PRectangle rc) const noexcept {
|
||||
return (rc.left >= left) && (rc.right <= right) &&
|
||||
(rc.top >= top) && (rc.bottom <= bottom);
|
||||
}
|
||||
bool Intersects(PRectangle other) const {
|
||||
constexpr bool Intersects(PRectangle other) const noexcept {
|
||||
return (right > other.left) && (left < other.right) &&
|
||||
(bottom > other.top) && (top < other.bottom);
|
||||
}
|
||||
void Move(XYPOSITION xDelta, XYPOSITION yDelta) {
|
||||
void Move(XYPOSITION xDelta, XYPOSITION yDelta) noexcept {
|
||||
left += xDelta;
|
||||
top += yDelta;
|
||||
right += xDelta;
|
||||
bottom += yDelta;
|
||||
}
|
||||
XYPOSITION Width() const { return right - left; }
|
||||
XYPOSITION Height() const { return bottom - top; }
|
||||
bool Empty() const {
|
||||
constexpr XYPOSITION Width() const noexcept { return right - left; }
|
||||
constexpr XYPOSITION Height() const noexcept { return bottom - top; }
|
||||
constexpr bool Empty() const noexcept {
|
||||
return (Height() <= 0) || (Width() <= 0);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds a desired RGB colour.
|
||||
* Holds an RGB colour with 8 bits for each component.
|
||||
*/
|
||||
constexpr const float componentMaximum = 255.0f;
|
||||
class ColourDesired {
|
||||
long co;
|
||||
int co;
|
||||
public:
|
||||
ColourDesired(long lcol=0) {
|
||||
co = lcol;
|
||||
constexpr explicit ColourDesired(int co_=0) noexcept : co(co_) {
|
||||
}
|
||||
|
||||
ColourDesired(unsigned int red, unsigned int green, unsigned int blue) {
|
||||
Set(red, green, blue);
|
||||
constexpr ColourDesired(unsigned int red, unsigned int green, unsigned int blue) noexcept :
|
||||
co(red | (green << 8) | (blue << 16)) {
|
||||
}
|
||||
|
||||
bool operator==(const ColourDesired &other) const {
|
||||
constexpr bool operator==(const ColourDesired &other) const noexcept {
|
||||
return co == other.co;
|
||||
}
|
||||
|
||||
void Set(long lcol) {
|
||||
co = lcol;
|
||||
}
|
||||
|
||||
void Set(unsigned int red, unsigned int green, unsigned int blue) {
|
||||
co = red | (green << 8) | (blue << 16);
|
||||
}
|
||||
|
||||
static inline unsigned int ValueOfHex(const char ch) {
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Set(const char *val) {
|
||||
if (*val == '#') {
|
||||
val++;
|
||||
}
|
||||
unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]);
|
||||
unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]);
|
||||
unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]);
|
||||
Set(r, g, b);
|
||||
}
|
||||
|
||||
long AsLong() const {
|
||||
constexpr int AsInteger() const noexcept {
|
||||
return co;
|
||||
}
|
||||
|
||||
unsigned int GetRed() const {
|
||||
// Red, green and blue values as bytes 0..255
|
||||
constexpr unsigned char GetRed() const noexcept {
|
||||
return co & 0xff;
|
||||
}
|
||||
|
||||
unsigned int GetGreen() const {
|
||||
constexpr unsigned char GetGreen() const noexcept {
|
||||
return (co >> 8) & 0xff;
|
||||
}
|
||||
|
||||
unsigned int GetBlue() const {
|
||||
constexpr unsigned char GetBlue() const noexcept {
|
||||
return (co >> 16) & 0xff;
|
||||
}
|
||||
|
||||
// Red, green and blue values as float 0..1.0
|
||||
constexpr float GetRedComponent() const noexcept {
|
||||
return GetRed() / componentMaximum;
|
||||
}
|
||||
constexpr float GetGreenComponent() const noexcept {
|
||||
return GetGreen() / componentMaximum;
|
||||
}
|
||||
constexpr float GetBlueComponent() const noexcept {
|
||||
return GetBlue() / componentMaximum;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds an RGBA colour.
|
||||
*/
|
||||
class ColourAlpha : public ColourDesired {
|
||||
public:
|
||||
constexpr explicit ColourAlpha(int co_ = 0) noexcept : ColourDesired(co_) {
|
||||
}
|
||||
|
||||
constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue) noexcept :
|
||||
ColourDesired(red | (green << 8) | (blue << 16)) {
|
||||
}
|
||||
|
||||
constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha) noexcept :
|
||||
ColourDesired(red | (green << 8) | (blue << 16) | (alpha << 24)) {
|
||||
}
|
||||
|
||||
constexpr ColourAlpha(ColourDesired cd, unsigned int alpha) noexcept :
|
||||
ColourDesired(cd.AsInteger() | (alpha << 24)) {
|
||||
}
|
||||
|
||||
constexpr ColourDesired GetColour() const noexcept {
|
||||
return ColourDesired(AsInteger() & 0xffffff);
|
||||
}
|
||||
|
||||
constexpr unsigned char GetAlpha() const noexcept {
|
||||
return (AsInteger() >> 24) & 0xff;
|
||||
}
|
||||
|
||||
constexpr float GetAlphaComponent() const noexcept {
|
||||
return GetAlpha() / componentMaximum;
|
||||
}
|
||||
|
||||
ColourAlpha MixedWith(ColourAlpha other) const noexcept {
|
||||
const unsigned int red = (GetRed() + other.GetRed()) / 2;
|
||||
const unsigned int green = (GetGreen() + other.GetGreen()) / 2;
|
||||
const unsigned int blue = (GetBlue() + other.GetBlue()) / 2;
|
||||
const unsigned int alpha = (GetAlpha() + other.GetAlpha()) / 2;
|
||||
return ColourAlpha(red, green, blue, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds an element of a gradient with an RGBA colour and a relative position.
|
||||
*/
|
||||
class ColourStop {
|
||||
public:
|
||||
float position;
|
||||
ColourAlpha colour;
|
||||
ColourStop(float position_, ColourAlpha colour_) noexcept :
|
||||
position(position_), colour(colour_) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -254,7 +298,7 @@ struct FontParameters {
|
|||
bool italic_=false,
|
||||
int extraFontFlag_=0,
|
||||
int technology_=0,
|
||||
int characterSet_=0) :
|
||||
int characterSet_=0) noexcept :
|
||||
|
||||
faceName(faceName_),
|
||||
size(size_),
|
||||
|
|
@ -271,19 +315,21 @@ struct FontParameters {
|
|||
class Font {
|
||||
protected:
|
||||
FontID fid;
|
||||
// Private so Font objects can not be copied
|
||||
Font(const Font &);
|
||||
Font &operator=(const Font &);
|
||||
public:
|
||||
Font();
|
||||
Font() noexcept;
|
||||
// Deleted so Font objects can not be copied
|
||||
Font(const Font &) = delete;
|
||||
Font(Font &&) = delete;
|
||||
Font &operator=(const Font &) = delete;
|
||||
Font &operator=(Font &&) = delete;
|
||||
virtual ~Font();
|
||||
|
||||
virtual void Create(const FontParameters &fp);
|
||||
virtual void Release();
|
||||
|
||||
FontID GetID() { return fid; }
|
||||
FontID GetID() const noexcept { return fid; }
|
||||
// Alias another font - caller guarantees not to Release
|
||||
void SetID(FontID fid_) { fid = fid_; }
|
||||
void SetID(FontID fid_) noexcept { fid = fid_; }
|
||||
friend class Surface;
|
||||
friend class SurfaceImpl;
|
||||
};
|
||||
|
|
@ -292,12 +338,12 @@ public:
|
|||
* A surface abstracts a place to draw.
|
||||
*/
|
||||
class Surface {
|
||||
private:
|
||||
// Private so Surface objects can not be copied
|
||||
Surface(const Surface &) {}
|
||||
Surface &operator=(const Surface &) { return *this; }
|
||||
public:
|
||||
Surface() {}
|
||||
Surface() noexcept = default;
|
||||
Surface(const Surface &) = delete;
|
||||
Surface(Surface &&) = delete;
|
||||
Surface &operator=(const Surface &) = delete;
|
||||
Surface &operator=(Surface &&) = delete;
|
||||
virtual ~Surface() {}
|
||||
static Surface *Allocate(int technology);
|
||||
|
||||
|
|
@ -312,27 +358,27 @@ public:
|
|||
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, ColourDesired fore, ColourDesired back)=0;
|
||||
virtual void Polygon(Point *pts, size_t 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, ColourDesired fore, ColourDesired back)=0;
|
||||
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill,
|
||||
ColourDesired outline, int alphaOutline, int flags)=0;
|
||||
enum class GradientOptions { leftToRight, topToBottom };
|
||||
virtual void GradientRectangle(PRectangle rc, const std::vector<ColourStop> &stops, GradientOptions options)=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_, 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 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 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;
|
||||
|
||||
|
|
@ -343,11 +389,6 @@ public:
|
|||
virtual void SetDBCSMode(int codePage)=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple callback action passing one piece of untyped user data.
|
||||
*/
|
||||
typedef void (*CallBackAction)(void*);
|
||||
|
||||
/**
|
||||
* Class to hide the details of window manipulation.
|
||||
* Does not own the window which will normally have a longer life than this object.
|
||||
|
|
@ -356,30 +397,31 @@ class Window {
|
|||
protected:
|
||||
WindowID wid;
|
||||
public:
|
||||
Window() : wid(0), cursorLast(cursorInvalid) {
|
||||
Window() noexcept : wid(nullptr), cursorLast(cursorInvalid) {
|
||||
}
|
||||
Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
|
||||
}
|
||||
virtual ~Window();
|
||||
Window &operator=(WindowID wid_) {
|
||||
Window(const Window &source) = delete;
|
||||
Window(Window &&) = delete;
|
||||
Window &operator=(WindowID wid_) noexcept {
|
||||
wid = wid_;
|
||||
cursorLast = cursorInvalid;
|
||||
return *this;
|
||||
}
|
||||
WindowID GetID() const { return wid; }
|
||||
bool Created() const { return wid != 0; }
|
||||
Window &operator=(const Window &) = delete;
|
||||
Window &operator=(Window &&) = delete;
|
||||
virtual ~Window();
|
||||
WindowID GetID() const noexcept { return wid; }
|
||||
bool Created() const noexcept { return wid != nullptr; }
|
||||
void Destroy();
|
||||
bool HasFocus();
|
||||
PRectangle GetPosition();
|
||||
PRectangle GetPosition() const;
|
||||
void SetPosition(PRectangle rc);
|
||||
void SetPositionRelative(PRectangle rc, Window relativeTo);
|
||||
PRectangle GetClientPosition();
|
||||
void SetPositionRelative(PRectangle rc, const Window *relativeTo);
|
||||
PRectangle GetClientPosition() const;
|
||||
void Show(bool show=true);
|
||||
void InvalidateAll();
|
||||
void InvalidateRectangle(PRectangle rc);
|
||||
virtual void SetFont(Font &font);
|
||||
enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
|
||||
void SetCursor(Cursor curs);
|
||||
void SetTitle(const char *s);
|
||||
PRectangle GetMonitorRect(Point pt);
|
||||
private:
|
||||
Cursor cursorLast;
|
||||
|
|
@ -389,13 +431,26 @@ private:
|
|||
* Listbox management.
|
||||
*/
|
||||
|
||||
// ScintillaBase implements IListBoxDelegate to receive ListBoxEvents from a ListBox
|
||||
|
||||
struct ListBoxEvent {
|
||||
enum class EventType { selectionChange, doubleClick } event;
|
||||
ListBoxEvent(EventType event_) noexcept : event(event_) {
|
||||
}
|
||||
};
|
||||
|
||||
class IListBoxDelegate {
|
||||
public:
|
||||
virtual void ListNotify(ListBoxEvent *plbe)=0;
|
||||
};
|
||||
|
||||
class ListBox : public Window {
|
||||
public:
|
||||
ListBox();
|
||||
virtual ~ListBox();
|
||||
ListBox() noexcept;
|
||||
~ListBox() override;
|
||||
static ListBox *Allocate();
|
||||
|
||||
virtual void SetFont(Font &font)=0;
|
||||
void SetFont(Font &font) override =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;
|
||||
|
|
@ -412,7 +467,7 @@ public:
|
|||
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 SetDelegate(IListBoxDelegate *lbDelegate)=0;
|
||||
virtual void SetList(const char* list, char separator, char typesep)=0;
|
||||
};
|
||||
|
||||
|
|
@ -422,27 +477,19 @@ public:
|
|||
class Menu {
|
||||
MenuID mid;
|
||||
public:
|
||||
Menu();
|
||||
MenuID GetID() { return mid; }
|
||||
Menu() noexcept;
|
||||
MenuID GetID() const noexcept { return mid; }
|
||||
void CreatePopUp();
|
||||
void Destroy();
|
||||
void Show(Point pt, Window &w);
|
||||
};
|
||||
|
||||
class ElapsedTime {
|
||||
long bigBit;
|
||||
long littleBit;
|
||||
public:
|
||||
ElapsedTime();
|
||||
double Duration(bool reset=false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamic Library (DLL/SO/...) loading
|
||||
*/
|
||||
class DynamicLibrary {
|
||||
public:
|
||||
virtual ~DynamicLibrary() {}
|
||||
virtual ~DynamicLibrary() = default;
|
||||
|
||||
/// @return Pointer to function "name", or NULL on failure.
|
||||
virtual Function FindFunction(const char *name) = 0;
|
||||
|
|
@ -469,61 +516,34 @@ public:
|
|||
* and chrome colour. Not a creatable object, more of a module with several functions.
|
||||
*/
|
||||
class Platform {
|
||||
// Private so Platform objects can not be copied
|
||||
Platform(const Platform &) {}
|
||||
Platform &operator=(const Platform &) { return *this; }
|
||||
public:
|
||||
// Should be private because no new Platforms are ever created
|
||||
// but gcc warns about this
|
||||
Platform() {}
|
||||
~Platform() {}
|
||||
Platform() = default;
|
||||
Platform(const Platform &) = delete;
|
||||
Platform(Platform &&) = delete;
|
||||
Platform &operator=(const Platform &) = delete;
|
||||
Platform &operator=(Platform &&) = delete;
|
||||
~Platform() = default;
|
||||
static ColourDesired Chrome();
|
||||
static ColourDesired ChromeHighlight();
|
||||
static const char *DefaultFont();
|
||||
static int DefaultFontSize();
|
||||
static unsigned int DoubleClickTime();
|
||||
static bool MouseButtonBounce();
|
||||
static void DebugDisplay(const char *s);
|
||||
static bool IsKeyDown(int key);
|
||||
static long SendScintilla(
|
||||
WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0);
|
||||
static long SendScintillaPointer(
|
||||
WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0);
|
||||
static bool IsDBCSLeadByte(int codePage, char ch);
|
||||
static int DBCSCharLength(int codePage, const char *s);
|
||||
static int DBCSCharMaxLength();
|
||||
|
||||
// These are utility functions not really tied to a platform
|
||||
static int Minimum(int a, int b);
|
||||
static int Maximum(int a, int b);
|
||||
// Next three assume 16 bit shorts and 32 bit longs
|
||||
static long LongFromTwoShorts(short a,short b) {
|
||||
static constexpr long LongFromTwoShorts(short a,short b) noexcept {
|
||||
return (a) | ((b) << 16);
|
||||
}
|
||||
static short HighShortFromLong(long x) {
|
||||
return static_cast<short>(x >> 16);
|
||||
}
|
||||
static short LowShortFromLong(long x) {
|
||||
return static_cast<short>(x & 0xffff);
|
||||
}
|
||||
|
||||
static void DebugPrintf(const char *format, ...);
|
||||
static bool ShowAssertionPopUps(bool assertionPopUps_);
|
||||
static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN;
|
||||
static int Clamp(int val, int minVal, int maxVal);
|
||||
};
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define PLATFORM_ASSERT(c) ((void)0)
|
||||
#else
|
||||
#ifdef SCI_NAMESPACE
|
||||
#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__))
|
||||
#else
|
||||
#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -134,6 +134,17 @@
|
|||
#define SCLEX_TEHEX 119
|
||||
#define SCLEX_JSON 120
|
||||
#define SCLEX_EDIFACT 121
|
||||
#define SCLEX_INDENT 122
|
||||
#define SCLEX_MAXIMA 123
|
||||
#define SCLEX_STATA 124
|
||||
#define SCLEX_SAS 125
|
||||
#define SCLEX_NIM 126
|
||||
#define SCLEX_CIL 127
|
||||
#define SCLEX_X12 128
|
||||
#define SCLEX_DATAFLEX 129
|
||||
#define SCLEX_HOLLYWOOD 130
|
||||
#define SCLEX_RAKU 131
|
||||
#define SCLEX_LPEG 999
|
||||
#define SCLEX_AUTOMATIC 1000
|
||||
#define SCE_P_DEFAULT 0
|
||||
#define SCE_P_COMMENTLINE 1
|
||||
|
|
@ -151,6 +162,10 @@
|
|||
#define SCE_P_STRINGEOL 13
|
||||
#define SCE_P_WORD2 14
|
||||
#define SCE_P_DECORATOR 15
|
||||
#define SCE_P_FSTRING 16
|
||||
#define SCE_P_FCHARACTER 17
|
||||
#define SCE_P_FTRIPLE 18
|
||||
#define SCE_P_FTRIPLEDOUBLE 19
|
||||
#define SCE_C_DEFAULT 0
|
||||
#define SCE_C_COMMENT 1
|
||||
#define SCE_C_COMMENTLINE 2
|
||||
|
|
@ -502,6 +517,7 @@
|
|||
#define SCE_ERR_GCC_INCLUDED_FROM 22
|
||||
#define SCE_ERR_ESCSEQ 23
|
||||
#define SCE_ERR_ESCSEQ_UNKNOWN 24
|
||||
#define SCE_ERR_GCC_EXCERPT 25
|
||||
#define SCE_ERR_ES_BLACK 40
|
||||
#define SCE_ERR_ES_RED 41
|
||||
#define SCE_ERR_ES_GREEN 42
|
||||
|
|
@ -552,6 +568,10 @@
|
|||
#define SCE_DIFF_DELETED 5
|
||||
#define SCE_DIFF_ADDED 6
|
||||
#define SCE_DIFF_CHANGED 7
|
||||
#define SCE_DIFF_PATCH_ADD 8
|
||||
#define SCE_DIFF_PATCH_DELETE 9
|
||||
#define SCE_DIFF_REMOVED_PATCH_ADD 10
|
||||
#define SCE_DIFF_REMOVED_PATCH_DELETE 11
|
||||
#define SCE_CONF_DEFAULT 0
|
||||
#define SCE_CONF_COMMENT 1
|
||||
#define SCE_CONF_NUMBER 2
|
||||
|
|
@ -667,6 +687,14 @@
|
|||
#define SCE_MATLAB_OPERATOR 6
|
||||
#define SCE_MATLAB_IDENTIFIER 7
|
||||
#define SCE_MATLAB_DOUBLEQUOTESTRING 8
|
||||
#define SCE_MAXIMA_OPERATOR 0
|
||||
#define SCE_MAXIMA_COMMANDENDING 1
|
||||
#define SCE_MAXIMA_COMMENT 2
|
||||
#define SCE_MAXIMA_NUMBER 3
|
||||
#define SCE_MAXIMA_STRING 4
|
||||
#define SCE_MAXIMA_COMMAND 5
|
||||
#define SCE_MAXIMA_VARIABLE 6
|
||||
#define SCE_MAXIMA_UNKNOWN 7
|
||||
#define SCE_SCRIPTOL_DEFAULT 0
|
||||
#define SCE_SCRIPTOL_WHITE 1
|
||||
#define SCE_SCRIPTOL_COMMENTLINE 2
|
||||
|
|
@ -1807,6 +1835,130 @@
|
|||
#define SCE_EDI_UNA 6
|
||||
#define SCE_EDI_UNH 7
|
||||
#define SCE_EDI_BADSEGMENT 8
|
||||
#define SCE_STATA_DEFAULT 0
|
||||
#define SCE_STATA_COMMENT 1
|
||||
#define SCE_STATA_COMMENTLINE 2
|
||||
#define SCE_STATA_COMMENTBLOCK 3
|
||||
#define SCE_STATA_NUMBER 4
|
||||
#define SCE_STATA_OPERATOR 5
|
||||
#define SCE_STATA_IDENTIFIER 6
|
||||
#define SCE_STATA_STRING 7
|
||||
#define SCE_STATA_TYPE 8
|
||||
#define SCE_STATA_WORD 9
|
||||
#define SCE_STATA_GLOBAL_MACRO 10
|
||||
#define SCE_STATA_MACRO 11
|
||||
#define SCE_SAS_DEFAULT 0
|
||||
#define SCE_SAS_COMMENT 1
|
||||
#define SCE_SAS_COMMENTLINE 2
|
||||
#define SCE_SAS_COMMENTBLOCK 3
|
||||
#define SCE_SAS_NUMBER 4
|
||||
#define SCE_SAS_OPERATOR 5
|
||||
#define SCE_SAS_IDENTIFIER 6
|
||||
#define SCE_SAS_STRING 7
|
||||
#define SCE_SAS_TYPE 8
|
||||
#define SCE_SAS_WORD 9
|
||||
#define SCE_SAS_GLOBAL_MACRO 10
|
||||
#define SCE_SAS_MACRO 11
|
||||
#define SCE_SAS_MACRO_KEYWORD 12
|
||||
#define SCE_SAS_BLOCK_KEYWORD 13
|
||||
#define SCE_SAS_MACRO_FUNCTION 14
|
||||
#define SCE_SAS_STATEMENT 15
|
||||
#define SCE_NIM_DEFAULT 0
|
||||
#define SCE_NIM_COMMENT 1
|
||||
#define SCE_NIM_COMMENTDOC 2
|
||||
#define SCE_NIM_COMMENTLINE 3
|
||||
#define SCE_NIM_COMMENTLINEDOC 4
|
||||
#define SCE_NIM_NUMBER 5
|
||||
#define SCE_NIM_STRING 6
|
||||
#define SCE_NIM_CHARACTER 7
|
||||
#define SCE_NIM_WORD 8
|
||||
#define SCE_NIM_TRIPLE 9
|
||||
#define SCE_NIM_TRIPLEDOUBLE 10
|
||||
#define SCE_NIM_BACKTICKS 11
|
||||
#define SCE_NIM_FUNCNAME 12
|
||||
#define SCE_NIM_STRINGEOL 13
|
||||
#define SCE_NIM_NUMERROR 14
|
||||
#define SCE_NIM_OPERATOR 15
|
||||
#define SCE_NIM_IDENTIFIER 16
|
||||
#define SCE_CIL_DEFAULT 0
|
||||
#define SCE_CIL_COMMENT 1
|
||||
#define SCE_CIL_COMMENTLINE 2
|
||||
#define SCE_CIL_WORD 3
|
||||
#define SCE_CIL_WORD2 4
|
||||
#define SCE_CIL_WORD3 5
|
||||
#define SCE_CIL_STRING 6
|
||||
#define SCE_CIL_LABEL 7
|
||||
#define SCE_CIL_OPERATOR 8
|
||||
#define SCE_CIL_IDENTIFIER 9
|
||||
#define SCE_CIL_STRINGEOL 10
|
||||
#define SCE_X12_DEFAULT 0
|
||||
#define SCE_X12_BAD 1
|
||||
#define SCE_X12_ENVELOPE 2
|
||||
#define SCE_X12_FUNCTIONGROUP 3
|
||||
#define SCE_X12_TRANSACTIONSET 4
|
||||
#define SCE_X12_SEGMENTHEADER 5
|
||||
#define SCE_X12_SEGMENTEND 6
|
||||
#define SCE_X12_SEP_ELEMENT 7
|
||||
#define SCE_X12_SEP_SUBELEMENT 8
|
||||
#define SCE_DF_DEFAULT 0
|
||||
#define SCE_DF_IDENTIFIER 1
|
||||
#define SCE_DF_METATAG 2
|
||||
#define SCE_DF_IMAGE 3
|
||||
#define SCE_DF_COMMENTLINE 4
|
||||
#define SCE_DF_PREPROCESSOR 5
|
||||
#define SCE_DF_PREPROCESSOR2 6
|
||||
#define SCE_DF_NUMBER 7
|
||||
#define SCE_DF_HEXNUMBER 8
|
||||
#define SCE_DF_WORD 9
|
||||
#define SCE_DF_STRING 10
|
||||
#define SCE_DF_STRINGEOL 11
|
||||
#define SCE_DF_SCOPEWORD 12
|
||||
#define SCE_DF_OPERATOR 13
|
||||
#define SCE_DF_ICODE 14
|
||||
#define SCE_HOLLYWOOD_DEFAULT 0
|
||||
#define SCE_HOLLYWOOD_COMMENT 1
|
||||
#define SCE_HOLLYWOOD_COMMENTBLOCK 2
|
||||
#define SCE_HOLLYWOOD_NUMBER 3
|
||||
#define SCE_HOLLYWOOD_KEYWORD 4
|
||||
#define SCE_HOLLYWOOD_STDAPI 5
|
||||
#define SCE_HOLLYWOOD_PLUGINAPI 6
|
||||
#define SCE_HOLLYWOOD_PLUGINMETHOD 7
|
||||
#define SCE_HOLLYWOOD_STRING 8
|
||||
#define SCE_HOLLYWOOD_STRINGBLOCK 9
|
||||
#define SCE_HOLLYWOOD_PREPROCESSOR 10
|
||||
#define SCE_HOLLYWOOD_OPERATOR 11
|
||||
#define SCE_HOLLYWOOD_IDENTIFIER 12
|
||||
#define SCE_HOLLYWOOD_CONSTANT 13
|
||||
#define SCE_HOLLYWOOD_HEXNUMBER 14
|
||||
#define SCE_RAKU_DEFAULT 0
|
||||
#define SCE_RAKU_ERROR 1
|
||||
#define SCE_RAKU_COMMENTLINE 2
|
||||
#define SCE_RAKU_COMMENTEMBED 3
|
||||
#define SCE_RAKU_POD 4
|
||||
#define SCE_RAKU_CHARACTER 5
|
||||
#define SCE_RAKU_HEREDOC_Q 6
|
||||
#define SCE_RAKU_HEREDOC_QQ 7
|
||||
#define SCE_RAKU_STRING 8
|
||||
#define SCE_RAKU_STRING_Q 9
|
||||
#define SCE_RAKU_STRING_QQ 10
|
||||
#define SCE_RAKU_STRING_Q_LANG 11
|
||||
#define SCE_RAKU_STRING_VAR 12
|
||||
#define SCE_RAKU_REGEX 13
|
||||
#define SCE_RAKU_REGEX_VAR 14
|
||||
#define SCE_RAKU_ADVERB 15
|
||||
#define SCE_RAKU_NUMBER 16
|
||||
#define SCE_RAKU_PREPROCESSOR 17
|
||||
#define SCE_RAKU_OPERATOR 18
|
||||
#define SCE_RAKU_WORD 19
|
||||
#define SCE_RAKU_FUNCTION 20
|
||||
#define SCE_RAKU_IDENTIFIER 21
|
||||
#define SCE_RAKU_TYPEDEF 22
|
||||
#define SCE_RAKU_MU 23
|
||||
#define SCE_RAKU_POSITIONAL 24
|
||||
#define SCE_RAKU_ASSOCIATIVE 25
|
||||
#define SCE_RAKU_CALLABLE 26
|
||||
#define SCE_RAKU_GRAMMAR 27
|
||||
#define SCE_RAKU_CLASS 28
|
||||
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,13 +9,21 @@
|
|||
#ifndef SCI_POSITION_H
|
||||
#define SCI_POSITION_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// Basic signed type used throughout interface
|
||||
typedef int Sci_Position;
|
||||
typedef ptrdiff_t Sci_Position;
|
||||
|
||||
// Unsigned variant used for ILexer::Lex and ILexer::Fold
|
||||
typedef unsigned int Sci_PositionU;
|
||||
typedef size_t Sci_PositionU;
|
||||
|
||||
// For Sci_CharacterRange which is defined as long to be compatible with Win32 CHARRANGE
|
||||
typedef long Sci_PositionCR;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SCI_METHOD __stdcall
|
||||
#else
|
||||
#define SCI_METHOD
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,14 +27,7 @@ int Scintilla_LinkLexers(void);
|
|||
#endif
|
||||
|
||||
// Include header that defines basic numeric types.
|
||||
#if defined(_MSC_VER)
|
||||
// Older releases of MSVC did not have stdint.h.
|
||||
#include <stddef.h>
|
||||
#elif defined( __VMS )
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
// Define uptr_t, an unsigned integer type large enough to hold a pointer.
|
||||
typedef uintptr_t uptr_t;
|
||||
|
|
@ -45,6 +38,8 @@ typedef intptr_t sptr_t;
|
|||
|
||||
typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
|
||||
|
||||
#ifndef SCI_DISABLE_AUTOGENERATED
|
||||
|
||||
/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
|
||||
#define INVALID_POSITION -1
|
||||
#define SCI_START 2000
|
||||
|
|
@ -70,6 +65,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_CANREDO 2016
|
||||
#define SCI_MARKERLINEFROMHANDLE 2017
|
||||
#define SCI_MARKERDELETEHANDLE 2018
|
||||
#define SCI_MARKERHANDLEFROMLINE 2732
|
||||
#define SCI_MARKERNUMBERFROMLINE 2733
|
||||
#define SCI_GETUNDOCOLLECTION 2019
|
||||
#define SCWS_INVISIBLE 0
|
||||
#define SCWS_VISIBLEALWAYS 1
|
||||
|
|
@ -100,6 +97,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETBUFFEREDDRAW 2035
|
||||
#define SCI_SETTABWIDTH 2036
|
||||
#define SCI_GETTABWIDTH 2121
|
||||
#define SCI_SETTABMINIMUMWIDTH 2724
|
||||
#define SCI_GETTABMINIMUMWIDTH 2725
|
||||
#define SCI_CLEARTABSTOPS 2675
|
||||
#define SCI_ADDTABSTOP 2676
|
||||
#define SCI_GETNEXTTABSTOP 2677
|
||||
|
|
@ -109,6 +108,13 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_IME_INLINE 1
|
||||
#define SCI_GETIMEINTERACTION 2678
|
||||
#define SCI_SETIMEINTERACTION 2679
|
||||
#define SC_ALPHA_TRANSPARENT 0
|
||||
#define SC_ALPHA_OPAQUE 255
|
||||
#define SC_ALPHA_NOALPHA 256
|
||||
#define SC_CURSORNORMAL -1
|
||||
#define SC_CURSORARROW 2
|
||||
#define SC_CURSORWAIT 4
|
||||
#define SC_CURSORREVERSEARROW 7
|
||||
#define MARKER_MAX 31
|
||||
#define SC_MARK_CIRCLE 0
|
||||
#define SC_MARK_ROUNDRECT 1
|
||||
|
|
@ -142,6 +148,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_MARK_UNDERLINE 29
|
||||
#define SC_MARK_RGBAIMAGE 30
|
||||
#define SC_MARK_BOOKMARK 31
|
||||
#define SC_MARK_VERTICALBOOKMARK 32
|
||||
#define SC_MARK_CHARACTER 10000
|
||||
#define SC_MARKNUM_FOLDEREND 25
|
||||
#define SC_MARKNUM_FOLDEROPENMID 26
|
||||
|
|
@ -273,6 +280,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETCARETPERIOD 2076
|
||||
#define SCI_SETWORDCHARS 2077
|
||||
#define SCI_GETWORDCHARS 2646
|
||||
#define SCI_SETCHARACTERCATEGORYOPTIMIZATION 2720
|
||||
#define SCI_GETCHARACTERCATEGORYOPTIMIZATION 2721
|
||||
#define SCI_BEGINUNDOACTION 2078
|
||||
#define SCI_ENDUNDOACTION 2079
|
||||
#define INDIC_PLAIN 0
|
||||
|
|
@ -295,14 +304,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define INDIC_TEXTFORE 17
|
||||
#define INDIC_POINT 18
|
||||
#define INDIC_POINTCHARACTER 19
|
||||
#define INDIC_GRADIENT 20
|
||||
#define INDIC_GRADIENTCENTRE 21
|
||||
#define INDIC_CONTAINER 8
|
||||
#define INDIC_IME 32
|
||||
#define INDIC_IME_MAX 35
|
||||
#define INDIC_MAX 35
|
||||
#define INDIC_CONTAINER 8
|
||||
#define INDIC0_MASK 0x20
|
||||
#define INDIC1_MASK 0x40
|
||||
#define INDIC2_MASK 0x80
|
||||
#define INDICS_MASK 0xE0
|
||||
#define INDICATOR_CONTAINER 8
|
||||
#define INDICATOR_IME 32
|
||||
#define INDICATOR_IME_MAX 35
|
||||
#define INDICATOR_MAX 35
|
||||
#define SCI_INDICSETSTYLE 2080
|
||||
#define SCI_INDICGETSTYLE 2081
|
||||
#define SCI_INDICSETFORE 2082
|
||||
|
|
@ -322,8 +333,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETWHITESPACEBACK 2085
|
||||
#define SCI_SETWHITESPACESIZE 2086
|
||||
#define SCI_GETWHITESPACESIZE 2087
|
||||
#define SCI_SETSTYLEBITS 2090
|
||||
#define SCI_GETSTYLEBITS 2091
|
||||
#define SCI_SETLINESTATE 2092
|
||||
#define SCI_GETLINESTATE 2093
|
||||
#define SCI_GETMAXLINESTATE 2094
|
||||
|
|
@ -331,6 +340,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETCARETLINEVISIBLE 2096
|
||||
#define SCI_GETCARETLINEBACK 2097
|
||||
#define SCI_SETCARETLINEBACK 2098
|
||||
#define SCI_GETCARETLINEFRAME 2704
|
||||
#define SCI_SETCARETLINEFRAME 2705
|
||||
#define SCI_STYLESETCHANGEABLE 2099
|
||||
#define SCI_AUTOCSHOW 2100
|
||||
#define SCI_AUTOCCANCEL 2101
|
||||
|
|
@ -370,6 +381,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_GETLINEINDENTPOSITION 2128
|
||||
#define SCI_GETCOLUMN 2129
|
||||
#define SCI_COUNTCHARACTERS 2633
|
||||
#define SCI_COUNTCODEUNITS 2715
|
||||
#define SCI_SETHSCROLLBAR 2130
|
||||
#define SCI_GETHSCROLLBAR 2131
|
||||
#define SC_IV_NONE 0
|
||||
|
|
@ -397,8 +409,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_PRINT_BLACKONWHITE 2
|
||||
#define SC_PRINT_COLOURONWHITE 3
|
||||
#define SC_PRINT_COLOURONWHITEDEFAULTBG 4
|
||||
#define SC_PRINT_SCREENCOLOURS 5
|
||||
#define SCI_SETPRINTCOLOURMODE 2148
|
||||
#define SCI_GETPRINTCOLOURMODE 2149
|
||||
#define SCFIND_NONE 0x0
|
||||
#define SCFIND_WHOLEWORD 0x2
|
||||
#define SCFIND_MATCHCASE 0x4
|
||||
#define SCFIND_WORDSTART 0x00100000
|
||||
|
|
@ -448,8 +462,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_GETCARETWIDTH 2189
|
||||
#define SCI_SETTARGETSTART 2190
|
||||
#define SCI_GETTARGETSTART 2191
|
||||
#define SCI_SETTARGETSTARTVIRTUALSPACE 2728
|
||||
#define SCI_GETTARGETSTARTVIRTUALSPACE 2729
|
||||
#define SCI_SETTARGETEND 2192
|
||||
#define SCI_GETTARGETEND 2193
|
||||
#define SCI_SETTARGETENDVIRTUALSPACE 2730
|
||||
#define SCI_GETTARGETENDVIRTUALSPACE 2731
|
||||
#define SCI_SETTARGETRANGE 2686
|
||||
#define SCI_GETTARGETTEXT 2687
|
||||
#define SCI_TARGETFROMSELECTION 2287
|
||||
|
|
@ -493,6 +511,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_FOLDDISPLAYTEXT_STANDARD 1
|
||||
#define SC_FOLDDISPLAYTEXT_BOXED 2
|
||||
#define SCI_FOLDDISPLAYTEXTSETSTYLE 2701
|
||||
#define SCI_FOLDDISPLAYTEXTGETSTYLE 2707
|
||||
#define SCI_SETDEFAULTFOLDDISPLAYTEXT 2722
|
||||
#define SCI_GETDEFAULTFOLDDISPLAYTEXT 2723
|
||||
#define SC_FOLDACTION_CONTRACT 0
|
||||
#define SC_FOLDACTION_EXPAND 1
|
||||
#define SC_FOLDACTION_TOGGLE 2
|
||||
|
|
@ -552,6 +573,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_WRAPINDENT_FIXED 0
|
||||
#define SC_WRAPINDENT_SAME 1
|
||||
#define SC_WRAPINDENT_INDENT 2
|
||||
#define SC_WRAPINDENT_DEEPINDENT 3
|
||||
#define SCI_SETWRAPINDENTMODE 2472
|
||||
#define SCI_GETWRAPINDENTMODE 2473
|
||||
#define SC_CACHE_NONE 0
|
||||
|
|
@ -595,6 +617,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_LINESSPLIT 2289
|
||||
#define SCI_SETFOLDMARGINCOLOUR 2290
|
||||
#define SCI_SETFOLDMARGINHICOLOUR 2291
|
||||
#define SC_ACCESSIBILITY_DISABLED 0
|
||||
#define SC_ACCESSIBILITY_ENABLED 1
|
||||
#define SCI_SETACCESSIBILITY 2702
|
||||
#define SCI_GETACCESSIBILITY 2703
|
||||
#define SCI_LINEDOWN 2300
|
||||
#define SCI_LINEDOWNEXTEND 2301
|
||||
#define SCI_LINEUP 2302
|
||||
|
|
@ -636,6 +662,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_LINECUT 2337
|
||||
#define SCI_LINEDELETE 2338
|
||||
#define SCI_LINETRANSPOSE 2339
|
||||
#define SCI_LINEREVERSE 2354
|
||||
#define SCI_LINEDUPLICATE 2404
|
||||
#define SCI_LOWERCASE 2340
|
||||
#define SCI_UPPERCASE 2341
|
||||
|
|
@ -660,6 +687,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_BRACEBADLIGHT 2352
|
||||
#define SCI_BRACEBADLIGHTINDICATOR 2499
|
||||
#define SCI_BRACEMATCH 2353
|
||||
#define SCI_BRACEMATCHNEXT 2369
|
||||
#define SCI_GETVIEWEOL 2355
|
||||
#define SCI_SETVIEWEOL 2356
|
||||
#define SCI_GETDOCPOINTER 2357
|
||||
|
|
@ -677,6 +705,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETEDGECOLOUR 2365
|
||||
#define SCI_MULTIEDGEADDLINE 2694
|
||||
#define SCI_MULTIEDGECLEARALL 2695
|
||||
#define SCI_GETMULTIEDGECOLUMN 2749
|
||||
#define SCI_SEARCHANCHOR 2366
|
||||
#define SCI_SEARCHNEXT 2367
|
||||
#define SCI_SEARCHPREV 2368
|
||||
|
|
@ -688,10 +717,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SELECTIONISRECTANGLE 2372
|
||||
#define SCI_SETZOOM 2373
|
||||
#define SCI_GETZOOM 2374
|
||||
#define SC_DOCUMENTOPTION_DEFAULT 0
|
||||
#define SC_DOCUMENTOPTION_STYLES_NONE 0x1
|
||||
#define SC_DOCUMENTOPTION_TEXT_LARGE 0x100
|
||||
#define SCI_CREATEDOCUMENT 2375
|
||||
#define SCI_ADDREFDOCUMENT 2376
|
||||
#define SCI_RELEASEDOCUMENT 2377
|
||||
#define SCI_GETDOCUMENTOPTIONS 2379
|
||||
#define SCI_GETMODEVENTMASK 2378
|
||||
#define SCI_SETCOMMANDEVENTS 2717
|
||||
#define SCI_GETCOMMANDEVENTS 2718
|
||||
#define SCI_SETFOCUS 2380
|
||||
#define SCI_GETFOCUS 2381
|
||||
#define SC_STATUS_OK 0
|
||||
|
|
@ -705,10 +740,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_GETMOUSEDOWNCAPTURES 2385
|
||||
#define SCI_SETMOUSEWHEELCAPTURES 2696
|
||||
#define SCI_GETMOUSEWHEELCAPTURES 2697
|
||||
#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
|
||||
|
|
@ -749,6 +780,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_POSITIONBEFORE 2417
|
||||
#define SCI_POSITIONAFTER 2418
|
||||
#define SCI_POSITIONRELATIVE 2670
|
||||
#define SCI_POSITIONRELATIVECODEUNITS 2716
|
||||
#define SCI_COPYRANGE 2419
|
||||
#define SCI_COPYTEXT 2420
|
||||
#define SC_SEL_STREAM 0
|
||||
|
|
@ -757,6 +789,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_SEL_THIN 3
|
||||
#define SCI_SETSELECTIONMODE 2422
|
||||
#define SCI_GETSELECTIONMODE 2423
|
||||
#define SCI_GETMOVEEXTENDSSELECTION 2706
|
||||
#define SCI_GETLINESELSTARTPOSITION 2424
|
||||
#define SCI_GETLINESELENDPOSITION 2425
|
||||
#define SCI_LINEDOWNRECTEXTEND 2426
|
||||
|
|
@ -801,23 +834,24 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETLENGTHFORENCODE 2448
|
||||
#define SCI_ENCODEDFROMUTF8 2449
|
||||
#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_GETCARETSTICKY 2457
|
||||
#define SCI_SETCARETSTICKY 2458
|
||||
#define SCI_TOGGLECARETSTICKY 2459
|
||||
#define SCI_SETPASTECONVERTENDINGS 2467
|
||||
#define SCI_GETPASTECONVERTENDINGS 2468
|
||||
#define SCI_SELECTIONDUPLICATE 2469
|
||||
#define SC_ALPHA_TRANSPARENT 0
|
||||
#define SC_ALPHA_OPAQUE 255
|
||||
#define SC_ALPHA_NOALPHA 256
|
||||
#define SCI_SETCARETLINEBACKALPHA 2470
|
||||
#define SCI_GETCARETLINEBACKALPHA 2471
|
||||
#define CARETSTYLE_INVISIBLE 0
|
||||
#define CARETSTYLE_LINE 1
|
||||
#define CARETSTYLE_BLOCK 2
|
||||
#define CARETSTYLE_OVERSTRIKE_BAR 0
|
||||
#define CARETSTYLE_OVERSTRIKE_BLOCK 0x10
|
||||
#define CARETSTYLE_INS_MASK 0xF
|
||||
#define CARETSTYLE_BLOCK_AFTER 0x100
|
||||
#define SCI_SETCARETSTYLE 2512
|
||||
#define SCI_GETCARETSTYLE 2513
|
||||
#define SCI_SETINDICATORCURRENT 2500
|
||||
|
|
@ -876,6 +910,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
|
||||
#define SCI_RELEASEALLEXTENDEDSTYLES 2552
|
||||
#define SCI_ALLOCATEEXTENDEDSTYLES 2553
|
||||
#define UNDO_NONE 0
|
||||
#define UNDO_MAY_COALESCE 1
|
||||
#define SCI_ADDUNDOACTION 2560
|
||||
#define SCI_CHARPOSITIONFROMPOINT 2561
|
||||
|
|
@ -908,7 +943,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583
|
||||
#define SCI_SETSELECTIONNSTART 2584
|
||||
#define SCI_GETSELECTIONNSTART 2585
|
||||
#define SCI_GETSELECTIONNSTARTVIRTUALSPACE 2726
|
||||
#define SCI_SETSELECTIONNEND 2586
|
||||
#define SCI_GETSELECTIONNENDVIRTUALSPACE 2727
|
||||
#define SCI_GETSELECTIONNEND 2587
|
||||
#define SCI_SETRECTANGULARSELECTIONCARET 2588
|
||||
#define SCI_GETRECTANGULARSELECTIONCARET 2589
|
||||
|
|
@ -972,6 +1009,18 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETREPRESENTATION 2665
|
||||
#define SCI_GETREPRESENTATION 2666
|
||||
#define SCI_CLEARREPRESENTATION 2667
|
||||
#define SCI_EOLANNOTATIONSETTEXT 2740
|
||||
#define SCI_EOLANNOTATIONGETTEXT 2741
|
||||
#define SCI_EOLANNOTATIONSETSTYLE 2742
|
||||
#define SCI_EOLANNOTATIONGETSTYLE 2743
|
||||
#define SCI_EOLANNOTATIONCLEARALL 2744
|
||||
#define EOLANNOTATION_HIDDEN 0
|
||||
#define EOLANNOTATION_STANDARD 1
|
||||
#define EOLANNOTATION_BOXED 2
|
||||
#define SCI_EOLANNOTATIONSETVISIBLE 2745
|
||||
#define SCI_EOLANNOTATIONGETVISIBLE 2746
|
||||
#define SCI_EOLANNOTATIONSETSTYLEOFFSET 2747
|
||||
#define SCI_EOLANNOTATIONGETSTYLEOFFSET 2748
|
||||
#define SCI_STARTRECORD 3001
|
||||
#define SCI_STOPRECORD 3002
|
||||
#define SCI_SETLEXER 4001
|
||||
|
|
@ -985,7 +1034,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_GETPROPERTY 4008
|
||||
#define SCI_GETPROPERTYEXPANDED 4009
|
||||
#define SCI_GETPROPERTYINT 4010
|
||||
#define SCI_GETSTYLEBITSNEEDED 4011
|
||||
#define SCI_GETLEXERLANGUAGE 4012
|
||||
#define SCI_PRIVATELEXERCALL 4013
|
||||
#define SCI_PROPERTYNAMES 4014
|
||||
|
|
@ -1005,6 +1053,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCI_SETIDENTIFIERS 4024
|
||||
#define SCI_DISTANCETOSECONDARYSTYLES 4025
|
||||
#define SCI_GETSUBSTYLEBASES 4026
|
||||
#define SCI_GETNAMEDSTYLES 4029
|
||||
#define SCI_NAMEOFSTYLE 4030
|
||||
#define SCI_TAGSOFSTYLE 4031
|
||||
#define SCI_DESCRIPTIONOFSTYLE 4032
|
||||
#define SC_MOD_NONE 0x0
|
||||
#define SC_MOD_INSERTTEXT 0x1
|
||||
#define SC_MOD_DELETETEXT 0x2
|
||||
#define SC_MOD_CHANGESTYLE 0x4
|
||||
|
|
@ -1027,7 +1080,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_MOD_LEXERSTATE 0x80000
|
||||
#define SC_MOD_INSERTCHECK 0x100000
|
||||
#define SC_MOD_CHANGETABSTOPS 0x200000
|
||||
#define SC_MODEVENTMASKALL 0x3FFFFF
|
||||
#define SC_MOD_CHANGEEOLANNOTATION 0x400000
|
||||
#define SC_MODEVENTMASKALL 0x7FFFFF
|
||||
#define SC_UPDATE_CONTENT 0x1
|
||||
#define SC_UPDATE_SELECTION 0x2
|
||||
#define SC_UPDATE_V_SCROLL 0x4
|
||||
|
|
@ -1066,6 +1120,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SC_AC_TAB 3
|
||||
#define SC_AC_NEWLINE 4
|
||||
#define SC_AC_COMMAND 5
|
||||
#define SC_CHARACTERSOURCE_DIRECT_INPUT 0
|
||||
#define SC_CHARACTERSOURCE_TENTATIVE_INPUT 1
|
||||
#define SC_CHARACTERSOURCE_IME_RESULT 2
|
||||
#define SCN_STYLENEEDED 2000
|
||||
#define SCN_CHARADDED 2001
|
||||
#define SCN_SAVEPOINTREACHED 2002
|
||||
|
|
@ -1097,8 +1154,21 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||
#define SCN_FOCUSOUT 2029
|
||||
#define SCN_AUTOCCOMPLETED 2030
|
||||
#define SCN_MARGINRIGHTCLICK 2031
|
||||
#define SCN_AUTOCSELECTIONCHANGE 2032
|
||||
#ifndef SCI_DISABLE_PROVISIONAL
|
||||
#define SC_LINECHARACTERINDEX_NONE 0
|
||||
#define SC_LINECHARACTERINDEX_UTF32 1
|
||||
#define SC_LINECHARACTERINDEX_UTF16 2
|
||||
#define SCI_GETLINECHARACTERINDEX 2710
|
||||
#define SCI_ALLOCATELINECHARACTERINDEX 2711
|
||||
#define SCI_RELEASELINECHARACTERINDEX 2712
|
||||
#define SCI_LINEFROMINDEXPOSITION 2713
|
||||
#define SCI_INDEXPOSITIONFROMLINE 2714
|
||||
#endif
|
||||
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
|
||||
|
||||
#endif
|
||||
|
||||
/* These structures are defined to be exactly the same shape as the Win32
|
||||
* CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs.
|
||||
* So older code that treats Scintilla as a RichEdit will work. */
|
||||
|
|
@ -1192,6 +1262,7 @@ struct SCNotification {
|
|||
int updated; /* SCN_UPDATEUI */
|
||||
int listCompletionMethod;
|
||||
/* SCN_AUTOCSELECTION, SCN_AUTOCCOMPLETED, SCN_USERLISTSELECTION, */
|
||||
int characterSource; /* SCN_CHARADDED */
|
||||
};
|
||||
|
||||
#ifdef INCLUDE_DEPRECATED_FEATURES
|
||||
|
|
@ -1205,6 +1276,17 @@ struct SCNotification {
|
|||
#define RangeToFormat Sci_RangeToFormat
|
||||
#define NotifyHeader Sci_NotifyHeader
|
||||
|
||||
#endif
|
||||
#define SCI_SETSTYLEBITS 2090
|
||||
#define SCI_GETSTYLEBITS 2091
|
||||
#define SCI_GETSTYLEBITSNEEDED 4011
|
||||
|
||||
#define INDIC0_MASK 0x20
|
||||
#define INDIC1_MASK 0x40
|
||||
#define INDIC2_MASK 0x80
|
||||
#define INDICS_MASK 0xE0
|
||||
|
||||
#endif
|
||||
|
||||
#include "Compat.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -26,9 +26,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
// Return values for GetOperatorType
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#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 == '_'));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Scintilla source code edit control
|
||||
// @file LexASY.cxx
|
||||
//Author: instanton (email: soft_share<at>126<dot>com)
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
|
|
@ -19,9 +20,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColouriseAsyDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
WordList *keywordlists[], Accessor &styler) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Scintilla source code edit control
|
||||
// @file LexAU3.cxx
|
||||
// Lexer for AutoIt3 http://www.hiddensoft.com/autoit3
|
||||
// Lexer for AutoIt3 https://www.autoitscript.com/site/
|
||||
// by Jos van der Zande, jvdzande@yahoo.com
|
||||
//
|
||||
// Changes:
|
||||
|
|
@ -68,9 +68,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsTypeCharacter(const int ch)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#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 == '_');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexABAQUS.cxx
|
||||
/** @file LexAbaqus.cxx
|
||||
** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
|
||||
** By Sergio Lucato.
|
||||
** Sort of completely rewritten by Gertjan Kloosterman
|
||||
|
|
@ -26,9 +26,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAKeywordChar(const int ch) {
|
||||
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interface
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
|
||||
|
|
@ -81,6 +80,7 @@ struct OptionsAsm {
|
|||
std::string foldExplicitEnd;
|
||||
bool foldExplicitAnywhere;
|
||||
bool foldCompact;
|
||||
std::string commentChar;
|
||||
OptionsAsm() {
|
||||
delimiter = "";
|
||||
fold = false;
|
||||
|
|
@ -91,6 +91,7 @@ struct OptionsAsm {
|
|||
foldExplicitEnd = "";
|
||||
foldExplicitAnywhere = false;
|
||||
foldCompact = true;
|
||||
commentChar = "";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -135,11 +136,14 @@ struct OptionSetAsm : public OptionSet<OptionsAsm> {
|
|||
|
||||
DefineProperty("fold.compact", &OptionsAsm::foldCompact);
|
||||
|
||||
DefineProperty("lexer.as.comment.character", &OptionsAsm::commentChar,
|
||||
"Overrides the default comment character (which is ';' for asm and '#' for as).");
|
||||
|
||||
DefineWordListSets(asmWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
class LexerAsm : public ILexer {
|
||||
class LexerAsm : public DefaultLexer {
|
||||
WordList cpuInstruction;
|
||||
WordList mathInstruction;
|
||||
WordList registers;
|
||||
|
|
@ -152,44 +156,47 @@ class LexerAsm : public ILexer {
|
|||
OptionSetAsm osAsm;
|
||||
int commentChar;
|
||||
public:
|
||||
LexerAsm(int commentChar_) {
|
||||
LexerAsm(const char *languageName_, int language_, int commentChar_) : DefaultLexer(languageName_, language_) {
|
||||
commentChar = commentChar_;
|
||||
}
|
||||
virtual ~LexerAsm() {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osAsm.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osAsm.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osAsm.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osAsm.PropertyGet(key);
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osAsm.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryAsm() {
|
||||
return new LexerAsm(';');
|
||||
return new LexerAsm("asm", SCLEX_ASM, ';');
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryAs() {
|
||||
return new LexerAsm('#');
|
||||
return new LexerAsm("as", SCLEX_AS, '#');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -243,6 +250,9 @@ Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
|
|||
void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
const char commentCharacter = options.commentChar.empty() ?
|
||||
commentChar : options.commentChar.front();
|
||||
|
||||
// Do not leak onto next line
|
||||
if (initStyle == SCE_ASM_STRINGEOL)
|
||||
initStyle = SCE_ASM_DEFAULT;
|
||||
|
|
@ -348,7 +358,7 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_ASM_DEFAULT) {
|
||||
if (sc.ch == commentChar){
|
||||
if (sc.ch == commentCharacter) {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Some char test functions
|
||||
static bool isAsn1Number(int ch)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
** Based heavily on LexCPP.cxx
|
||||
**/
|
||||
// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>
|
||||
// Maintainer Email: oirfeodent@yahoo.co.in
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
// C standard library
|
||||
|
|
@ -33,10 +34,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
# ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
# endif
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
|
@ -129,7 +129,7 @@ static inline bool IsAnOperator(int ch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline int IsAnyOtherIdentifier(char *s, int sLength) {
|
||||
static inline int IsAnyOtherIdentifier(char *s, Sci_Position sLength) {
|
||||
|
||||
/* IsAnyOtherIdentifier uses standard templates used in baan.
|
||||
The matching template is shown as comments just above the return condition.
|
||||
|
|
@ -380,7 +380,7 @@ public:
|
|||
|
||||
}
|
||||
|
||||
class LexerBaan : public ILexer {
|
||||
class LexerBaan : public DefaultLexer {
|
||||
WordListAbridged keywords;
|
||||
WordListAbridged keywords2;
|
||||
WordListAbridged keywords3;
|
||||
|
|
@ -393,45 +393,49 @@ class LexerBaan : public ILexer {
|
|||
OptionsBaan options;
|
||||
OptionSetBaan osBaan;
|
||||
public:
|
||||
LexerBaan() {
|
||||
LexerBaan() : DefaultLexer("baan", SCLEX_BAAN) {
|
||||
}
|
||||
|
||||
virtual ~LexerBaan() {
|
||||
}
|
||||
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osBaan.PropertyNames();
|
||||
}
|
||||
|
||||
int SCI_METHOD PropertyType(const char * name) {
|
||||
int SCI_METHOD PropertyType(const char * name) override {
|
||||
return osBaan.PropertyType(name);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeProperty(const char * name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char * name) override {
|
||||
return osBaan.DescribeProperty(name);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osBaan.PropertyGet(key);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osBaan.DescribeWordListSets();
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -504,10 +508,12 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
bool lineHasPreProc = false;
|
||||
bool lineIgnoreString = false;
|
||||
bool lineHasDefines = false;
|
||||
bool numberIsHex = false;
|
||||
char word[1000];
|
||||
int wordlen = 0;
|
||||
|
||||
std::string preProcessorTags[11] = { "#define", "#elif", "#else", "#endif",
|
||||
std::string preProcessorTags[13] = { "#context_off", "#context_on",
|
||||
"#define", "#elif", "#else", "#endif",
|
||||
"#ident", "#if", "#ifdef", "#ifndef",
|
||||
"#include", "#pragma", "#undef" };
|
||||
LexAccessor styler(pAccess);
|
||||
|
|
@ -521,9 +527,18 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
sc.SetState(SCE_BAAN_DEFAULT);
|
||||
break;
|
||||
case SCE_BAAN_NUMBER:
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
if (IsASpaceOrTab(sc.ch) || sc.ch == '\r' || sc.ch == '\n' || IsAnOperator(sc.ch)) {
|
||||
sc.SetState(SCE_BAAN_DEFAULT);
|
||||
}
|
||||
else if ((numberIsHex && !(MakeLowerCase(sc.ch) == 'x' || MakeLowerCase(sc.ch) == 'e' ||
|
||||
IsADigit(sc.ch, 16) || sc.ch == '.' || sc.ch == '-' || sc.ch == '+')) ||
|
||||
(!numberIsHex && !(MakeLowerCase(sc.ch) == 'e' || IsADigit(sc.ch)
|
||||
|| sc.ch == '.' || sc.ch == '-' || sc.ch == '+'))) {
|
||||
// check '-' for possible -10e-5. Add '+' as well.
|
||||
numberIsHex = false;
|
||||
sc.ChangeState(SCE_BAAN_IDENTIFIER);
|
||||
sc.SetState(SCE_BAAN_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_BAAN_IDENTIFIER:
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
|
|
@ -556,7 +571,10 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
sc.ChangeState(SCE_BAAN_WORD2);
|
||||
}
|
||||
else if ((keywords3.kwHasSection && (sc.ch == ':')) ? keywords3.Contains(s1) : keywords3.Contains(s)) {
|
||||
sc.ChangeState(SCE_BAAN_WORD3);
|
||||
if (sc.ch == '(')
|
||||
sc.ChangeState(SCE_BAAN_WORD3);
|
||||
else
|
||||
sc.ChangeState(SCE_BAAN_IDENTIFIER);
|
||||
}
|
||||
else if ((keywords4.kwHasSection && (sc.ch == ':')) ? keywords4.Contains(s1) : keywords4.Contains(s)) {
|
||||
sc.ChangeState(SCE_BAAN_WORD4);
|
||||
|
|
@ -606,7 +624,7 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
break;
|
||||
case SCE_BAAN_COMMENT:
|
||||
if (sc.atLineEnd) {
|
||||
if (sc.ch == '\r' || sc.ch == '\n') {
|
||||
sc.SetState(SCE_BAAN_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
|
@ -638,7 +656,13 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_BAAN_DEFAULT) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))
|
||||
|| ((sc.ch == '-' || sc.ch == '+') && (IsADigit(sc.chNext) || sc.chNext == '.'))
|
||||
|| (MakeLowerCase(sc.ch) == 'e' && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-'))) {
|
||||
if ((sc.ch == '0' && MakeLowerCase(sc.chNext) == 'x') ||
|
||||
((sc.ch == '-' || sc.ch == '+') && sc.chNext == '0' && MakeLowerCase(sc.GetRelativeCharacter(2)) == 'x')){
|
||||
numberIsHex = true;
|
||||
}
|
||||
sc.SetState(SCE_BAAN_NUMBER);
|
||||
}
|
||||
else if (sc.MatchIgnoreCase("dllusage") || sc.MatchIgnoreCase("functionusage")) {
|
||||
|
|
@ -670,7 +694,7 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
word[wordlen++] = sc.ch;
|
||||
word[wordlen++] = '\0';
|
||||
}
|
||||
if (!wordInArray(word, preProcessorTags, 11))
|
||||
if (!wordInArray(word, preProcessorTags, 13))
|
||||
// Colorise only preprocessor built in Baan.
|
||||
sc.ChangeState(SCE_BAAN_IDENTIFIER);
|
||||
if (strcmp(word, "#pragma") == 0 || strcmp(word, "#include") == 0) {
|
||||
|
|
@ -697,6 +721,7 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
lineHasPreProc = false;
|
||||
lineIgnoreString = false;
|
||||
lineHasDefines = false;
|
||||
numberIsHex = false;
|
||||
}
|
||||
if (!IsASpace(sc.ch)) {
|
||||
visibleChars++;
|
||||
|
|
@ -781,9 +806,10 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int
|
|||
else if (style == SCE_BAAN_PREPROCESSOR) {
|
||||
// folds #ifdef/#if/#ifndef - they are not part of the IsPreProcLine folding.
|
||||
if (ch == '#') {
|
||||
if (styler.Match(i, "#ifdef") || styler.Match(i, "#if") || styler.Match(i, "#ifndef"))
|
||||
if (styler.Match(i, "#ifdef") || styler.Match(i, "#if") || styler.Match(i, "#ifndef")
|
||||
|| styler.Match(i, "#context_on"))
|
||||
levelCurrent++;
|
||||
else if (styler.Match(i, "#endif"))
|
||||
else if (styler.Match(i, "#endif") || styler.Match(i, "#context_off"))
|
||||
levelCurrent--;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,20 +12,25 @@
|
|||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "SubStyles.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
#define HERE_DELIM_MAX 256
|
||||
|
||||
|
|
@ -60,7 +65,9 @@ using namespace Scintilla;
|
|||
|
||||
#define BASH_DELIM_STACK_MAX 7
|
||||
|
||||
static inline int translateBashDigit(int ch) {
|
||||
namespace {
|
||||
|
||||
inline int translateBashDigit(int ch) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
return ch - '0';
|
||||
} else if (ch >= 'a' && ch <= 'z') {
|
||||
|
|
@ -75,7 +82,7 @@ static inline int translateBashDigit(int ch) {
|
|||
return BASH_BASE_ERROR;
|
||||
}
|
||||
|
||||
static inline int getBashNumberBase(char *s) {
|
||||
inline int getBashNumberBase(char *s) {
|
||||
int i = 0;
|
||||
int base = 0;
|
||||
while (*s) {
|
||||
|
|
@ -88,7 +95,7 @@ static inline int getBashNumberBase(char *s) {
|
|||
return base;
|
||||
}
|
||||
|
||||
static int opposite(int ch) {
|
||||
int opposite(int ch) {
|
||||
if (ch == '(') return ')';
|
||||
if (ch == '[') return ']';
|
||||
if (ch == '{') return '}';
|
||||
|
|
@ -96,23 +103,200 @@ static int opposite(int ch) {
|
|||
return ch;
|
||||
}
|
||||
|
||||
static int GlobScan(StyleContext &sc) {
|
||||
// forward scan for a glob-like (...), no whitespace allowed
|
||||
int GlobScan(StyleContext &sc) {
|
||||
// forward scan for zsh globs, disambiguate versus bash arrays
|
||||
// complex expressions may still fail, e.g. unbalanced () '' "" etc
|
||||
int c, sLen = 0;
|
||||
int pCount = 0;
|
||||
int hash = 0;
|
||||
while ((c = sc.GetRelativeCharacter(++sLen)) != 0) {
|
||||
if (IsASpace(c)) {
|
||||
return 0;
|
||||
} else if (c == '\'' || c == '\"') {
|
||||
if (hash != 2) return 0;
|
||||
} else if (c == '#' && hash == 0) {
|
||||
hash = (sLen == 1) ? 2:1;
|
||||
} else if (c == '(') {
|
||||
pCount++;
|
||||
} else if (c == ')') {
|
||||
return sLen;
|
||||
if (pCount == 0) {
|
||||
if (hash) return sLen;
|
||||
return 0;
|
||||
}
|
||||
pCount--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
WordList *keywordlists[], Accessor &styler) {
|
||||
bool IsCommentLine(Sci_Position line, LexAccessor &styler) {
|
||||
Sci_Position pos = styler.LineStart(line);
|
||||
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position i = pos; i < eol_pos; i++) {
|
||||
char ch = styler[i];
|
||||
if (ch == '#')
|
||||
return true;
|
||||
else if (ch != ' ' && ch != '\t')
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
WordList &keywords = *keywordlists[0];
|
||||
struct OptionsBash {
|
||||
bool fold;
|
||||
bool foldComment;
|
||||
bool foldCompact;
|
||||
|
||||
OptionsBash() {
|
||||
fold = false;
|
||||
foldComment = false;
|
||||
foldCompact = true;
|
||||
}
|
||||
};
|
||||
|
||||
const char * const bashWordListDesc[] = {
|
||||
"Keywords",
|
||||
0
|
||||
};
|
||||
|
||||
struct OptionSetBash : public OptionSet<OptionsBash> {
|
||||
OptionSetBash() {
|
||||
DefineProperty("fold", &OptionsBash::fold);
|
||||
|
||||
DefineProperty("fold.comment", &OptionsBash::foldComment);
|
||||
|
||||
DefineProperty("fold.compact", &OptionsBash::foldCompact);
|
||||
|
||||
DefineWordListSets(bashWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
const char styleSubable[] = { SCE_SH_IDENTIFIER, SCE_SH_SCALAR, 0 };
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer Bash SCLEX_BASH SCE_SH_:
|
||||
0, "SCE_SH_DEFAULT", "default", "White space",
|
||||
1, "SCE_SH_ERROR", "error", "Error",
|
||||
2, "SCE_SH_COMMENTLINE", "comment line", "Line comment: #",
|
||||
3, "SCE_SH_NUMBER", "literal numeric", "Number",
|
||||
4, "SCE_SH_WORD", "keyword", "Keyword",
|
||||
5, "SCE_SH_STRING", "literal string", "String",
|
||||
6, "SCE_SH_CHARACTER", "literal string", "Single quoted string",
|
||||
7, "SCE_SH_OPERATOR", "operator", "Operators",
|
||||
8, "SCE_SH_IDENTIFIER", "identifier", "Identifiers",
|
||||
9, "SCE_SH_SCALAR", "identifier", "Scalar variable",
|
||||
10, "SCE_SH_PARAM", "identifier", "Parameter",
|
||||
11, "SCE_SH_BACKTICKS", "literal string", "Backtick quoted command",
|
||||
12, "SCE_SH_HERE_DELIM", "operator", "Heredoc delimiter",
|
||||
13, "SCE_SH_HERE_Q", "literal string", "Heredoc quoted string",
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class LexerBash : public DefaultLexer {
|
||||
WordList keywords;
|
||||
OptionsBash options;
|
||||
OptionSetBash osBash;
|
||||
enum { ssIdentifier, ssScalar };
|
||||
SubStyles subStyles;
|
||||
public:
|
||||
LexerBash() :
|
||||
DefaultLexer("bash", SCLEX_BASH, lexicalClasses, ELEMENTS(lexicalClasses)),
|
||||
subStyles(styleSubable, 0x80, 0x40, 0) {
|
||||
}
|
||||
virtual ~LexerBash() {
|
||||
}
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osBash.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char* name) override {
|
||||
return osBash.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osBash.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char* key) override {
|
||||
return osBash.PropertyGet(key);
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osBash.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {
|
||||
return subStyles.Allocate(styleBase, numberStyles);
|
||||
}
|
||||
int SCI_METHOD SubStylesStart(int styleBase) override {
|
||||
return subStyles.Start(styleBase);
|
||||
}
|
||||
int SCI_METHOD SubStylesLength(int styleBase) override {
|
||||
return subStyles.Length(styleBase);
|
||||
}
|
||||
int SCI_METHOD StyleFromSubStyle(int subStyle) override {
|
||||
const int styleBase = subStyles.BaseStyle(subStyle);
|
||||
return styleBase;
|
||||
}
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) override {
|
||||
return style;
|
||||
}
|
||||
void SCI_METHOD FreeSubStyles() override {
|
||||
subStyles.Free();
|
||||
}
|
||||
void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {
|
||||
subStyles.SetIdentifiers(style, identifiers);
|
||||
}
|
||||
int SCI_METHOD DistanceToSecondaryStyles() override {
|
||||
return 0;
|
||||
}
|
||||
const char *SCI_METHOD GetSubStyleBases() override {
|
||||
return styleSubable;
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryBash() {
|
||||
return new LexerBash();
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerBash::PropertySet(const char *key, const char *val) {
|
||||
if (osBash.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerBash::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = 0;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywords;
|
||||
break;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN) {
|
||||
WordList wlNew;
|
||||
wlNew.Set(wl);
|
||||
if (*wordListN != wlNew) {
|
||||
wordListN->Set(wl);
|
||||
firstModification = 0;
|
||||
}
|
||||
}
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
WordList cmdDelimiter, bashStruct, bashStruct_in;
|
||||
cmdDelimiter.Set("| || |& & && ; ;; ( ) { }");
|
||||
bashStruct.Set("if elif fi while until else then do done esac eval");
|
||||
|
|
@ -226,11 +410,15 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
};
|
||||
QuoteStackCls QuoteStack;
|
||||
|
||||
const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_SH_IDENTIFIER);
|
||||
const WordClassifier &classifierScalars = subStyles.Classifier(SCE_SH_SCALAR);
|
||||
|
||||
int numBase = 0;
|
||||
int digit;
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
int cmdState = BASH_CMD_START;
|
||||
int testExprType = 0;
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
// 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)
|
||||
|
|
@ -295,6 +483,11 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
char s[500];
|
||||
char s2[10];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
int identifierStyle = SCE_SH_IDENTIFIER;
|
||||
int subStyle = classifierIdentifiers.ValueFor(s);
|
||||
if (subStyle >= 0) {
|
||||
identifierStyle = subStyle;
|
||||
}
|
||||
// allow keywords ending in a whitespace or command delimiter
|
||||
s2[0] = static_cast<char>(sc.ch);
|
||||
s2[1] = '\0';
|
||||
|
|
@ -306,7 +499,7 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
else if (strcmp(s, "do") == 0 && keywordEnds)
|
||||
cmdStateNew = BASH_CMD_START;
|
||||
else
|
||||
sc.ChangeState(SCE_SH_IDENTIFIER);
|
||||
sc.ChangeState(identifierStyle);
|
||||
sc.SetState(SCE_SH_DEFAULT);
|
||||
break;
|
||||
}
|
||||
|
|
@ -316,42 +509,49 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
cmdStateNew = BASH_CMD_TEST;
|
||||
testExprType = 0;
|
||||
} else
|
||||
sc.ChangeState(SCE_SH_IDENTIFIER);
|
||||
sc.ChangeState(identifierStyle);
|
||||
}
|
||||
// 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);
|
||||
sc.ChangeState(identifierStyle);
|
||||
}
|
||||
// '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);
|
||||
sc.ChangeState(identifierStyle);
|
||||
}
|
||||
// disambiguate option items and file test operators
|
||||
else if (s[0] == '-') {
|
||||
if (cmdState != BASH_CMD_TEST)
|
||||
sc.ChangeState(SCE_SH_IDENTIFIER);
|
||||
sc.ChangeState(identifierStyle);
|
||||
}
|
||||
// disambiguate keywords and identifiers
|
||||
else if (cmdState != BASH_CMD_START
|
||||
|| !(keywords.InList(s) && keywordEnds)) {
|
||||
sc.ChangeState(SCE_SH_IDENTIFIER);
|
||||
sc.ChangeState(identifierStyle);
|
||||
}
|
||||
sc.SetState(SCE_SH_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_SH_IDENTIFIER:
|
||||
if (sc.chPrev == '\\') { // for escaped chars
|
||||
sc.ForwardSetState(SCE_SH_DEFAULT);
|
||||
} else if (!setWord.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_SH_DEFAULT);
|
||||
} else if (cmdState == BASH_CMD_ARITH && !setWordStart.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_SH_DEFAULT);
|
||||
if (sc.chPrev == '\\' || !setWord.Contains(sc.ch) ||
|
||||
(cmdState == BASH_CMD_ARITH && !setWordStart.Contains(sc.ch))) {
|
||||
char s[500];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
int subStyle = classifierIdentifiers.ValueFor(s);
|
||||
if (subStyle >= 0) {
|
||||
sc.ChangeState(subStyle);
|
||||
}
|
||||
if (sc.chPrev == '\\') { // for escaped chars
|
||||
sc.ForwardSetState(SCE_SH_DEFAULT);
|
||||
} else {
|
||||
sc.SetState(SCE_SH_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_SH_NUMBER:
|
||||
|
|
@ -505,6 +705,12 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
break;
|
||||
case SCE_SH_SCALAR: // variable names
|
||||
if (!setParam.Contains(sc.ch)) {
|
||||
char s[500];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
int subStyle = classifierScalars.ValueFor(&s[1]); // skip the $
|
||||
if (subStyle >= 0) {
|
||||
sc.ChangeState(subStyle);
|
||||
}
|
||||
if (sc.LengthCurrent() == 1) {
|
||||
// Special variable: $(, $_ etc.
|
||||
sc.ForwardSetState(SCE_SH_DEFAULT);
|
||||
|
|
@ -788,23 +994,12 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
sc.Complete();
|
||||
}
|
||||
|
||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
|
||||
Sci_Position pos = styler.LineStart(line);
|
||||
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position i = pos; i < eol_pos; i++) {
|
||||
char ch = styler[i];
|
||||
if (ch == '#')
|
||||
return true;
|
||||
else if (ch != ' ' && ch != '\t')
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {
|
||||
if(!options.fold)
|
||||
return;
|
||||
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
|
||||
Accessor &styler) {
|
||||
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
int skipHereCh = 0;
|
||||
|
|
@ -813,6 +1008,8 @@ static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordLi
|
|||
int levelCurrent = levelPrev;
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
char word[8] = { '\0' }; // we're not interested in long words anyway
|
||||
unsigned int wordlen = 0;
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
|
|
@ -820,7 +1017,7 @@ static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordLi
|
|||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
// Comment folding
|
||||
if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
|
||||
if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler))
|
||||
{
|
||||
if (!IsCommentLine(lineCurrent - 1, styler)
|
||||
&& IsCommentLine(lineCurrent + 1, styler))
|
||||
|
|
@ -829,6 +1026,19 @@ static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordLi
|
|||
&& !IsCommentLine(lineCurrent + 1, styler))
|
||||
levelCurrent--;
|
||||
}
|
||||
if (style == SCE_SH_WORD) {
|
||||
if ((wordlen + 1) < sizeof(word))
|
||||
word[wordlen++] = ch;
|
||||
if (styleNext != style) {
|
||||
word[wordlen] = '\0';
|
||||
wordlen = 0;
|
||||
if (strcmp(word, "if") == 0 || strcmp(word, "case") == 0 || strcmp(word, "do") == 0) {
|
||||
levelCurrent++;
|
||||
} else if (strcmp(word, "fi") == 0 || strcmp(word, "esac") == 0 || strcmp(word, "done") == 0) {
|
||||
levelCurrent--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (style == SCE_SH_OPERATOR) {
|
||||
if (ch == '{') {
|
||||
levelCurrent++;
|
||||
|
|
@ -854,7 +1064,7 @@ static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordLi
|
|||
}
|
||||
if (atEOL) {
|
||||
int lev = levelPrev;
|
||||
if (visibleChars == 0 && foldCompact)
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if ((levelCurrent > levelPrev) && (visibleChars > 0))
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
|
|
@ -873,9 +1083,4 @@ static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordLi
|
|||
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
|
||||
}
|
||||
|
||||
static const char * const bashWordListDesc[] = {
|
||||
"Keywords",
|
||||
0
|
||||
};
|
||||
|
||||
LexerModule lmBash(SCLEX_BASH, ColouriseBashDoc, "bash", FoldBashDoc, bashWordListDesc);
|
||||
LexerModule lmBash(SCLEX_BASH, LexerBash::LexerFactoryBash, "bash", bashWordListDesc);
|
||||
|
|
|
|||
|
|
@ -37,10 +37,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/* Bits:
|
||||
* 1 - whitespace
|
||||
|
|
@ -226,54 +225,59 @@ struct OptionSetBasic : public OptionSet<OptionsBasic> {
|
|||
}
|
||||
};
|
||||
|
||||
class LexerBasic : public ILexer {
|
||||
class LexerBasic : public DefaultLexer {
|
||||
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[]) :
|
||||
LexerBasic(const char *languageName_, int language_, char comment_char_,
|
||||
int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
|
||||
DefaultLexer(languageName_, language_),
|
||||
comment_char(comment_char_),
|
||||
CheckFoldPoint(CheckFoldPoint_),
|
||||
osBasic(wordListDescriptions) {
|
||||
}
|
||||
virtual ~LexerBasic() {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osBasic.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osBasic.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osBasic.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osBasic.PropertyGet(key);
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osBasic.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
static ILexer *LexerFactoryBlitzBasic() {
|
||||
return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
|
||||
return new LexerBasic("blitzbasic", SCLEX_BLITZBASIC, ';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
|
||||
}
|
||||
static ILexer *LexerFactoryPureBasic() {
|
||||
return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
|
||||
return new LexerBasic("purebasic", SCLEX_PUREBASIC, ';', CheckPureFoldPoint, purebasicWordListDesc);
|
||||
}
|
||||
static ILexer *LexerFactoryFreeBasic() {
|
||||
return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
|
||||
return new LexerBasic("freebasic", SCLEX_FREEBASIC, '\'', CheckFreeFoldPoint, freebasicWordListDesc );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static bool Is0To9(char ch) {
|
||||
return (ch >= '0') && (ch <= '9');
|
||||
|
|
@ -43,7 +41,8 @@ static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
|||
// Tests for BATCH Operators
|
||||
static bool IsBOperator(char ch) {
|
||||
return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
|
||||
(ch == '|') || (ch == '?') || (ch == '*');
|
||||
(ch == '|') || (ch == '?') || (ch == '*')||
|
||||
(ch == '&') || (ch == '(') || (ch == ')');
|
||||
}
|
||||
|
||||
// Tests for BATCH Separators
|
||||
|
|
@ -52,413 +51,35 @@ static bool IsBSeparator(char ch) {
|
|||
(ch == '\"') || (ch == '\'') || (ch == '/');
|
||||
}
|
||||
|
||||
static void ColouriseBatchLine(
|
||||
char *lineBuffer,
|
||||
Sci_PositionU lengthLine,
|
||||
Sci_PositionU startLine,
|
||||
Sci_PositionU endPos,
|
||||
WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
|
||||
Sci_PositionU offset = 0; // Line Buffer Offset
|
||||
Sci_PositionU cmdLoc; // External Command / Program Location
|
||||
char wordBuffer[81]; // Word Buffer - large to catch long paths
|
||||
Sci_PositionU wbl; // Word Buffer Length
|
||||
Sci_PositionU wbo; // Word Buffer Offset - also Special Keyword Buffer Length
|
||||
WordList &keywords = *keywordlists[0]; // Internal Commands
|
||||
WordList &keywords2 = *keywordlists[1]; // External Commands (optional)
|
||||
|
||||
// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
|
||||
// Toggling Regular Keyword Checking off improves readability
|
||||
// Other Regular Keywords and External Commands / Programs might also benefit from toggling
|
||||
// Need a more robust algorithm to properly toggle Regular Keyword Checking
|
||||
bool continueProcessing = true; // Used to toggle Regular Keyword Checking
|
||||
// Special Keywords are those that allow certain characters without whitespace after the command
|
||||
// Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
|
||||
// Special Keyword Buffer used to determine if the first n characters is a Keyword
|
||||
char sKeywordBuffer[10]; // Special Keyword Buffer
|
||||
bool sKeywordFound; // Exit Special Keyword for-loop if found
|
||||
|
||||
// Skip initial spaces
|
||||
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
|
||||
offset++;
|
||||
// Tests for escape character
|
||||
static bool IsEscaped(char* wordStr, Sci_PositionU pos) {
|
||||
bool isQoted=false;
|
||||
while (pos>0){
|
||||
pos--;
|
||||
if (wordStr[pos]=='^')
|
||||
isQoted=!isQoted;
|
||||
else
|
||||
break;
|
||||
}
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
// Set External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
return isQoted;
|
||||
}
|
||||
|
||||
// Check for Fake Label (Comment) or Real Label - return if found
|
||||
if (lineBuffer[offset] == ':') {
|
||||
if (lineBuffer[offset + 1] == ':') {
|
||||
// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
|
||||
styler.ColourTo(endPos, SCE_BAT_COMMENT);
|
||||
} else {
|
||||
// Colorize Real Label
|
||||
styler.ColourTo(endPos, SCE_BAT_LABEL);
|
||||
// Tests for quote character
|
||||
static bool textQuoted(char *lineBuffer, Sci_PositionU endPos) {
|
||||
char strBuffer[1024];
|
||||
strncpy(strBuffer, lineBuffer, endPos);
|
||||
strBuffer[endPos] = '\0';
|
||||
char *pQuote;
|
||||
pQuote = strchr(strBuffer, '"');
|
||||
bool CurrentStatus = false;
|
||||
while (pQuote != NULL)
|
||||
{
|
||||
if (!IsEscaped(strBuffer, pQuote - strBuffer)) {
|
||||
CurrentStatus = !CurrentStatus;
|
||||
}
|
||||
return;
|
||||
// Check for Drive Change (Drive Change is internal command) - return if found
|
||||
} else if ((IsAlphabetic(lineBuffer[offset])) &&
|
||||
(lineBuffer[offset + 1] == ':') &&
|
||||
((isspacechar(lineBuffer[offset + 2])) ||
|
||||
(((lineBuffer[offset + 2] == '\\')) &&
|
||||
(isspacechar(lineBuffer[offset + 3]))))) {
|
||||
// Colorize Regular Keyword
|
||||
styler.ColourTo(endPos, SCE_BAT_WORD);
|
||||
return;
|
||||
pQuote = strchr(pQuote + 1, '"');
|
||||
}
|
||||
|
||||
// Check for Hide Command (@ECHO OFF/ON)
|
||||
if (lineBuffer[offset] == '@') {
|
||||
styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
|
||||
offset++;
|
||||
}
|
||||
// Skip next spaces
|
||||
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Read remainder of line word-at-a-time or remainder-of-word-at-a-time
|
||||
while (offset < lengthLine) {
|
||||
if (offset > startLine) {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Copy word from Line Buffer into Word Buffer
|
||||
wbl = 0;
|
||||
for (; offset < lengthLine && wbl < 80 &&
|
||||
!isspacechar(lineBuffer[offset]); wbl++, offset++) {
|
||||
wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
|
||||
}
|
||||
wordBuffer[wbl] = '\0';
|
||||
wbo = 0;
|
||||
|
||||
// Check for Comment - return if found
|
||||
if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
|
||||
styler.ColourTo(endPos, SCE_BAT_COMMENT);
|
||||
return;
|
||||
}
|
||||
// Check for Separator
|
||||
if (IsBSeparator(wordBuffer[0])) {
|
||||
// Check for External Command / Program
|
||||
if ((cmdLoc == offset - wbl) &&
|
||||
((wordBuffer[0] == ':') ||
|
||||
(wordBuffer[0] == '\\') ||
|
||||
(wordBuffer[0] == '.'))) {
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
// Colorize External Command / Program
|
||||
if (!keywords2) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else if (keywords2.InList(wordBuffer)) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
} else {
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Check for Regular Keyword in list
|
||||
} else if ((keywords.InList(wordBuffer)) &&
|
||||
(continueProcessing)) {
|
||||
// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
|
||||
if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "set") == 0)) {
|
||||
continueProcessing = false;
|
||||
}
|
||||
// Identify External Command / Program Location for ERRORLEVEL, and EXIST
|
||||
if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Skip comparison
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(!isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
|
||||
} else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "do") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
}
|
||||
// Colorize Regular keyword
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
|
||||
// No need to Reset Offset
|
||||
// Check for Special Keyword in list, External Command / Program, or Default Text
|
||||
} else if ((wordBuffer[0] != '%') &&
|
||||
(wordBuffer[0] != '!') &&
|
||||
(!IsBOperator(wordBuffer[0])) &&
|
||||
(continueProcessing)) {
|
||||
// Check for Special Keyword
|
||||
// Affected Commands are in Length range 2-6
|
||||
// Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
|
||||
sKeywordFound = false;
|
||||
for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
|
||||
wbo = 0;
|
||||
// Copy Keyword Length from Word Buffer into Special Keyword Buffer
|
||||
for (; wbo < keywordLength; wbo++) {
|
||||
sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
|
||||
}
|
||||
sKeywordBuffer[wbo] = '\0';
|
||||
// Check for Special Keyword in list
|
||||
if ((keywords.InList(sKeywordBuffer)) &&
|
||||
((IsBOperator(wordBuffer[wbo])) ||
|
||||
(IsBSeparator(wordBuffer[wbo])))) {
|
||||
sKeywordFound = true;
|
||||
// ECHO requires no further Regular Keyword Checking
|
||||
if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
|
||||
continueProcessing = false;
|
||||
}
|
||||
// Colorize Special Keyword as Regular Keyword
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
}
|
||||
// Check for External Command / Program or Default Text
|
||||
if (!sKeywordFound) {
|
||||
wbo = 0;
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
// Read up to %, Operator or Separator
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '%') &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))) {
|
||||
wbo++;
|
||||
}
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// CHOICE requires no further Regular Keyword Checking
|
||||
if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
|
||||
continueProcessing = false;
|
||||
}
|
||||
// Check for START (and its switches) - What follows is External Command \ Program
|
||||
if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Reset External Command / Program Location if command switch detected
|
||||
if (lineBuffer[cmdLoc] == '/') {
|
||||
// Skip command switch
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(!isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Colorize External Command / Program
|
||||
if (!keywords2) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else if (keywords2.InList(wordBuffer)) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// No need to Reset Offset
|
||||
// Check for Default Text
|
||||
} else {
|
||||
// Read up to %, Operator or Separator
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '%') &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))) {
|
||||
wbo++;
|
||||
}
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
}
|
||||
// Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
|
||||
} else if (wordBuffer[0] == '%') {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
|
||||
wbo++;
|
||||
// Search to end of word for second % (can be a long path)
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '%') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))) {
|
||||
wbo++;
|
||||
}
|
||||
// Check for Argument (%n) or (%*)
|
||||
if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
|
||||
(wordBuffer[wbo] != '%')) {
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - 2);
|
||||
}
|
||||
// Colorize Argument
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 2);
|
||||
// Check for Expanded Argument (%~...) / Variable (%%~...)
|
||||
} else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
|
||||
((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
// Colorize Expanded Argument / Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// Check for Environment Variable (%x...%)
|
||||
} else if ((wordBuffer[1] != '%') &&
|
||||
(wordBuffer[wbo] == '%')) {
|
||||
wbo++;
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
// Colorize Environment Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// Check for Local Variable (%%a)
|
||||
} else if (
|
||||
(wbl > 2) &&
|
||||
(wordBuffer[1] == '%') &&
|
||||
(wordBuffer[2] != '%') &&
|
||||
(!IsBOperator(wordBuffer[2])) &&
|
||||
(!IsBSeparator(wordBuffer[2]))) {
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - 3);
|
||||
}
|
||||
// Colorize Local Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 3);
|
||||
}
|
||||
// Check for Environment Variable (!x...!)
|
||||
} else if (wordBuffer[0] == '!') {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
|
||||
wbo++;
|
||||
// Search to end of word for second ! (can be a long path)
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))) {
|
||||
wbo++;
|
||||
}
|
||||
if (wordBuffer[wbo] == '!') {
|
||||
wbo++;
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
// Colorize Environment Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
// Check for Operator
|
||||
} else if (IsBOperator(wordBuffer[0])) {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
|
||||
// Check for Comparison Operator
|
||||
if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
|
||||
// Identify External Command / Program Location for IF
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Colorize Comparison Operator
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 2);
|
||||
// Check for Pipe Operator
|
||||
} else if (wordBuffer[0] == '|') {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset - wbl + 1;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Colorize Pipe Operator
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
// Check for Other Operator
|
||||
} else {
|
||||
// Check for > Operator
|
||||
if (wordBuffer[0] == '>') {
|
||||
// Turn Keyword and External Command / Program checking back on
|
||||
continueProcessing = true;
|
||||
}
|
||||
// Colorize Other Operator
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
}
|
||||
// Check for Default Text
|
||||
} else {
|
||||
// Read up to %, Operator or Separator
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '%') &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))) {
|
||||
wbo++;
|
||||
}
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
// Skip next spaces - nothing happens if Offset was Reset
|
||||
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
// Colorize Default Text for remainder of line - currently not lexed
|
||||
styler.ColourTo(endPos, SCE_BAT_DEFAULT);
|
||||
return CurrentStatus;
|
||||
}
|
||||
|
||||
static void ColouriseBatchDoc(
|
||||
|
|
@ -467,6 +88,23 @@ static void ColouriseBatchDoc(
|
|||
int /*initStyle*/,
|
||||
WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
// Always backtracks to the start of a line that is not a continuation
|
||||
// of the previous line
|
||||
if (startPos > 0) {
|
||||
Sci_Position ln = styler.GetLine(startPos); // Current line number
|
||||
while (startPos > 0) {
|
||||
ln--;
|
||||
if ((styler.SafeGetCharAt(startPos-3) == '^' && styler.SafeGetCharAt(startPos-2) == '\r' && styler.SafeGetCharAt(startPos-1) == '\n')
|
||||
|| styler.SafeGetCharAt(startPos-2) == '^') { // handle '^' line continuation
|
||||
// When the line continuation is found,
|
||||
// set the Start Position to the Start of the previous line
|
||||
length+=startPos-styler.LineStart(ln);
|
||||
startPos=styler.LineStart(ln);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char lineBuffer[1024];
|
||||
|
||||
|
|
@ -474,21 +112,459 @@ static void ColouriseBatchDoc(
|
|||
styler.StartSegment(startPos);
|
||||
Sci_PositionU linePos = 0;
|
||||
Sci_PositionU startLine = startPos;
|
||||
bool continueProcessing = true; // Used to toggle Regular Keyword Checking
|
||||
bool isNotAssigned=false; // Used to flag Assignment in Set operation
|
||||
|
||||
for (Sci_PositionU i = startPos; i < startPos + length; i++) {
|
||||
lineBuffer[linePos++] = styler[i];
|
||||
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
|
||||
// End of line (or of line buffer) met, colourise it
|
||||
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1) || (i==startPos + length-1)) {
|
||||
// End of line (or of line buffer) (or End of Last Line) met, colourise it
|
||||
lineBuffer[linePos] = '\0';
|
||||
ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);
|
||||
Sci_PositionU lengthLine=linePos;
|
||||
Sci_PositionU endPos=i;
|
||||
Sci_PositionU offset = 0; // Line Buffer Offset
|
||||
Sci_PositionU cmdLoc; // External Command / Program Location
|
||||
char wordBuffer[81]; // Word Buffer - large to catch long paths
|
||||
Sci_PositionU wbl; // Word Buffer Length
|
||||
Sci_PositionU wbo; // Word Buffer Offset - also Special Keyword Buffer Length
|
||||
WordList &keywords = *keywordlists[0]; // Internal Commands
|
||||
WordList &keywords2 = *keywordlists[1]; // External Commands (optional)
|
||||
|
||||
// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
|
||||
// Toggling Regular Keyword Checking off improves readability
|
||||
// Other Regular Keywords and External Commands / Programs might also benefit from toggling
|
||||
// Need a more robust algorithm to properly toggle Regular Keyword Checking
|
||||
bool stopLineProcessing=false; // Used to stop line processing if Comment or Drive Change found
|
||||
// Special Keywords are those that allow certain characters without whitespace after the command
|
||||
// Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
|
||||
// Special Keyword Buffer used to determine if the first n characters is a Keyword
|
||||
char sKeywordBuffer[10]; // Special Keyword Buffer
|
||||
bool sKeywordFound; // Exit Special Keyword for-loop if found
|
||||
|
||||
// Skip initial spaces
|
||||
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
|
||||
offset++;
|
||||
}
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
// Set External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
|
||||
// Check for Fake Label (Comment) or Real Label - return if found
|
||||
if (lineBuffer[offset] == ':') {
|
||||
if (lineBuffer[offset + 1] == ':') {
|
||||
// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
|
||||
styler.ColourTo(endPos, SCE_BAT_COMMENT);
|
||||
} else {
|
||||
// Colorize Real Label
|
||||
styler.ColourTo(endPos, SCE_BAT_LABEL);
|
||||
}
|
||||
stopLineProcessing=true;
|
||||
// Check for Drive Change (Drive Change is internal command) - return if found
|
||||
} else if ((IsAlphabetic(lineBuffer[offset])) &&
|
||||
(lineBuffer[offset + 1] == ':') &&
|
||||
((isspacechar(lineBuffer[offset + 2])) ||
|
||||
(((lineBuffer[offset + 2] == '\\')) &&
|
||||
(isspacechar(lineBuffer[offset + 3]))))) {
|
||||
// Colorize Regular Keyword
|
||||
styler.ColourTo(endPos, SCE_BAT_WORD);
|
||||
stopLineProcessing=true;
|
||||
}
|
||||
|
||||
// Check for Hide Command (@ECHO OFF/ON)
|
||||
if (lineBuffer[offset] == '@') {
|
||||
styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
|
||||
offset++;
|
||||
}
|
||||
// Skip next spaces
|
||||
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Read remainder of line word-at-a-time or remainder-of-word-at-a-time
|
||||
while (offset < lengthLine && !stopLineProcessing) {
|
||||
if (offset > startLine) {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Copy word from Line Buffer into Word Buffer
|
||||
wbl = 0;
|
||||
for (; offset < lengthLine && wbl < 80 &&
|
||||
!isspacechar(lineBuffer[offset]); wbl++, offset++) {
|
||||
wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
|
||||
}
|
||||
wordBuffer[wbl] = '\0';
|
||||
wbo = 0;
|
||||
|
||||
// Check for Comment - return if found
|
||||
if ((CompareCaseInsensitive(wordBuffer, "rem") == 0) && continueProcessing) {
|
||||
styler.ColourTo(endPos, SCE_BAT_COMMENT);
|
||||
break;
|
||||
}
|
||||
// Check for Separator
|
||||
if (IsBSeparator(wordBuffer[0])) {
|
||||
// Check for External Command / Program
|
||||
if ((cmdLoc == offset - wbl) &&
|
||||
((wordBuffer[0] == ':') ||
|
||||
(wordBuffer[0] == '\\') ||
|
||||
(wordBuffer[0] == '.'))) {
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
// Colorize External Command / Program
|
||||
if (!keywords2) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else if (keywords2.InList(wordBuffer)) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
} else {
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// Check for Regular Keyword in list
|
||||
} else if ((keywords.InList(wordBuffer)) &&
|
||||
(continueProcessing)) {
|
||||
// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
|
||||
if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "prompt") == 0)) {
|
||||
continueProcessing = false;
|
||||
}
|
||||
// SET requires additional processing for the assignment operator
|
||||
if (CompareCaseInsensitive(wordBuffer, "set") == 0) {
|
||||
continueProcessing = false;
|
||||
isNotAssigned=true;
|
||||
}
|
||||
// Identify External Command / Program Location for ERRORLEVEL, and EXIST
|
||||
if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Skip comparison
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(!isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
|
||||
} else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "do") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
|
||||
(CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
}
|
||||
// Colorize Regular keyword
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
|
||||
// No need to Reset Offset
|
||||
// Check for Special Keyword in list, External Command / Program, or Default Text
|
||||
} else if ((wordBuffer[0] != '%') &&
|
||||
(wordBuffer[0] != '!') &&
|
||||
(!IsBOperator(wordBuffer[0])) &&
|
||||
(continueProcessing)) {
|
||||
// Check for Special Keyword
|
||||
// Affected Commands are in Length range 2-6
|
||||
// Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
|
||||
sKeywordFound = false;
|
||||
for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
|
||||
wbo = 0;
|
||||
// Copy Keyword Length from Word Buffer into Special Keyword Buffer
|
||||
for (; wbo < keywordLength; wbo++) {
|
||||
sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
|
||||
}
|
||||
sKeywordBuffer[wbo] = '\0';
|
||||
// Check for Special Keyword in list
|
||||
if ((keywords.InList(sKeywordBuffer)) &&
|
||||
((IsBOperator(wordBuffer[wbo])) ||
|
||||
(IsBSeparator(wordBuffer[wbo])))) {
|
||||
sKeywordFound = true;
|
||||
// ECHO requires no further Regular Keyword Checking
|
||||
if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
|
||||
continueProcessing = false;
|
||||
}
|
||||
// Colorize Special Keyword as Regular Keyword
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
}
|
||||
// Check for External Command / Program or Default Text
|
||||
if (!sKeywordFound) {
|
||||
wbo = 0;
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
// Read up to %, Operator or Separator
|
||||
while ((wbo < wbl) &&
|
||||
(((wordBuffer[wbo] != '%') &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))))) {
|
||||
wbo++;
|
||||
}
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// CHOICE requires no further Regular Keyword Checking
|
||||
if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
|
||||
continueProcessing = false;
|
||||
}
|
||||
// Check for START (and its switches) - What follows is External Command \ Program
|
||||
if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Reset External Command / Program Location if command switch detected
|
||||
if (lineBuffer[cmdLoc] == '/') {
|
||||
// Skip command switch
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(!isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Colorize External Command / Program
|
||||
if (!keywords2) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else if (keywords2.InList(wordBuffer)) {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
|
||||
} else {
|
||||
styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
|
||||
}
|
||||
// No need to Reset Offset
|
||||
// Check for Default Text
|
||||
} else {
|
||||
// Read up to %, Operator or Separator
|
||||
while ((wbo < wbl) &&
|
||||
(((wordBuffer[wbo] != '%') &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo]))))) {
|
||||
wbo++;
|
||||
}
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
}
|
||||
// Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
|
||||
} else if (wordBuffer[0] == '%') {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
|
||||
wbo++;
|
||||
// Search to end of word for second % (can be a long path)
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '%')) {
|
||||
wbo++;
|
||||
}
|
||||
// Check for Argument (%n) or (%*)
|
||||
if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
|
||||
(wordBuffer[wbo] != '%')) {
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - 2);
|
||||
}
|
||||
// Colorize Argument
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 2);
|
||||
// Check for Expanded Argument (%~...) / Variable (%%~...)
|
||||
} else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
|
||||
((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
// Colorize Expanded Argument / Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// Check for Environment Variable (%x...%)
|
||||
} else if ((wordBuffer[1] != '%') &&
|
||||
(wordBuffer[wbo] == '%')) {
|
||||
wbo++;
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
// Colorize Environment Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
// Check for Local Variable (%%a)
|
||||
} else if (
|
||||
(wbl > 2) &&
|
||||
(wordBuffer[1] == '%') &&
|
||||
(wordBuffer[2] != '%') &&
|
||||
(!IsBOperator(wordBuffer[2])) &&
|
||||
(!IsBSeparator(wordBuffer[2]))) {
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - 3);
|
||||
}
|
||||
// Colorize Local Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 3);
|
||||
}
|
||||
// Check for Environment Variable (!x...!)
|
||||
} else if (wordBuffer[0] == '!') {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
|
||||
wbo++;
|
||||
// Search to end of word for second ! (can be a long path)
|
||||
while ((wbo < wbl) &&
|
||||
(wordBuffer[wbo] != '!')) {
|
||||
wbo++;
|
||||
}
|
||||
if (wordBuffer[wbo] == '!') {
|
||||
wbo++;
|
||||
// Check for External Command / Program
|
||||
if (cmdLoc == offset - wbl) {
|
||||
cmdLoc = offset - (wbl - wbo);
|
||||
}
|
||||
// Colorize Environment Variable
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
// Check for Operator
|
||||
} else if (IsBOperator(wordBuffer[0])) {
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
|
||||
// Check for Comparison Operator
|
||||
if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
|
||||
// Identify External Command / Program Location for IF
|
||||
cmdLoc = offset;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Colorize Comparison Operator
|
||||
if (continueProcessing)
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
|
||||
else
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 2);
|
||||
// Check for Pipe Operator
|
||||
} else if ((wordBuffer[0] == '|') &&
|
||||
!(IsEscaped(lineBuffer,offset - wbl + wbo) || textQuoted(lineBuffer, offset - wbl) )) {
|
||||
// Reset External Command / Program Location
|
||||
cmdLoc = offset - wbl + 1;
|
||||
// Skip next spaces
|
||||
while ((cmdLoc < lengthLine) &&
|
||||
(isspacechar(lineBuffer[cmdLoc]))) {
|
||||
cmdLoc++;
|
||||
}
|
||||
// Colorize Pipe Operator
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
continueProcessing = true;
|
||||
// Check for Other Operator
|
||||
} else {
|
||||
// Check for Operators: >, |, &
|
||||
if (((wordBuffer[0] == '>')||
|
||||
(wordBuffer[0] == ')')||
|
||||
(wordBuffer[0] == '(')||
|
||||
(wordBuffer[0] == '&' )) &&
|
||||
!(!continueProcessing && (IsEscaped(lineBuffer,offset - wbl + wbo)
|
||||
|| textQuoted(lineBuffer, offset - wbl) ))){
|
||||
// Turn Keyword and External Command / Program checking back on
|
||||
continueProcessing = true;
|
||||
isNotAssigned=false;
|
||||
}
|
||||
// Colorize Other Operators
|
||||
// Do not Colorize Paranthesis, quoted text and escaped operators
|
||||
if (((wordBuffer[0] != ')') && (wordBuffer[0] != '(')
|
||||
&& !textQuoted(lineBuffer, offset - wbl) && !IsEscaped(lineBuffer,offset - wbl + wbo))
|
||||
&& !((wordBuffer[0] == '=') && !isNotAssigned ))
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
|
||||
else
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_DEFAULT);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - 1);
|
||||
|
||||
if ((wordBuffer[0] == '=') && isNotAssigned ){
|
||||
isNotAssigned=false;
|
||||
}
|
||||
}
|
||||
// Check for Default Text
|
||||
} else {
|
||||
// Read up to %, Operator or Separator
|
||||
while ((wbo < wbl) &&
|
||||
((wordBuffer[wbo] != '%') &&
|
||||
(wordBuffer[wbo] != '!') &&
|
||||
(!IsBOperator(wordBuffer[wbo])) &&
|
||||
(!IsBSeparator(wordBuffer[wbo])))) {
|
||||
wbo++;
|
||||
}
|
||||
// Colorize Default Text
|
||||
styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
|
||||
// Reset Offset to re-process remainder of word
|
||||
offset -= (wbl - wbo);
|
||||
}
|
||||
// Skip next spaces - nothing happens if Offset was Reset
|
||||
while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
// Colorize Default Text for remainder of line - currently not lexed
|
||||
styler.ColourTo(endPos, SCE_BAT_DEFAULT);
|
||||
|
||||
// handle line continuation for SET and ECHO commands except the last line
|
||||
if (!continueProcessing && (i<startPos + length-1)) {
|
||||
if (linePos==1 || (linePos==2 && lineBuffer[1]=='\r')) // empty line on Unix and Mac or on Windows
|
||||
continueProcessing=true;
|
||||
else {
|
||||
Sci_PositionU lineContinuationPos;
|
||||
if ((linePos>2) && lineBuffer[linePos-2]=='\r') // Windows EOL
|
||||
lineContinuationPos=linePos-3;
|
||||
else
|
||||
lineContinuationPos=linePos-2; // Unix or Mac EOL
|
||||
// Reset continueProcessing if line continuation was not found
|
||||
if ((lineBuffer[lineContinuationPos]!='^')
|
||||
|| IsEscaped(lineBuffer, lineContinuationPos)
|
||||
|| textQuoted(lineBuffer, lineContinuationPos))
|
||||
continueProcessing=true;
|
||||
}
|
||||
}
|
||||
|
||||
linePos = 0;
|
||||
startLine = i + 1;
|
||||
}
|
||||
}
|
||||
if (linePos > 0) { // Last line does not have ending characters
|
||||
lineBuffer[linePos] = '\0';
|
||||
ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
|
||||
keywordlists, styler);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const batchWordListDesc[] = {
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
bool IsAlphabetic(unsigned int ch)
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static int classifyWordBullant(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler) {
|
||||
char s[100];
|
||||
|
|
|
|||
407
src/stc/scintilla/lexers/LexCIL.cxx
Normal file
407
src/stc/scintilla/lexers/LexCIL.cxx
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexCIL.cxx
|
||||
** Lexer for Common Intermediate Language
|
||||
** Written by Jad Altahan (github.com/xv)
|
||||
** CIL manual: https://www.ecma-international.org/publications/standards/Ecma-335.htm
|
||||
**/
|
||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
bool IsAWordChar(const int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
|
||||
}
|
||||
|
||||
bool IsOperator(const int ch) {
|
||||
if ((ch < 0x80) && (isalnum(ch)))
|
||||
return false;
|
||||
|
||||
if (strchr("!%&*+-/<=>@^|~()[]{}", ch)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool IsStreamCommentStyle(const int style) noexcept {
|
||||
return style == SCE_CIL_COMMENT;
|
||||
}
|
||||
|
||||
struct OptionsCIL {
|
||||
bool fold;
|
||||
bool foldComment;
|
||||
bool foldCommentMultiline;
|
||||
bool foldCompact;
|
||||
|
||||
OptionsCIL() {
|
||||
fold = true;
|
||||
foldComment = false;
|
||||
foldCommentMultiline = true;
|
||||
foldCompact = true;
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const cilWordListDesc[] = {
|
||||
"Primary CIL keywords",
|
||||
"Metadata",
|
||||
"Opcode instructions",
|
||||
0
|
||||
};
|
||||
|
||||
struct OptionSetCIL : public OptionSet<OptionsCIL> {
|
||||
OptionSetCIL() {
|
||||
DefineProperty("fold", &OptionsCIL::fold);
|
||||
DefineProperty("fold.comment", &OptionsCIL::foldComment);
|
||||
|
||||
DefineProperty("fold.cil.comment.multiline", &OptionsCIL::foldCommentMultiline,
|
||||
"Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
|
||||
|
||||
DefineProperty("fold.compact", &OptionsCIL::foldCompact);
|
||||
|
||||
DefineWordListSets(cilWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer CIL SCLEX_CIL SCE_CIL_:
|
||||
0, "SCE_CIL_DEFAULT", "default", "White space",
|
||||
1, "SCE_CIL_COMMENT", "comment", "Multi-line comment",
|
||||
2, "SCE_CIL_COMMENTLINE", "comment line", "Line comment",
|
||||
3, "SCE_CIL_WORD", "keyword", "Keyword 1",
|
||||
4, "SCE_CIL_WORD2", "keyword", "Keyword 2",
|
||||
5, "SCE_CIL_WORD3", "keyword", "Keyword 3",
|
||||
6, "SCE_CIL_STRING", "literal string", "Double quoted string",
|
||||
7, "SCE_CIL_LABEL", "label", "Code label",
|
||||
8, "SCE_CIL_OPERATOR", "operator", "Operators",
|
||||
9, "SCE_CIL_STRINGEOL", "error literal string", "String is not closed",
|
||||
10, "SCE_CIL_IDENTIFIER", "identifier", "Identifiers",
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class LexerCIL : public DefaultLexer {
|
||||
WordList keywords, keywords2, keywords3;
|
||||
OptionsCIL options;
|
||||
OptionSetCIL osCIL;
|
||||
|
||||
public:
|
||||
LexerCIL() : DefaultLexer("cil", SCLEX_CIL, lexicalClasses, ELEMENTS(lexicalClasses)) { }
|
||||
|
||||
virtual ~LexerCIL() { }
|
||||
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osCIL.PropertyNames();
|
||||
}
|
||||
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osCIL.PropertyType(name);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osCIL.DescribeProperty(name);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
|
||||
const char * SCI_METHOD PropertyGet(const char* key) override {
|
||||
return osCIL.PropertyGet(key);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osCIL.DescribeWordListSets();
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SCI_METHOD LineEndTypesSupported() override {
|
||||
return SC_LINE_END_TYPE_UNICODE;
|
||||
}
|
||||
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) override {
|
||||
return style;
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryCIL() {
|
||||
return new LexerCIL();
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerCIL::PropertySet(const char *key, const char *val) {
|
||||
if (osCIL.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerCIL::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;
|
||||
}
|
||||
|
||||
Sci_Position firstModification = -1;
|
||||
|
||||
if (wordListN) {
|
||||
WordList wlNew;
|
||||
wlNew.Set(wl);
|
||||
|
||||
if (*wordListN != wlNew) {
|
||||
wordListN->Set(wl);
|
||||
firstModification = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerCIL::Lex(Sci_PositionU startPos, Sci_Position length,
|
||||
int initStyle, IDocument *pAccess) {
|
||||
if (initStyle == SCE_CIL_STRINGEOL) {
|
||||
initStyle = SCE_CIL_DEFAULT;
|
||||
}
|
||||
|
||||
Accessor styler(pAccess, NULL);
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
bool identAtLineStart = false, // Checks if an identifier is at line start (ignoring spaces)
|
||||
canStyleLabels = false; // Checks if conditions are met to style SCE_CIL_LABEL
|
||||
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
if (sc.atLineStart) {
|
||||
if (sc.state == SCE_CIL_STRING) {
|
||||
sc.SetState(SCE_CIL_STRING);
|
||||
}
|
||||
|
||||
identAtLineStart = true;
|
||||
}
|
||||
|
||||
// Handle string line continuation
|
||||
if (sc.ch == '\\' && (sc.chNext == '\n' || sc.chNext == '\r') &&
|
||||
(sc.state == SCE_CIL_STRING)) {
|
||||
sc.Forward();
|
||||
|
||||
if (sc.ch == '\r' && sc.chNext == '\n') {
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (sc.state) {
|
||||
case SCE_CIL_OPERATOR:
|
||||
sc.SetState(SCE_CIL_DEFAULT);
|
||||
break;
|
||||
case SCE_CIL_IDENTIFIER:
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
if (canStyleLabels && (sc.ch == ':' && sc.chNext != ':')) {
|
||||
sc.ChangeState(SCE_CIL_LABEL);
|
||||
sc.ForwardSetState(SCE_CIL_DEFAULT);
|
||||
} else {
|
||||
char kwSize[100];
|
||||
sc.GetCurrent(kwSize, sizeof(kwSize));
|
||||
int style = SCE_CIL_IDENTIFIER;
|
||||
|
||||
if (keywords.InList(kwSize)) {
|
||||
style = SCE_CIL_WORD;
|
||||
} else if (keywords2.InList(kwSize)) {
|
||||
style = SCE_CIL_WORD2;
|
||||
} else if (keywords3.InList(kwSize)) {
|
||||
style = SCE_CIL_WORD3;
|
||||
}
|
||||
|
||||
sc.ChangeState(style);
|
||||
sc.SetState(SCE_CIL_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_CIL_COMMENT:
|
||||
if (sc.Match('*', '/')) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_CIL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_CIL_COMMENTLINE:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_CIL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_CIL_STRING:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '"' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (sc.ch == '"') {
|
||||
sc.ForwardSetState(SCE_CIL_DEFAULT);
|
||||
} else if (sc.atLineEnd) {
|
||||
sc.ChangeState(SCE_CIL_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_CIL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc.state == SCE_CIL_DEFAULT) {
|
||||
// String
|
||||
if (sc.ch == '"') {
|
||||
sc.SetState(SCE_CIL_STRING);
|
||||
}
|
||||
// Keyword
|
||||
else if (IsAWordChar(sc.ch)) {
|
||||
// Allow setting SCE_CIL_LABEL style only if the label is the
|
||||
// first token in the line and does not start with a dot or a digit
|
||||
canStyleLabels = identAtLineStart && !(sc.ch == '.' || IsADigit(sc.ch));
|
||||
sc.SetState(SCE_CIL_IDENTIFIER);
|
||||
}
|
||||
// Multi-line comment
|
||||
else if (sc.Match('/', '*')) {
|
||||
sc.SetState(SCE_CIL_COMMENT);
|
||||
sc.Forward();
|
||||
}
|
||||
// Line comment
|
||||
else if (sc.Match('/', '/')) {
|
||||
sc.SetState(SCE_CIL_COMMENTLINE);
|
||||
}
|
||||
// Operators
|
||||
else if (IsOperator(sc.ch)) {
|
||||
sc.SetState(SCE_CIL_OPERATOR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsASpace(sc.ch)) {
|
||||
identAtLineStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerCIL::Fold(Sci_PositionU startPos, Sci_Position length,
|
||||
int initStyle, IDocument *pAccess) {
|
||||
if (!options.fold) {
|
||||
return;
|
||||
}
|
||||
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
const Sci_PositionU endPos = startPos + length;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0)
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
|
||||
int style = initStyle;
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int levelNext = levelCurrent;
|
||||
int visibleChars = 0;
|
||||
|
||||
char chNext = styler[startPos];
|
||||
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
const char ch = chNext;
|
||||
int stylePrev = style;
|
||||
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
|
||||
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
|
||||
if (options.foldComment &&
|
||||
options.foldCommentMultiline && IsStreamCommentStyle(style)) {
|
||||
if (!IsStreamCommentStyle(stylePrev)) {
|
||||
levelNext++;
|
||||
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
|
||||
if (style == SCE_CIL_OPERATOR) {
|
||||
if (ch == '{') {
|
||||
levelNext++;
|
||||
} else if (ch == '}') {
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsASpace(ch)) {
|
||||
visibleChars++;
|
||||
}
|
||||
|
||||
if (atEOL || (i == endPos - 1)) {
|
||||
int lev = levelCurrent | levelNext << 16;
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if (levelCurrent < levelNext)
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
|
||||
lineCurrent++;
|
||||
levelCurrent = levelNext;
|
||||
|
||||
if (options.foldCompact &&
|
||||
i == static_cast<Sci_PositionU>(styler.Length() - 1)) {
|
||||
styler.SetLevel(lineCurrent, lev | SC_FOLDLEVELWHITEFLAG);
|
||||
}
|
||||
|
||||
visibleChars = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LexerModule lmCIL(SCLEX_CIL, LexerCIL::LexerFactoryCIL, "cil", cilWordListDesc);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexClw.cxx
|
||||
/** @file LexCLW.cxx
|
||||
** Lexer for Clarion.
|
||||
** 2004/12/17 Updated Lexer
|
||||
**/
|
||||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Is an end of line character
|
||||
inline bool IsEOL(const int ch) {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
#define IN_DIVISION 0x01
|
||||
#define IN_DECLARATIVES 0x02
|
||||
|
|
|
|||
|
|
@ -6,22 +6,22 @@
|
|||
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
|
@ -32,14 +32,12 @@
|
|||
#include "SparseState.h"
|
||||
#include "SubStyles.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
bool IsSpaceEquiv(int state) {
|
||||
constexpr bool IsSpaceEquiv(int state) noexcept {
|
||||
return (state <= SCE_C_COMMENTDOC) ||
|
||||
// including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
|
||||
(state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
|
||||
|
|
@ -53,10 +51,10 @@ bool IsSpaceEquiv(int state) {
|
|||
// a = b+++/ptn/...
|
||||
// Putting a space between the '++' post-inc operator and the '+' binary op
|
||||
// fixes this, and is highly recommended for readability anyway.
|
||||
bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) {
|
||||
Sci_Position pos = (Sci_Position) sc.currentPos;
|
||||
bool FollowsPostfixOperator(const StyleContext &sc, LexAccessor &styler) {
|
||||
Sci_Position pos = sc.currentPos;
|
||||
while (--pos > 0) {
|
||||
char ch = styler[pos];
|
||||
const char ch = styler[pos];
|
||||
if (ch == '+' || ch == '-') {
|
||||
return styler[pos - 1] == ch;
|
||||
}
|
||||
|
|
@ -64,13 +62,13 @@ bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) {
|
||||
bool followsReturnKeyword(const StyleContext &sc, LexAccessor &styler) {
|
||||
// Don't look at styles, so no need to flush.
|
||||
Sci_Position pos = (Sci_Position) sc.currentPos;
|
||||
Sci_Position currentLine = styler.GetLine(pos);
|
||||
Sci_Position lineStartPos = styler.LineStart(currentLine);
|
||||
Sci_Position pos = sc.currentPos;
|
||||
const Sci_Position currentLine = styler.GetLine(pos);
|
||||
const Sci_Position lineStartPos = styler.LineStart(currentLine);
|
||||
while (--pos > lineStartPos) {
|
||||
char ch = styler.SafeGetCharAt(pos);
|
||||
const char ch = styler.SafeGetCharAt(pos);
|
||||
if (ch != ' ' && ch != '\t') {
|
||||
break;
|
||||
}
|
||||
|
|
@ -86,13 +84,13 @@ bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) {
|
|||
return !*s;
|
||||
}
|
||||
|
||||
bool IsSpaceOrTab(int ch) {
|
||||
constexpr bool IsSpaceOrTab(int ch) noexcept {
|
||||
return ch == ' ' || ch == '\t';
|
||||
}
|
||||
|
||||
bool OnlySpaceOrTab(const std::string &s) {
|
||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||
if (!IsSpaceOrTab(*it))
|
||||
bool OnlySpaceOrTab(const std::string &s) noexcept {
|
||||
for (const char ch : s) {
|
||||
if (!IsSpaceOrTab(ch))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -100,11 +98,11 @@ bool OnlySpaceOrTab(const std::string &s) {
|
|||
|
||||
std::vector<std::string> StringSplit(const std::string &text, int separator) {
|
||||
std::vector<std::string> vs(text.empty() ? 0 : 1);
|
||||
for (std::string::const_iterator it = text.begin(); it != text.end(); ++it) {
|
||||
if (*it == separator) {
|
||||
vs.push_back(std::string());
|
||||
for (const char ch : text) {
|
||||
if (ch == separator) {
|
||||
vs.emplace_back();
|
||||
} else {
|
||||
vs.back() += *it;
|
||||
vs.back() += ch;
|
||||
}
|
||||
}
|
||||
return vs;
|
||||
|
|
@ -141,21 +139,21 @@ BracketPair FindBracketPair(std::vector<std::string> &tokens) {
|
|||
}
|
||||
|
||||
void highlightTaskMarker(StyleContext &sc, LexAccessor &styler,
|
||||
int activity, WordList &markerList, bool caseSensitive){
|
||||
int activity, const WordList &markerList, bool caseSensitive){
|
||||
if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) {
|
||||
const int lengthMarker = 50;
|
||||
char marker[lengthMarker+1];
|
||||
Sci_Position currPos = (Sci_Position) sc.currentPos;
|
||||
int i = 0;
|
||||
constexpr Sci_PositionU lengthMarker = 50;
|
||||
char marker[lengthMarker+1] = "";
|
||||
const Sci_PositionU currPos = sc.currentPos;
|
||||
Sci_PositionU i = 0;
|
||||
while (i < lengthMarker) {
|
||||
char ch = styler.SafeGetCharAt(currPos + i);
|
||||
const char ch = styler.SafeGetCharAt(currPos + i);
|
||||
if (IsASpace(ch) || isoperator(ch)) {
|
||||
break;
|
||||
}
|
||||
if (caseSensitive)
|
||||
marker[i] = ch;
|
||||
else
|
||||
marker[i] = static_cast<char>(tolower(ch));
|
||||
marker[i] = MakeLowerCase(ch);
|
||||
i++;
|
||||
}
|
||||
marker[i] = '\0';
|
||||
|
|
@ -165,18 +163,14 @@ void highlightTaskMarker(StyleContext &sc, LexAccessor &styler,
|
|||
}
|
||||
}
|
||||
|
||||
struct EscapeSequence {
|
||||
int digitsLeft;
|
||||
CharacterSet setHexDigits;
|
||||
CharacterSet setOctDigits;
|
||||
CharacterSet setNoneNumeric;
|
||||
CharacterSet *escapeSetValid;
|
||||
EscapeSequence() {
|
||||
digitsLeft = 0;
|
||||
escapeSetValid = 0;
|
||||
setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef");
|
||||
setOctDigits = CharacterSet(CharacterSet::setNone, "01234567");
|
||||
}
|
||||
class EscapeSequence {
|
||||
const CharacterSet setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef");
|
||||
const CharacterSet setOctDigits = CharacterSet(CharacterSet::setNone, "01234567");
|
||||
const CharacterSet setNoneNumeric;
|
||||
const CharacterSet *escapeSetValid = nullptr;
|
||||
int digitsLeft = 0;
|
||||
public:
|
||||
EscapeSequence() = default;
|
||||
void resetEscapeState(int nextChar) {
|
||||
digitsLeft = 0;
|
||||
escapeSetValid = &setNoneNumeric;
|
||||
|
|
@ -197,26 +191,39 @@ struct EscapeSequence {
|
|||
bool atEscapeEnd(int currChar) const {
|
||||
return (digitsLeft <= 0) || !escapeSetValid->Contains(currChar);
|
||||
}
|
||||
void consumeDigit() noexcept {
|
||||
digitsLeft--;
|
||||
}
|
||||
};
|
||||
|
||||
std::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpace) {
|
||||
std::string restOfLine;
|
||||
Sci_Position i =0;
|
||||
Sci_Position line = styler.GetLine(start);
|
||||
Sci_Position pos = start;
|
||||
Sci_Position endLine = styler.LineEnd(line);
|
||||
char ch = styler.SafeGetCharAt(start, '\n');
|
||||
Sci_Position endLine = styler.LineEnd(styler.GetLine(start));
|
||||
while (((start+i) < endLine) && (ch != '\r')) {
|
||||
char chNext = styler.SafeGetCharAt(start + i + 1, '\n');
|
||||
if (ch == '/' && (chNext == '/' || chNext == '*'))
|
||||
break;
|
||||
if (allowSpace || (ch != ' '))
|
||||
restOfLine += ch;
|
||||
i++;
|
||||
ch = chNext;
|
||||
while (pos < endLine) {
|
||||
if (ch == '\\' && ((pos + 1) == endLine)) {
|
||||
// Continuation line
|
||||
line++;
|
||||
pos = styler.LineStart(line);
|
||||
endLine = styler.LineEnd(line);
|
||||
ch = styler.SafeGetCharAt(pos, '\n');
|
||||
} else {
|
||||
const char chNext = styler.SafeGetCharAt(pos + 1, '\n');
|
||||
if (ch == '/' && (chNext == '/' || chNext == '*'))
|
||||
break;
|
||||
if (allowSpace || (ch != ' ')) {
|
||||
restOfLine += ch;
|
||||
}
|
||||
pos++;
|
||||
ch = chNext;
|
||||
}
|
||||
}
|
||||
return restOfLine;
|
||||
}
|
||||
|
||||
bool IsStreamCommentStyle(int style) {
|
||||
constexpr bool IsStreamCommentStyle(int style) noexcept {
|
||||
return style == SCE_C_COMMENT ||
|
||||
style == SCE_C_COMMENTDOC ||
|
||||
style == SCE_C_COMMENTDOCKEYWORD ||
|
||||
|
|
@ -234,26 +241,48 @@ struct PPDefinition {
|
|||
}
|
||||
};
|
||||
|
||||
constexpr int inactiveFlag = 0x40;
|
||||
|
||||
class LinePPState {
|
||||
int state;
|
||||
int ifTaken;
|
||||
int level;
|
||||
bool ValidLevel() const {
|
||||
return level >= 0 && level < 32;
|
||||
// Track the state of preprocessor conditionals to allow showing active and inactive
|
||||
// code in different styles.
|
||||
// Only works up to 31 levels of conditional nesting.
|
||||
|
||||
// state is a bit mask with 1 bit per level
|
||||
// bit is 1 for level if section inactive, so any bits set = inactive style
|
||||
int state = 0;
|
||||
// ifTaken is a bit mask with 1 bit per level
|
||||
// bit is 1 for level if some branch at this level has been taken
|
||||
int ifTaken = 0;
|
||||
// level is the nesting level of #if constructs
|
||||
int level = -1;
|
||||
static const int maximumNestingLevel = 31;
|
||||
bool ValidLevel() const noexcept {
|
||||
return level >= 0 && level < maximumNestingLevel;
|
||||
}
|
||||
int maskLevel() const {
|
||||
return 1 << level;
|
||||
int maskLevel() const noexcept {
|
||||
if (level >= 0) {
|
||||
return 1 << level;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
public:
|
||||
LinePPState() : state(0), ifTaken(0), level(-1) {
|
||||
LinePPState() noexcept {
|
||||
}
|
||||
bool IsInactive() const {
|
||||
bool IsActive() const noexcept {
|
||||
return state == 0;
|
||||
}
|
||||
bool IsInactive() const noexcept {
|
||||
return state != 0;
|
||||
}
|
||||
bool CurrentIfTaken() const {
|
||||
int ActiveState() const noexcept {
|
||||
return state ? inactiveFlag : 0;
|
||||
}
|
||||
bool CurrentIfTaken() const noexcept {
|
||||
return (ifTaken & maskLevel()) != 0;
|
||||
}
|
||||
void StartSection(bool on) {
|
||||
void StartSection(bool on) noexcept {
|
||||
level++;
|
||||
if (ValidLevel()) {
|
||||
if (on) {
|
||||
|
|
@ -265,14 +294,14 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
void EndSection() {
|
||||
void EndSection() noexcept {
|
||||
if (ValidLevel()) {
|
||||
state &= ~maskLevel();
|
||||
ifTaken &= ~maskLevel();
|
||||
}
|
||||
level--;
|
||||
}
|
||||
void InvertCurrentLevel() {
|
||||
void InvertCurrentLevel() noexcept {
|
||||
if (ValidLevel()) {
|
||||
state ^= maskLevel();
|
||||
ifTaken |= maskLevel();
|
||||
|
|
@ -285,7 +314,7 @@ public:
|
|||
class PPStates {
|
||||
std::vector<LinePPState> vlls;
|
||||
public:
|
||||
LinePPState ForLine(Sci_Position line) const {
|
||||
LinePPState ForLine(Sci_Position line) const noexcept {
|
||||
if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {
|
||||
return vlls[line];
|
||||
} else {
|
||||
|
|
@ -355,7 +384,7 @@ const char *const cppWordLists[] = {
|
|||
"Global classes and typedefs",
|
||||
"Preprocessor definitions",
|
||||
"Task marker and error marker keywords",
|
||||
0,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
struct OptionSetCPP : public OptionSet<OptionsCPP> {
|
||||
|
|
@ -432,13 +461,48 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
|
|||
|
||||
const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer Cpp SCLEX_CPP SCE_C_:
|
||||
0, "SCE_C_DEFAULT", "default", "White space",
|
||||
1, "SCE_C_COMMENT", "comment", "Comment: /* */.",
|
||||
2, "SCE_C_COMMENTLINE", "comment line", "Line Comment: //.",
|
||||
3, "SCE_C_COMMENTDOC", "comment documentation", "Doc comment: block comments beginning with /** or /*!",
|
||||
4, "SCE_C_NUMBER", "literal numeric", "Number",
|
||||
5, "SCE_C_WORD", "keyword", "Keyword",
|
||||
6, "SCE_C_STRING", "literal string", "Double quoted string",
|
||||
7, "SCE_C_CHARACTER", "literal string character", "Single quoted string",
|
||||
8, "SCE_C_UUID", "literal uuid", "UUIDs (only in IDL)",
|
||||
9, "SCE_C_PREPROCESSOR", "preprocessor", "Preprocessor",
|
||||
10, "SCE_C_OPERATOR", "operator", "Operators",
|
||||
11, "SCE_C_IDENTIFIER", "identifier", "Identifiers",
|
||||
12, "SCE_C_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
13, "SCE_C_VERBATIM", "literal string multiline raw", "Verbatim strings for C#",
|
||||
14, "SCE_C_REGEX", "literal regex", "Regular expressions for JavaScript",
|
||||
15, "SCE_C_COMMENTLINEDOC", "comment documentation line", "Doc Comment Line: line comments beginning with /// or //!.",
|
||||
16, "SCE_C_WORD2", "identifier", "Keywords2",
|
||||
17, "SCE_C_COMMENTDOCKEYWORD", "comment documentation keyword", "Comment keyword",
|
||||
18, "SCE_C_COMMENTDOCKEYWORDERROR", "error comment documentation keyword", "Comment keyword error",
|
||||
19, "SCE_C_GLOBALCLASS", "identifier", "Global class",
|
||||
20, "SCE_C_STRINGRAW", "literal string multiline raw", "Raw strings for C++0x",
|
||||
21, "SCE_C_TRIPLEVERBATIM", "literal string multiline raw", "Triple-quoted strings for Vala",
|
||||
22, "SCE_C_HASHQUOTEDSTRING", "literal string", "Hash-quoted strings for Pike",
|
||||
23, "SCE_C_PREPROCESSORCOMMENT", "comment preprocessor", "Preprocessor stream comment",
|
||||
24, "SCE_C_PREPROCESSORCOMMENTDOC", "comment preprocessor documentation", "Preprocessor stream doc comment",
|
||||
25, "SCE_C_USERLITERAL", "literal", "User defined literals",
|
||||
26, "SCE_C_TASKMARKER", "comment taskmarker", "Task Marker",
|
||||
27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence",
|
||||
};
|
||||
|
||||
const int sizeLexicalClasses = static_cast<int>(Sci::size(lexicalClasses));
|
||||
|
||||
}
|
||||
|
||||
class LexerCPP : public ILexerWithSubStyles {
|
||||
class LexerCPP : public ILexerWithIdentity {
|
||||
bool caseSensitive;
|
||||
CharacterSet setWord;
|
||||
CharacterSet setNegationOp;
|
||||
CharacterSet setArithmethicOp;
|
||||
CharacterSet setAddOp;
|
||||
CharacterSet setMultOp;
|
||||
CharacterSet setRelOp;
|
||||
CharacterSet setLogicalOp;
|
||||
CharacterSet setWordStart;
|
||||
|
|
@ -453,14 +517,15 @@ class LexerCPP : public ILexerWithSubStyles {
|
|||
struct SymbolValue {
|
||||
std::string value;
|
||||
std::string arguments;
|
||||
SymbolValue(const std::string &value_="", const std::string &arguments_="") : value(value_), arguments(arguments_) {
|
||||
SymbolValue() = default;
|
||||
SymbolValue(const std::string &value_, const std::string &arguments_) : value(value_), arguments(arguments_) {
|
||||
}
|
||||
SymbolValue &operator = (const std::string &value_) {
|
||||
value = value_;
|
||||
arguments.clear();
|
||||
return *this;
|
||||
}
|
||||
bool IsMacro() const {
|
||||
bool IsMacro() const noexcept {
|
||||
return !arguments.empty();
|
||||
}
|
||||
};
|
||||
|
|
@ -470,81 +535,149 @@ class LexerCPP : public ILexerWithSubStyles {
|
|||
OptionSetCPP osCPP;
|
||||
EscapeSequence escapeSeq;
|
||||
SparseState<std::string> rawStringTerminators;
|
||||
enum { activeFlag = 0x40 };
|
||||
enum { ssIdentifier, ssDocKeyword };
|
||||
SubStyles subStyles;
|
||||
std::string returnBuffer;
|
||||
public:
|
||||
explicit LexerCPP(bool caseSensitive_) :
|
||||
caseSensitive(caseSensitive_),
|
||||
setWord(CharacterSet::setAlphaNum, "._", 0x80, true),
|
||||
setNegationOp(CharacterSet::setNone, "!"),
|
||||
setArithmethicOp(CharacterSet::setNone, "+-/*%"),
|
||||
setAddOp(CharacterSet::setNone, "+-"),
|
||||
setMultOp(CharacterSet::setNone, "*/%"),
|
||||
setRelOp(CharacterSet::setNone, "=!<>"),
|
||||
setLogicalOp(CharacterSet::setNone, "|&"),
|
||||
subStyles(styleSubable, 0x80, 0x40, activeFlag) {
|
||||
subStyles(styleSubable, 0x80, 0x40, inactiveFlag) {
|
||||
}
|
||||
// Deleted so LexerCPP objects can not be copied.
|
||||
LexerCPP(const LexerCPP &) = delete;
|
||||
LexerCPP(LexerCPP &&) = delete;
|
||||
void operator=(const LexerCPP &) = delete;
|
||||
void operator=(LexerCPP &&) = delete;
|
||||
virtual ~LexerCPP() {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() noexcept override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvSubStyles;
|
||||
int SCI_METHOD Version() const noexcept override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osCPP.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osCPP.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osCPP.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osCPP.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
return 0;
|
||||
void * SCI_METHOD PrivateCall(int, void *) noexcept override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int SCI_METHOD LineEndTypesSupported() {
|
||||
int SCI_METHOD LineEndTypesSupported() noexcept override {
|
||||
return SC_LINE_END_TYPE_UNICODE;
|
||||
}
|
||||
|
||||
int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) {
|
||||
int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {
|
||||
return subStyles.Allocate(styleBase, numberStyles);
|
||||
}
|
||||
int SCI_METHOD SubStylesStart(int styleBase) {
|
||||
int SCI_METHOD SubStylesStart(int styleBase) override {
|
||||
return subStyles.Start(styleBase);
|
||||
}
|
||||
int SCI_METHOD SubStylesLength(int styleBase) {
|
||||
int SCI_METHOD SubStylesLength(int styleBase) override {
|
||||
return subStyles.Length(styleBase);
|
||||
}
|
||||
int SCI_METHOD StyleFromSubStyle(int subStyle) {
|
||||
int styleBase = subStyles.BaseStyle(MaskActive(subStyle));
|
||||
int active = subStyle & activeFlag;
|
||||
return styleBase | active;
|
||||
int SCI_METHOD StyleFromSubStyle(int subStyle) override {
|
||||
const int styleBase = subStyles.BaseStyle(MaskActive(subStyle));
|
||||
const int inactive = subStyle & inactiveFlag;
|
||||
return styleBase | inactive;
|
||||
}
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) {
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) noexcept override {
|
||||
return MaskActive(style);
|
||||
}
|
||||
void SCI_METHOD FreeSubStyles() {
|
||||
}
|
||||
void SCI_METHOD FreeSubStyles() override {
|
||||
subStyles.Free();
|
||||
}
|
||||
void SCI_METHOD SetIdentifiers(int style, const char *identifiers) {
|
||||
void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {
|
||||
subStyles.SetIdentifiers(style, identifiers);
|
||||
}
|
||||
int SCI_METHOD DistanceToSecondaryStyles() {
|
||||
return activeFlag;
|
||||
int SCI_METHOD DistanceToSecondaryStyles() noexcept override {
|
||||
return inactiveFlag;
|
||||
}
|
||||
const char * SCI_METHOD GetSubStyleBases() {
|
||||
const char * SCI_METHOD GetSubStyleBases() noexcept override {
|
||||
return styleSubable;
|
||||
}
|
||||
int SCI_METHOD NamedStyles() override {
|
||||
return std::max(subStyles.LastAllocated() + 1,
|
||||
sizeLexicalClasses) +
|
||||
inactiveFlag;
|
||||
}
|
||||
const char * SCI_METHOD NameOfStyle(int style) override {
|
||||
if (style >= NamedStyles())
|
||||
return "";
|
||||
if (style < sizeLexicalClasses)
|
||||
return lexicalClasses[style].name;
|
||||
// TODO: inactive and substyles
|
||||
return "";
|
||||
}
|
||||
const char * SCI_METHOD TagsOfStyle(int style) override {
|
||||
if (style >= NamedStyles())
|
||||
return "Excess";
|
||||
returnBuffer.clear();
|
||||
const int firstSubStyle = subStyles.FirstAllocated();
|
||||
if (firstSubStyle >= 0) {
|
||||
const int lastSubStyle = subStyles.LastAllocated();
|
||||
if (((style >= firstSubStyle) && (style <= (lastSubStyle))) ||
|
||||
((style >= firstSubStyle + inactiveFlag) && (style <= (lastSubStyle + inactiveFlag)))) {
|
||||
int styleActive = style;
|
||||
if (style > lastSubStyle) {
|
||||
returnBuffer = "inactive ";
|
||||
styleActive -= inactiveFlag;
|
||||
}
|
||||
const int styleMain = StyleFromSubStyle(styleActive);
|
||||
returnBuffer += lexicalClasses[styleMain].tags;
|
||||
return returnBuffer.c_str();
|
||||
}
|
||||
}
|
||||
if (style < sizeLexicalClasses)
|
||||
return lexicalClasses[style].tags;
|
||||
if (style >= inactiveFlag) {
|
||||
returnBuffer = "inactive ";
|
||||
const int styleActive = style - inactiveFlag;
|
||||
if (styleActive < sizeLexicalClasses)
|
||||
returnBuffer += lexicalClasses[styleActive].tags;
|
||||
else
|
||||
returnBuffer = "";
|
||||
return returnBuffer.c_str();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
const char * SCI_METHOD DescriptionOfStyle(int style) override {
|
||||
if (style >= NamedStyles())
|
||||
return "";
|
||||
if (style < sizeLexicalClasses)
|
||||
return lexicalClasses[style].description;
|
||||
// TODO: inactive and substyles
|
||||
return "";
|
||||
}
|
||||
|
||||
// ILexerWithIdentity methods
|
||||
const char * SCI_METHOD GetName() override {
|
||||
return caseSensitive ? "cpp" : "cppnocase";
|
||||
}
|
||||
int SCI_METHOD GetIdentifier() override {
|
||||
return caseSensitive ? SCLEX_CPP : SCLEX_CPPNOCASE;
|
||||
}
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override;
|
||||
|
||||
static ILexer *LexerFactoryCPP() {
|
||||
return new LexerCPP(true);
|
||||
|
|
@ -552,8 +685,8 @@ public:
|
|||
static ILexer *LexerFactoryCPPInsensitive() {
|
||||
return new LexerCPP(false);
|
||||
}
|
||||
static int MaskActive(int style) {
|
||||
return style & ~activeFlag;
|
||||
constexpr static int MaskActive(int style) noexcept {
|
||||
return style & ~inactiveFlag;
|
||||
}
|
||||
void EvaluateTokens(std::vector<std::string> &tokens, const SymbolTable &preprocessorDefinitions);
|
||||
std::vector<std::string> Tokenize(const std::string &expr) const;
|
||||
|
|
@ -573,8 +706,12 @@ Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val)
|
|||
return -1;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD LexerCPP::PropertyGet(const char *key) {
|
||||
return osCPP.PropertyGet(key);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = 0;
|
||||
WordList *wordListN = nullptr;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywords;
|
||||
|
|
@ -611,8 +748,8 @@ Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
|
|||
if (cpEquals) {
|
||||
std::string name(cpDefinition, cpEquals - cpDefinition);
|
||||
std::string val(cpEquals+1);
|
||||
size_t bracket = name.find('(');
|
||||
size_t bracketEnd = name.find(')');
|
||||
const size_t bracket = name.find('(');
|
||||
const size_t bracketEnd = name.find(')');
|
||||
if ((bracket != std::string::npos) && (bracketEnd != std::string::npos)) {
|
||||
// Macro
|
||||
std::string args = name.substr(bracket + 1, bracketEnd - bracket - 1);
|
||||
|
|
@ -633,15 +770,6 @@ Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
|
|||
return firstModification;
|
||||
}
|
||||
|
||||
// Functor used to truncate history
|
||||
struct After {
|
||||
Sci_Position line;
|
||||
explicit After(Sci_Position line_) : line(line_) {}
|
||||
bool operator()(PPDefinition &p) const {
|
||||
return p.line > line;
|
||||
}
|
||||
};
|
||||
|
||||
void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
|
|
@ -675,7 +803,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
(MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) {
|
||||
// Set continuationLine if last character of previous line is '\'
|
||||
if (lineCurrent > 0) {
|
||||
Sci_Position endLinePrevious = styler.LineEnd(lineCurrent - 1);
|
||||
const Sci_Position endLinePrevious = styler.LineEnd(lineCurrent - 1);
|
||||
if (endLinePrevious > 0) {
|
||||
continuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\';
|
||||
}
|
||||
|
|
@ -702,29 +830,30 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
if (!options.updatePreprocessor)
|
||||
ppDefineHistory.clear();
|
||||
|
||||
std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(lineCurrent-1));
|
||||
std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(),
|
||||
[lineCurrent](const PPDefinition &p) noexcept { return p.line >= lineCurrent; });
|
||||
if (itInvalid != ppDefineHistory.end()) {
|
||||
ppDefineHistory.erase(itInvalid, ppDefineHistory.end());
|
||||
definitionsChanged = true;
|
||||
}
|
||||
|
||||
SymbolTable preprocessorDefinitions = preprocessorDefinitionsStart;
|
||||
for (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) {
|
||||
if (itDef->isUndef)
|
||||
preprocessorDefinitions.erase(itDef->key);
|
||||
for (const PPDefinition &ppDef : ppDefineHistory) {
|
||||
if (ppDef.isUndef)
|
||||
preprocessorDefinitions.erase(ppDef.key);
|
||||
else
|
||||
preprocessorDefinitions[itDef->key] = SymbolValue(itDef->value, itDef->arguments);
|
||||
preprocessorDefinitions[ppDef.key] = SymbolValue(ppDef.value, ppDef.arguments);
|
||||
}
|
||||
|
||||
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
|
||||
SparseState<std::string> rawSTNew(lineCurrent);
|
||||
|
||||
int activitySet = preproc.IsInactive() ? activeFlag : 0;
|
||||
int activitySet = preproc.ActiveState();
|
||||
|
||||
const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER);
|
||||
const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD);
|
||||
|
||||
Sci_Position lineEndNext = styler.LineEnd(lineCurrent);
|
||||
Sci_PositionU lineEndNext = styler.LineEnd(lineCurrent);
|
||||
|
||||
for (; sc.More();) {
|
||||
|
||||
|
|
@ -746,7 +875,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
isIncludePreprocessor = false;
|
||||
inRERange = false;
|
||||
if (preproc.IsInactive()) {
|
||||
activitySet = activeFlag;
|
||||
activitySet = inactiveFlag;
|
||||
sc.SetState(sc.state | activitySet);
|
||||
}
|
||||
}
|
||||
|
|
@ -762,7 +891,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
|
||||
// Handle line continuation generically.
|
||||
if (sc.ch == '\\') {
|
||||
if (static_cast<Sci_Position>((sc.currentPos+1)) >= lineEndNext) {
|
||||
if ((sc.currentPos+1) >= lineEndNext) {
|
||||
lineCurrent++;
|
||||
lineEndNext = styler.LineEnd(lineCurrent);
|
||||
vlls.Add(lineCurrent, preproc);
|
||||
|
|
@ -829,7 +958,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
const bool raw = literalString && sc.chPrev == 'R' && !setInvalidRawFirst.Contains(sc.chNext);
|
||||
if (raw)
|
||||
s[lenS--] = '\0';
|
||||
bool valid =
|
||||
const bool valid =
|
||||
(lenS == 0) ||
|
||||
((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||
|
||||
((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8'));
|
||||
|
|
@ -856,7 +985,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
break;
|
||||
case SCE_C_PREPROCESSOR:
|
||||
if (options.stylingWithinPreprocessor) {
|
||||
if (IsASpace(sc.ch)) {
|
||||
if (IsASpace(sc.ch) || (sc.ch == '(')) {
|
||||
sc.SetState(SCE_C_DEFAULT|activitySet);
|
||||
}
|
||||
} else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"') || sc.atLineEnd)) {
|
||||
|
|
@ -977,7 +1106,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
}
|
||||
break;
|
||||
case SCE_C_ESCAPESEQUENCE:
|
||||
escapeSeq.digitsLeft--;
|
||||
escapeSeq.consumeDigit();
|
||||
if (!escapeSeq.atEscapeEnd(sc.ch)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -1029,12 +1158,12 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
case SCE_C_REGEX:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_C_DEFAULT|activitySet);
|
||||
} else if (! inRERange && sc.ch == '/') {
|
||||
} else if (!inRERange && sc.ch == '/') {
|
||||
sc.Forward();
|
||||
while ((sc.ch < 0x80) && islower(sc.ch))
|
||||
while (IsLowerCase(sc.ch))
|
||||
sc.Forward(); // gobble regex flags
|
||||
sc.SetState(SCE_C_DEFAULT|activitySet);
|
||||
} else if (sc.ch == '\\' && (static_cast<Sci_Position>(sc.currentPos+1) < lineEndNext)) {
|
||||
} else if (sc.ch == '\\' && ((sc.currentPos+1) < lineEndNext)) {
|
||||
// Gobble up the escaped character
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '[') {
|
||||
|
|
@ -1060,7 +1189,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
}
|
||||
break;
|
||||
case SCE_C_TRIPLEVERBATIM:
|
||||
if (sc.Match("\"\"\"")) {
|
||||
if (sc.Match(R"(""")")) {
|
||||
while (sc.Match('"')) {
|
||||
sc.Forward();
|
||||
}
|
||||
|
|
@ -1091,7 +1220,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
if (sc.Match('@', '\"')) {
|
||||
sc.SetState(SCE_C_VERBATIM|activitySet);
|
||||
sc.Forward();
|
||||
} else if (options.triplequotedStrings && sc.Match("\"\"\"")) {
|
||||
} else if (options.triplequotedStrings && sc.Match(R"(""")")) {
|
||||
sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
|
||||
sc.Forward(2);
|
||||
} else if (options.hashquotedStrings && sc.Match('#', '\"')) {
|
||||
|
|
@ -1141,7 +1270,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
sc.SetState(SCE_C_STRINGRAW|activitySet);
|
||||
rawStringTerminator = ")";
|
||||
for (Sci_Position termPos = sc.currentPos + 1;; termPos++) {
|
||||
char chTerminator = styler.SafeGetCharAt(termPos, '(');
|
||||
const char chTerminator = styler.SafeGetCharAt(termPos, '(');
|
||||
if (chTerminator == '(')
|
||||
break;
|
||||
rawStringTerminator += chTerminator;
|
||||
|
|
@ -1171,58 +1300,71 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
isIncludePreprocessor = true;
|
||||
} else {
|
||||
if (options.trackPreprocessor) {
|
||||
// If #if is nested too deeply (>31 levels) the active/inactive appearance
|
||||
// will stop reflecting the code.
|
||||
if (sc.Match("ifdef") || sc.Match("ifndef")) {
|
||||
bool isIfDef = sc.Match("ifdef");
|
||||
int i = isIfDef ? 5 : 6;
|
||||
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false);
|
||||
const bool isIfDef = sc.Match("ifdef");
|
||||
const int startRest = isIfDef ? 5 : 6;
|
||||
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + startRest + 1, false);
|
||||
bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();
|
||||
preproc.StartSection(isIfDef == foundDef);
|
||||
} else if (sc.Match("if")) {
|
||||
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
|
||||
bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
|
||||
const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
|
||||
preproc.StartSection(ifGood);
|
||||
} else if (sc.Match("else")) {
|
||||
// #else is shown as active if either preceding or following section is active
|
||||
// as that means that it contributed to the result.
|
||||
if (!preproc.CurrentIfTaken()) {
|
||||
// Inactive, may become active if parent scope active
|
||||
assert(sc.state == (SCE_C_PREPROCESSOR|inactiveFlag));
|
||||
preproc.InvertCurrentLevel();
|
||||
activitySet = preproc.IsInactive() ? activeFlag : 0;
|
||||
activitySet = preproc.ActiveState();
|
||||
// If following is active then show "else" as active
|
||||
if (!activitySet)
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
|
||||
} else if (!preproc.IsInactive()) {
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR);
|
||||
} else if (preproc.IsActive()) {
|
||||
// Active -> inactive
|
||||
assert(sc.state == SCE_C_PREPROCESSOR);
|
||||
preproc.InvertCurrentLevel();
|
||||
activitySet = preproc.IsInactive() ? activeFlag : 0;
|
||||
if (!activitySet)
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
|
||||
activitySet = preproc.ActiveState();
|
||||
// Continue to show "else" as active as it ends active section.
|
||||
}
|
||||
} else if (sc.Match("elif")) {
|
||||
// Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif
|
||||
// #elif is shown as active if either preceding or following section is active
|
||||
// as that means that it contributed to the result.
|
||||
if (!preproc.CurrentIfTaken()) {
|
||||
// Inactive, if expression true then may become active if parent scope active
|
||||
assert(sc.state == (SCE_C_PREPROCESSOR|inactiveFlag));
|
||||
// Similar to #if
|
||||
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
|
||||
bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
|
||||
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 4, true);
|
||||
const bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
|
||||
if (ifGood) {
|
||||
preproc.InvertCurrentLevel();
|
||||
activitySet = preproc.IsInactive() ? activeFlag : 0;
|
||||
activitySet = preproc.ActiveState();
|
||||
if (!activitySet)
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR);
|
||||
}
|
||||
} else if (!preproc.IsInactive()) {
|
||||
} else if (preproc.IsActive()) {
|
||||
// Active -> inactive
|
||||
assert(sc.state == SCE_C_PREPROCESSOR);
|
||||
preproc.InvertCurrentLevel();
|
||||
activitySet = preproc.IsInactive() ? activeFlag : 0;
|
||||
if (!activitySet)
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
|
||||
activitySet = preproc.ActiveState();
|
||||
// Continue to show "elif" as active as it ends active section.
|
||||
}
|
||||
} else if (sc.Match("endif")) {
|
||||
preproc.EndSection();
|
||||
activitySet = preproc.IsInactive() ? activeFlag : 0;
|
||||
activitySet = preproc.ActiveState();
|
||||
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
|
||||
} else if (sc.Match("define")) {
|
||||
if (options.updatePreprocessor && !preproc.IsInactive()) {
|
||||
if (options.updatePreprocessor && preproc.IsActive()) {
|
||||
std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);
|
||||
size_t startName = 0;
|
||||
while ((startName < restOfLine.length()) && IsSpaceOrTab(restOfLine[startName]))
|
||||
startName++;
|
||||
size_t endName = startName;
|
||||
while ((endName < restOfLine.length()) && setWord.Contains(static_cast<unsigned char>(restOfLine[endName])))
|
||||
while ((endName < restOfLine.length()) && setWord.Contains(restOfLine[endName]))
|
||||
endName++;
|
||||
std::string key = restOfLine.substr(startName, endName-startName);
|
||||
if ((endName < restOfLine.length()) && (restOfLine.at(endName) == '(')) {
|
||||
|
|
@ -1246,13 +1388,15 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
while ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue]))
|
||||
startValue++;
|
||||
std::string value = restOfLine.substr(startValue);
|
||||
if (OnlySpaceOrTab(value))
|
||||
value = "1"; // No value defaults to 1
|
||||
preprocessorDefinitions[key] = value;
|
||||
ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value));
|
||||
definitionsChanged = true;
|
||||
}
|
||||
}
|
||||
} else if (sc.Match("undef")) {
|
||||
if (options.updatePreprocessor && !preproc.IsInactive()) {
|
||||
if (options.updatePreprocessor && preproc.IsActive()) {
|
||||
const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false);
|
||||
std::vector<std::string> tokens = Tokenize(restOfLine);
|
||||
if (tokens.size() >= 1) {
|
||||
|
|
@ -1294,7 +1438,7 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
|
|||
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
const Sci_PositionU endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
bool inLineComment = false;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
|
|
@ -1309,12 +1453,12 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
|
|||
int style = MaskActive(initStyle);
|
||||
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
char ch = chNext;
|
||||
const char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
int stylePrev = style;
|
||||
const int stylePrev = style;
|
||||
style = styleNext;
|
||||
styleNext = MaskActive(styler.StyleAt(i + 1));
|
||||
bool atEOL = i == (lineStartNext-1);
|
||||
const bool atEOL = i == (lineStartNext-1);
|
||||
if ((style == SCE_C_COMMENTLINE) || (style == SCE_C_COMMENTLINEDOC))
|
||||
inLineComment = true;
|
||||
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) {
|
||||
|
|
@ -1334,7 +1478,7 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
} else {
|
||||
if ((ch == '/') && (chNext == '/')) {
|
||||
char chNext2 = styler.SafeGetCharAt(i + 2);
|
||||
const char chNext2 = styler.SafeGetCharAt(i + 2);
|
||||
if (chNext2 == '{') {
|
||||
levelNext++;
|
||||
} else if (chNext2 == '}') {
|
||||
|
|
@ -1433,6 +1577,7 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
|
|||
if (it != preprocessorDefinitions.end()) {
|
||||
val = "1";
|
||||
}
|
||||
tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 2);
|
||||
}
|
||||
tokens[i] = val;
|
||||
} else {
|
||||
|
|
@ -1441,11 +1586,11 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
|
|||
}
|
||||
|
||||
// Evaluate identifiers
|
||||
const size_t maxIterations = 100;
|
||||
constexpr size_t maxIterations = 100;
|
||||
size_t iterations = 0; // Limit number of iterations in case there is a recursive macro.
|
||||
for (size_t i = 0; (i<tokens.size()) && (iterations < maxIterations);) {
|
||||
iterations++;
|
||||
if (setWordStart.Contains(static_cast<unsigned char>(tokens[i][0]))) {
|
||||
if (setWordStart.Contains(tokens[i][0])) {
|
||||
SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i]);
|
||||
if (it != preprocessorDefinitions.end()) {
|
||||
// Tokenize value
|
||||
|
|
@ -1472,7 +1617,7 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
|
|||
macroTokens.erase(std::remove_if(macroTokens.begin(), macroTokens.end(), OnlySpaceOrTab), macroTokens.end());
|
||||
|
||||
for (size_t iMacro = 0; iMacro < macroTokens.size();) {
|
||||
if (setWordStart.Contains(static_cast<unsigned char>(macroTokens[iMacro][0]))) {
|
||||
if (setWordStart.Contains(macroTokens[iMacro][0])) {
|
||||
std::map<std::string, std::string>::const_iterator itFind = arguments.find(macroTokens[iMacro]);
|
||||
if (itFind != arguments.end()) {
|
||||
// TODO: Possible that value will be expression so should insert tokenized form
|
||||
|
|
@ -1495,8 +1640,8 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
|
|||
tokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end());
|
||||
}
|
||||
} else {
|
||||
// Identifier not found
|
||||
tokens.erase(tokens.begin() + i);
|
||||
// Identifier not found and value defaults to zero
|
||||
tokens[i] = "0";
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
|
|
@ -1533,18 +1678,20 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
|
|||
}
|
||||
|
||||
// Evaluate expressions in precedence order
|
||||
enum precedence { precArithmetic, precRelative, precLogical };
|
||||
for (int prec=precArithmetic; prec <= precLogical; prec++) {
|
||||
enum precedence { precMult, precAdd, precRelative
|
||||
, precLogical, /* end marker */ precLast };
|
||||
for (int prec = precMult; prec < precLast; prec++) {
|
||||
// Looking at 3 tokens at a time so end at 2 before end
|
||||
for (size_t k=0; (k+2)<tokens.size();) {
|
||||
char chOp = tokens[k+1][0];
|
||||
const char chOp = tokens[k+1][0];
|
||||
if (
|
||||
((prec==precArithmetic) && setArithmethicOp.Contains(chOp)) ||
|
||||
((prec==precMult) && setMultOp.Contains(chOp)) ||
|
||||
((prec==precAdd) && setAddOp.Contains(chOp)) ||
|
||||
((prec==precRelative) && setRelOp.Contains(chOp)) ||
|
||||
((prec==precLogical) && setLogicalOp.Contains(chOp))
|
||||
) {
|
||||
int valA = atoi(tokens[k].c_str());
|
||||
int valB = atoi(tokens[k+2].c_str());
|
||||
const int valA = atoi(tokens[k].c_str());
|
||||
const int valB = atoi(tokens[k+2].c_str());
|
||||
int result = 0;
|
||||
if (tokens[k+1] == "+")
|
||||
result = valA + valB;
|
||||
|
|
@ -1572,11 +1719,9 @@ void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens, const SymbolTabl
|
|||
result = valA || valB;
|
||||
else if (tokens[k+1] == "&&")
|
||||
result = valA && valB;
|
||||
char sResult[30];
|
||||
sprintf(sResult, "%d", result);
|
||||
std::vector<std::string>::iterator itInsert =
|
||||
tokens.erase(tokens.begin() + k, tokens.begin() + k + 3);
|
||||
tokens.insert(itInsert, sResult);
|
||||
tokens.insert(itInsert, std::to_string(result));
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
|
|
@ -1590,9 +1735,9 @@ std::vector<std::string> LexerCPP::Tokenize(const std::string &expr) const {
|
|||
const char *cp = expr.c_str();
|
||||
while (*cp) {
|
||||
std::string word;
|
||||
if (setWord.Contains(static_cast<unsigned char>(*cp))) {
|
||||
if (setWord.Contains(*cp)) {
|
||||
// Identifiers and numbers
|
||||
while (setWord.Contains(static_cast<unsigned char>(*cp))) {
|
||||
while (setWord.Contains(*cp)) {
|
||||
word += *cp;
|
||||
cp++;
|
||||
}
|
||||
|
|
@ -1601,17 +1746,17 @@ std::vector<std::string> LexerCPP::Tokenize(const std::string &expr) const {
|
|||
word += *cp;
|
||||
cp++;
|
||||
}
|
||||
} else if (setRelOp.Contains(static_cast<unsigned char>(*cp))) {
|
||||
} else if (setRelOp.Contains(*cp)) {
|
||||
word += *cp;
|
||||
cp++;
|
||||
if (setRelOp.Contains(static_cast<unsigned char>(*cp))) {
|
||||
if (setRelOp.Contains(*cp)) {
|
||||
word += *cp;
|
||||
cp++;
|
||||
}
|
||||
} else if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) {
|
||||
} else if (setLogicalOp.Contains(*cp)) {
|
||||
word += *cp;
|
||||
cp++;
|
||||
if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) {
|
||||
if (setLogicalOp.Contains(*cp)) {
|
||||
word += *cp;
|
||||
cp++;
|
||||
}
|
||||
|
|
@ -1631,7 +1776,7 @@ bool LexerCPP::EvaluateExpression(const std::string &expr, const SymbolTable &pr
|
|||
EvaluateTokens(tokens, preprocessorDefinitions);
|
||||
|
||||
// "0" or "" -> false else true
|
||||
bool isFalse = tokens.empty() ||
|
||||
const bool isFalse = tokens.empty() ||
|
||||
((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0"));
|
||||
return !isFalse;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// Scintilla source code edit control
|
||||
// Encoding: UTF-8
|
||||
/** @file LexCSS.cxx
|
||||
** Lexer for Cascading Style Sheets
|
||||
** Written by Jakub Vrána
|
||||
** Written by Jakub Vrána
|
||||
** Improved by Philippe Lhoste (CSS2)
|
||||
** Improved by Ross McKay (SCSS mode; see http://sass-lang.com/ )
|
||||
**/
|
||||
|
|
@ -31,9 +32,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
static inline bool IsAWordChar(const unsigned int ch) {
|
||||
|
|
@ -347,6 +346,7 @@ static void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position length, int ini
|
|||
case SCE_CSS_DEFAULT:
|
||||
if (isLessDocument) // give priority to pseudo elements
|
||||
break;
|
||||
// Falls through.
|
||||
case SCE_CSS_VALUE:
|
||||
lastStateVar = sc.state;
|
||||
sc.SetState(SCE_CSS_VARIABLE);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wcomma"
|
||||
#endif
|
||||
|
||||
// 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 == '_';}
|
||||
|
|
@ -46,9 +50,7 @@ static const int baseT[24] = {
|
|||
0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
|
||||
};
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_AS_EXTERNAL_LEXER
|
||||
/*
|
||||
|
|
@ -368,6 +370,7 @@ void ColouriseCamlDoc(
|
|||
break;
|
||||
}/* else
|
||||
// fall through for SML char literal (handle like string) */
|
||||
// Falls through.
|
||||
|
||||
case SCE_CAML_STRING:
|
||||
// [try to] interpret as [additional] [SML char/] string literal char
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static bool isCmakeNumber(char ch)
|
||||
{
|
||||
|
|
@ -87,10 +85,11 @@ static int calculateFoldCmake(Sci_PositionU start, Sci_PositionU end, int foldle
|
|||
|
||||
if ( CompareCaseInsensitive(s, "IF") == 0 || CompareCaseInsensitive(s, "WHILE") == 0
|
||||
|| CompareCaseInsensitive(s, "MACRO") == 0 || CompareCaseInsensitive(s, "FOREACH") == 0
|
||||
|| CompareCaseInsensitive(s, "ELSEIF") == 0 )
|
||||
|| CompareCaseInsensitive(s, "FUNCTION") == 0 || CompareCaseInsensitive(s, "ELSEIF") == 0)
|
||||
newFoldlevel++;
|
||||
else if ( CompareCaseInsensitive(s, "ENDIF") == 0 || CompareCaseInsensitive(s, "ENDWHILE") == 0
|
||||
|| CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0)
|
||||
|| CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0
|
||||
|| CompareCaseInsensitive(s, "ENDFUNCTION") == 0)
|
||||
newFoldlevel--;
|
||||
else if ( bElse && CompareCaseInsensitive(s, "ELSEIF") == 0 )
|
||||
newFoldlevel++;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Platform.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
|
@ -26,9 +27,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static bool IsSpaceEquiv(int state) {
|
||||
return (state == SCE_COFFEESCRIPT_DEFAULT
|
||||
|
|
@ -427,7 +426,7 @@ static void FoldCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
|
||||
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
|
||||
const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
|
||||
const int levelBeforeComments = std::max(indentCurrentLevel,levelAfterComments);
|
||||
|
||||
// Now set all the indent levels on the lines we skipped
|
||||
// Do this from end to start. Once we encounter one line
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColouriseConfDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColouriseNncrontabDoc(Sci_PositionU startPos, Sci_Position length, int, WordList
|
||||
*keywordLists[], Accessor &styler)
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#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 == '.' ||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/* Nested comments require keeping the value of the nesting level for every
|
||||
position in the document. But since scintilla always styles line by line,
|
||||
|
|
@ -145,7 +144,7 @@ struct OptionSetD : public OptionSet<OptionsD> {
|
|||
}
|
||||
};
|
||||
|
||||
class LexerD : public ILexer {
|
||||
class LexerD : public DefaultLexer {
|
||||
bool caseSensitive;
|
||||
WordList keywords;
|
||||
WordList keywords2;
|
||||
|
|
@ -158,34 +157,38 @@ class LexerD : public ILexer {
|
|||
OptionSetD osD;
|
||||
public:
|
||||
LexerD(bool caseSensitive_) :
|
||||
DefaultLexer("D", SCLEX_D),
|
||||
caseSensitive(caseSensitive_) {
|
||||
}
|
||||
virtual ~LexerD() {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osD.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osD.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osD.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osD.PropertyGet(key);
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osD.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include "LexerModule.h"
|
||||
/***************************************/
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/***********************************************/
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,9 @@
|
|||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
static const char *const DMISWordListDesc[] = {
|
||||
|
|
@ -38,7 +37,7 @@ static const char *const DMISWordListDesc[] = {
|
|||
};
|
||||
|
||||
|
||||
class LexerDMIS : public ILexer
|
||||
class LexerDMIS : public DefaultLexer
|
||||
{
|
||||
private:
|
||||
char *m_wordListSets;
|
||||
|
|
@ -56,33 +55,37 @@ class LexerDMIS : public ILexer
|
|||
LexerDMIS(void);
|
||||
virtual ~LexerDMIS(void);
|
||||
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int SCI_METHOD PropertyType(const char *) {
|
||||
int SCI_METHOD PropertyType(const char *) override {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeProperty(const char *) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *) override {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD PropertySet(const char *, const char *) {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *, const char *) override {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
const char * SCI_METHOD PropertyGet(const char *) override {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -90,9 +93,9 @@ class LexerDMIS : public ILexer
|
|||
return new LexerDMIS;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets();
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess);
|
||||
const char * SCI_METHOD DescribeWordListSets() override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -130,7 +133,7 @@ void SCI_METHOD LexerDMIS::InitWordListSets(void)
|
|||
}
|
||||
|
||||
|
||||
LexerDMIS::LexerDMIS(void) {
|
||||
LexerDMIS::LexerDMIS(void) : DefaultLexer("DMIS", SCLEX_DMIS) {
|
||||
this->InitWordListSets();
|
||||
|
||||
this->m_majorWords.Clear();
|
||||
|
|
|
|||
614
src/stc/scintilla/lexers/LexDataflex.cxx
Normal file
614
src/stc/scintilla/lexers/LexDataflex.cxx
Normal file
|
|
@ -0,0 +1,614 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexDataflex.cxx
|
||||
** Lexer for DataFlex.
|
||||
** Based on LexPascal.cxx
|
||||
** Written by Wil van Antwerpen, June 2019
|
||||
**/
|
||||
|
||||
/*
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
A few words about features of LexDataflex...
|
||||
|
||||
Generally speaking LexDataflex tries to support all available DataFlex features (up
|
||||
to DataFlex 19.1 at this time).
|
||||
|
||||
~ FOLDING:
|
||||
|
||||
Folding is supported in the following cases:
|
||||
|
||||
- Folding of stream-like comments
|
||||
- Folding of groups of consecutive line comments
|
||||
- Folding of preprocessor blocks (the following preprocessor blocks are
|
||||
supported: #IFDEF, #IFNDEF, #ENDIF and #HEADER / #ENDHEADER
|
||||
blocks),
|
||||
- Folding of code blocks on appropriate keywords (the following code blocks are
|
||||
supported: "begin, struct, type, case / end" blocks, class & object
|
||||
declarations and interface declarations)
|
||||
|
||||
Remarks:
|
||||
|
||||
- We pass 4 arrays to the lexer:
|
||||
1. The DataFlex keyword list, these are normal DataFlex keywords
|
||||
2. The Scope Open list, for example, begin / procedure / while
|
||||
3. The Scope Close list, for example, end / end_procedure / loop
|
||||
4. Operator list, for ex. + / - / * / Lt / iand
|
||||
These lists are all mutually exclusive, scope open words should not be in the keyword list and vice versa
|
||||
|
||||
- Folding of code blocks tries to handle all special cases in which folding
|
||||
should not occur.
|
||||
|
||||
~ KEYWORDS:
|
||||
|
||||
The list of keywords that can be used in dataflex.properties file (up to DataFlex
|
||||
19.1):
|
||||
|
||||
- Keywords: .. snipped .. see dataflex.properties file.
|
||||
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
|
||||
static void GetRangeLowered(Sci_PositionU start,
|
||||
Sci_PositionU end,
|
||||
Accessor &styler,
|
||||
char *s,
|
||||
Sci_PositionU len) {
|
||||
Sci_PositionU i = 0;
|
||||
while ((i < end - start + 1) && (i < len-1)) {
|
||||
s[i] = static_cast<char>(tolower(styler[start + i]));
|
||||
i++;
|
||||
}
|
||||
s[i] = '\0';
|
||||
}
|
||||
|
||||
static void GetForwardRangeLowered(Sci_PositionU start,
|
||||
CharacterSet &charSet,
|
||||
Accessor &styler,
|
||||
char *s,
|
||||
Sci_PositionU len) {
|
||||
Sci_PositionU i = 0;
|
||||
while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
|
||||
s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
|
||||
i++;
|
||||
}
|
||||
s[i] = '\0';
|
||||
|
||||
}
|
||||
|
||||
enum {
|
||||
stateInICode = 0x1000,
|
||||
stateSingleQuoteOpen = 0x2000,
|
||||
stateDoubleQuoteOpen = 0x4000,
|
||||
stateFoldInPreprocessor = 0x0100,
|
||||
stateFoldInCaseStatement = 0x0200,
|
||||
stateFoldInPreprocessorLevelMask = 0x00FF,
|
||||
stateFoldMaskAll = 0x0FFF
|
||||
};
|
||||
|
||||
|
||||
static bool IsFirstDataFlexWord(Sci_Position pos, Accessor &styler) {
|
||||
Sci_Position line = styler.GetLine(pos);
|
||||
Sci_Position start_pos = styler.LineStart(line);
|
||||
for (Sci_Position i = start_pos; i < pos; i++) {
|
||||
char ch = styler.SafeGetCharAt(i);
|
||||
if (!(ch == ' ' || ch == '\t'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool IsADataFlexField(int ch) {
|
||||
return (ch == '.');
|
||||
}
|
||||
|
||||
|
||||
size_t _strnlen(const char *s, size_t max) {
|
||||
const char *end = (const char*)memchr((void *)s, 0, max);
|
||||
return end ? (size_t)(end - s) : max;
|
||||
}
|
||||
|
||||
|
||||
static void ClassifyDataFlexWord(WordList *keywordlists[], StyleContext &sc, Accessor &styler) {
|
||||
WordList& keywords = *keywordlists[0];
|
||||
WordList& scopeOpen = *keywordlists[1];
|
||||
WordList& scopeClosed = *keywordlists[2];
|
||||
WordList& operators = *keywordlists[3];
|
||||
|
||||
char s[100];
|
||||
int oldState;
|
||||
int newState;
|
||||
size_t tokenlen;
|
||||
|
||||
oldState = sc.state;
|
||||
newState = oldState;
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
tokenlen = _strnlen(s,sizeof(s));
|
||||
if (keywords.InList(s)) {
|
||||
// keywords in DataFlex can be used as table column names (file.field) and as such they
|
||||
// should not be characterized as a keyword. So test for that.
|
||||
// for ex. somebody using date as field name.
|
||||
if (!IsADataFlexField(sc.GetRelative(-static_cast<int>(tokenlen+1)))) {
|
||||
newState = SCE_DF_WORD;
|
||||
}
|
||||
}
|
||||
if (oldState == newState) {
|
||||
if ((scopeOpen.InList(s) || scopeClosed.InList(s)) && (strcmp(s, "for") != 0) && (strcmp(s, "repeat") != 0)) {
|
||||
// scope words in DataFlex can be used as table column names (file.field) and as such they
|
||||
// should not be characterized as a scope word. So test for that.
|
||||
// for ex. somebody using procedure for field name.
|
||||
if (!IsADataFlexField(sc.GetRelative(-static_cast<int>(tokenlen+1)))) {
|
||||
newState = SCE_DF_SCOPEWORD;
|
||||
}
|
||||
}
|
||||
// no code folding on the next words, but just want to paint them like keywords (as they are) (??? doesn't the code to the opposite?)
|
||||
if (strcmp(s, "if") == 0 ||
|
||||
strcmp(s, "ifnot") == 0 ||
|
||||
strcmp(s, "case") == 0 ||
|
||||
strcmp(s, "else") == 0 ) {
|
||||
newState = SCE_DF_SCOPEWORD;
|
||||
}
|
||||
}
|
||||
if (oldState != newState && newState == SCE_DF_WORD) {
|
||||
// a for loop must have for at the start of the line, for is also used in "define abc for 123"
|
||||
if ( (strcmp(s, "for") == 0) && (IsFirstDataFlexWord(sc.currentPos-3, styler)) ) {
|
||||
newState = SCE_DF_SCOPEWORD;
|
||||
}
|
||||
}
|
||||
if (oldState != newState && newState == SCE_DF_WORD) {
|
||||
// a repeat loop must have repeat at the start of the line, repeat is also used in 'move (repeat("d",5)) to sFoo'
|
||||
if ( (strcmp(s, "repeat") == 0) && (IsFirstDataFlexWord(sc.currentPos-6, styler)) ) {
|
||||
newState = SCE_DF_SCOPEWORD;
|
||||
}
|
||||
}
|
||||
if (oldState == newState) {
|
||||
if (operators.InList(s)) {
|
||||
newState = SCE_DF_OPERATOR;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldState != newState) {
|
||||
sc.ChangeState(newState);
|
||||
}
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
|
||||
static void ColouriseDataFlexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
// bool bSmartHighlighting = styler.GetPropertyInt("lexer.dataflex.smart.highlighting", 1) != 0;
|
||||
|
||||
CharacterSet setWordStart(CharacterSet::setAlpha, "_$#@", 0x80, true);
|
||||
CharacterSet setWord(CharacterSet::setAlphaNum, "_$#@", 0x80, true);
|
||||
CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
|
||||
CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
|
||||
CharacterSet setOperator(CharacterSet::setNone, "*+-/<=>^");
|
||||
|
||||
Sci_Position curLine = styler.GetLine(startPos);
|
||||
int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
|
||||
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
if (sc.atLineEnd) {
|
||||
// Update the line state, so it can be seen by next line
|
||||
curLine = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(curLine, curLineState);
|
||||
}
|
||||
|
||||
// Determine if the current state should terminate.
|
||||
switch (sc.state) {
|
||||
case SCE_DF_NUMBER:
|
||||
if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
} else if (sc.ch == '-' || sc.ch == '+') {
|
||||
if (sc.chPrev != 'E' && sc.chPrev != 'e') {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_DF_IDENTIFIER:
|
||||
if (!setWord.Contains(sc.ch)) {
|
||||
ClassifyDataFlexWord(keywordlists, sc, styler);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_HEXNUMBER:
|
||||
if (!(setHexNumber.Contains(sc.ch) || sc.ch == 'I') ) { // in |CI$22a we also want to color the "I"
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_METATAG:
|
||||
if (sc.atLineStart || sc.chPrev == '}') {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_PREPROCESSOR:
|
||||
if (sc.atLineStart || IsASpaceOrTab(sc.ch)) {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_IMAGE:
|
||||
if (sc.atLineStart && sc.Match("/*")) {
|
||||
sc.Forward(); // these characters are still part of the DF Image
|
||||
sc.ForwardSetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_PREPROCESSOR2:
|
||||
// we don't have inline comments or preprocessor2 commands
|
||||
//if (sc.Match('*', ')')) {
|
||||
// sc.Forward();
|
||||
// sc.ForwardSetState(SCE_DF_DEFAULT);
|
||||
//}
|
||||
break;
|
||||
case SCE_DF_COMMENTLINE:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_STRING:
|
||||
if (sc.atLineEnd) {
|
||||
sc.ChangeState(SCE_DF_STRINGEOL);
|
||||
} else if (sc.ch == '\'' && sc.chNext == '\'') {
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '\"' && sc.chNext == '\"') {
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '\'' || sc.ch == '\"') {
|
||||
if (sc.ch == '\'' && (curLineState & stateSingleQuoteOpen) ) {
|
||||
curLineState &= ~(stateSingleQuoteOpen);
|
||||
sc.ForwardSetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
else if (sc.ch == '\"' && (curLineState & stateDoubleQuoteOpen) ) {
|
||||
curLineState &= ~(stateDoubleQuoteOpen);
|
||||
sc.ForwardSetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_DF_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_DF_SCOPEWORD:
|
||||
//if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
|
||||
// sc.SetState(SCE_DF_DEFAULT);
|
||||
//}
|
||||
break;
|
||||
case SCE_DF_OPERATOR:
|
||||
// if (bSmartHighlighting && sc.chPrev == ';') {
|
||||
// curLineState &= ~(stateInProperty | stateInExport);
|
||||
// }
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
break;
|
||||
case SCE_DF_ICODE:
|
||||
if (sc.atLineStart || IsASpace(sc.ch) || isoperator(sc.ch)) {
|
||||
sc.SetState(SCE_DF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_DF_DEFAULT) {
|
||||
if (IsADigit(sc.ch)) {
|
||||
sc.SetState(SCE_DF_NUMBER);
|
||||
} else if (sc.Match('/', '/') || sc.Match("#REM")) {
|
||||
sc.SetState(SCE_DF_COMMENTLINE);
|
||||
} else if ((sc.ch == '#' && !sc.Match("#REM")) && IsFirstDataFlexWord(sc.currentPos, styler)) {
|
||||
sc.SetState(SCE_DF_PREPROCESSOR);
|
||||
// || (sc.ch == '|' && sc.chNext == 'C' && sc.GetRelativeCharacter(2) == 'I' && sc.GetRelativeCharacter(3) == '$') ) {
|
||||
} else if ((sc.ch == '$' && ((!setWord.Contains(sc.chPrev)) || sc.chPrev == 'I' ) ) || (sc.Match("|CI$")) ) {
|
||||
sc.SetState(SCE_DF_HEXNUMBER); // start with $ and previous character not in a..zA..Z0..9 excluding "I" OR start with |CI$
|
||||
} else if (setWordStart.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_DF_IDENTIFIER);
|
||||
} else if (sc.ch == '{') {
|
||||
sc.SetState(SCE_DF_METATAG);
|
||||
//} else if (sc.Match("(*$")) {
|
||||
// sc.SetState(SCE_DF_PREPROCESSOR2);
|
||||
} else if (sc.ch == '/' && setWord.Contains(sc.chNext) && sc.atLineStart) {
|
||||
sc.SetState(SCE_DF_IMAGE);
|
||||
// sc.Forward(); // Eat the * so it isn't used for the end of the comment
|
||||
} else if (sc.ch == '\'' || sc.ch == '\"') {
|
||||
if (sc.ch == '\'' && !(curLineState & stateDoubleQuoteOpen)) {
|
||||
curLineState |= stateSingleQuoteOpen;
|
||||
} else if (sc.ch == '\"' && !(curLineState & stateSingleQuoteOpen)) {
|
||||
curLineState |= stateDoubleQuoteOpen;
|
||||
}
|
||||
sc.SetState(SCE_DF_STRING);
|
||||
} else if (setOperator.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_DF_OPERATOR);
|
||||
// } else if (curLineState & stateInICode) {
|
||||
// ICode start ! in a string followed by close string mark is not icode
|
||||
} else if ((sc.ch == '!') && !(sc.ch == '!' && ((sc.chNext == '\"') || (sc.ch == '\'')) )) {
|
||||
sc.SetState(SCE_DF_ICODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.state == SCE_DF_IDENTIFIER && setWord.Contains(sc.chPrev)) {
|
||||
ClassifyDataFlexWord(keywordlists, sc, styler);
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
static bool IsStreamCommentStyle(int style) {
|
||||
return style == SCE_DF_IMAGE;
|
||||
}
|
||||
|
||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
|
||||
Sci_Position pos = styler.LineStart(line);
|
||||
Sci_Position eolPos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position 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_DF_COMMENTLINE) {
|
||||
return true;
|
||||
} else if (!IsASpaceOrTab(ch)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
|
||||
return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
|
||||
}
|
||||
|
||||
static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
|
||||
lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
|
||||
lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
|
||||
}
|
||||
|
||||
static int ClassifyDataFlexPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
|
||||
Sci_PositionU startPos, Accessor &styler) {
|
||||
CharacterSet setWord(CharacterSet::setAlpha);
|
||||
|
||||
char s[100]; // Size of the longest possible keyword + one additional character + null
|
||||
GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
|
||||
size_t iLen = _strnlen(s,sizeof(s));
|
||||
size_t iWordSize = 0;
|
||||
|
||||
unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
|
||||
|
||||
if (strcmp(s, "command") == 0 ||
|
||||
// The #if/#ifdef etcetera commands are not currently foldable as it is easy to write code that
|
||||
// breaks the collaps logic, so we keep things simple and not include that for now.
|
||||
strcmp(s, "header") == 0) {
|
||||
nestLevel++;
|
||||
SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
|
||||
lineFoldStateCurrent |= stateFoldInPreprocessor;
|
||||
levelCurrent++;
|
||||
iWordSize = iLen;
|
||||
} else if (strcmp(s, "endcommand") == 0 ||
|
||||
strcmp(s, "endheader") == 0) {
|
||||
nestLevel--;
|
||||
SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
|
||||
if (nestLevel == 0) {
|
||||
lineFoldStateCurrent &= ~stateFoldInPreprocessor;
|
||||
}
|
||||
levelCurrent--;
|
||||
iWordSize = iLen;
|
||||
if (levelCurrent < SC_FOLDLEVELBASE) {
|
||||
levelCurrent = SC_FOLDLEVELBASE;
|
||||
}
|
||||
}
|
||||
return static_cast<int>(iWordSize);
|
||||
}
|
||||
|
||||
|
||||
static void ClassifyDataFlexWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
|
||||
Sci_PositionU lastStart, Sci_PositionU currentPos, WordList *[], Accessor &styler) {
|
||||
char s[100];
|
||||
|
||||
// property fold.dataflex.compilerlist
|
||||
// Set to 1 for enabling the code folding feature in *.prn files
|
||||
bool foldPRN = styler.GetPropertyInt("fold.dataflex.compilerlist",0) != 0;
|
||||
|
||||
GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
|
||||
|
||||
if (strcmp(s, "case") == 0) {
|
||||
lineFoldStateCurrent |= stateFoldInCaseStatement;
|
||||
} else if (strcmp(s, "begin") == 0) {
|
||||
levelCurrent++;
|
||||
} else if (strcmp(s, "for") == 0 ||
|
||||
strcmp(s, "while") == 0 ||
|
||||
strcmp(s, "repeat") == 0 ||
|
||||
strcmp(s, "for_all") == 0 ||
|
||||
strcmp(s, "struct") == 0 ||
|
||||
strcmp(s, "type") == 0 ||
|
||||
strcmp(s, "begin_row") == 0 ||
|
||||
strcmp(s, "item_list") == 0 ||
|
||||
strcmp(s, "begin_constraints") == 0 ||
|
||||
strcmp(s, "begin_transaction") == 0 ||
|
||||
strcmp(s, "enum_list") == 0 ||
|
||||
strcmp(s, "class") == 0 ||
|
||||
strcmp(s, "object") == 0 ||
|
||||
strcmp(s, "cd_popup_object") == 0 ||
|
||||
strcmp(s, "procedure") == 0 ||
|
||||
strcmp(s, "procedure_section") == 0 ||
|
||||
strcmp(s, "function") == 0 ) {
|
||||
if ((IsFirstDataFlexWord(lastStart, styler )) || foldPRN) {
|
||||
levelCurrent++;
|
||||
}
|
||||
} else if (strcmp(s, "end") == 0) { // end is not always the first keyword, for example "case end"
|
||||
levelCurrent--;
|
||||
if (levelCurrent < SC_FOLDLEVELBASE) {
|
||||
levelCurrent = SC_FOLDLEVELBASE;
|
||||
}
|
||||
} else if (strcmp(s, "loop") == 0 ||
|
||||
strcmp(s, "until") == 0 ||
|
||||
strcmp(s, "end_class") == 0 ||
|
||||
strcmp(s, "end_object") == 0 ||
|
||||
strcmp(s, "cd_end_object") == 0 ||
|
||||
strcmp(s, "end_procedure") == 0 ||
|
||||
strcmp(s, "end_function") == 0 ||
|
||||
strcmp(s, "end_for_all") == 0 ||
|
||||
strcmp(s, "end_struct") == 0 ||
|
||||
strcmp(s, "end_type") == 0 ||
|
||||
strcmp(s, "end_row") == 0 ||
|
||||
strcmp(s, "end_item_list") == 0 ||
|
||||
strcmp(s, "end_constraints") == 0 ||
|
||||
strcmp(s, "end_transaction") == 0 ||
|
||||
strcmp(s, "end_enum_list") == 0 ) {
|
||||
// lineFoldStateCurrent &= ~stateFoldInRecord;
|
||||
if ((IsFirstDataFlexWord(lastStart, styler )) || foldPRN) {
|
||||
levelCurrent--;
|
||||
if (levelCurrent < SC_FOLDLEVELBASE) {
|
||||
levelCurrent = SC_FOLDLEVELBASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void ClassifyDataFlexMetaDataFoldPoint(int &levelCurrent,
|
||||
Sci_PositionU lastStart, Sci_PositionU currentPos, WordList *[], Accessor &styler) {
|
||||
char s[100];
|
||||
|
||||
GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
|
||||
|
||||
if (strcmp(s, "#beginsection") == 0) {
|
||||
levelCurrent++;
|
||||
} else if (strcmp(s, "#endsection") == 0) {
|
||||
levelCurrent--;
|
||||
if (levelCurrent < SC_FOLDLEVELBASE) {
|
||||
levelCurrent = SC_FOLDLEVELBASE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void FoldDataFlexDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
|
||||
bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
int levelCurrent = levelPrev;
|
||||
int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int style = initStyle;
|
||||
int iWordSize;
|
||||
|
||||
Sci_Position lastStart = 0;
|
||||
CharacterSet setWord(CharacterSet::setAlphaNum, "_$#@", 0x80, true);
|
||||
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
int stylePrev = style;
|
||||
style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
|
||||
if (foldComment && IsStreamCommentStyle(style)) {
|
||||
if (!IsStreamCommentStyle(stylePrev)) {
|
||||
levelCurrent++;
|
||||
} else if (!IsStreamCommentStyle(styleNext)) {
|
||||
levelCurrent--;
|
||||
}
|
||||
}
|
||||
if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
|
||||
{
|
||||
if (!IsCommentLine(lineCurrent - 1, styler)
|
||||
&& IsCommentLine(lineCurrent + 1, styler))
|
||||
levelCurrent++;
|
||||
else if (IsCommentLine(lineCurrent - 1, styler)
|
||||
&& !IsCommentLine(lineCurrent+1, styler))
|
||||
levelCurrent--;
|
||||
}
|
||||
if (foldPreprocessor) {
|
||||
if (style == SCE_DF_PREPROCESSOR) {
|
||||
iWordSize = ClassifyDataFlexPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 1, styler);
|
||||
//} else if (style == SCE_DF_PREPROCESSOR2 && ch == '(' && chNext == '*'
|
||||
// && styler.SafeGetCharAt(i + 2) == '$') {
|
||||
// ClassifyDataFlexPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
|
||||
i = i + iWordSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (stylePrev != SCE_DF_SCOPEWORD && style == SCE_DF_SCOPEWORD)
|
||||
{
|
||||
// Store last word start point.
|
||||
lastStart = i;
|
||||
}
|
||||
if (stylePrev == SCE_DF_SCOPEWORD) {
|
||||
if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
|
||||
ClassifyDataFlexWordFoldPoint(levelCurrent, lineFoldStateCurrent, lastStart, i, keywordlists, styler);
|
||||
}
|
||||
}
|
||||
|
||||
if (stylePrev == SCE_DF_METATAG && ch == '#')
|
||||
{
|
||||
// Store last word start point.
|
||||
lastStart = i;
|
||||
}
|
||||
if (stylePrev == SCE_DF_METATAG) {
|
||||
if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
|
||||
ClassifyDataFlexMetaDataFoldPoint(levelCurrent, lastStart, i, keywordlists, styler);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsASpace(ch))
|
||||
visibleChars++;
|
||||
|
||||
if (atEOL) {
|
||||
int lev = levelPrev;
|
||||
if (visibleChars == 0 && foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if ((levelCurrent > levelPrev) && (visibleChars > 0))
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
|
||||
styler.SetLineState(lineCurrent, newLineState);
|
||||
lineCurrent++;
|
||||
levelPrev = levelCurrent;
|
||||
visibleChars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't reach the EOL in previous loop, store line level and whitespace information.
|
||||
// The rest will be filled in later...
|
||||
int lev = levelPrev;
|
||||
if (visibleChars == 0 && foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
|
||||
static const char * const dataflexWordListDesc[] = {
|
||||
"Keywords",
|
||||
"Scope open",
|
||||
"Scope close",
|
||||
"Operators",
|
||||
0
|
||||
};
|
||||
|
||||
LexerModule lmDataflex(SCLEX_DATAFLEX, ColouriseDataFlexDoc, "dataflex", FoldDataFlexDoc, dataflexWordListDesc);
|
||||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
return (styler[i] == '\n') ||
|
||||
|
|
@ -51,8 +49,10 @@ static void ColouriseDiffLine(char *lineBuffer, Sci_Position endLine, Accessor &
|
|||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||
else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
|
||||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||
else
|
||||
else if (lineBuffer[3] == ' ')
|
||||
styler.ColourTo(endLine, SCE_DIFF_HEADER);
|
||||
else
|
||||
styler.ColourTo(endLine, SCE_DIFF_DELETED);
|
||||
} else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
|
||||
// I don't know of any diff where "+++ " is a position marker, but for
|
||||
// consistency, do the same as with "--- " and "*** ".
|
||||
|
|
@ -78,6 +78,14 @@ static void ColouriseDiffLine(char *lineBuffer, Sci_Position endLine, Accessor &
|
|||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||
} else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') {
|
||||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||
} else if (0 == strncmp(lineBuffer, "++", 2)) {
|
||||
styler.ColourTo(endLine, SCE_DIFF_PATCH_ADD);
|
||||
} else if (0 == strncmp(lineBuffer, "+-", 2)) {
|
||||
styler.ColourTo(endLine, SCE_DIFF_PATCH_DELETE);
|
||||
} else if (0 == strncmp(lineBuffer, "-+", 2)) {
|
||||
styler.ColourTo(endLine, SCE_DIFF_REMOVED_PATCH_ADD);
|
||||
} else if (0 == strncmp(lineBuffer, "--", 2)) {
|
||||
styler.ColourTo(endLine, SCE_DIFF_REMOVED_PATCH_DELETE);
|
||||
} else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
|
||||
styler.ColourTo(endLine, SCE_DIFF_DELETED);
|
||||
} else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
|
||||
|
|
@ -124,7 +132,7 @@ static void FoldDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordLi
|
|||
int nextLevel;
|
||||
|
||||
do {
|
||||
int lineType = styler.StyleAt(curLineStart);
|
||||
const int lineType = styler.StyleAt(curLineStart);
|
||||
if (lineType == SCE_DIFF_COMMAND)
|
||||
nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
|
||||
else if (lineType == SCE_DIFF_HEADER)
|
||||
|
|
|
|||
|
|
@ -42,9 +42,7 @@
|
|||
#define SET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
#define SET_DIGITS "0123456789"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static bool IsSpaceEquiv(int state) {
|
||||
switch (state) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Scintilla Lexer for EDIFACT
|
||||
// @file LexEDIFACT.cxx
|
||||
// Written by Iain Clarke, IMCSoft & Inobiz AB.
|
||||
// EDIFACT documented here: https://www.unece.org/cefact/edifact/welcome.html
|
||||
// and more readably here: https://en.wikipedia.org/wiki/EDIFACT
|
||||
|
|
@ -12,18 +13,19 @@
|
|||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "LexAccessor.h"
|
||||
#include "LexerModule.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
class LexerEDIFACT : public ILexer
|
||||
class LexerEDIFACT : public DefaultLexer
|
||||
{
|
||||
public:
|
||||
LexerEDIFACT();
|
||||
|
|
@ -33,48 +35,72 @@ public:
|
|||
return new LexerEDIFACT;
|
||||
}
|
||||
|
||||
virtual int SCI_METHOD Version() const
|
||||
int SCI_METHOD Version() const override
|
||||
{
|
||||
return lvOriginal;
|
||||
return lvIdentity;
|
||||
}
|
||||
virtual void SCI_METHOD Release()
|
||||
void SCI_METHOD Release() override
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD PropertyNames()
|
||||
const char * SCI_METHOD PropertyNames() override
|
||||
{
|
||||
return "fold";
|
||||
return "fold\nlexer.edifact.highlight.un.all";
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *)
|
||||
int SCI_METHOD PropertyType(const char *) override
|
||||
{
|
||||
return SC_TYPE_BOOLEAN; // Only one property!
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name)
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override
|
||||
{
|
||||
if (strcmp(name, "fold"))
|
||||
return NULL;
|
||||
return "Whether to apply folding to document or not";
|
||||
if (!strcmp(name, "fold"))
|
||||
return "Whether to apply folding to document or not";
|
||||
if (!strcmp(name, "lexer.edifact.highlight.un.all"))
|
||||
return "Whether to apply UN* highlighting to all UN segments, or just to UNH";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual Sci_Position SCI_METHOD PropertySet(const char *key, const char *val)
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override
|
||||
{
|
||||
if (strcmp(key, "fold"))
|
||||
return -1;
|
||||
m_bFold = strcmp(val, "0") ? true : false;
|
||||
return 0;
|
||||
if (!strcmp(key, "fold"))
|
||||
{
|
||||
m_bFold = strcmp(val, "0") ? true : false;
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(key, "lexer.edifact.highlight.un.all")) // GetProperty
|
||||
{
|
||||
m_bHighlightAllUN = strcmp(val, "0") ? true : false;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets()
|
||||
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override
|
||||
{
|
||||
m_lastPropertyValue = "";
|
||||
if (!strcmp(key, "fold"))
|
||||
{
|
||||
m_lastPropertyValue = m_bFold ? "1" : "0";
|
||||
}
|
||||
if (!strcmp(key, "lexer.edifact.highlight.un.all")) // GetProperty
|
||||
{
|
||||
m_lastPropertyValue = m_bHighlightAllUN ? "1" : "0";
|
||||
}
|
||||
return m_lastPropertyValue.c_str();
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
virtual Sci_Position SCI_METHOD WordListSet(int, const char *)
|
||||
Sci_Position SCI_METHOD WordListSet(int, const char *) override
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
virtual void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess);
|
||||
virtual void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess);
|
||||
virtual void * SCI_METHOD PrivateCall(int, void *)
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void * SCI_METHOD PrivateCall(int, void *) override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -86,11 +112,18 @@ protected:
|
|||
int DetectSegmentHeader(char SegmentHeader[3]) const;
|
||||
|
||||
bool m_bFold;
|
||||
|
||||
// property lexer.edifact.highlight.un.all
|
||||
// Set to 0 to highlight only UNA segments, or 1 to highlight all UNx segments.
|
||||
bool m_bHighlightAllUN;
|
||||
|
||||
char m_chComponent;
|
||||
char m_chData;
|
||||
char m_chDecimal;
|
||||
char m_chRelease;
|
||||
char m_chSegment;
|
||||
|
||||
std::string m_lastPropertyValue;
|
||||
};
|
||||
|
||||
LexerModule lmEDIFACT(SCLEX_EDIFACT, LexerEDIFACT::Factory, "edifact");
|
||||
|
|
@ -101,9 +134,10 @@ LexerModule lmEDIFACT(SCLEX_EDIFACT, LexerEDIFACT::Factory, "edifact");
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LexerEDIFACT::LexerEDIFACT()
|
||||
LexerEDIFACT::LexerEDIFACT() : DefaultLexer("edifact", SCLEX_EDIFACT)
|
||||
{
|
||||
m_bFold = false;
|
||||
m_bHighlightAllUN = false;
|
||||
m_chComponent = ':';
|
||||
m_chData = '+';
|
||||
m_chDecimal = '.';
|
||||
|
|
@ -111,9 +145,9 @@ LexerEDIFACT::LexerEDIFACT()
|
|||
m_chSegment = '\'';
|
||||
}
|
||||
|
||||
void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess)
|
||||
void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)
|
||||
{
|
||||
Sci_PositionU posFinish = startPos + lengthDoc;
|
||||
Sci_PositionU posFinish = startPos + length;
|
||||
InitialiseFromUNA(pAccess, posFinish);
|
||||
|
||||
// Look backwards for a ' or a document beginning
|
||||
|
|
@ -191,40 +225,85 @@ void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDoc
|
|||
pAccess->SetStyleFor(posFinish - posSegmentStart, SCE_EDI_BADSEGMENT);
|
||||
}
|
||||
|
||||
void LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess)
|
||||
void LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess)
|
||||
{
|
||||
if (!m_bFold)
|
||||
return;
|
||||
|
||||
// Fold at UNx lines. ie, UNx segments = 0, other segments = 1.
|
||||
// There's no sub folding, so we can be quite simple.
|
||||
Sci_Position endPos = startPos + lengthDoc;
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
startPos = FindPreviousEnd(pAccess, startPos);
|
||||
char c;
|
||||
char SegmentHeader[4] = { 0 };
|
||||
|
||||
int iIndentPrevious = 0;
|
||||
Sci_Position lineLast = pAccess->LineFromPosition(endPos);
|
||||
bool AwaitingSegment = true;
|
||||
Sci_PositionU currLine = pAccess->LineFromPosition(startPos);
|
||||
int levelCurrentStyle = SC_FOLDLEVELBASE;
|
||||
if (currLine > 0)
|
||||
levelCurrentStyle = pAccess->GetLevel(currLine - 1); // bottom 12 bits are level
|
||||
int indentCurrent = levelCurrentStyle & SC_FOLDLEVELNUMBERMASK;
|
||||
int indentNext = indentCurrent;
|
||||
|
||||
for (Sci_Position lineCurrent = pAccess->LineFromPosition(startPos); lineCurrent <= lineLast; lineCurrent++)
|
||||
while (startPos < endPos)
|
||||
{
|
||||
Sci_Position posLineStart = pAccess->LineStart(lineCurrent);
|
||||
posLineStart = ForwardPastWhitespace(pAccess, posLineStart, endPos);
|
||||
Sci_Position lineDataStart = pAccess->LineFromPosition(posLineStart);
|
||||
// Fill in whitespace lines?
|
||||
for (; lineCurrent < lineDataStart; lineCurrent++)
|
||||
pAccess->SetLevel(lineCurrent, SC_FOLDLEVELBASE | SC_FOLDLEVELWHITEFLAG | iIndentPrevious);
|
||||
pAccess->GetCharRange(SegmentHeader, posLineStart, 3);
|
||||
//if (DetectSegmentHeader(SegmentHeader) == SCE_EDI_BADSEGMENT) // Abort if this is not a proper segment header
|
||||
pAccess->GetCharRange(&c, startPos, 1);
|
||||
switch (c)
|
||||
{
|
||||
case '\t':
|
||||
case '\r':
|
||||
case ' ':
|
||||
startPos++;
|
||||
continue;
|
||||
case '\n':
|
||||
currLine = pAccess->LineFromPosition(startPos);
|
||||
pAccess->SetLevel(currLine, levelCurrentStyle | indentCurrent);
|
||||
startPos++;
|
||||
levelCurrentStyle = SC_FOLDLEVELBASE;
|
||||
indentCurrent = indentNext;
|
||||
continue;
|
||||
}
|
||||
if (c == m_chRelease)
|
||||
{
|
||||
startPos += 2;
|
||||
continue;
|
||||
}
|
||||
if (c == m_chSegment)
|
||||
{
|
||||
AwaitingSegment = true;
|
||||
startPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int level = 0;
|
||||
if (memcmp(SegmentHeader, "UNH", 3) == 0) // UNH starts blocks
|
||||
level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
|
||||
// Check for UNA,B and Z. All others are inside messages
|
||||
else if (!memcmp(SegmentHeader, "UNA", 3) || !memcmp(SegmentHeader, "UNB", 3) || !memcmp(SegmentHeader, "UNZ", 3))
|
||||
level = SC_FOLDLEVELBASE;
|
||||
else
|
||||
level = SC_FOLDLEVELBASE | 1;
|
||||
pAccess->SetLevel(lineCurrent, level);
|
||||
iIndentPrevious = level & SC_FOLDLEVELNUMBERMASK;
|
||||
if (!AwaitingSegment)
|
||||
{
|
||||
startPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Segment!
|
||||
pAccess->GetCharRange(SegmentHeader, startPos, 3);
|
||||
if (SegmentHeader[0] != 'U' || SegmentHeader[1] != 'N')
|
||||
{
|
||||
startPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
AwaitingSegment = false;
|
||||
switch (SegmentHeader[2])
|
||||
{
|
||||
case 'H':
|
||||
case 'G':
|
||||
indentNext++;
|
||||
levelCurrentStyle = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
case 'E':
|
||||
if (indentNext > 0)
|
||||
indentNext--;
|
||||
break;
|
||||
}
|
||||
|
||||
startPos += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -295,9 +374,14 @@ int LexerEDIFACT::DetectSegmentHeader(char SegmentHeader[3]) const
|
|||
SegmentHeader[2] < 'A' || SegmentHeader[2] > 'Z')
|
||||
return SCE_EDI_BADSEGMENT;
|
||||
|
||||
if (memcmp(SegmentHeader, "UNA", 3) == 0)
|
||||
if (!memcmp(SegmentHeader, "UNA", 3))
|
||||
return SCE_EDI_UNA;
|
||||
if (memcmp(SegmentHeader, "UNH", 3) == 0)
|
||||
|
||||
if (m_bHighlightAllUN && !memcmp(SegmentHeader, "UN", 2))
|
||||
return SCE_EDI_UNH;
|
||||
else if (!memcmp(SegmentHeader, "UNH", 3))
|
||||
return SCE_EDI_UNH;
|
||||
else if (!memcmp(SegmentHeader, "UNG", 3))
|
||||
return SCE_EDI_UNH;
|
||||
|
||||
return SCE_EDI_SEGMENTSTART;
|
||||
|
|
@ -315,3 +399,5 @@ Sci_Position LexerEDIFACT::FindPreviousEnd(IDocument *pAccess, Sci_Position star
|
|||
// We didn't find a ', so just go with the beginning
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexESCRIPT.cxx
|
||||
/** @file LexEScript.cxx
|
||||
** Lexer for ESCRIPT
|
||||
**/
|
||||
// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)
|
||||
|
|
@ -22,9 +22,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool isEiffelOperator(unsigned int ch) {
|
||||
// '.' left out as it is used to make up numbers
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
// Scintilla source code edit control
|
||||
// Encoding: UTF-8
|
||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
/** @file LexErlang.cxx
|
||||
** Lexer for Erlang.
|
||||
** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
|
||||
** Originally wrote by Peter-Henry Mander,
|
||||
** based on Matlab lexer by José Fonseca.
|
||||
** based on Matlab lexer by José Fonseca.
|
||||
**/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
@ -26,9 +27,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static int is_radix(int radix, int ch) {
|
||||
int digit;
|
||||
|
|
@ -116,6 +115,7 @@ static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
}
|
||||
// V--- Falling through!
|
||||
// Falls through.
|
||||
case COMMENT_FUNCTION : {
|
||||
if (sc.ch != '%') {
|
||||
to_late_to_comment = true;
|
||||
|
|
@ -128,6 +128,7 @@ static void ColouriseErlangDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
}
|
||||
// V--- Falling through!
|
||||
// Falls through.
|
||||
case COMMENT_MODULE : {
|
||||
if (parse_state != COMMENT) {
|
||||
// Search for comment documentation
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
|
@ -23,32 +25,45 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static bool strstart(const char *haystack, const char *needle) {
|
||||
namespace {
|
||||
|
||||
bool strstart(const char *haystack, const char *needle) noexcept {
|
||||
return strncmp(haystack, needle, strlen(needle)) == 0;
|
||||
}
|
||||
|
||||
static bool Is0To9(char ch) {
|
||||
constexpr bool Is0To9(char ch) noexcept {
|
||||
return (ch >= '0') && (ch <= '9');
|
||||
}
|
||||
|
||||
static bool Is1To9(char ch) {
|
||||
constexpr bool Is1To9(char ch) noexcept {
|
||||
return (ch >= '1') && (ch <= '9');
|
||||
}
|
||||
|
||||
static bool IsAlphabetic(int ch) {
|
||||
bool IsAlphabetic(int ch) {
|
||||
return IsASCII(ch) && isalpha(ch);
|
||||
}
|
||||
|
||||
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
return (styler[i] == '\n') ||
|
||||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
|
||||
}
|
||||
|
||||
static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLine, Sci_Position &startValue) {
|
||||
bool IsGccExcerpt(const char *s) noexcept {
|
||||
while (*s) {
|
||||
if (s[0] == ' ' && s[1] == '|' && (s[2] == ' ' || s[2] == '+')) {
|
||||
return true;
|
||||
}
|
||||
if (!(s[0] == ' ' || s[0] == '+' || Is0To9(s[0]))) {
|
||||
return false;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLine, Sci_Position &startValue) {
|
||||
if (lineBuffer[0] == '>') {
|
||||
// Command or return status
|
||||
return SCE_ERR_CMD;
|
||||
|
|
@ -106,7 +121,8 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
// perl error message:
|
||||
// <message> at <file> line <line>
|
||||
return SCE_ERR_PERL;
|
||||
} else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
|
||||
} else if ((lengthLine >= 6) &&
|
||||
(memcmp(lineBuffer, " at ", 6) == 0) &&
|
||||
strstr(lineBuffer, ":line ")) {
|
||||
// A .NET traceback
|
||||
return SCE_ERR_NET;
|
||||
|
|
@ -131,6 +147,11 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
// Microsoft linker warning:
|
||||
// {<object> : } warning LNK9999
|
||||
return SCE_ERR_MS;
|
||||
} else if (IsGccExcerpt(lineBuffer)) {
|
||||
// GCC code excerpt and pointer to issue
|
||||
// 73 | GTimeVal last_popdown;
|
||||
// | ^~~~~~~~~~~~
|
||||
return SCE_ERR_GCC_EXCERPT;
|
||||
} else {
|
||||
// Look for one of the following formats:
|
||||
// GCC: <filename>:<line>:<message>
|
||||
|
|
@ -141,7 +162,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
// CTags: <identifier>\t<filename>\t<message>
|
||||
// Lua 5 traceback: \t<filename>:<line>:<message>
|
||||
// Lua 5.1: <exe>: <filename>:<line>:<message>
|
||||
bool initialTab = (lineBuffer[0] == '\t');
|
||||
const bool initialTab = (lineBuffer[0] == '\t');
|
||||
bool initialColonPart = false;
|
||||
bool canBeCtags = !initialTab; // For ctags must have an identifier with no spaces then a tab
|
||||
enum { stInitial,
|
||||
|
|
@ -151,7 +172,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
stUnrecognized
|
||||
} state = stInitial;
|
||||
for (Sci_PositionU i = 0; i < lengthLine; i++) {
|
||||
char ch = lineBuffer[i];
|
||||
const char ch = lineBuffer[i];
|
||||
char chNext = ' ';
|
||||
if ((i + 1) < lengthLine)
|
||||
chNext = lineBuffer[i + 1];
|
||||
|
|
@ -176,7 +197,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
canBeCtags = false;
|
||||
}
|
||||
} else if (state == stGccStart) { // <filename>:
|
||||
state = Is0To9(ch) ? stGccDigit : stUnrecognized;
|
||||
state = ((ch == '-') || Is0To9(ch)) ? stGccDigit : stUnrecognized;
|
||||
} else if (state == stGccDigit) { // <filename>:<line>
|
||||
if (ch == ':') {
|
||||
state = stGccColumn; // :9.*: is GCC
|
||||
|
|
@ -207,14 +228,13 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
} else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {
|
||||
// Possibly Delphi.. don't test against chNext as it's one of the strings below.
|
||||
char word[512];
|
||||
Sci_PositionU j, chPos;
|
||||
unsigned numstep;
|
||||
chPos = 0;
|
||||
if (ch == ' ')
|
||||
numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
|
||||
else
|
||||
numstep = 2; // otherwise add 2.
|
||||
for (j = i + numstep; j < lengthLine && IsAlphabetic(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
|
||||
Sci_PositionU chPos = 0;
|
||||
for (Sci_PositionU 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") ||
|
||||
|
|
@ -269,13 +289,11 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi
|
|||
|
||||
#define CSI "\033["
|
||||
|
||||
namespace {
|
||||
|
||||
bool SequenceEnd(int ch) {
|
||||
constexpr bool SequenceEnd(int ch) noexcept {
|
||||
return (ch == 0) || ((ch >= '@') && (ch <= '~'));
|
||||
}
|
||||
|
||||
int StyleFromSequence(const char *seq) {
|
||||
int StyleFromSequence(const char *seq) noexcept {
|
||||
int bold = 0;
|
||||
int colour = 0;
|
||||
while (!SequenceEnd(*seq)) {
|
||||
|
|
@ -302,21 +320,19 @@ int StyleFromSequence(const char *seq) {
|
|||
return SCE_ERR_ES_BLACK + bold * 8 + colour;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ColouriseErrorListLine(
|
||||
char *lineBuffer,
|
||||
Sci_PositionU lengthLine,
|
||||
void ColouriseErrorListLine(
|
||||
const std::string &lineBuffer,
|
||||
Sci_PositionU endPos,
|
||||
Accessor &styler,
|
||||
bool valueSeparate,
|
||||
bool escapeSequences) {
|
||||
Sci_Position startValue = -1;
|
||||
int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue);
|
||||
if (escapeSequences && strstr(lineBuffer, CSI)) {
|
||||
const int startPos = endPos - lengthLine;
|
||||
const char *linePortion = lineBuffer;
|
||||
int startPortion = startPos;
|
||||
const Sci_PositionU lengthLine = lineBuffer.length();
|
||||
const int style = RecogniseErrorListLine(lineBuffer.c_str(), lengthLine, startValue);
|
||||
if (escapeSequences && strstr(lineBuffer.c_str(), CSI)) {
|
||||
const Sci_Position startPos = endPos - lengthLine;
|
||||
const char *linePortion = lineBuffer.c_str();
|
||||
Sci_Position startPortion = startPos;
|
||||
int portionStyle = style;
|
||||
while (const char *startSeq = strstr(linePortion, CSI)) {
|
||||
if (startSeq > linePortion) {
|
||||
|
|
@ -325,7 +341,7 @@ static void ColouriseErrorListLine(
|
|||
const char *endSeq = startSeq + 2;
|
||||
while (!SequenceEnd(*endSeq))
|
||||
endSeq++;
|
||||
const int endSeqPosition = startPortion + static_cast<int>(endSeq - linePortion) + 1;
|
||||
const Sci_Position endSeqPosition = startPortion + static_cast<Sci_Position>(endSeq - linePortion) + 1;
|
||||
switch (*endSeq) {
|
||||
case 0:
|
||||
styler.ColourTo(endPos, SCE_ERR_ESCSEQ_UNKNOWN);
|
||||
|
|
@ -355,40 +371,39 @@ static void ColouriseErrorListLine(
|
|||
}
|
||||
}
|
||||
|
||||
static void ColouriseErrorListDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||||
char lineBuffer[10000];
|
||||
void ColouriseErrorListDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||||
std::string lineBuffer;
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
Sci_PositionU linePos = 0;
|
||||
|
||||
// property lexer.errorlist.value.separate
|
||||
// For lines in the output pane that are matches from Find in Files or GCC-style
|
||||
// diagnostics, style the path and line number separately from the rest of the
|
||||
// line with style 21 used for the rest of the line.
|
||||
// This allows matched text to be more easily distinguished from its location.
|
||||
bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
|
||||
const bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
|
||||
|
||||
// property lexer.errorlist.escape.sequences
|
||||
// Set to 1 to interpret escape sequences.
|
||||
const bool escapeSequences = styler.GetPropertyInt("lexer.errorlist.escape.sequences") != 0;
|
||||
|
||||
for (Sci_PositionU i = startPos; i < startPos + length; i++) {
|
||||
lineBuffer[linePos++] = styler[i];
|
||||
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
|
||||
// End of line (or of line buffer) met, colourise it
|
||||
lineBuffer[linePos] = '\0';
|
||||
ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate, escapeSequences);
|
||||
linePos = 0;
|
||||
lineBuffer.push_back(styler[i]);
|
||||
if (AtEOL(styler, i)) {
|
||||
// End of line met, colourise it
|
||||
ColouriseErrorListLine(lineBuffer, i, styler, valueSeparate, escapeSequences);
|
||||
lineBuffer.clear();
|
||||
}
|
||||
}
|
||||
if (linePos > 0) { // Last line does not have ending characters
|
||||
lineBuffer[linePos] = '\0';
|
||||
ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate, escapeSequences);
|
||||
if (!lineBuffer.empty()) { // Last line does not have ending characters
|
||||
ColouriseErrorListLine(lineBuffer, startPos + length - 1, styler, valueSeparate, escapeSequences);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const emptyWordListDesc[] = {
|
||||
0
|
||||
const char *const emptyWordListDesc[] = {
|
||||
nullptr
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexFlagShip.cxx
|
||||
/** @file LexFlagship.cxx
|
||||
** Lexer for Harbour and FlagShip.
|
||||
** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)
|
||||
**/
|
||||
|
|
@ -26,9 +26,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Extended to accept accented characters
|
||||
static inline bool IsAWordChar(int ch)
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordStart(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include "LexerModule.h"
|
||||
/***************************************/
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/***********************************************/
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
|
|
@ -120,14 +118,6 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
continue;
|
||||
}
|
||||
/***************************************/
|
||||
// Hanndle preprocessor directives
|
||||
if (sc.ch == '#' && numNonBlank == 1)
|
||||
{
|
||||
sc.SetState(SCE_F_PREPROCESSOR);
|
||||
while (!sc.atLineEnd && sc.More())
|
||||
sc.Forward(); // Until line end
|
||||
}
|
||||
/***************************************/
|
||||
// Handle line continuation generically.
|
||||
if (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) {
|
||||
char chTemp = ' ';
|
||||
|
|
@ -143,7 +133,11 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
int currentState = sc.state;
|
||||
sc.SetState(SCE_F_CONTINUATION);
|
||||
sc.ForwardSetState(SCE_F_DEFAULT);
|
||||
while (IsASpace(sc.ch) && sc.More()) sc.Forward();
|
||||
while (IsASpace(sc.ch) && sc.More()) {
|
||||
sc.Forward();
|
||||
if (sc.atLineStart) numNonBlank = 0;
|
||||
if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
|
||||
}
|
||||
if (sc.ch == '&') {
|
||||
sc.SetState(SCE_F_CONTINUATION);
|
||||
sc.Forward();
|
||||
|
|
@ -152,6 +146,14 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
}
|
||||
/***************************************/
|
||||
// Hanndle preprocessor directives
|
||||
if (sc.ch == '#' && numNonBlank == 1)
|
||||
{
|
||||
sc.SetState(SCE_F_PREPROCESSOR);
|
||||
while (!sc.atLineEnd && sc.More())
|
||||
sc.Forward(); // Until line end
|
||||
}
|
||||
/***************************************/
|
||||
// Determine if the current state should terminate.
|
||||
if (sc.state == SCE_F_OPERATOR) {
|
||||
sc.SetState(SCE_F_DEFAULT);
|
||||
|
|
@ -223,7 +225,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
if (sc.state == SCE_F_DEFAULT) {
|
||||
if (sc.ch == '!') {
|
||||
if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
|
||||
sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
|
||||
sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
|
||||
sc.SetState(SCE_F_PREPROCESSOR);
|
||||
} else {
|
||||
sc.SetState(SCE_F_COMMENT);
|
||||
|
|
@ -233,7 +235,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
sc.SetState(SCE_F_NUMBER);
|
||||
} else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
|
||||
tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
|
||||
tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
|
||||
sc.SetState(SCE_F_NUMBER);
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '.' && isalpha(sc.chNext)) {
|
||||
|
|
@ -252,6 +254,165 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
sc.Complete();
|
||||
}
|
||||
/***************************************/
|
||||
static void CheckLevelCommentLine(const unsigned int nComL,
|
||||
Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
|
||||
bool comLineB[], bool comLineF[], bool &comLineCur,
|
||||
int &levelDeltaNext) {
|
||||
levelDeltaNext = 0;
|
||||
if (!comLineCur) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!comLineF[0] || nComColF[0] != nComCur) {
|
||||
unsigned int i=0;
|
||||
for (; i<nComL; i++) {
|
||||
if (!comLineB[i] || nComColB[i] != nComCur) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == nComL) {
|
||||
levelDeltaNext = -1;
|
||||
}
|
||||
}
|
||||
else if (!comLineB[0] || nComColB[0] != nComCur) {
|
||||
unsigned int i=0;
|
||||
for (; i<nComL; i++) {
|
||||
if (!comLineF[i] || nComColF[i] != nComCur) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == nComL) {
|
||||
levelDeltaNext = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***************************************/
|
||||
static void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Position line, bool &isComLine, Sci_Position &comCol) {
|
||||
Sci_Position col = 0;
|
||||
isComLine = false;
|
||||
Sci_Position pos = styler.LineStart(line);
|
||||
Sci_Position len = styler.Length();
|
||||
while(pos<len) {
|
||||
char ch = styler.SafeGetCharAt(pos);
|
||||
if (ch == '!' || (isFixFormat && col == 0 && (tolower(ch) == 'c' || ch == '*'))) {
|
||||
isComLine = true;
|
||||
comCol = col;
|
||||
break;
|
||||
}
|
||||
else if (!IsABlank(ch) || IsALineEnd(ch)) {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
/***************************************/
|
||||
static void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
|
||||
Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
|
||||
bool comLineB[], bool comLineF[], bool &comLineCur) {
|
||||
Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
|
||||
if (lineCurrent >= nLineTotal) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=nComL-2; i>=0; i--) {
|
||||
nComColB[i+1] = nComColB[i];
|
||||
comLineB[i+1] = comLineB[i];
|
||||
}
|
||||
nComColB[0] = nComCur;
|
||||
comLineB[0] = comLineCur;
|
||||
nComCur = nComColF[0];
|
||||
comLineCur = comLineF[0];
|
||||
for (unsigned int i=0; i+1<nComL; i++) {
|
||||
nComColF[i] = nComColF[i+1];
|
||||
comLineF[i] = comLineF[i+1];
|
||||
}
|
||||
Sci_Position chL = lineCurrent + nComL;
|
||||
if (chL < nLineTotal) {
|
||||
GetIfLineComment(styler, isFixFormat, chL, comLineF[nComL-1], nComColF[nComL-1]);
|
||||
}
|
||||
else {
|
||||
comLineF[nComL-1] = false;
|
||||
}
|
||||
}
|
||||
/***************************************/
|
||||
static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
|
||||
Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position nComCur,
|
||||
bool comLineB[], bool comLineF[], bool &comLineCur) {
|
||||
unsigned int nLines = nComL + nComL + 1;
|
||||
bool* comL = new bool[nLines];
|
||||
Sci_Position* nComCol = new Sci_Position[nLines];
|
||||
bool comL0;
|
||||
Sci_Position nComCol0;
|
||||
GetIfLineComment(styler, isFixFormat, lineCurrent-nComL-1, comL0, nComCol0);
|
||||
for (unsigned int i=0; i<nComL; i++) {
|
||||
unsigned copyTo = nComL - i - 1;
|
||||
comL[copyTo] = comLineB[i];
|
||||
nComCol[copyTo] = nComColB[i];
|
||||
}
|
||||
assert(nComL < nLines);
|
||||
comL[nComL] = comLineCur;
|
||||
nComCol[nComL] = nComCur;
|
||||
for (unsigned int i=0; i<nComL; i++) {
|
||||
unsigned copyTo = i + nComL + 1;
|
||||
comL[copyTo] = comLineF[i];
|
||||
nComCol[copyTo] = nComColF[i];
|
||||
}
|
||||
|
||||
Sci_Position lineC = lineCurrent - nComL + 1;
|
||||
Sci_PositionU iStart;
|
||||
if (lineC <= 0) {
|
||||
lineC = 0;
|
||||
iStart = nComL - lineCurrent;
|
||||
}
|
||||
else {
|
||||
iStart = 1;
|
||||
}
|
||||
bool levChanged = false;
|
||||
int lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
|
||||
|
||||
for (Sci_PositionU i=iStart; i<=nComL; i++) {
|
||||
if (comL[i] && (!comL[i-1] || nComCol[i] != nComCol[i-1])) {
|
||||
bool increase = true;
|
||||
Sci_PositionU until = i + nComL;
|
||||
for (Sci_PositionU j=i+1; j<=until; j++) {
|
||||
if (!comL[j] || nComCol[j] != nComCol[i]) {
|
||||
increase = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
|
||||
if (increase) {
|
||||
int levH = lev | SC_FOLDLEVELHEADERFLAG;
|
||||
lev += 1;
|
||||
if (levH != styler.LevelAt(lineC)) {
|
||||
styler.SetLevel(lineC, levH);
|
||||
}
|
||||
for (Sci_Position j=lineC+1; j<=lineCurrent; j++) {
|
||||
if (lev != styler.LevelAt(j)) {
|
||||
styler.SetLevel(j, lev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (lev != styler.LevelAt(lineC)) {
|
||||
styler.SetLevel(lineC, lev);
|
||||
}
|
||||
}
|
||||
levChanged = true;
|
||||
}
|
||||
else if (levChanged && comL[i]) {
|
||||
if (lev != styler.LevelAt(lineC)) {
|
||||
styler.SetLevel(lineC, lev);
|
||||
}
|
||||
}
|
||||
lineC++;
|
||||
}
|
||||
delete[] comL;
|
||||
delete[] nComCol;
|
||||
}
|
||||
/***************************************/
|
||||
// To determine the folding level depending on keywords
|
||||
static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
|
||||
int lev = 0;
|
||||
|
|
@ -282,7 +443,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|
|||
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|
||||
|| strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0
|
||||
|| (strcmp(prevWord, "module") == 0 && strcmp(s, "procedure") == 0) // Take care of the "module procedure" statement
|
||||
|| strcmp(s, "endsubmodule") == 0) {
|
||||
|| strcmp(s, "endsubmodule") == 0 || strcmp(s, "endteam") == 0) {
|
||||
lev = -1;
|
||||
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
|
||||
lev = 0;
|
||||
|
|
@ -291,6 +452,8 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|
|||
} else if ((strcmp(prevWord, "end") == 0 && strcmp(s, "procedure") == 0)
|
||||
|| strcmp(s, "endprocedure") == 0) {
|
||||
lev = 1; // level back to 0, because no folding support for "module procedure" in submodule
|
||||
} else if (strcmp(prevWord, "change") == 0 && strcmp(s, "team") == 0){ // change team
|
||||
lev = 1;
|
||||
}
|
||||
return lev;
|
||||
}
|
||||
|
|
@ -298,29 +461,62 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|
|||
// Folding the code
|
||||
static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
Accessor &styler, bool isFixFormat) {
|
||||
//
|
||||
// bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
|
||||
// Do not know how to fold the comment at the moment.
|
||||
//
|
||||
|
||||
bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelCurrent;
|
||||
bool isPrevLine;
|
||||
if (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
startPos = styler.LineStart(lineCurrent);
|
||||
levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
isPrevLine = true;
|
||||
} else {
|
||||
levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
isPrevLine = false;
|
||||
}
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int style = initStyle;
|
||||
int levelDeltaNext = 0;
|
||||
|
||||
const unsigned int nComL = 3; // defines how many comment lines should be before they are folded
|
||||
Sci_Position nComColB[nComL] = {};
|
||||
Sci_Position nComColF[nComL] = {};
|
||||
Sci_Position nComCur = 0;
|
||||
bool comLineB[nComL] = {};
|
||||
bool comLineF[nComL] = {};
|
||||
bool comLineCur;
|
||||
Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
|
||||
if (foldComment) {
|
||||
for (unsigned int i=0; i<nComL; i++) {
|
||||
Sci_Position chL = lineCurrent-(i+1);
|
||||
if (chL < 0) {
|
||||
comLineB[i] = false;
|
||||
break;
|
||||
}
|
||||
GetIfLineComment(styler, isFixFormat, chL, comLineB[i], nComColB[i]);
|
||||
if (!comLineB[i]) {
|
||||
for (unsigned int j=i+1; j<nComL; j++) {
|
||||
comLineB[j] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (unsigned int i=0; i<nComL; i++) {
|
||||
Sci_Position chL = lineCurrent+i+1;
|
||||
if (chL >= nLineTotal) {
|
||||
comLineF[i] = false;
|
||||
break;
|
||||
}
|
||||
GetIfLineComment(styler, isFixFormat, chL, comLineF[i], nComColF[i]);
|
||||
}
|
||||
GetIfLineComment(styler, isFixFormat, lineCurrent, comLineCur, nComCur);
|
||||
CheckBackComLines(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
|
||||
comLineB, comLineF, comLineCur);
|
||||
}
|
||||
int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
|
||||
/***************************************/
|
||||
Sci_Position lastStart = 0;
|
||||
char prevWord[32] = "";
|
||||
|
|
@ -463,6 +659,11 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
|
|||
}
|
||||
}
|
||||
if (atEOL) {
|
||||
if (foldComment) {
|
||||
int ldNext;
|
||||
CheckLevelCommentLine(nComL, nComColB, nComColF, nComCur, comLineB, comLineF, comLineCur, ldNext);
|
||||
levelDeltaNext += ldNext;
|
||||
}
|
||||
int lev = levelCurrent;
|
||||
if (visibleChars == 0 && foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
|
|
@ -477,6 +678,11 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
|
|||
visibleChars = 0;
|
||||
strcpy(prevWord, "");
|
||||
isPrevLine = false;
|
||||
|
||||
if (foldComment) {
|
||||
StepCommentLine(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
|
||||
comLineB, comLineF, comLineCur);
|
||||
}
|
||||
}
|
||||
/***************************************/
|
||||
if (!isspacechar(ch)) visibleChars++;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsGAPOperator(char ch) {
|
||||
if (IsASCII(ch) && isalnum(ch)) return false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// Scintilla source code edit control
|
||||
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
|
||||
// @file LexGui4Cli.cxx
|
||||
/*
|
||||
This is the Lexer for Gui4Cli, included in SciLexer.dll
|
||||
- by d. Keletsekis, 2/10/2003
|
||||
|
|
@ -39,9 +40,7 @@ val SCE_GC_OPERATOR=9
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
#define debug Platform::DebugPrintf
|
||||
|
||||
|
|
@ -68,7 +67,7 @@ inline bool isGCOperator(int ch)
|
|||
#define isFoldPoint(x) ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)
|
||||
|
||||
static void colorFirstWord(WordList *keywordlists[], Accessor &styler,
|
||||
StyleContext *sc, char *buff, Sci_Position length, int)
|
||||
StyleContext *sc, char *buff, Sci_Position length, Sci_Position)
|
||||
{
|
||||
Sci_Position c = 0;
|
||||
while (sc->More() && isSpaceOrNL(sc->ch))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -26,6 +26,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "ILexer.h"
|
||||
|
|
@ -41,10 +42,9 @@
|
|||
#include "CharacterCategory.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// See https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x#L1682
|
||||
// Note, letter modifiers are prohibited.
|
||||
|
|
@ -269,7 +269,7 @@ struct OptionSetHaskell : public OptionSet<OptionsHaskell> {
|
|||
}
|
||||
};
|
||||
|
||||
class LexerHaskell : public ILexer {
|
||||
class LexerHaskell : public DefaultLexer {
|
||||
bool literate;
|
||||
Sci_Position firstImportLine;
|
||||
int firstImportIndent;
|
||||
|
|
@ -390,45 +390,50 @@ class LexerHaskell : public ILexer {
|
|||
|
||||
public:
|
||||
LexerHaskell(bool literate_)
|
||||
: literate(literate_)
|
||||
: DefaultLexer(literate_ ? "literatehaskell" : "haskell", literate_ ? SCLEX_LITERATEHASKELL : SCLEX_HASKELL)
|
||||
, literate(literate_)
|
||||
, firstImportLine(-1)
|
||||
, firstImportIndent(0)
|
||||
{}
|
||||
virtual ~LexerHaskell() {}
|
||||
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osHaskell.PropertyNames();
|
||||
}
|
||||
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osHaskell.PropertyType(name);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osHaskell.DescribeProperty(name);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osHaskell.PropertyGet(key);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osHaskell.DescribeWordListSets();
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,9 +118,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// prototypes for general helper functions
|
||||
static inline bool IsNewline(const int ch);
|
||||
|
|
@ -651,7 +649,9 @@ static void ColouriseSrecDoc(Sci_PositionU startPos, Sci_Position length, int in
|
|||
|
||||
while (sc.More()) {
|
||||
Sci_PositionU recStartPos;
|
||||
int byteCount, reqByteCount, addrFieldSize, addrFieldType, dataFieldSize, dataFieldType;
|
||||
Sci_Position reqByteCount;
|
||||
Sci_Position dataFieldSize;
|
||||
int byteCount, addrFieldSize, addrFieldType, dataFieldType;
|
||||
int cs1, cs2;
|
||||
|
||||
switch (sc.state) {
|
||||
|
|
|
|||
516
src/stc/scintilla/lexers/LexHollywood.cxx
Normal file
516
src/stc/scintilla/lexers/LexHollywood.cxx
Normal file
|
|
@ -0,0 +1,516 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexHollywood.cxx
|
||||
** Lexer for Hollywood
|
||||
** Written by Andreas Falkenhahn, based on the BlitzBasic/PureBasic/Lua lexers
|
||||
** Thanks to Nicholai Benalal
|
||||
** For more information on Hollywood, see http://www.hollywood-mal.com/
|
||||
** Mail me (andreas <at> airsoftsoftwair <dot> de) for any bugs.
|
||||
** This code is subject to the same license terms as the rest of the Scintilla project:
|
||||
** The License.txt file describes the conditions under which this software may be distributed.
|
||||
**/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
/* Bits:
|
||||
* 1 - whitespace
|
||||
* 2 - operator
|
||||
* 4 - identifier
|
||||
* 8 - decimal digit
|
||||
* 16 - hex digit
|
||||
* 32 - bin digit
|
||||
* 64 - letter
|
||||
*/
|
||||
static int character_classification[128] =
|
||||
{
|
||||
0, // NUL ($0)
|
||||
0, // SOH ($1)
|
||||
0, // STX ($2)
|
||||
0, // ETX ($3)
|
||||
0, // EOT ($4)
|
||||
0, // ENQ ($5)
|
||||
0, // ACK ($6)
|
||||
0, // BEL ($7)
|
||||
0, // BS ($8)
|
||||
1, // HT ($9)
|
||||
1, // LF ($A)
|
||||
0, // VT ($B)
|
||||
0, // FF ($C)
|
||||
1, // CR ($D)
|
||||
0, // SO ($E)
|
||||
0, // SI ($F)
|
||||
0, // DLE ($10)
|
||||
0, // DC1 ($11)
|
||||
0, // DC2 ($12)
|
||||
0, // DC3 ($13)
|
||||
0, // DC4 ($14)
|
||||
0, // NAK ($15)
|
||||
0, // SYN ($16)
|
||||
0, // ETB ($17)
|
||||
0, // CAN ($18)
|
||||
0, // EM ($19)
|
||||
0, // SUB ($1A)
|
||||
0, // ESC ($1B)
|
||||
0, // FS ($1C)
|
||||
0, // GS ($1D)
|
||||
0, // RS ($1E)
|
||||
0, // US ($1F)
|
||||
1, // space ($20)
|
||||
4, // ! ($21)
|
||||
0, // " ($22)
|
||||
0, // # ($23)
|
||||
4, // $ ($24)
|
||||
2, // % ($25)
|
||||
2, // & ($26)
|
||||
2, // ' ($27)
|
||||
2, // ( ($28)
|
||||
2, // ) ($29)
|
||||
2, // * ($2A)
|
||||
2, // + ($2B)
|
||||
2, // , ($2C)
|
||||
2, // - ($2D)
|
||||
// NB: we treat "." as an identifier although it is also an operator and a decimal digit
|
||||
// the reason why we treat it as an identifier is to support syntax highlighting for
|
||||
// plugin commands which always use a "." in their names, e.g. pdf.OpenDocument();
|
||||
// we handle the decimal digit case manually below so that 3.1415 and .123 is styled correctly
|
||||
// the collateral damage of treating "." as an identifier is that "." is never styled
|
||||
// SCE_HOLLYWOOD_OPERATOR
|
||||
4, // . ($2E)
|
||||
2, // / ($2F)
|
||||
28, // 0 ($30)
|
||||
28, // 1 ($31)
|
||||
28, // 2 ($32)
|
||||
28, // 3 ($33)
|
||||
28, // 4 ($34)
|
||||
28, // 5 ($35)
|
||||
28, // 6 ($36)
|
||||
28, // 7 ($37)
|
||||
28, // 8 ($38)
|
||||
28, // 9 ($39)
|
||||
2, // : ($3A)
|
||||
2, // ; ($3B)
|
||||
2, // < ($3C)
|
||||
2, // = ($3D)
|
||||
2, // > ($3E)
|
||||
2, // ? ($3F)
|
||||
0, // @ ($40)
|
||||
84, // A ($41)
|
||||
84, // B ($42)
|
||||
84, // C ($43)
|
||||
84, // D ($44)
|
||||
84, // E ($45)
|
||||
84, // F ($46)
|
||||
68, // G ($47)
|
||||
68, // H ($48)
|
||||
68, // I ($49)
|
||||
68, // J ($4A)
|
||||
68, // K ($4B)
|
||||
68, // L ($4C)
|
||||
68, // M ($4D)
|
||||
68, // N ($4E)
|
||||
68, // O ($4F)
|
||||
68, // P ($50)
|
||||
68, // Q ($51)
|
||||
68, // R ($52)
|
||||
68, // S ($53)
|
||||
68, // T ($54)
|
||||
68, // U ($55)
|
||||
68, // V ($56)
|
||||
68, // W ($57)
|
||||
68, // X ($58)
|
||||
68, // Y ($59)
|
||||
68, // Z ($5A)
|
||||
2, // [ ($5B)
|
||||
2, // \ ($5C)
|
||||
2, // ] ($5D)
|
||||
2, // ^ ($5E)
|
||||
68, // _ ($5F)
|
||||
2, // ` ($60)
|
||||
84, // a ($61)
|
||||
84, // b ($62)
|
||||
84, // c ($63)
|
||||
84, // d ($64)
|
||||
84, // e ($65)
|
||||
84, // f ($66)
|
||||
68, // g ($67)
|
||||
68, // h ($68)
|
||||
68, // i ($69)
|
||||
68, // j ($6A)
|
||||
68, // k ($6B)
|
||||
68, // l ($6C)
|
||||
68, // m ($6D)
|
||||
68, // n ($6E)
|
||||
68, // o ($6F)
|
||||
68, // p ($70)
|
||||
68, // q ($71)
|
||||
68, // r ($72)
|
||||
68, // s ($73)
|
||||
68, // t ($74)
|
||||
68, // u ($75)
|
||||
68, // v ($76)
|
||||
68, // w ($77)
|
||||
68, // x ($78)
|
||||
68, // y ($79)
|
||||
68, // z ($7A)
|
||||
2, // { ($7B)
|
||||
2, // | ($7C)
|
||||
2, // } ($7D)
|
||||
2, // ~ ($7E)
|
||||
0, //  ($7F)
|
||||
};
|
||||
|
||||
static bool IsSpace(int c) {
|
||||
return c < 128 && (character_classification[c] & 1);
|
||||
}
|
||||
|
||||
static bool IsOperator(int c) {
|
||||
return c < 128 && (character_classification[c] & 2);
|
||||
}
|
||||
|
||||
static bool IsIdentifier(int c) {
|
||||
return c < 128 && (character_classification[c] & 4);
|
||||
}
|
||||
|
||||
static bool IsDigit(int c) {
|
||||
return c < 128 && (character_classification[c] & 8);
|
||||
}
|
||||
|
||||
static bool IsHexDigit(int c) {
|
||||
return c < 128 && (character_classification[c] & 16);
|
||||
}
|
||||
|
||||
static int LowerCase(int c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return 'a' + c - 'A';
|
||||
return c;
|
||||
}
|
||||
|
||||
static int CheckHollywoodFoldPoint(char const *token) {
|
||||
if (!strcmp(token, "function")) {
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(token, "endfunction")) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// An individual named option for use in an OptionSet
|
||||
|
||||
// Options used for LexerHollywood
|
||||
struct OptionsHollywood {
|
||||
bool fold;
|
||||
bool foldCompact;
|
||||
OptionsHollywood() {
|
||||
fold = false;
|
||||
foldCompact = false;
|
||||
}
|
||||
};
|
||||
|
||||
static const char * const hollywoodWordListDesc[] = {
|
||||
"Hollywood keywords",
|
||||
"Hollywood standard API functions",
|
||||
"Hollywood plugin API functions",
|
||||
"Hollywood plugin methods",
|
||||
0
|
||||
};
|
||||
|
||||
struct OptionSetHollywood : public OptionSet<OptionsHollywood> {
|
||||
OptionSetHollywood(const char * const wordListDescriptions[]) {
|
||||
DefineProperty("fold", &OptionsHollywood::fold);
|
||||
DefineProperty("fold.compact", &OptionsHollywood::foldCompact);
|
||||
DefineWordListSets(wordListDescriptions);
|
||||
}
|
||||
};
|
||||
|
||||
class LexerHollywood : public DefaultLexer {
|
||||
int (*CheckFoldPoint)(char const *);
|
||||
WordList keywordlists[4];
|
||||
OptionsHollywood options;
|
||||
OptionSetHollywood osHollywood;
|
||||
public:
|
||||
LexerHollywood(int (*CheckFoldPoint_)(char const *), const char * const wordListDescriptions[]) :
|
||||
DefaultLexer("hollywood", SCLEX_HOLLYWOOD),
|
||||
CheckFoldPoint(CheckFoldPoint_),
|
||||
osHollywood(wordListDescriptions) {
|
||||
}
|
||||
virtual ~LexerHollywood() {
|
||||
}
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osHollywood.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osHollywood.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osHollywood.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char* key) override {
|
||||
return osHollywood.PropertyGet(key);
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osHollywood.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
static ILexer *LexerFactoryHollywood() {
|
||||
return new LexerHollywood(CheckHollywoodFoldPoint, hollywoodWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerHollywood::PropertySet(const char *key, const char *val) {
|
||||
if (osHollywood.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerHollywood::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;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN) {
|
||||
WordList wlNew;
|
||||
wlNew.Set(wl);
|
||||
if (*wordListN != wlNew) {
|
||||
wordListN->Set(wl);
|
||||
firstModification = 0;
|
||||
}
|
||||
}
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerHollywood::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
styler.StartAt(startPos);
|
||||
bool inString = false;
|
||||
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
// Can't use sc.More() here else we miss the last character
|
||||
for (; ; sc.Forward())
|
||||
{
|
||||
if (sc.atLineStart) inString = false;
|
||||
|
||||
if (sc.ch == '\"' && sc.chPrev != '\\') inString = !inString;
|
||||
|
||||
if (sc.state == SCE_HOLLYWOOD_IDENTIFIER) {
|
||||
if (!IsIdentifier(sc.ch)) {
|
||||
char s[100];
|
||||
int kstates[4] = {
|
||||
SCE_HOLLYWOOD_KEYWORD,
|
||||
SCE_HOLLYWOOD_STDAPI,
|
||||
SCE_HOLLYWOOD_PLUGINAPI,
|
||||
SCE_HOLLYWOOD_PLUGINMETHOD,
|
||||
};
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (keywordlists[i].InList(s)) {
|
||||
sc.ChangeState(kstates[i]);
|
||||
}
|
||||
}
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_HOLLYWOOD_OPERATOR) {
|
||||
|
||||
// always reset to default on operators because otherwise
|
||||
// comments won't be recognized in sequences like "+/* Hello*/"
|
||||
// --> "+/*" would be recognized as a sequence of operators
|
||||
|
||||
// if (!IsOperator(sc.ch)) sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
|
||||
} else if (sc.state == SCE_HOLLYWOOD_PREPROCESSOR) {
|
||||
if (!IsIdentifier(sc.ch))
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
} else if (sc.state == SCE_HOLLYWOOD_CONSTANT) {
|
||||
if (!IsIdentifier(sc.ch))
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
} else if (sc.state == SCE_HOLLYWOOD_NUMBER) {
|
||||
if (!IsDigit(sc.ch) && sc.ch != '.')
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
} else if (sc.state == SCE_HOLLYWOOD_HEXNUMBER) {
|
||||
if (!IsHexDigit(sc.ch))
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
} else if (sc.state == SCE_HOLLYWOOD_STRING) {
|
||||
if (sc.ch == '"') {
|
||||
sc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
}
|
||||
if (sc.atLineEnd) {
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_HOLLYWOOD_COMMENT) {
|
||||
if (sc.atLineEnd) {
|
||||
sc.SetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_HOLLYWOOD_COMMENTBLOCK) {
|
||||
if (sc.Match("*/") && !inString) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_HOLLYWOOD_STRINGBLOCK) {
|
||||
if (sc.Match("]]") && !inString) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_HOLLYWOOD_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.state == SCE_HOLLYWOOD_DEFAULT) {
|
||||
if (sc.Match(';')) {
|
||||
sc.SetState(SCE_HOLLYWOOD_COMMENT);
|
||||
} else if (sc.Match("/*")) {
|
||||
sc.SetState(SCE_HOLLYWOOD_COMMENTBLOCK);
|
||||
sc.Forward();
|
||||
} else if (sc.Match("[[")) {
|
||||
sc.SetState(SCE_HOLLYWOOD_STRINGBLOCK);
|
||||
sc.Forward();
|
||||
} else if (sc.Match('"')) {
|
||||
sc.SetState(SCE_HOLLYWOOD_STRING);
|
||||
} else if (sc.Match('$')) {
|
||||
sc.SetState(SCE_HOLLYWOOD_HEXNUMBER);
|
||||
} else if (sc.Match("0x") || sc.Match("0X")) { // must be before IsDigit() because of 0x
|
||||
sc.SetState(SCE_HOLLYWOOD_HEXNUMBER);
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '.' && (sc.chNext >= '0' && sc.chNext <= '9')) { // ".1234" style numbers
|
||||
sc.SetState(SCE_HOLLYWOOD_NUMBER);
|
||||
sc.Forward();
|
||||
} else if (IsDigit(sc.ch)) {
|
||||
sc.SetState(SCE_HOLLYWOOD_NUMBER);
|
||||
} else if (sc.Match('#')) {
|
||||
sc.SetState(SCE_HOLLYWOOD_CONSTANT);
|
||||
} else if (sc.Match('@')) {
|
||||
sc.SetState(SCE_HOLLYWOOD_PREPROCESSOR);
|
||||
} else if (IsOperator(sc.ch)) {
|
||||
sc.SetState(SCE_HOLLYWOOD_OPERATOR);
|
||||
} else if (IsIdentifier(sc.ch)) {
|
||||
sc.SetState(SCE_HOLLYWOOD_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sc.More())
|
||||
break;
|
||||
}
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerHollywood::Fold(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {
|
||||
|
||||
if (!options.fold)
|
||||
return;
|
||||
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
Sci_PositionU lengthDoc = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
int levelCurrent = levelPrev;
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int done = 0;
|
||||
char word[256];
|
||||
int wordlen = 0;
|
||||
|
||||
for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
|
||||
char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
int style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
if (!done) {
|
||||
if (wordlen) { // are we scanning a token already?
|
||||
word[wordlen] = static_cast<char>(LowerCase(ch));
|
||||
if (!IsIdentifier(ch)) { // done with token
|
||||
word[wordlen] = '\0';
|
||||
levelCurrent += CheckFoldPoint(word);
|
||||
done = 1;
|
||||
} else if (wordlen < 255) {
|
||||
wordlen++;
|
||||
}
|
||||
} else { // start scanning at first non-whitespace character
|
||||
if (!IsSpace(ch)) {
|
||||
if (style != SCE_HOLLYWOOD_COMMENTBLOCK && IsIdentifier(ch)) {
|
||||
word[0] = static_cast<char>(LowerCase(ch));
|
||||
wordlen = 1;
|
||||
} else // done with this line
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (atEOL) {
|
||||
int lev = levelPrev;
|
||||
if (visibleChars == 0 && options.foldCompact) {
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
}
|
||||
if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
lineCurrent++;
|
||||
levelPrev = levelCurrent;
|
||||
visibleChars = 0;
|
||||
done = 0;
|
||||
wordlen = 0;
|
||||
}
|
||||
if (!IsSpace(ch)) {
|
||||
visibleChars++;
|
||||
}
|
||||
}
|
||||
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
|
||||
|
||||
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
|
||||
}
|
||||
|
||||
LexerModule lmHollywood(SCLEX_HOLLYWOOD, LexerHollywood::LexerFactoryHollywood, "hollywood", hollywoodWordListDesc);
|
||||
71
src/stc/scintilla/lexers/LexIndent.cxx
Normal file
71
src/stc/scintilla/lexers/LexIndent.cxx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexIndent.cxx
|
||||
** Lexer for no language. Used for indentation-based folding of files.
|
||||
**/
|
||||
// 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"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
static void ColouriseIndentDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
|
||||
Accessor &styler) {
|
||||
// Indent language means all style bytes are 0 so just mark the end - no need to fill in.
|
||||
if (length > 0) {
|
||||
styler.StartAt(startPos + length - 1);
|
||||
styler.StartSegment(startPos + length - 1);
|
||||
styler.ColourTo(startPos + length - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void FoldIndentDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[], Accessor &styler) {
|
||||
int visibleCharsCurrent, visibleCharsNext;
|
||||
int levelCurrent, levelNext;
|
||||
Sci_PositionU i, lineEnd;
|
||||
Sci_PositionU lengthDoc = startPos + length;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
|
||||
i = styler.LineStart(lineCurrent );
|
||||
lineEnd = styler.LineStart(lineCurrent+1)-1;
|
||||
if(lineEnd>=lengthDoc) lineEnd = lengthDoc-1;
|
||||
while(styler[lineEnd]=='\n' || styler[lineEnd]=='\r') lineEnd--;
|
||||
for(visibleCharsCurrent=0, levelCurrent=SC_FOLDLEVELBASE; !visibleCharsCurrent && i<=lineEnd; i++){
|
||||
if(isspacechar(styler[i])) levelCurrent++;
|
||||
else visibleCharsCurrent=1;
|
||||
}
|
||||
|
||||
for(; i<lengthDoc; lineCurrent++) {
|
||||
i = styler.LineStart(lineCurrent+1);
|
||||
lineEnd = styler.LineStart(lineCurrent+2)-1;
|
||||
if(lineEnd>=lengthDoc) lineEnd = lengthDoc-1;
|
||||
while(styler[lineEnd]=='\n' || styler[lineEnd]=='\r') lineEnd--;
|
||||
for(visibleCharsNext=0, levelNext=SC_FOLDLEVELBASE; !visibleCharsNext && i<=lineEnd; i++){
|
||||
if(isspacechar(styler[i])) levelNext++;
|
||||
else visibleCharsNext=1;
|
||||
}
|
||||
int lev = levelCurrent;
|
||||
if(!visibleCharsCurrent) lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
else if(levelNext > levelCurrent) lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
levelCurrent = levelNext;
|
||||
visibleCharsCurrent = visibleCharsNext;
|
||||
}
|
||||
}
|
||||
|
||||
LexerModule lmIndent(SCLEX_INDENT, ColouriseIndentDoc, "indent", FoldIndentDoc);
|
||||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColouriseInnoDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler) {
|
||||
int state = SCE_INNO_DEFAULT;
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static const char *const JSONWordListDesc[] = {
|
||||
"JSON Keywords",
|
||||
|
|
@ -128,7 +127,7 @@ struct OptionSetJSON : public OptionSet<OptionsJSON> {
|
|||
}
|
||||
};
|
||||
|
||||
class LexerJSON : public ILexer {
|
||||
class LexerJSON : public DefaultLexer {
|
||||
OptionsJSON options;
|
||||
OptionSetJSON optSetJSON;
|
||||
EscapeSequence escapeSeq;
|
||||
|
|
@ -202,34 +201,38 @@ class LexerJSON : public ILexer {
|
|||
|
||||
public:
|
||||
LexerJSON() :
|
||||
DefaultLexer("json", SCLEX_JSON),
|
||||
setOperators(CharacterSet::setNone, "[{}]:,"),
|
||||
setURL(CharacterSet::setAlphaNum, "-._~:/?#[]@!$&'()*+,),="),
|
||||
setKeywordJSONLD(CharacterSet::setAlpha, ":@"),
|
||||
setKeywordJSON(CharacterSet::setAlpha, "$_") {
|
||||
}
|
||||
virtual ~LexerJSON() {}
|
||||
virtual int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
virtual void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
virtual const char *SCI_METHOD PropertyNames() {
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return optSetJSON.PropertyNames();
|
||||
}
|
||||
virtual int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return optSetJSON.PropertyType(name);
|
||||
}
|
||||
virtual const char *SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return optSetJSON.DescribeProperty(name);
|
||||
}
|
||||
virtual Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {
|
||||
if (optSetJSON.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
virtual Sci_Position SCI_METHOD WordListSet(int n, const char *wl) {
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return optSetJSON.PropertyGet(key);
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override {
|
||||
WordList *wordListN = 0;
|
||||
switch (n) {
|
||||
case 0:
|
||||
|
|
@ -250,23 +253,23 @@ class LexerJSON : public ILexer {
|
|||
}
|
||||
return firstModification;
|
||||
}
|
||||
virtual void *SCI_METHOD PrivateCall(int, void *) {
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
static ILexer *LexerFactoryJSON() {
|
||||
return new LexerJSON;
|
||||
}
|
||||
virtual const char *SCI_METHOD DescribeWordListSets() {
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return optSetJSON.DescribeWordListSets();
|
||||
}
|
||||
virtual void SCI_METHOD Lex(Sci_PositionU startPos,
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos,
|
||||
Sci_Position length,
|
||||
int initStyle,
|
||||
IDocument *pAccess);
|
||||
virtual void SCI_METHOD Fold(Sci_PositionU startPos,
|
||||
IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos,
|
||||
Sci_Position length,
|
||||
int initStyle,
|
||||
IDocument *pAccess);
|
||||
IDocument *pAccess) override;
|
||||
};
|
||||
|
||||
void SCI_METHOD LexerJSON::Lex(Sci_PositionU startPos,
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
/* KVIrc Script syntactic rules: http://www.kvirc.net/doc/doc_syntactic_rules.html */
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Extended to accept accented characters
|
||||
static inline bool IsAWordChar(int ch) {
|
||||
|
|
|
|||
968
src/stc/scintilla/lexers/LexLPeg.cxx
Normal file
968
src/stc/scintilla/lexers/LexLPeg.cxx
Normal file
|
|
@ -0,0 +1,968 @@
|
|||
/**
|
||||
* Copyright 2006-2020 Mitchell mitchell.att.foicica.com. See License.txt.
|
||||
*
|
||||
* Lua-powered dynamic language lexer for Scintilla.
|
||||
*
|
||||
* For documentation on writing lexers, see *../doc/LPegLexer.html*.
|
||||
*/
|
||||
|
||||
#if LPEG_LEXER
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#if CURSES
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#if !_WIN32
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "LexerModule.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
LUALIB_API int luaopen_lpeg(lua_State *L);
|
||||
}
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define RECORD_STACK_TOP(l) int orig_stack_top = lua_gettop(l)
|
||||
#define ASSERT_STACK_TOP(l) assert(lua_gettop(l) == orig_stack_top)
|
||||
#else
|
||||
#define RECORD_STACK_TOP(_) (void)0
|
||||
#define ASSERT_STACK_TOP(_) (void)0
|
||||
#endif
|
||||
#if LUA_VERSION_NUM < 502
|
||||
#define luaL_traceback(_,__,___,____) (void)0
|
||||
#define luaL_requiref(l, s, f, _) \
|
||||
(lua_pushcfunction(l, f), lua_pushstring(l, s), lua_call(l, 1, 1))
|
||||
#define lua_rawlen lua_objlen
|
||||
#define LUA_OK 0
|
||||
#define lua_rawgetp(l, i, p) \
|
||||
(lua_pushlightuserdata(l, p), lua_rawget(l, i), lua_type(l, -1))
|
||||
#define lua_rawsetp(l, i, p) \
|
||||
(lua_pushlightuserdata(l, p), lua_insert(l, -2), lua_rawset(l, i))
|
||||
#endif
|
||||
#if LUA_VERSION_NUM < 503
|
||||
#define lua_getfield(l, i, k) (lua_getfield(l, i, k), lua_type(l, -1))
|
||||
#define lua_rawget(l, i) (lua_rawget(l, i), lua_type(l, -1))
|
||||
#endif
|
||||
|
||||
/** The LPeg Scintilla lexer. */
|
||||
class LexerLPeg : public DefaultLexer {
|
||||
// Lexer property keys.
|
||||
const char * const LexerErrorKey = "lexer.lpeg.error";
|
||||
const char * const LexerHomeKey = "lexer.lpeg.home";
|
||||
const char * const LexerNameKey = "lexer.lpeg.name";
|
||||
const char * const LexerThemeKey = "lexer.lpeg.color.theme";
|
||||
|
||||
/**
|
||||
* The lexer's Lua state.
|
||||
* It is cleared each time the lexer language changes unless `ownLua` is
|
||||
* `true`.
|
||||
*/
|
||||
lua_State *L;
|
||||
/**
|
||||
* The flag indicating whether or not the Lua State is owned by the lexer.
|
||||
*/
|
||||
bool ownLua = true;
|
||||
/**
|
||||
* The set of properties for the lexer.
|
||||
* The LexerHomeKey and LexerNameKey properties must be defined before running
|
||||
* the lexer.
|
||||
*/
|
||||
PropSetSimple props;
|
||||
/** The function to send Scintilla messages with. */
|
||||
SciFnDirect SS = nullptr;
|
||||
/** The Scintilla object the lexer belongs to. */
|
||||
sptr_t sci = 0;
|
||||
/**
|
||||
* The flag indicating whether or not the lexer needs to be re-initialized.
|
||||
* Re-initialization is required after the lexer language changes.
|
||||
*/
|
||||
bool reinit = true;
|
||||
/**
|
||||
* The flag indicating whether or not the lexer language has embedded lexers.
|
||||
*/
|
||||
bool multilang = false;
|
||||
/**
|
||||
* The list of style numbers considered to be whitespace styles.
|
||||
* This is used in multi-language lexers when backtracking to whitespace to
|
||||
* determine which lexer grammar to use.
|
||||
*/
|
||||
bool ws[STYLE_MAX + 1];
|
||||
/** List of known lexer names. */
|
||||
std::set<std::string> lexerNames;
|
||||
/** Style name to return for `NameOfStyle()`. */
|
||||
std::string styleName;
|
||||
|
||||
/**
|
||||
* Searches the given directory for lexers and records their names.
|
||||
* @param path Path to a directory containing lexers.
|
||||
*/
|
||||
void ReadLexerNames(const char *path);
|
||||
|
||||
/**
|
||||
* Logs the given error message or a Lua error message, prints it, and clears
|
||||
* the stack.
|
||||
* Error messages are logged to the LexerErrorKey property.
|
||||
* @param L The Lua State.
|
||||
* @param str The error message to log and print. If `nullptr`, logs and
|
||||
* prints the Lua error message at the top of the stack.
|
||||
*/
|
||||
void LogError(lua_State *L, const char *str = nullptr);
|
||||
|
||||
/**
|
||||
* Parses the given style string to set the properties for the given style
|
||||
* number.
|
||||
* Style strings mimic SciTE's "style.*.stylenumber" properties.
|
||||
* (https://scintilla.org/SciTEDoc.html)
|
||||
* @param num The style number to set properties for.
|
||||
* @param style The style string containing properties to set.
|
||||
*/
|
||||
void SetStyle(int num, const char *style);
|
||||
|
||||
/**
|
||||
* Iterates through the lexer's `_TOKENSTYLES`, setting the style properties
|
||||
* for all defined styles.
|
||||
*/
|
||||
void SetStyles();
|
||||
|
||||
/**
|
||||
* Initializes the lexer once the LexerHomeKey and LexerNameKey properties are
|
||||
* set.
|
||||
*/
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* When *lparam* is `0`, returns the size of the buffer needed to store the
|
||||
* given string *str* in; otherwise copies *str* into the buffer *lparam* and
|
||||
* returns the number of bytes copied.
|
||||
* @param lparam `0` to get the number of bytes needed to store *str* or a
|
||||
* pointer to a buffer large enough to copy *str* into.
|
||||
* @param str The string to copy.
|
||||
* @return number of bytes needed to hold *str*
|
||||
*/
|
||||
void *StringResult(long lparam, const char *str);
|
||||
|
||||
public:
|
||||
/** Constructor. */
|
||||
LexerLPeg();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~LexerLPeg() = default;
|
||||
|
||||
/** Destroys the lexer object. */
|
||||
void SCI_METHOD Release() override;
|
||||
|
||||
/**
|
||||
* Lexes the Scintilla document.
|
||||
* @param startPos The position in the document to start lexing at.
|
||||
* @param lengthDoc The number of bytes in the document to lex.
|
||||
* @param initStyle The initial style at position *startPos* in the document.
|
||||
* @param buffer The document interface.
|
||||
*/
|
||||
void SCI_METHOD Lex(
|
||||
Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,
|
||||
IDocument *buffer) override;
|
||||
|
||||
/**
|
||||
* Folds the Scintilla document.
|
||||
* @param startPos The position in the document to start folding at.
|
||||
* @param lengthDoc The number of bytes in the document to fold.
|
||||
* @param initStyle The initial style at position *startPos* in the document.
|
||||
* @param buffer The document interface.
|
||||
*/
|
||||
void SCI_METHOD Fold(
|
||||
Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *buffer)
|
||||
override;
|
||||
|
||||
/**
|
||||
* Sets the *key* lexer property to *value*.
|
||||
* If *key* starts with "style.", also set the style for the token.
|
||||
* @param key The string property key.
|
||||
* @param val The string value.
|
||||
*/
|
||||
Sci_Position SCI_METHOD PropertySet(
|
||||
const char *key, const char *value) override;
|
||||
|
||||
/**
|
||||
* Allows for direct communication between the application and the lexer.
|
||||
* The application uses this to set `SS`, `sci`, `L`, and lexer properties,
|
||||
* and to retrieve style names.
|
||||
* @param code The communication code.
|
||||
* @param arg The argument.
|
||||
* @return void *data
|
||||
*/
|
||||
void * SCI_METHOD PrivateCall(int code, void *arg) override;
|
||||
|
||||
/**
|
||||
* Returns the style name for the given style number.
|
||||
* Note: the returned pointer is not guaranteed to exist after the next call
|
||||
* to `NameOfStyle()`, so its contents should be immediately copied.
|
||||
* @param style The style number to get the style name for.
|
||||
* @return style name or nullptr
|
||||
*/
|
||||
const char * SCI_METHOD NameOfStyle(int style) override;
|
||||
|
||||
/**
|
||||
* Returns the lexer property for *key*.
|
||||
* @param key The string property key.
|
||||
*/
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override;
|
||||
|
||||
/** Constructs a new instance of the lexer. */
|
||||
static ILexer *LexerFactoryLPeg();
|
||||
};
|
||||
|
||||
/** Lua pcall error message handler that adds a traceback. */
|
||||
static int lua_error_handler(lua_State *L) {
|
||||
luaL_traceback(L, L, lua_tostring(L, -1), 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** lexer.property[key] metamethod. */
|
||||
static int lexer_property_index(lua_State *L) {
|
||||
const char *property = lua_tostring(L, lua_upvalueindex(1));
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
LexerLPeg *lexer = reinterpret_cast<LexerLPeg *>(lua_touserdata(L, -1));
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, lua_touserdata(L, -1));
|
||||
lua_getfield(L, -1, "_BUFFER");
|
||||
auto buffer = static_cast<IDocument *>(lua_touserdata(L, -1));
|
||||
if (strcmp(property, "fold_level") == 0) {
|
||||
luaL_argcheck(L, buffer, 1, "must be lexing or folding");
|
||||
lua_pushinteger(L, buffer->GetLevel(luaL_checkinteger(L, 2) - 1));
|
||||
} else if (strcmp(property, "indent_amount") == 0) {
|
||||
luaL_argcheck(L, buffer, 1, "must be lexing or folding");
|
||||
lua_pushinteger(L, buffer->GetLineIndentation(luaL_checkinteger(L, 2) - 1));
|
||||
} else if (strcmp(property, "property") == 0) {
|
||||
lua_pushstring(L, lexer->PropertyGet(luaL_checkstring(L, 2)));
|
||||
} else if (strcmp(property, "property_int") == 0) {
|
||||
lua_pushstring(L, lexer->PropertyGet(luaL_checkstring(L, 2)));
|
||||
lua_pushinteger(L, lua_tointeger(L, -1));
|
||||
} else if (strcmp(property, "style_at") == 0) {
|
||||
luaL_argcheck(L, buffer, 1, "must be lexing or folding");
|
||||
int style = buffer->StyleAt(luaL_checkinteger(L, 2) - 1);
|
||||
lua_getfield(L, 4, "_TOKENSTYLES");
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
|
||||
if (luaL_checkinteger(L, -1) - 1 == style) break;
|
||||
lua_pop(L, 1); // style_num, leaving name on top
|
||||
} else if (strcmp(property, "line_state") == 0) {
|
||||
luaL_argcheck(L, buffer, 1, "must be lexing or folding");
|
||||
lua_pushinteger(L, buffer->GetLineState(luaL_checkinteger(L, 2) - 1));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** lexer.property[key] = value metamethod. */
|
||||
static int lexer_property_newindex(lua_State *L) {
|
||||
const char *property = lua_tostring(L, lua_upvalueindex(1));
|
||||
luaL_argcheck(
|
||||
L, strcmp(property, "fold_level") != 0 &&
|
||||
strcmp(property, "indent_amount") != 0 &&
|
||||
strcmp(property, "property_int") != 0 &&
|
||||
strcmp(property, "style_at") != 0 &&
|
||||
strcmp(property, "line_from_position") != 0, 3, "read-only property");
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
LexerLPeg *lexer = reinterpret_cast<LexerLPeg *>(lua_touserdata(L, -1));
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, lua_touserdata(L, -1));
|
||||
if (strcmp(property, "property") == 0)
|
||||
lexer->PropertySet(luaL_checkstring(L, 2), luaL_checkstring(L, 3));
|
||||
else if (strcmp(property, "line_state") == 0) {
|
||||
luaL_argcheck(
|
||||
L, lua_getfield(L, -1, "_BUFFER"), 1, "must be lexing or folding");
|
||||
auto buffer = static_cast<IDocument *>(lua_touserdata(L, -1));
|
||||
buffer->SetLineState(luaL_checkinteger(L, 2) - 1, luaL_checkinteger(L, 3));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** The lexer's `line_from_position` Lua function. */
|
||||
static int line_from_position(lua_State *L) {
|
||||
auto buffer = static_cast<IDocument *>(
|
||||
lua_touserdata(L, lua_upvalueindex(1)));
|
||||
lua_pushinteger(L, buffer->LineFromPosition(luaL_checkinteger(L, 1) - 1) + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** lexer.property metamethod. */
|
||||
static int lexer_index(lua_State *L) {
|
||||
const char *key = lua_tostring(L, 2);
|
||||
if (strcmp(key, "fold_level") == 0 || strcmp(key, "indent_amount") == 0 ||
|
||||
strcmp(key, "property") == 0 || strcmp(key, "property_int") == 0 ||
|
||||
strcmp(key, "style_at") == 0 || strcmp(key, "line_state") == 0) {
|
||||
lua_newtable(L);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushvalue(L, 2), lua_pushcclosure(L, lexer_property_index, 1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pushvalue(L, 2), lua_pushcclosure(L, lexer_property_newindex, 1);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_setmetatable(L, -2);
|
||||
} else if (strcmp(key, "line_from_position") == 0) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, lua_touserdata(L, -1));
|
||||
luaL_argcheck(
|
||||
L, lua_getfield(L, -1, "_BUFFER"), 2, "must be lexing or folding");
|
||||
lua_pushcclosure(L, line_from_position, 1);
|
||||
} else if (strncmp(key, "fold", 4) == 0) {
|
||||
// Alias lexer.fold* to lexer.property['fold*'].
|
||||
if (strcmp(key, "folding") == 0) key = "fold"; // lexer.fold() exists
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
LexerLPeg *lexer = reinterpret_cast<LexerLPeg *>(lua_touserdata(L, -1));
|
||||
const char *value = lexer->PropertyGet(luaL_gsub(L, key, "_", "."));
|
||||
lua_pushboolean(L, strcmp(value, "1") == 0);
|
||||
} else lua_rawget(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** lexer.property = value metamethod. */
|
||||
static int lexer_newindex(lua_State *L) {
|
||||
const char *key = lua_tostring(L, 2);
|
||||
luaL_argcheck(
|
||||
L, strcmp(key, "fold_level") != 0 && strcmp(key, "indent_amount") != 0 &&
|
||||
strcmp(key, "property") != 0 && strcmp(key, "property_int") != 0 &&
|
||||
strcmp(key, "style_at") != 0 && strcmp(key, "line_state") != 0 &&
|
||||
strcmp(key, "line_from_position") != 0, 3, "read-only property");
|
||||
if (strncmp(key, "fold", 4) == 0 && strcmp(key, "fold_level") != 0) {
|
||||
// Alias lexer.fold* to lexer.property['fold*'].
|
||||
if (strcmp(key, "folding") == 0) key = "fold"; // lexer.fold() exists
|
||||
key = luaL_gsub(L, key, "_", ".");
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
LexerLPeg *lexer = reinterpret_cast<LexerLPeg *>(lua_touserdata(L, -1));
|
||||
if (lua_toboolean(L, 3))
|
||||
lexer->PropertySet(
|
||||
key, (!lua_isnumber(L, 3) || lua_tonumber(L, 3) == 1) ? "1" : "0");
|
||||
else
|
||||
lexer->PropertySet(key, "0");
|
||||
} else lua_rawset(L, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the string property key the top of the stack with its expanded
|
||||
* value.
|
||||
* Invokes `lexer.property_expanded[]` to perform the expansion.
|
||||
* @param L The Lua State.
|
||||
*/
|
||||
static void expand_property(lua_State *L) {
|
||||
RECORD_STACK_TOP(L);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"), lua_getfield(L, -1, "lexer");
|
||||
lua_getfield(L, -1, "property_expanded");
|
||||
lua_pushvalue(L, -4), lua_gettable(L, -2), lua_replace(L, -5);
|
||||
lua_pop(L, 3); // property_expanded, lexer, _LOADED
|
||||
ASSERT_STACK_TOP(L);
|
||||
}
|
||||
|
||||
void LexerLPeg::ReadLexerNames(const char *path) {
|
||||
#if !_WIN32
|
||||
DIR *dir = opendir(path);
|
||||
if (!dir) return;
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir))) {
|
||||
char *p = strstr(entry->d_name, ".lua");
|
||||
if (p) lexerNames.emplace(entry->d_name, p - entry->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
#else
|
||||
struct _finddata_t file;
|
||||
std::string glob(path);
|
||||
glob += "/*";
|
||||
intptr_t handle = _findfirst(glob.c_str(), &file);
|
||||
if (handle == -1) return;
|
||||
do {
|
||||
char *p = strstr(file.name, ".lua");
|
||||
if (p) lexerNames.emplace(file.name, p - file.name);
|
||||
} while (_findnext(handle, &file) != -1);
|
||||
_findclose(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LexerLPeg::LogError(lua_State *L, const char *str) {
|
||||
const char *value = str ? str : lua_tostring(L, -1);
|
||||
PropertySet(LexerErrorKey, value);
|
||||
fprintf(stderr, "Lua Error: %s.\n", value);
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
|
||||
void LexerLPeg::SetStyle(int num, const char *style) {
|
||||
auto style_copy = static_cast<char *>(malloc(strlen(style) + 1));
|
||||
char *key = strcpy(style_copy, style), *next = nullptr, *val = nullptr;
|
||||
while (key) {
|
||||
if ((next = strchr(key, ','))) *next++ = '\0';
|
||||
if ((val = strchr(key, ':'))) *val++ = '\0';
|
||||
if (strcmp(key, "font") == 0 && val)
|
||||
SS(sci, SCI_STYLESETFONT, num, reinterpret_cast<sptr_t>(val));
|
||||
else if (strcmp(key, "size") == 0 && val)
|
||||
SS(sci, SCI_STYLESETSIZE, num, static_cast<int>(atoi(val)));
|
||||
else if (strcmp(key, "bold") == 0 || strcmp(key, "notbold") == 0 ||
|
||||
strcmp(key, "weight") == 0) {
|
||||
#if !CURSES
|
||||
int weight = SC_WEIGHT_NORMAL;
|
||||
if (*key == 'b')
|
||||
weight = SC_WEIGHT_BOLD;
|
||||
else if (*key == 'w' && val)
|
||||
weight = atoi(val);
|
||||
SS(sci, SCI_STYLESETWEIGHT, num, weight);
|
||||
#else
|
||||
// Scintilla curses requires font attributes to be stored in the "font
|
||||
// weight" style attribute.
|
||||
// First, clear any existing SC_WEIGHT_NORMAL, SC_WEIGHT_SEMIBOLD, or
|
||||
// SC_WEIGHT_BOLD values stored in the lower 16 bits. Then set the
|
||||
// appropriate curses attr.
|
||||
sptr_t weight =
|
||||
SS(sci, SCI_STYLEGETWEIGHT, num, 0) & ~(A_COLOR | A_CHARTEXT);
|
||||
int bold =
|
||||
*key == 'b' || (*key == 'w' && val && atoi(val) > SC_WEIGHT_NORMAL);
|
||||
SS(
|
||||
sci, SCI_STYLESETWEIGHT, num,
|
||||
bold ? weight | A_BOLD : weight & ~A_BOLD);
|
||||
#endif
|
||||
} else if (strcmp(key, "italics") == 0 || strcmp(key, "notitalics") == 0)
|
||||
SS(sci, SCI_STYLESETITALIC, num, *key == 'i');
|
||||
else if (strcmp(key, "underlined") == 0 ||
|
||||
strcmp(key, "notunderlined") == 0) {
|
||||
#if !CURSES
|
||||
SS(sci, SCI_STYLESETUNDERLINE, num, *key == 'u');
|
||||
#else
|
||||
// Scintilla curses requires font attributes to be stored in the "font
|
||||
// weight" style attribute.
|
||||
// First, clear any existing SC_WEIGHT_NORMAL, SC_WEIGHT_SEMIBOLD, or
|
||||
// SC_WEIGHT_BOLD values stored in the lower 16 bits. Then set the
|
||||
// appropriate curses attr.
|
||||
sptr_t weight =
|
||||
SS(sci, SCI_STYLEGETWEIGHT, num, 0) & ~(A_COLOR | A_CHARTEXT);
|
||||
SS(
|
||||
sci, SCI_STYLESETWEIGHT, num,
|
||||
(*key == 'u') ? weight | A_UNDERLINE : weight & ~A_UNDERLINE);
|
||||
#endif
|
||||
} else if ((strcmp(key, "fore") == 0 || strcmp(key, "back") == 0) &&
|
||||
val) {
|
||||
int msg = (*key == 'f') ? SCI_STYLESETFORE : SCI_STYLESETBACK;
|
||||
int color = static_cast<int>(strtol(val, nullptr, 0));
|
||||
if (*val == '#') { // #RRGGBB format; Scintilla format is 0xBBGGRR
|
||||
color = static_cast<int>(strtol(val + 1, nullptr, 16));
|
||||
color =
|
||||
((color & 0xFF0000) >> 16) | (color & 0xFF00) |
|
||||
((color & 0xFF) << 16); // convert to 0xBBGGRR
|
||||
}
|
||||
SS(sci, msg, num, color);
|
||||
} else if (strcmp(key, "eolfilled") == 0 ||
|
||||
strcmp(key, "noteolfilled") == 0)
|
||||
SS(sci, SCI_STYLESETEOLFILLED, num, *key == 'e');
|
||||
else if (strcmp(key, "characterset") == 0 && val)
|
||||
SS(sci, SCI_STYLESETCHARACTERSET, num, static_cast<int>(atoi(val)));
|
||||
else if (strcmp(key, "case") == 0 && val) {
|
||||
if (*val == 'u')
|
||||
SS(sci, SCI_STYLESETCASE, num, SC_CASE_UPPER);
|
||||
else if (*val == 'l')
|
||||
SS(sci, SCI_STYLESETCASE, num, SC_CASE_LOWER);
|
||||
} else if (strcmp(key, "visible") == 0 || strcmp(key, "notvisible") == 0)
|
||||
SS(sci, SCI_STYLESETVISIBLE, num, *key == 'v');
|
||||
else if (strcmp(key, "changeable") == 0 ||
|
||||
strcmp(key, "notchangeable") == 0)
|
||||
SS(sci, SCI_STYLESETCHANGEABLE, num, *key == 'c');
|
||||
else if (strcmp(key, "hotspot") == 0 || strcmp(key, "nothotspot") == 0)
|
||||
SS(sci, SCI_STYLESETHOTSPOT, num, *key == 'h');
|
||||
key = next;
|
||||
}
|
||||
free(style_copy);
|
||||
}
|
||||
|
||||
void LexerLPeg::SetStyles() {
|
||||
RECORD_STACK_TOP(L);
|
||||
// If the lexer defines additional styles, set their properties first (if
|
||||
// the user has not already defined them).
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
lua_getfield(L, -1, "_EXTRASTYLES");
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
|
||||
if (lua_isstring(L, -2) && lua_isstring(L, -1)) {
|
||||
lua_pushstring(L, "style."), lua_pushvalue(L, -3), lua_concat(L, 2);
|
||||
if (!*props.Get(lua_tostring(L, -1)))
|
||||
PropertySet(lua_tostring(L, -1), lua_tostring(L, -2));
|
||||
lua_pop(L, 1); // style name
|
||||
}
|
||||
lua_pop(L, 1); // _EXTRASTYLES
|
||||
|
||||
if (!SS || !sci) {
|
||||
lua_pop(L, 1); // lexer object
|
||||
// Skip, but do not report an error since `reinit` would remain `false`
|
||||
// and subsequent calls to `Lex()` and `Fold()` would repeatedly call this
|
||||
// function and error.
|
||||
ASSERT_STACK_TOP(L);
|
||||
return;
|
||||
}
|
||||
lua_pushstring(L, "style.default"), expand_property(L);
|
||||
SetStyle(STYLE_DEFAULT, lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // style
|
||||
SS(sci, SCI_STYLECLEARALL, 0, 0); // set default styles
|
||||
lua_getfield(L, -1, "_TOKENSTYLES");
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
|
||||
if (lua_isstring(L, -2) && lua_isnumber(L, -1) &&
|
||||
lua_tointeger(L, -1) - 1 != STYLE_DEFAULT) {
|
||||
lua_pushstring(L, "style."), lua_pushvalue(L, -3), lua_concat(L, 2);
|
||||
expand_property(L);
|
||||
SetStyle(lua_tointeger(L, -2) - 1, lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // style
|
||||
}
|
||||
lua_pop(L, 2); // _TOKENSTYLES, lexer object
|
||||
ASSERT_STACK_TOP(L);
|
||||
}
|
||||
|
||||
bool LexerLPeg::Init() {
|
||||
if (!props.GetExpanded(LexerHomeKey, nullptr) ||
|
||||
!*props.Get(LexerNameKey) || !L)
|
||||
return false;
|
||||
char *_home = reinterpret_cast<char *>(
|
||||
malloc(props.GetExpanded(LexerHomeKey, nullptr) + 1));
|
||||
props.GetExpanded(LexerHomeKey, _home);
|
||||
std::string home(_home);
|
||||
free(_home);
|
||||
const char *lexer = props.Get(LexerNameKey);
|
||||
RECORD_STACK_TOP(L);
|
||||
|
||||
// Designate the currently running LexerLPeg instance.
|
||||
// This needs to be done prior to calling any Lua lexer code, particularly
|
||||
// when `ownLua` is `false`, as there may be multiple LexerLPeg instances
|
||||
// floating around, and the lexer module methods and metamethods need to
|
||||
// know which instance to use.
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(this));
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
|
||||
// Determine where to look for the lexer module and themes.
|
||||
std::vector<std::string> dirs;
|
||||
size_t start = 0, end;
|
||||
while ((end = home.find(';', start)) != std::string::npos) {
|
||||
dirs.emplace_back(home, start, end - start);
|
||||
start = end + 1;
|
||||
}
|
||||
dirs.emplace_back(home, start);
|
||||
|
||||
// If necessary, load the lexer module.
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
|
||||
if (lua_getfield(L, -1, "lexer") == LUA_TNIL) {
|
||||
for (const std::string& dir : dirs) {
|
||||
lua_pushstring(L, dir.c_str());
|
||||
lua_pushstring(L, "/lexer.lua");
|
||||
lua_concat(L, 2);
|
||||
int status = luaL_loadfile(L, lua_tostring(L, -1));
|
||||
if (status == LUA_ERRFILE) {
|
||||
lua_pop(L, 2); // error message, filename
|
||||
continue; // try next directory
|
||||
}
|
||||
lua_remove(L, -2); // filename
|
||||
lua_pushcfunction(L, lua_error_handler);
|
||||
lua_insert(L, -2);
|
||||
if (status == LUA_OK && lua_pcall(L, 0, 1, -2) == LUA_OK) break;
|
||||
return (LogError(L), false);
|
||||
}
|
||||
if (lua_isnil(L, -1))
|
||||
return (LogError(L, "'lexer.lua' module not found"), false);
|
||||
lua_remove(L, -2); // lua_error_handler
|
||||
lua_replace(L, -2); // nil
|
||||
lua_pushinteger(L, SC_FOLDLEVELBASE);
|
||||
lua_setfield(L, -2, "FOLD_BASE");
|
||||
lua_pushinteger(L, SC_FOLDLEVELWHITEFLAG);
|
||||
lua_setfield(L, -2, "FOLD_BLANK");
|
||||
lua_pushinteger(L, SC_FOLDLEVELHEADERFLAG);
|
||||
lua_setfield(L, -2, "FOLD_HEADER");
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lexer_index), lua_setfield(L, -2, "__index");
|
||||
lua_pushcfunction(L, lexer_newindex), lua_setfield(L, -2, "__newindex");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushvalue(L, -1), lua_setfield(L, -3, "lexer");
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
// Update the userdata needed by lexer metamethods.
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawsetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
|
||||
// Load the language lexer.
|
||||
if (lua_getfield(L, -1, "load") != LUA_TFUNCTION)
|
||||
return (LogError(L, "'lexer.load' function not found"), false);
|
||||
lua_pushcfunction(L, lua_error_handler), lua_insert(L, -2);
|
||||
lua_pushstring(L, lexer), lua_pushnil(L), lua_pushboolean(L, 1);
|
||||
if (lua_pcall(L, 3, 1, -5) != LUA_OK) return (LogError(L), false);
|
||||
lua_remove(L, -2); // lua_error_handler
|
||||
lua_remove(L, -2); // lexer module
|
||||
lua_rawsetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
|
||||
// Load the theme and set up styles.
|
||||
if (props.GetExpanded(LexerThemeKey, nullptr)) {
|
||||
char *theme = reinterpret_cast<char *>(
|
||||
malloc(props.GetExpanded(LexerThemeKey, nullptr) + 1));
|
||||
props.GetExpanded(LexerThemeKey, theme);
|
||||
if (!strstr(theme, "/") && !strstr(theme, "\\")) { // theme name
|
||||
for (const std::string& dir : dirs) {
|
||||
lua_pushstring(L, dir.c_str());
|
||||
lua_pushstring(L, "/themes/");
|
||||
lua_pushstring(L, theme);
|
||||
lua_pushstring(L, ".lua");
|
||||
lua_concat(L, 4);
|
||||
if (luaL_loadfile(L, lua_tostring(L, -1)) != LUA_ERRFILE ||
|
||||
dir == dirs.back()) {
|
||||
lua_pop(L, 1); // function, leaving filename on top
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 2); // error message, filename
|
||||
}
|
||||
} else lua_pushstring(L, theme); // path to theme
|
||||
lua_pushcfunction(L, lua_error_handler);
|
||||
lua_insert(L, -2);
|
||||
if (luaL_loadfile(L, lua_tostring(L, -1)) == LUA_OK &&
|
||||
lua_pcall(L, 0, 0, -3) == LUA_OK)
|
||||
lua_pop(L, 2); // theme, lua_error_handler
|
||||
else
|
||||
LogError(L);
|
||||
free(theme);
|
||||
}
|
||||
SetStyles();
|
||||
|
||||
// If the lexer is a parent, it will have children in its _CHILDREN table.
|
||||
// In that case, determine which styles are language whitespace styles
|
||||
// ([lang]_whitespace). This is necessary for determining which language
|
||||
// to start lexing with.
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
if (lua_getfield(L, -1, "_CHILDREN") == LUA_TTABLE) {
|
||||
multilang = true;
|
||||
for (int i = 0; i <= STYLE_MAX; i++)
|
||||
ws[i] = strstr(NameOfStyle(i), "whitespace") ? true : false;
|
||||
}
|
||||
lua_pop(L, 2); // _CHILDREN, lexer object
|
||||
|
||||
reinit = false;
|
||||
PropertySet(LexerErrorKey, "");
|
||||
ASSERT_STACK_TOP(L);
|
||||
return true;
|
||||
}
|
||||
|
||||
void *LexerLPeg::StringResult(long lparam, const char *str) {
|
||||
if (lparam) strcpy(reinterpret_cast<char *>(lparam), str);
|
||||
return reinterpret_cast<void *>(strlen(str));
|
||||
}
|
||||
|
||||
LexerLPeg::LexerLPeg() : DefaultLexer("lpeg", SCLEX_LPEG), L(luaL_newstate()) {
|
||||
// Initialize the Lua state, load libraries, and set platform variables.
|
||||
if (!L) {
|
||||
fprintf(stderr, "Lua failed to initialize.\n");
|
||||
return;
|
||||
}
|
||||
#if LUA_VERSION_NUM < 502
|
||||
luaL_requiref(L, "", luaopen_base, 1), lua_pop(L, 1);
|
||||
#else
|
||||
luaL_requiref(L, "_G", luaopen_base, 1), lua_pop(L, 1);
|
||||
#endif
|
||||
luaL_requiref(L, LUA_TABLIBNAME, luaopen_table, 1), lua_pop(L, 1);
|
||||
luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1), lua_pop(L, 1);
|
||||
// TODO: figure out why lua_setglobal() is needed for lpeg.
|
||||
luaL_requiref(L, "lpeg", luaopen_lpeg, 1), lua_setglobal(L, "lpeg");
|
||||
#if _WIN32
|
||||
lua_pushboolean(L, 1), lua_setglobal(L, "WIN32");
|
||||
#endif
|
||||
#if __APPLE__
|
||||
lua_pushboolean(L, 1), lua_setglobal(L, "OSX");
|
||||
#endif
|
||||
#if GTK
|
||||
lua_pushboolean(L, 1), lua_setglobal(L, "GTK");
|
||||
#endif
|
||||
#if CURSES
|
||||
lua_pushboolean(L, 1), lua_setglobal(L, "CURSES");
|
||||
#endif
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerLPeg::Release() {
|
||||
if (ownLua && L)
|
||||
lua_close(L);
|
||||
else if (!ownLua) {
|
||||
lua_pushnil(L);
|
||||
lua_rawsetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
lua_pushnil(L), lua_setfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerLPeg::Lex(
|
||||
Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle,
|
||||
IDocument *buffer)
|
||||
{
|
||||
LexAccessor styler(buffer);
|
||||
if ((reinit && !Init()) || !L) {
|
||||
// Style everything in the default style.
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
styler.ColourTo(startPos + lengthDoc - 1, STYLE_DEFAULT);
|
||||
styler.Flush();
|
||||
return;
|
||||
}
|
||||
RECORD_STACK_TOP(L);
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(this));
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(buffer));
|
||||
lua_setfield(L, -2, "_BUFFER");
|
||||
|
||||
// Ensure the lexer has a grammar.
|
||||
// This could be done in the lexer module's `lex()`, but for large files,
|
||||
// passing string arguments from C to Lua is expensive.
|
||||
if (!lua_getfield(L, -1, "_GRAMMAR")) {
|
||||
lua_pop(L, 2); // _GRAMMAR, lexer object
|
||||
// Style everything in the default style.
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
styler.ColourTo(startPos + lengthDoc - 1, STYLE_DEFAULT);
|
||||
styler.Flush();
|
||||
return;
|
||||
} else lua_pop(L, 1); // _GRAMMAR
|
||||
|
||||
// Start from the beginning of the current style so LPeg matches it.
|
||||
// For multilang lexers, start at whitespace since embedded languages have
|
||||
// [lang]_whitespace styles. This is so LPeg can start matching child
|
||||
// languages instead of parent ones if necessary.
|
||||
if (startPos > 0) {
|
||||
Sci_PositionU i = startPos;
|
||||
while (i > 0 && styler.StyleAt(i - 1) == initStyle) i--;
|
||||
if (multilang)
|
||||
while (i > 0 && !ws[static_cast<size_t>(styler.StyleAt(i))]) i--;
|
||||
lengthDoc += startPos - i, startPos = i;
|
||||
}
|
||||
|
||||
if (lua_getfield(L, -1, "lex") != LUA_TFUNCTION)
|
||||
return LogError(L, "'lexer.lex' function not found");
|
||||
lua_pushcfunction(L, lua_error_handler), lua_insert(L, -2);
|
||||
lua_pushvalue(L, -3);
|
||||
lua_pushlstring(L, buffer->BufferPointer() + startPos, lengthDoc);
|
||||
lua_pushinteger(L, styler.StyleAt(startPos) + 1);
|
||||
if (lua_pcall(L, 3, 1, -5) != LUA_OK) return LogError(L);
|
||||
if (!lua_istable(L, -1))
|
||||
return LogError(L, "Table of tokens expected from 'lexer.lex'");
|
||||
// Style the text from the token table returned.
|
||||
int len = lua_rawlen(L, -1);
|
||||
if (len > 0) {
|
||||
int style = STYLE_DEFAULT;
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
lua_getfield(L, -3, "_TOKENSTYLES");
|
||||
// Loop through token-position pairs.
|
||||
for (int i = 1; i < len; i += 2) {
|
||||
style = STYLE_DEFAULT;
|
||||
if (lua_rawgeti(L, -2, i), lua_rawget(L, -2))
|
||||
style = lua_tointeger(L, -1) - 1;
|
||||
lua_pop(L, 1); // _TOKENSTYLES[token]
|
||||
lua_rawgeti(L, -2, i + 1); // pos
|
||||
unsigned int position = lua_tointeger(L, -1) - 1;
|
||||
lua_pop(L, 1); // pos
|
||||
if (style >= 0 && style <= STYLE_MAX)
|
||||
styler.ColourTo(startPos + position - 1, style);
|
||||
else
|
||||
lua_pushfstring(L, "Bad style number: %d", style), LogError(L);
|
||||
if (position > startPos + lengthDoc) break;
|
||||
}
|
||||
lua_pop(L, 1); // _TOKENSTYLES
|
||||
styler.ColourTo(startPos + lengthDoc - 1, style);
|
||||
styler.Flush();
|
||||
}
|
||||
lua_pop(L, 3); // token table returned, lua_error_handler, lexer object
|
||||
ASSERT_STACK_TOP(L);
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerLPeg::Fold(
|
||||
Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *buffer)
|
||||
{
|
||||
if ((reinit && !Init()) || !L) return;
|
||||
RECORD_STACK_TOP(L);
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(this));
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(buffer));
|
||||
lua_setfield(L, -2, "_BUFFER");
|
||||
LexAccessor styler(buffer);
|
||||
|
||||
if (lua_getfield(L, -1, "fold") != LUA_TFUNCTION)
|
||||
return LogError(L, "'lexer.fold' function not found");
|
||||
lua_pushcfunction(L, lua_error_handler), lua_insert(L, -2);
|
||||
lua_pushvalue(L, -3);
|
||||
Sci_Position currentLine = styler.GetLine(startPos);
|
||||
lua_pushlstring(L, buffer->BufferPointer() + startPos, lengthDoc);
|
||||
lua_pushinteger(L, startPos + 1);
|
||||
lua_pushinteger(L, currentLine + 1);
|
||||
lua_pushinteger(L, styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK);
|
||||
if (lua_pcall(L, 5, 1, -7) != LUA_OK) return LogError(L);
|
||||
if (!lua_istable(L, -1))
|
||||
return LogError(L, "Table of folds expected from 'lexer.fold'");
|
||||
// Fold the text from the fold table returned.
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) // line = level
|
||||
styler.SetLevel(lua_tointeger(L, -2) - 1, lua_tointeger(L, -1));
|
||||
lua_pop(L, 3); // fold table returned, lua_error_handler, lexer object
|
||||
ASSERT_STACK_TOP(L);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerLPeg::PropertySet(
|
||||
const char *key, const char *value)
|
||||
{
|
||||
props.Set(key, value, strlen(key), strlen(value));
|
||||
if (strcmp(key, LexerHomeKey) == 0 && lexerNames.empty())
|
||||
ReadLexerNames(value); // not using SCI_LOADLEXERLIBRARY private call
|
||||
if (reinit &&
|
||||
(strcmp(key, LexerHomeKey) == 0 || strcmp(key, LexerNameKey) == 0))
|
||||
Init();
|
||||
else if (L && SS && sci && strncmp(key, "style.", 6) == 0) {
|
||||
// The container is managing styles manually.
|
||||
RECORD_STACK_TOP(L);
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(this));
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "sci_lexer_lpeg");
|
||||
if (lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this))) {
|
||||
lua_getfield(L, -1, "_TOKENSTYLES");
|
||||
lua_pushstring(L, key + 6);
|
||||
if (lua_rawget(L, -2) == LUA_TNUMBER) {
|
||||
lua_pushstring(L, key), expand_property(L);
|
||||
int style_num = lua_tointeger(L, -2) - 1;
|
||||
SetStyle(style_num, lua_tostring(L, -1));
|
||||
if (style_num == STYLE_DEFAULT)
|
||||
// Assume a theme change, with the default style being set first.
|
||||
// Subsequent style settings will be based on the default.
|
||||
SS(sci, SCI_STYLECLEARALL, 0, 0);
|
||||
lua_pop(L, 1); // style
|
||||
}
|
||||
lua_pop(L, 2); // style number, _TOKENSTYLES
|
||||
}
|
||||
lua_pop(L, 1); // lexer object or nil
|
||||
ASSERT_STACK_TOP(L);
|
||||
}
|
||||
return -1; // no need to re-lex
|
||||
}
|
||||
|
||||
void * SCI_METHOD LexerLPeg::PrivateCall(int code, void *arg) {
|
||||
auto lParam = reinterpret_cast<sptr_t>(arg);
|
||||
switch(code) {
|
||||
case SCI_GETDIRECTFUNCTION:
|
||||
SS = reinterpret_cast<SciFnDirect>(lParam);
|
||||
return nullptr;
|
||||
case SCI_SETDOCPOINTER:
|
||||
sci = lParam;
|
||||
return nullptr;
|
||||
case SCI_CHANGELEXERSTATE:
|
||||
if (ownLua) lua_close(L);
|
||||
L = reinterpret_cast<lua_State *>(arg), ownLua = false;
|
||||
return nullptr;
|
||||
case SCI_LOADLEXERLIBRARY: {
|
||||
const char *path = reinterpret_cast<const char*>(arg);
|
||||
ReadLexerNames(path);
|
||||
std::string home(props.Get(LexerHomeKey));
|
||||
if (!home.empty()) home.push_back(';');
|
||||
home.append(path);
|
||||
PropertySet(LexerHomeKey, home.c_str());
|
||||
return nullptr;
|
||||
} case SCI_PROPERTYNAMES: {
|
||||
std::stringstream names;
|
||||
for (const std::string& name : lexerNames) names << name << '\n';
|
||||
return StringResult(lParam, names.str().c_str());
|
||||
} case SCI_SETLEXERLANGUAGE:
|
||||
if (strcmp(
|
||||
props.Get(LexerNameKey),
|
||||
reinterpret_cast<const char *>(arg)) != 0) {
|
||||
reinit = true;
|
||||
PropertySet(LexerErrorKey, "");
|
||||
PropertySet(LexerNameKey, reinterpret_cast<const char *>(arg));
|
||||
} else if (L)
|
||||
ownLua ? SetStyles() : static_cast<void>(Init());
|
||||
return nullptr;
|
||||
case SCI_GETLEXERLANGUAGE: {
|
||||
if (!L) return StringResult(lParam, "null");
|
||||
RECORD_STACK_TOP(L);
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
lua_getfield(L, -1, "_NAME");
|
||||
std::string val(lua_tostring(L, -1));
|
||||
lua_pop(L, 2); // lexer name, lexer object
|
||||
ASSERT_STACK_TOP(L);
|
||||
if (!SS || !sci || !multilang) return StringResult(lParam, val.c_str());
|
||||
val.push_back('/');
|
||||
int pos = SS(sci, SCI_GETCURRENTPOS, 0, 0);
|
||||
while (pos >= 0 && !ws[SS(sci, SCI_GETSTYLEAT, pos, 0)]) pos--;
|
||||
if (pos >= 0) {
|
||||
const char *name = NameOfStyle(SS(sci, SCI_GETSTYLEAT, pos, 0)), *p;
|
||||
if (name && (p = strstr(name, "_whitespace"))) {
|
||||
val.append(name, p - name);
|
||||
return StringResult(lParam, val.c_str());
|
||||
}
|
||||
}
|
||||
val.append(val, 0, val.length() - 1); // "lexer/lexer" fallback
|
||||
return StringResult(lParam, val.c_str());
|
||||
} case SCI_GETNAMEDSTYLES:
|
||||
if (!L) return reinterpret_cast<void *>(STYLE_DEFAULT);
|
||||
for (int i = 0; i < STYLE_MAX; i++)
|
||||
if (strcmp(NameOfStyle(i), reinterpret_cast<const char *>(arg)) == 0)
|
||||
return reinterpret_cast<void *>(i);
|
||||
return reinterpret_cast<void *>(STYLE_DEFAULT);
|
||||
case SCI_GETSTATUS:
|
||||
return StringResult(lParam, props.Get(LexerErrorKey));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD LexerLPeg::NameOfStyle(int style) {
|
||||
if (style < 0 || style > STYLE_MAX || !L) return nullptr;
|
||||
RECORD_STACK_TOP(L);
|
||||
styleName = "Not Available";
|
||||
lua_rawgetp(L, LUA_REGISTRYINDEX, reinterpret_cast<void *>(this));
|
||||
lua_getfield(L, -1, "_TOKENSTYLES");
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
|
||||
if (lua_tointeger(L, -1) - 1 == style) {
|
||||
styleName = lua_tostring(L, -2);
|
||||
lua_pop(L, 2); // value and key
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 2); // _TOKENSTYLES, lexer object
|
||||
ASSERT_STACK_TOP(L);
|
||||
return styleName.c_str();
|
||||
}
|
||||
|
||||
const char * SCI_METHOD LexerLPeg::PropertyGet(const char *key) {
|
||||
return props.Get(key);
|
||||
}
|
||||
|
||||
ILexer *LexerLPeg::LexerFactoryLPeg() { return new LexerLPeg(); }
|
||||
|
||||
LexerModule lmLPeg(SCLEX_LPEG, LexerLPeg::LexerFactoryLPeg, "lpeg");
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
static void LPegLex(Sci_PositionU, Sci_Position, int, WordList*[], Accessor&) {
|
||||
return;
|
||||
}
|
||||
|
||||
LexerModule lmLPeg(SCLEX_LPEG, LPegLex, "lpeg");
|
||||
|
||||
#endif // LPEG_LEXER
|
||||
|
|
@ -26,11 +26,10 @@
|
|||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "DefaultLexer.h"
|
||||
#include "LexerBase.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -41,8 +40,15 @@ struct latexFoldSave {
|
|||
latexFoldSave(const latexFoldSave &save) : structLev(save.structLev) {
|
||||
for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];
|
||||
}
|
||||
latexFoldSave &operator=(const latexFoldSave &save) {
|
||||
if (this != &save) {
|
||||
structLev = save.structLev;
|
||||
for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
int openBegins[8];
|
||||
int structLev;
|
||||
Sci_Position structLev;
|
||||
};
|
||||
|
||||
class LexerLaTeX : public LexerBase {
|
||||
|
|
@ -81,8 +87,16 @@ public:
|
|||
static ILexer *LexerFactoryLaTeX() {
|
||||
return new LexerLaTeX();
|
||||
}
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
// ILexerWithIdentity methods
|
||||
const char * SCI_METHOD GetName() override {
|
||||
return "latex";
|
||||
}
|
||||
int SCI_METHOD GetIdentifier() override {
|
||||
return SCLEX_LATEX;
|
||||
}
|
||||
};
|
||||
|
||||
static bool latexIsSpecial(int ch) {
|
||||
|
|
@ -291,6 +305,8 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
latexStateReset(mode, state);
|
||||
if (latexLastWordIs(i, styler, "{verbatim}")) {
|
||||
state = SCE_L_VERBATIM;
|
||||
} else if (latexLastWordIs(i, styler, "{lstlisting}")) {
|
||||
state = SCE_L_VERBATIM;
|
||||
} else if (latexLastWordIs(i, styler, "{comment}")) {
|
||||
state = SCE_L_COMMENT2;
|
||||
} else if (latexLastWordIs(i, styler, "{math}") && mode == 0) {
|
||||
|
|
@ -439,6 +455,9 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
if (latexLastWordIs(match, styler, "{verbatim}")) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_L_COMMAND;
|
||||
} else if (latexLastWordIs(match, styler, "{lstlisting}")) {
|
||||
styler.ColourTo(i - 1, state);
|
||||
state = SCE_L_COMMAND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
#define SCE_LISP_CHARACTER 29
|
||||
#define SCE_LISP_MACRO 30
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
|
||||
|
|
|
|||
|
|
@ -14,10 +14,13 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
|
@ -25,9 +28,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],
|
||||
// return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.
|
||||
|
|
@ -48,14 +49,14 @@ static void ColouriseLuaDoc(
|
|||
WordList *keywordlists[],
|
||||
Accessor &styler) {
|
||||
|
||||
WordList &keywords = *keywordlists[0];
|
||||
WordList &keywords2 = *keywordlists[1];
|
||||
WordList &keywords3 = *keywordlists[2];
|
||||
WordList &keywords4 = *keywordlists[3];
|
||||
WordList &keywords5 = *keywordlists[4];
|
||||
WordList &keywords6 = *keywordlists[5];
|
||||
WordList &keywords7 = *keywordlists[6];
|
||||
WordList &keywords8 = *keywordlists[7];
|
||||
const WordList &keywords = *keywordlists[0];
|
||||
const WordList &keywords2 = *keywordlists[1];
|
||||
const WordList &keywords3 = *keywordlists[2];
|
||||
const WordList &keywords4 = *keywordlists[3];
|
||||
const WordList &keywords5 = *keywordlists[4];
|
||||
const WordList &keywords6 = *keywordlists[5];
|
||||
const WordList &keywords7 = *keywordlists[6];
|
||||
const WordList &keywords8 = *keywordlists[7];
|
||||
|
||||
// Accepts accented characters
|
||||
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
|
||||
|
|
@ -77,20 +78,26 @@ static void ColouriseLuaDoc(
|
|||
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);
|
||||
const int lineState = styler.GetLineState(currentLine - 1);
|
||||
nestLevel = lineState >> 9;
|
||||
sepCount = lineState & 0xFF;
|
||||
stringWs = lineState & 0x100;
|
||||
}
|
||||
|
||||
// results of identifier/keyword matching
|
||||
Sci_Position idenPos = 0;
|
||||
Sci_Position idenWordPos = 0;
|
||||
int idenStyle = SCE_LUA_IDENTIFIER;
|
||||
bool foundGoto = false;
|
||||
|
||||
// Do not leak onto next line
|
||||
if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
|
||||
initStyle = SCE_LUA_DEFAULT;
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
if (startPos == 0 && sc.ch == '#') {
|
||||
// shbang line: # is a comment only if first char of the script
|
||||
if (startPos == 0 && sc.ch == '#' && sc.chNext == '!') {
|
||||
// shbang line: "#!" is a comment only if located at the start of the script
|
||||
sc.SetState(SCE_LUA_COMMENTLINE);
|
||||
}
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
|
|
@ -178,40 +185,32 @@ static void ColouriseLuaDoc(
|
|||
sc.SetState(SCE_LUA_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_LUA_IDENTIFIER) {
|
||||
if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (keywords.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD);
|
||||
if (strcmp(s, "goto") == 0) { // goto <label> forward scan
|
||||
sc.SetState(SCE_LUA_DEFAULT);
|
||||
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
|
||||
sc.Forward();
|
||||
if (setWordStart.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_LUA_LABEL);
|
||||
sc.Forward();
|
||||
while (setWord.Contains(sc.ch))
|
||||
sc.Forward();
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (keywords.InList(s))
|
||||
sc.ChangeState(SCE_LUA_WORD);
|
||||
}
|
||||
sc.SetState(SCE_LUA_DEFAULT);
|
||||
}
|
||||
} else if (keywords2.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD2);
|
||||
} else if (keywords3.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD3);
|
||||
} else if (keywords4.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD4);
|
||||
} else if (keywords5.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD5);
|
||||
} else if (keywords6.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD6);
|
||||
} else if (keywords7.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD7);
|
||||
} else if (keywords8.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD8);
|
||||
idenPos--; // commit already-scanned identitier/word parts
|
||||
if (idenWordPos > 0) {
|
||||
idenWordPos--;
|
||||
sc.ChangeState(idenStyle);
|
||||
sc.ForwardBytes(idenWordPos);
|
||||
idenPos -= idenWordPos;
|
||||
if (idenPos > 0) {
|
||||
sc.SetState(SCE_LUA_IDENTIFIER);
|
||||
sc.ForwardBytes(idenPos);
|
||||
}
|
||||
} else {
|
||||
sc.ForwardBytes(idenPos);
|
||||
}
|
||||
sc.SetState(SCE_LUA_DEFAULT);
|
||||
if (foundGoto) { // goto <label> forward scan
|
||||
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();
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (keywords.InList(s)) // labels cannot be keywords
|
||||
sc.ChangeState(SCE_LUA_WORD);
|
||||
}
|
||||
sc.SetState(SCE_LUA_DEFAULT);
|
||||
}
|
||||
|
|
@ -257,7 +256,7 @@ static void ColouriseLuaDoc(
|
|||
}
|
||||
} else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) {
|
||||
if (sc.ch == '[') {
|
||||
int sep = LongDelimCheck(sc);
|
||||
const int sep = LongDelimCheck(sc);
|
||||
if (sep == 1 && sepCount == 1) { // [[-only allowed to nest
|
||||
nestLevel++;
|
||||
sc.Forward();
|
||||
|
|
@ -285,6 +284,66 @@ static void ColouriseLuaDoc(
|
|||
sc.Forward();
|
||||
}
|
||||
} else if (setWordStart.Contains(sc.ch)) {
|
||||
// For matching various identifiers with dots and colons, multiple
|
||||
// matches are done as identifier segments are added. Longest match is
|
||||
// set to a word style. The non-matched part is in identifier style.
|
||||
std::string ident;
|
||||
idenPos = 0;
|
||||
idenWordPos = 0;
|
||||
idenStyle = SCE_LUA_IDENTIFIER;
|
||||
foundGoto = false;
|
||||
int cNext;
|
||||
do {
|
||||
int c;
|
||||
const Sci_Position idenPosOld = idenPos;
|
||||
std::string identSeg;
|
||||
identSeg += static_cast<char>(sc.GetRelative(idenPos++));
|
||||
while (setWord.Contains(c = sc.GetRelative(idenPos))) {
|
||||
identSeg += static_cast<char>(c);
|
||||
idenPos++;
|
||||
}
|
||||
if (keywords.InList(identSeg.c_str()) && (idenPosOld > 0)) {
|
||||
idenPos = idenPosOld - 1; // keywords cannot mix
|
||||
ident.pop_back();
|
||||
break;
|
||||
}
|
||||
ident += identSeg;
|
||||
const char* s = ident.c_str();
|
||||
int newStyle = SCE_LUA_IDENTIFIER;
|
||||
if (keywords.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD;
|
||||
} else if (keywords2.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD2;
|
||||
} else if (keywords3.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD3;
|
||||
} else if (keywords4.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD4;
|
||||
} else if (keywords5.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD5;
|
||||
} else if (keywords6.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD6;
|
||||
} else if (keywords7.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD7;
|
||||
} else if (keywords8.InList(s)) {
|
||||
newStyle = SCE_LUA_WORD8;
|
||||
}
|
||||
if (newStyle != SCE_LUA_IDENTIFIER) {
|
||||
idenStyle = newStyle;
|
||||
idenWordPos = idenPos;
|
||||
}
|
||||
if (idenStyle == SCE_LUA_WORD) // keywords cannot mix
|
||||
break;
|
||||
cNext = sc.GetRelative(idenPos + 1);
|
||||
if ((c == '.' || c == ':') && setWordStart.Contains(cNext)) {
|
||||
ident += static_cast<char>(c);
|
||||
idenPos++;
|
||||
} else {
|
||||
cNext = 0;
|
||||
}
|
||||
} while (cNext);
|
||||
if ((idenStyle == SCE_LUA_WORD) && (ident.compare("goto") == 0)) {
|
||||
foundGoto = true;
|
||||
}
|
||||
sc.SetState(SCE_LUA_IDENTIFIER);
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.SetState(SCE_LUA_STRING);
|
||||
|
|
@ -322,48 +381,26 @@ static void ColouriseLuaDoc(
|
|||
}
|
||||
}
|
||||
|
||||
if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (keywords.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD);
|
||||
} else if (keywords2.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD2);
|
||||
} else if (keywords3.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD3);
|
||||
} else if (keywords4.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD4);
|
||||
} else if (keywords5.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD5);
|
||||
} else if (keywords6.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD6);
|
||||
} else if (keywords7.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD7);
|
||||
} else if (keywords8.InList(s)) {
|
||||
sc.ChangeState(SCE_LUA_WORD8);
|
||||
}
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
static void FoldLuaDoc(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, WordList *[],
|
||||
Accessor &styler) {
|
||||
Sci_PositionU lengthDoc = startPos + length;
|
||||
const Sci_PositionU lengthDoc = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
int levelCurrent = levelPrev;
|
||||
char chNext = styler[startPos];
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
|
||||
for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
|
||||
char ch = chNext;
|
||||
const char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
int style = styleNext;
|
||||
const int style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
if (style == SCE_LUA_WORD) {
|
||||
if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
|
||||
char s[10] = "";
|
||||
|
|
@ -433,4 +470,33 @@ static const char * const luaWordListDesc[] = {
|
|||
0
|
||||
};
|
||||
|
||||
LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);
|
||||
namespace {
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer Lua SCLEX_LUA SCE_LUA_:
|
||||
0, "SCE_LUA_DEFAULT", "default", "White space: Visible only in View Whitespace mode (or if it has a back colour)",
|
||||
1, "SCE_LUA_COMMENT", "comment", "Block comment (Lua 5.0)",
|
||||
2, "SCE_LUA_COMMENTLINE", "comment line", "Line comment",
|
||||
3, "SCE_LUA_COMMENTDOC", "comment documentation", "Doc comment -- Not used in Lua (yet?)",
|
||||
4, "SCE_LUA_NUMBER", "literal numeric", "Number",
|
||||
5, "SCE_LUA_WORD", "keyword", "Keyword",
|
||||
6, "SCE_LUA_STRING", "literal string", "(Double quoted) String",
|
||||
7, "SCE_LUA_CHARACTER", "literal string character", "Character (Single quoted string)",
|
||||
8, "SCE_LUA_LITERALSTRING", "literal string", "Literal string",
|
||||
9, "SCE_LUA_PREPROCESSOR", "preprocessor", "Preprocessor (obsolete in Lua 4.0 and up)",
|
||||
10, "SCE_LUA_OPERATOR", "operator", "Operators",
|
||||
11, "SCE_LUA_IDENTIFIER", "identifier", "Identifier (everything else...)",
|
||||
12, "SCE_LUA_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
13, "SCE_LUA_WORD2", "identifier", "Other keywords",
|
||||
14, "SCE_LUA_WORD3", "identifier", "Other keywords",
|
||||
15, "SCE_LUA_WORD4", "identifier", "Other keywords",
|
||||
16, "SCE_LUA_WORD5", "identifier", "Other keywords",
|
||||
17, "SCE_LUA_WORD6", "identifier", "Other keywords",
|
||||
18, "SCE_LUA_WORD7", "identifier", "Other keywords",
|
||||
19, "SCE_LUA_WORD8", "identifier", "Other keywords",
|
||||
20, "SCE_LUA_LABEL", "label", "Labels",
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc, lexicalClasses, ELEMENTS(lexicalClasses));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// Scintilla source code edit control
|
||||
// Encoding: UTF-8
|
||||
/** @file LexMMIXAL.cxx
|
||||
** Lexer for MMIX Assembler Language.
|
||||
** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
|
||||
** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
|
||||
** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
|
||||
**/
|
||||
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
|
||||
|
|
@ -25,16 +26,14 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
|
||||
}
|
||||
|
||||
inline bool isMMIXALOperator(char ch) {
|
||||
static inline bool isMMIXALOperator(char ch) {
|
||||
if (IsASCII(ch) && isalnum(ch))
|
||||
return false;
|
||||
if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
|
||||
|
|
@ -86,8 +85,6 @@ static void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
} else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER
|
||||
if (!isdigit(sc.ch)) {
|
||||
if (IsAWordChar(sc.ch)) {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
sc.ChangeState(SCE_MMIXAL_REF);
|
||||
sc.SetState(SCE_MMIXAL_REF);
|
||||
} else {
|
||||
|
|
@ -100,12 +97,11 @@ static void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
}
|
||||
} else if (sc.state == SCE_MMIXAL_REF) { // REF
|
||||
if (!IsAWordChar(sc.ch) ) {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
char s0[100];
|
||||
sc.GetCurrent(s0, sizeof(s0));
|
||||
const char *s = s0;
|
||||
if (*s == ':') { // ignore base prefix for match
|
||||
for (size_t i = 0; i != sizeof(s)-1; ++i) {
|
||||
*(s+i) = *(s+i+1);
|
||||
}
|
||||
++s;
|
||||
}
|
||||
if (special_register.InList(s)) {
|
||||
sc.ChangeState(SCE_MMIXAL_REGISTER);
|
||||
|
|
@ -155,9 +151,7 @@ static void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST
|
||||
sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS
|
||||
if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
|
||||
if (!sc.atLineEnd) {
|
||||
sc.SetState(SCE_MMIXAL_COMMENT);
|
||||
}
|
||||
sc.SetState(SCE_MMIXAL_COMMENT);
|
||||
} else if (isdigit(sc.ch)) {
|
||||
sc.SetState(SCE_MMIXAL_NUMBER);
|
||||
} else if (IsAWordChar(sc.ch) || sc.Match('@')) {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static int GetLotLineState(std::string &line) {
|
||||
if (line.length()) {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
#define KW_MSSQL_STATEMENTS 0
|
||||
#define KW_MSSQL_DATA_TYPES 1
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Is it a core character (C isalpha(), exclamation and question mark)
|
||||
|
|
@ -84,7 +82,7 @@ static inline bool IsAlNumSym(int ch) {
|
|||
* \param startPos Where to start scanning
|
||||
* \param length Where to scan to
|
||||
* \param initStyle The style at the initial point, not used in this folder
|
||||
* \param keywordslists The keywordslists, currently, number 5 is used
|
||||
* \param keywordlists The keywordslists, currently, number 5 is used
|
||||
* \param styler The styler
|
||||
*/
|
||||
static void ColouriseMagikDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
|
|
@ -330,7 +328,7 @@ static const char * const magikWordListDesc[] = {
|
|||
*
|
||||
* \param keywordslist The list of keywords that are scanned, they should only
|
||||
* contain the start keywords, not the end keywords
|
||||
* \param The actual keyword
|
||||
* \param keyword The actual keyword
|
||||
* \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
|
||||
* 0 otherwise
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
return (styler[i] == '\n') ||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,7 @@
|
|||
#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');
|
||||
|
|
@ -147,6 +145,7 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
WordList **, Accessor &styler) {
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
int precharCount = 0;
|
||||
bool isLinkNameDetecting = false;
|
||||
// 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.
|
||||
|
|
@ -339,6 +338,27 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
++precharCount;
|
||||
}
|
||||
|
||||
// Any link
|
||||
if (sc.state == SCE_MARKDOWN_LINK) {
|
||||
if (sc.Match("](") && sc.GetRelative(-1) != '\\') {
|
||||
sc.Forward(2);
|
||||
isLinkNameDetecting = true;
|
||||
}
|
||||
else if (sc.Match("]:") && sc.GetRelative(-1) != '\\') {
|
||||
sc.Forward(2);
|
||||
sc.SetState(SCE_MARKDOWN_DEFAULT);
|
||||
}
|
||||
else if (!isLinkNameDetecting && sc.ch == ']' && sc.GetRelative(-1) != '\\') {
|
||||
sc.Forward();
|
||||
sc.SetState(SCE_MARKDOWN_DEFAULT);
|
||||
}
|
||||
else if (isLinkNameDetecting && sc.ch == ')' && sc.GetRelative(-1) != '\\') {
|
||||
sc.Forward();
|
||||
sc.SetState(SCE_MARKDOWN_DEFAULT);
|
||||
isLinkNameDetecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
// New state anywhere in doc
|
||||
if (sc.state == SCE_MARKDOWN_DEFAULT) {
|
||||
if (sc.atLineStart && sc.ch == '#') {
|
||||
|
|
@ -346,38 +366,16 @@ static void ColorizeMarkdownDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
freezeCursor = true;
|
||||
}
|
||||
// Links and Images
|
||||
if (sc.Match("![") || sc.ch == '[') {
|
||||
Sci_Position i = 0, j = 0, k = 0;
|
||||
Sci_Position len = endPos - sc.currentPos;
|
||||
while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
|
||||
;
|
||||
if (sc.GetRelative(i) == ']') {
|
||||
j = i;
|
||||
if (sc.GetRelative(++i) == '(') {
|
||||
while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\'))
|
||||
;
|
||||
if (sc.GetRelative(i) == ')')
|
||||
k = i;
|
||||
}
|
||||
else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
|
||||
while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
|
||||
;
|
||||
if (sc.GetRelative(i) == ']')
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
// At least a link text
|
||||
if (j) {
|
||||
sc.SetState(SCE_MARKDOWN_LINK);
|
||||
sc.Forward(j);
|
||||
// Also has a URL or reference portion
|
||||
if (k)
|
||||
sc.Forward(k - j);
|
||||
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
|
||||
}
|
||||
if (sc.Match("![")) {
|
||||
sc.SetState(SCE_MARKDOWN_LINK);
|
||||
sc.Forward(2);
|
||||
}
|
||||
else if (sc.ch == '[' && sc.GetRelative(-1) != '\\') {
|
||||
sc.SetState(SCE_MARKDOWN_LINK);
|
||||
sc.Forward();
|
||||
}
|
||||
// Code - also a special case for alternate inside spacing
|
||||
if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
|
||||
else if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
|
||||
sc.SetState(SCE_MARKDOWN_CODE2);
|
||||
sc.Forward();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// Scintilla source code edit control
|
||||
// Encoding: UTF-8
|
||||
/** @file LexMatlab.cxx
|
||||
** Lexer for Matlab.
|
||||
** Written by José Fonseca
|
||||
** Written by José Fonseca
|
||||
**
|
||||
** Changes by Christoph Dalitz 2003/12/04:
|
||||
** - added support for Octave
|
||||
|
|
@ -18,6 +19,9 @@
|
|||
**
|
||||
** Changes by John Donoghue 2016/11/15
|
||||
** - update matlab code folding
|
||||
**
|
||||
** Changes by John Donoghue 2017/01/18
|
||||
** - update matlab block comment detection
|
||||
**/
|
||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
|
@ -40,9 +44,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static bool IsMatlabCommentChar(int c) {
|
||||
return (c == '%') ;
|
||||
|
|
@ -62,6 +64,7 @@ static int CheckKeywordFoldPoint(char *str) {
|
|||
if (strcmp ("if", str) == 0 ||
|
||||
strcmp ("for", str) == 0 ||
|
||||
strcmp ("switch", str) == 0 ||
|
||||
strcmp ("while", str) == 0 ||
|
||||
strcmp ("try", str) == 0 ||
|
||||
strcmp ("do", str) == 0 ||
|
||||
strcmp ("parfor", str) == 0 ||
|
||||
|
|
@ -73,6 +76,15 @@ static int CheckKeywordFoldPoint(char *str) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
|
||||
Sci_Position line = styler.GetLine(startPos);
|
||||
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position i = startPos; i < eol_pos; i++) {
|
||||
char ch = styler[i];
|
||||
if(!IsASpace(ch)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ColouriseMatlabOctaveDoc(
|
||||
Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
|
|
@ -88,6 +100,9 @@ static void ColouriseMatlabOctaveDoc(
|
|||
// of a string
|
||||
bool transpose = false;
|
||||
|
||||
// count of brackets as boolean for when end could be an operator not a keyword
|
||||
int allow_end_op = 0;
|
||||
|
||||
// approximate position of first non space character in a line
|
||||
int nonSpaceColumn = -1;
|
||||
// approximate column position of the current character in a line
|
||||
|
|
@ -140,8 +155,12 @@ static void ColouriseMatlabOctaveDoc(
|
|||
} else if (sc.state == SCE_MATLAB_KEYWORD) {
|
||||
if (!isalnum(sc.ch) && sc.ch != '_') {
|
||||
char s[100];
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
|
||||
if (keywords.InList(s)) {
|
||||
if (strcmp ("end", s) == 0 && allow_end_op) {
|
||||
sc.ChangeState(SCE_MATLAB_NUMBER);
|
||||
}
|
||||
sc.SetState(SCE_MATLAB_DEFAULT);
|
||||
transpose = false;
|
||||
} else {
|
||||
|
|
@ -180,7 +199,7 @@ static void ColouriseMatlabOctaveDoc(
|
|||
}
|
||||
} else if (sc.state == SCE_MATLAB_COMMENT) {
|
||||
// end or start of a nested a block comment?
|
||||
if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) {
|
||||
if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler)) {
|
||||
if(commentDepth > 0) commentDepth --;
|
||||
|
||||
curLine = styler.GetLine(sc.currentPos);
|
||||
|
|
@ -192,7 +211,7 @@ static void ColouriseMatlabOctaveDoc(
|
|||
transpose = false;
|
||||
}
|
||||
}
|
||||
else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column)
|
||||
else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler))
|
||||
{
|
||||
commentDepth ++;
|
||||
|
||||
|
|
@ -214,8 +233,11 @@ static void ColouriseMatlabOctaveDoc(
|
|||
if (sc.state == SCE_MATLAB_DEFAULT) {
|
||||
if (IsCommentChar(sc.ch)) {
|
||||
// ncrement depth if we are a block comment
|
||||
if(sc.chNext == '{' && nonSpaceColumn == column)
|
||||
commentDepth ++;
|
||||
if(sc.chNext == '{' && nonSpaceColumn == column) {
|
||||
if(IsSpaceToEOL(sc.currentPos+2, styler)) {
|
||||
commentDepth ++;
|
||||
}
|
||||
}
|
||||
curLine = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(curLine, commentDepth);
|
||||
sc.SetState(SCE_MATLAB_COMMENT);
|
||||
|
|
@ -238,6 +260,12 @@ static void ColouriseMatlabOctaveDoc(
|
|||
} else if (isalpha(sc.ch)) {
|
||||
sc.SetState(SCE_MATLAB_KEYWORD);
|
||||
} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
|
||||
if (sc.ch == '(' || sc.ch == '[' || sc.ch == '{') {
|
||||
allow_end_op ++;
|
||||
} else if ((sc.ch == ')' || sc.ch == ']' || sc.ch == '}') && (allow_end_op > 0)) {
|
||||
allow_end_op --;
|
||||
}
|
||||
|
||||
if (sc.ch == ')' || sc.ch == ']' || sc.ch == '}') {
|
||||
transpose = true;
|
||||
} else {
|
||||
|
|
@ -266,6 +294,12 @@ static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
WordList *[], Accessor &styler,
|
||||
bool (*IsComment)(int ch)) {
|
||||
|
||||
if (styler.GetPropertyInt("fold") == 0)
|
||||
return;
|
||||
|
||||
const bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
|
||||
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
|
|
@ -286,11 +320,11 @@ static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
|
||||
// a line that starts with a comment
|
||||
if (style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {
|
||||
if (foldComment && style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {
|
||||
// start/end of block comment
|
||||
if (chNext == '{')
|
||||
if (chNext == '{' && IsSpaceToEOL(i+2, styler))
|
||||
levelNext ++;
|
||||
if (chNext == '}')
|
||||
if (chNext == '}' && IsSpaceToEOL(i+2, styler))
|
||||
levelNext --;
|
||||
}
|
||||
// keyword
|
||||
|
|
@ -305,14 +339,14 @@ static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
|
|||
wordlen = 0;
|
||||
|
||||
levelNext += CheckKeywordFoldPoint(word);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IsASpace(ch))
|
||||
visibleChars++;
|
||||
if (atEOL || (i == endPos-1)) {
|
||||
int levelUse = levelCurrent;
|
||||
int lev = levelUse | levelNext << 16;
|
||||
if (visibleChars == 0)
|
||||
if (visibleChars == 0 && foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if (levelUse < levelNext)
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
|
|
|
|||
222
src/stc/scintilla/lexers/LexMaxima.cxx
Normal file
222
src/stc/scintilla/lexers/LexMaxima.cxx
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexMaxima.cxx
|
||||
** Lexer for Maxima (http://maxima.sourceforge.net).
|
||||
** Written by Gunter Königsmann based on the lisp lexer by Alexey Yutkin and Neil Hodgson .
|
||||
**/
|
||||
// Copyright 2018 by Gunter Königsmann <wxMaxima@physikbuch.de>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
using namespace Scintilla;
|
||||
|
||||
static inline bool isMaximaoperator(char ch) {
|
||||
return (ch == '\'' || ch == '`' || ch == '(' ||
|
||||
ch == ')' || ch == '[' || ch == ']' ||
|
||||
ch == '{' || ch == '}' || ch == '!' ||
|
||||
ch == '*' || ch == '/' || ch == '^' ||
|
||||
ch == ',' || ch == ':' || ch == '+' ||
|
||||
ch == '-');
|
||||
}
|
||||
|
||||
static void ColouriseMaximaDoc(Sci_PositionU startPos, Sci_Position length, int lastStyle,
|
||||
WordList *[],
|
||||
Accessor &styler) {
|
||||
|
||||
styler.StartAt(startPos);
|
||||
|
||||
Sci_PositionU lengthDoc = startPos + length;
|
||||
styler.StartSegment(startPos);
|
||||
|
||||
Sci_PositionU i = startPos;
|
||||
|
||||
// If we are in the middle of a comment we go back to its start before highlighting
|
||||
if(lastStyle == SCE_MAXIMA_COMMENT)
|
||||
{
|
||||
while((i>0) &&
|
||||
!((styler.SafeGetCharAt(i+1) == '*') && (styler.SafeGetCharAt(i) == '/')))
|
||||
i--;
|
||||
}
|
||||
|
||||
for (; i < lengthDoc; i++) {
|
||||
char ch = styler.SafeGetCharAt(i);
|
||||
char chNext = styler.SafeGetCharAt(i + 1);
|
||||
|
||||
if (styler.IsLeadByte(ch))
|
||||
continue;
|
||||
|
||||
// Handle comments.
|
||||
// Comments start with /* and end with */
|
||||
if((ch == '/') && (chNext == '*'))
|
||||
{
|
||||
i++;i++;
|
||||
|
||||
chNext = styler.SafeGetCharAt(i);
|
||||
for (; i < lengthDoc; i++)
|
||||
{
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
if((ch == '*') && (chNext == '/'))
|
||||
{
|
||||
i++;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i > lengthDoc)
|
||||
i = lengthDoc;
|
||||
i--;
|
||||
styler.ColourTo(i, SCE_MAXIMA_COMMENT);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle Operators
|
||||
if(isMaximaoperator(ch))
|
||||
{
|
||||
styler.ColourTo(i, SCE_MAXIMA_OPERATOR);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle command endings.
|
||||
if((ch == '$') || (ch == ';'))
|
||||
{
|
||||
styler.ColourTo(i, SCE_MAXIMA_COMMANDENDING);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle numbers. Numbers always begin with a digit.
|
||||
if(IsASCII(ch) && isdigit(ch))
|
||||
{
|
||||
i++;
|
||||
for (; i < lengthDoc; i++)
|
||||
{
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
|
||||
if(ch == '.')
|
||||
continue;
|
||||
|
||||
// A "e" or similar can be followed by a "+" or a "-"
|
||||
if(((ch == 'e') || (ch == 'b') || (ch == 'g') || (ch == 'f')) &&
|
||||
((chNext == '+') || (chNext == '-')))
|
||||
{
|
||||
i++;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!IsASCII(ch) || !(isdigit(ch) || islower(ch) || isupper(ch)))
|
||||
{
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
styler.ColourTo(i, SCE_MAXIMA_NUMBER);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if(ch == '\"')
|
||||
{
|
||||
i++;
|
||||
for (; i < lengthDoc; i++)
|
||||
{
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
if(ch == '\\')
|
||||
i++;
|
||||
else
|
||||
{
|
||||
if(ch == '\"')
|
||||
break;
|
||||
}
|
||||
}
|
||||
styler.ColourTo(i, SCE_MAXIMA_STRING);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle keywords. Maxima treats Non-ASCII chars as ordinary letters.
|
||||
if(((!IsASCII(ch))) || isalpha(ch) || (ch == '_'))
|
||||
{
|
||||
char cmd[100];
|
||||
int cmdidx = 0;
|
||||
memset(cmd,0,100);
|
||||
cmd[cmdidx++] = ch;
|
||||
i++;
|
||||
for (; i < lengthDoc; i++)
|
||||
{
|
||||
ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
if(ch == '\\')
|
||||
{
|
||||
if(cmdidx < 99)
|
||||
cmd[cmdidx++] = ch;
|
||||
i++;
|
||||
if(cmdidx < 99)
|
||||
cmd[cmdidx++] = ch;
|
||||
continue;
|
||||
}
|
||||
if(isMaximaoperator(ch) || ((IsASCII(ch) && !isalpha(ch) && !isdigit(ch) && (ch != '_'))))
|
||||
{
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
if(cmdidx < 99)
|
||||
cmd[cmdidx++] = ch;
|
||||
}
|
||||
|
||||
// A few known keywords
|
||||
if(
|
||||
(strncmp(cmd,"if",99) == 0) ||
|
||||
(strncmp(cmd,"then",99) == 0) ||
|
||||
(strncmp(cmd,"else",99) == 0) ||
|
||||
(strncmp(cmd,"thru",99) == 0) ||
|
||||
(strncmp(cmd,"for",99) == 0) ||
|
||||
(strncmp(cmd,"while",99) == 0) ||
|
||||
(strncmp(cmd,"do",99) == 0)
|
||||
)
|
||||
{
|
||||
styler.ColourTo(i, SCE_MAXIMA_COMMAND);
|
||||
continue;
|
||||
}
|
||||
|
||||
// All other keywords are functions if they are followed
|
||||
// by an opening parenthesis
|
||||
char nextNonwhitespace = ' ';
|
||||
for (Sci_PositionU o = i + 1; o < lengthDoc; o++)
|
||||
{
|
||||
nextNonwhitespace = styler.SafeGetCharAt(o);
|
||||
if(!IsASCII(nextNonwhitespace) || !isspacechar(nextNonwhitespace))
|
||||
break;
|
||||
}
|
||||
if(nextNonwhitespace == '(')
|
||||
{
|
||||
styler.ColourTo(i, SCE_MAXIMA_COMMAND);
|
||||
}
|
||||
else
|
||||
{
|
||||
styler.ColourTo(i, SCE_MAXIMA_VARIABLE);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
styler.ColourTo(i-1, SCE_MAXIMA_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
LexerModule lmMaxima(SCLEX_MAXIMA, ColouriseMaximaDoc, "maxima", 0, 0);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// Scintilla source code edit control
|
||||
|
||||
// File: LexMetapost.cxx - general context conformant metapost coloring scheme
|
||||
// @file LexMetapost.cxx - general context conformant metapost coloring scheme
|
||||
// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
|
||||
// Version: September 28, 2003
|
||||
// Modified by instanton: July 10, 2007
|
||||
|
|
@ -30,9 +30,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// val SCE_METAPOST_DEFAULT = 0
|
||||
// val SCE_METAPOST_SPECIAL = 1
|
||||
|
|
@ -179,7 +177,8 @@ static void ColouriseMETAPOSTDoc(
|
|||
}
|
||||
|
||||
WordList &keywords = *keywordlists[0] ;
|
||||
WordList &keywords2 = *keywordlists[extraInterface-1] ;
|
||||
WordList kwEmpty;
|
||||
WordList &keywords2 = (extraInterface > 0) ? *keywordlists[extraInterface - 1] : kwEmpty;
|
||||
|
||||
StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,11 @@
|
|||
#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 = %ud, char = '%c'\n", p, c );
|
||||
fprintf( stderr, "Unknown state: currentPos = %u, char = '%c'\n", static_cast<unsigned int>(p), c );
|
||||
#else
|
||||
#define DEBUG_STATE( p, c )
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordChar(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '_');
|
||||
|
|
@ -55,7 +53,7 @@ static inline bool IsANumberChar(int ch) {
|
|||
*/
|
||||
static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState)
|
||||
{
|
||||
int length = sc.LengthCurrent() + 1; // +1 for the next char
|
||||
Sci_Position length = sc.LengthCurrent() + 1; // +1 for the next char
|
||||
char* s = new char[length];
|
||||
sc.GetCurrentLowered(s, length);
|
||||
if (keywordlists[0]->InList(s))
|
||||
|
|
|
|||
811
src/stc/scintilla/lexers/LexNim.cxx
Normal file
811
src/stc/scintilla/lexers/LexNim.cxx
Normal file
|
|
@ -0,0 +1,811 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexNim.cxx
|
||||
** Lexer for Nim
|
||||
** Written by Jad Altahan (github.com/xv)
|
||||
** Nim manual: https://nim-lang.org/docs/manual.html
|
||||
**/
|
||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
enum NumType {
|
||||
Binary,
|
||||
Octal,
|
||||
Exponent,
|
||||
Hexadecimal,
|
||||
Decimal,
|
||||
FormatError
|
||||
};
|
||||
|
||||
int GetNumStyle(const int numType) noexcept {
|
||||
if (numType == NumType::FormatError) {
|
||||
return SCE_NIM_NUMERROR;
|
||||
}
|
||||
|
||||
return SCE_NIM_NUMBER;
|
||||
}
|
||||
|
||||
constexpr bool IsLetter(const int ch) noexcept {
|
||||
// 97 to 122 || 65 to 90
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
|
||||
}
|
||||
|
||||
bool IsAWordChar(const int ch) noexcept {
|
||||
return ch < 0x80 && (isalnum(ch) || ch == '_' || ch == '.');
|
||||
}
|
||||
|
||||
int IsNumHex(const StyleContext &sc) noexcept {
|
||||
return sc.chNext == 'x' || sc.chNext == 'X';
|
||||
}
|
||||
|
||||
int IsNumBinary(const StyleContext &sc) noexcept {
|
||||
return sc.chNext == 'b' || sc.chNext == 'B';
|
||||
}
|
||||
|
||||
int IsNumOctal(const StyleContext &sc) {
|
||||
return IsADigit(sc.chNext) || sc.chNext == 'o';
|
||||
}
|
||||
|
||||
constexpr bool IsNewline(const int ch) noexcept {
|
||||
return (ch == '\n' || ch == '\r');
|
||||
}
|
||||
|
||||
bool IsFuncName(const char *str) noexcept {
|
||||
const char *identifiers[] = {
|
||||
"proc",
|
||||
"func",
|
||||
"macro",
|
||||
"method",
|
||||
"template",
|
||||
"iterator",
|
||||
"converter"
|
||||
};
|
||||
|
||||
for (const char *id : identifiers) {
|
||||
if (strcmp(str, id) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool IsTripleLiteral(const int style) noexcept {
|
||||
return style == SCE_NIM_TRIPLE || style == SCE_NIM_TRIPLEDOUBLE;
|
||||
}
|
||||
|
||||
constexpr bool IsLineComment(const int style) noexcept {
|
||||
return style == SCE_NIM_COMMENTLINE || style == SCE_NIM_COMMENTLINEDOC;
|
||||
}
|
||||
|
||||
constexpr bool IsStreamComment(const int style) noexcept {
|
||||
return style == SCE_NIM_COMMENT || style == SCE_NIM_COMMENTDOC;
|
||||
}
|
||||
|
||||
// Adopted from Accessor.cxx
|
||||
int GetIndent(const Sci_Position line, Accessor &styler) {
|
||||
Sci_Position startPos = styler.LineStart(line);
|
||||
const Sci_Position eolPos = styler.LineStart(line + 1) - 1;
|
||||
|
||||
char ch = styler[startPos];
|
||||
int style = styler.StyleAt(startPos);
|
||||
|
||||
int indent = 0;
|
||||
bool inPrevPrefix = line > 0;
|
||||
Sci_Position posPrev = inPrevPrefix ? styler.LineStart(line - 1) : 0;
|
||||
|
||||
// No fold points inside triple literals
|
||||
while ((IsASpaceOrTab(ch) || IsTripleLiteral(style)) && (startPos < eolPos)) {
|
||||
if (inPrevPrefix) {
|
||||
const char chPrev = styler[posPrev++];
|
||||
if (chPrev != ' ' && chPrev != '\t') {
|
||||
inPrevPrefix = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == '\t') {
|
||||
indent = (indent / 8 + 1) * 8;
|
||||
} else {
|
||||
indent++;
|
||||
}
|
||||
|
||||
startPos++;
|
||||
ch = styler[startPos];
|
||||
style = styler.StyleAt(startPos);
|
||||
}
|
||||
|
||||
// Prevent creating fold lines for comments if indented
|
||||
if (!(IsStreamComment(style) || IsLineComment(style)))
|
||||
indent += SC_FOLDLEVELBASE;
|
||||
|
||||
if (styler.LineStart(line) == styler.Length()
|
||||
|| IsASpaceOrTab(ch)
|
||||
|| IsNewline(ch)
|
||||
|| IsStreamComment(style)
|
||||
|| IsLineComment(style)) {
|
||||
return indent | SC_FOLDLEVELWHITEFLAG;
|
||||
} else {
|
||||
return indent;
|
||||
}
|
||||
}
|
||||
|
||||
int IndentAmount(const Sci_Position line, Accessor &styler) {
|
||||
const int indent = GetIndent(line, styler);
|
||||
const int indentLevel = indent & SC_FOLDLEVELNUMBERMASK;
|
||||
return indentLevel <= SC_FOLDLEVELBASE ? indent : indentLevel | (indent & ~SC_FOLDLEVELNUMBERMASK);
|
||||
}
|
||||
|
||||
struct OptionsNim {
|
||||
bool fold;
|
||||
bool foldCompact;
|
||||
bool highlightRawStrIdent;
|
||||
|
||||
OptionsNim() {
|
||||
fold = true;
|
||||
foldCompact = true;
|
||||
highlightRawStrIdent = false;
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const nimWordListDesc[] = {
|
||||
"Keywords",
|
||||
nullptr
|
||||
};
|
||||
|
||||
struct OptionSetNim : public OptionSet<OptionsNim> {
|
||||
OptionSetNim() {
|
||||
DefineProperty("lexer.nim.raw.strings.highlight.ident", &OptionsNim::highlightRawStrIdent,
|
||||
"Set to 1 to enable highlighting generalized raw string identifiers. "
|
||||
"Generalized raw string identifiers are anything other than r (or R).");
|
||||
|
||||
DefineProperty("fold", &OptionsNim::fold);
|
||||
DefineProperty("fold.compact", &OptionsNim::foldCompact);
|
||||
|
||||
DefineWordListSets(nimWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer Nim SCLEX_NIM SCE_NIM_:
|
||||
0, "SCE_NIM_DEFAULT", "default", "White space",
|
||||
1, "SCE_NIM_COMMENT", "comment block", "Block comment",
|
||||
2, "SCE_NIM_COMMENTDOC", "comment block doc", "Block doc comment",
|
||||
3, "SCE_NIM_COMMENTLINE", "comment line", "Line comment",
|
||||
4, "SCE_NIM_COMMENTLINEDOC", "comment doc", "Line doc comment",
|
||||
5, "SCE_NIM_NUMBER", "literal numeric", "Number",
|
||||
6, "SCE_NIM_STRING", "literal string", "String",
|
||||
7, "SCE_NIM_CHARACTER", "literal string", "Single quoted string",
|
||||
8, "SCE_NIM_WORD", "keyword", "Keyword",
|
||||
9, "SCE_NIM_TRIPLE", "literal string", "Triple quotes",
|
||||
10, "SCE_NIM_TRIPLEDOUBLE", "literal string", "Triple double quotes",
|
||||
11, "SCE_NIM_BACKTICKS", "operator definition", "Identifiers",
|
||||
12, "SCE_NIM_FUNCNAME", "identifier", "Function name definition",
|
||||
13, "SCE_NIM_STRINGEOL", "error literal string", "String is not closed",
|
||||
14, "SCE_NIM_NUMERROR", "numeric error", "Numeric format error",
|
||||
15, "SCE_NIM_OPERATOR", "operator", "Operators",
|
||||
16, "SCE_NIM_IDENTIFIER", "identifier", "Identifiers",
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class LexerNim : public DefaultLexer {
|
||||
CharacterSet setWord;
|
||||
WordList keywords;
|
||||
OptionsNim options;
|
||||
OptionSetNim osNim;
|
||||
|
||||
public:
|
||||
LexerNim() :
|
||||
DefaultLexer("nim", SCLEX_NIM, lexicalClasses, ELEMENTS(lexicalClasses)),
|
||||
setWord(CharacterSet::setAlphaNum, "_", 0x80, true) { }
|
||||
|
||||
virtual ~LexerNim() { }
|
||||
|
||||
void SCI_METHOD Release() noexcept override {
|
||||
delete this;
|
||||
}
|
||||
|
||||
int SCI_METHOD Version() const noexcept override {
|
||||
return lvIdentity;
|
||||
}
|
||||
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osNim.PropertyNames();
|
||||
}
|
||||
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osNim.PropertyType(name);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osNim.DescribeProperty(name);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
|
||||
const char * SCI_METHOD PropertyGet(const char* key) override {
|
||||
return osNim.PropertyGet(key);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osNim.DescribeWordListSets();
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) noexcept override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int SCI_METHOD LineEndTypesSupported() noexcept override {
|
||||
return SC_LINE_END_TYPE_UNICODE;
|
||||
}
|
||||
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) noexcept override {
|
||||
return style;
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryNim() {
|
||||
return new LexerNim();
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerNim::PropertySet(const char *key, const char *val) {
|
||||
if (osNim.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerNim::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = nullptr;
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywords;
|
||||
break;
|
||||
}
|
||||
|
||||
Sci_Position firstModification = -1;
|
||||
|
||||
if (wordListN) {
|
||||
WordList wlNew;
|
||||
wlNew.Set(wl);
|
||||
|
||||
if (*wordListN != wlNew) {
|
||||
wordListN->Set(wl);
|
||||
firstModification = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerNim::Lex(Sci_PositionU startPos, Sci_Position length,
|
||||
int initStyle, IDocument *pAccess) {
|
||||
// No one likes a leaky string
|
||||
if (initStyle == SCE_NIM_STRINGEOL) {
|
||||
initStyle = SCE_NIM_DEFAULT;
|
||||
}
|
||||
|
||||
Accessor styler(pAccess, nullptr);
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
// Nim supports nested block comments!
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int commentNestLevel = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) : 0;
|
||||
|
||||
int numType = NumType::Decimal;
|
||||
int decimalCount = 0;
|
||||
|
||||
bool funcNameExists = false;
|
||||
bool isStylingRawString = false;
|
||||
bool isStylingRawStringIdent = false;
|
||||
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
if (sc.atLineStart) {
|
||||
if (sc.state == SCE_NIM_STRING) {
|
||||
sc.SetState(SCE_NIM_STRING);
|
||||
}
|
||||
|
||||
lineCurrent = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(lineCurrent, commentNestLevel);
|
||||
}
|
||||
|
||||
// Handle string line continuation
|
||||
if (sc.ch == '\\' && (sc.chNext == '\n' || sc.chNext == '\r') &&
|
||||
(sc.state == SCE_NIM_STRING || sc.state == SCE_NIM_CHARACTER) && !isStylingRawString) {
|
||||
sc.Forward();
|
||||
|
||||
if (sc.ch == '\r' && sc.chNext == '\n') {
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (sc.state) {
|
||||
case SCE_NIM_OPERATOR:
|
||||
funcNameExists = false;
|
||||
sc.SetState(SCE_NIM_DEFAULT);
|
||||
break;
|
||||
case SCE_NIM_NUMBER:
|
||||
// For a type suffix, such as 0x80'u8
|
||||
if (sc.ch == '\'') {
|
||||
if (sc.chNext == 'i' || sc.chNext == 'I' ||
|
||||
sc.chNext == 'u' || sc.chNext == 'U' ||
|
||||
sc.chNext == 'f' || sc.chNext == 'F' ||
|
||||
sc.chNext == 'd' || sc.chNext == 'D') {
|
||||
sc.Forward(2);
|
||||
}
|
||||
} else if (sc.ch == '.') {
|
||||
if (IsADigit(sc.chNext)) {
|
||||
sc.Forward();
|
||||
} else if (numType <= NumType::Exponent) {
|
||||
sc.SetState(SCE_NIM_OPERATOR);
|
||||
break;
|
||||
} else {
|
||||
decimalCount++;
|
||||
|
||||
if (numType == NumType::Decimal) {
|
||||
if (decimalCount <= 1 && !IsAWordChar(sc.chNext)) {
|
||||
break;
|
||||
}
|
||||
} else if (numType == NumType::Hexadecimal) {
|
||||
if (decimalCount <= 1 && IsADigit(sc.chNext, 16)) {
|
||||
break;
|
||||
}
|
||||
|
||||
sc.SetState(SCE_NIM_OPERATOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (sc.ch == '_') {
|
||||
// Accept only one underscore between digits
|
||||
if (IsADigit(sc.chNext)) {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (numType == NumType::Decimal) {
|
||||
if (sc.chPrev != '\'' && (sc.ch == 'e' || sc.ch == 'E')) {
|
||||
numType = NumType::Exponent;
|
||||
|
||||
if (sc.chNext == '-' || sc.chNext == '+') {
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsADigit(sc.ch)) {
|
||||
break;
|
||||
}
|
||||
} else if (numType == NumType::Hexadecimal) {
|
||||
if (IsADigit(sc.ch, 16)) {
|
||||
break;
|
||||
}
|
||||
} else if (IsADigit(sc.ch)) {
|
||||
if (numType == NumType::Exponent) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (numType == NumType::Octal) {
|
||||
// Accept only 0-7
|
||||
if (sc.ch <= '7') {
|
||||
break;
|
||||
}
|
||||
} else if (numType == NumType::Binary) {
|
||||
// Accept only 0 and 1
|
||||
if (sc.ch <= '1') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
numType = NumType::FormatError;
|
||||
break;
|
||||
}
|
||||
|
||||
sc.ChangeState(GetNumStyle(numType));
|
||||
sc.SetState(SCE_NIM_DEFAULT);
|
||||
break;
|
||||
case SCE_NIM_IDENTIFIER:
|
||||
if (sc.ch == '.' || !IsAWordChar(sc.ch)) {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
int style = SCE_NIM_IDENTIFIER;
|
||||
|
||||
if (keywords.InList(s) && !funcNameExists) {
|
||||
// Prevent styling keywords if they are sub-identifiers
|
||||
const Sci_Position segStart = styler.GetStartSegment() - 1;
|
||||
if (segStart < 0 || styler.SafeGetCharAt(segStart, '\0') != '.') {
|
||||
style = SCE_NIM_WORD;
|
||||
}
|
||||
} else if (funcNameExists) {
|
||||
style = SCE_NIM_FUNCNAME;
|
||||
}
|
||||
|
||||
sc.ChangeState(style);
|
||||
sc.SetState(SCE_NIM_DEFAULT);
|
||||
|
||||
if (style == SCE_NIM_WORD) {
|
||||
funcNameExists = IsFuncName(s);
|
||||
} else {
|
||||
funcNameExists = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsAlphaNumeric(sc.ch) && sc.chNext == '\"') {
|
||||
isStylingRawStringIdent = true;
|
||||
|
||||
if (options.highlightRawStrIdent) {
|
||||
if (styler.SafeGetCharAt(sc.currentPos + 2) == '\"' &&
|
||||
styler.SafeGetCharAt(sc.currentPos + 3) == '\"') {
|
||||
sc.ChangeState(SCE_NIM_TRIPLEDOUBLE);
|
||||
} else {
|
||||
sc.ChangeState(SCE_NIM_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_FUNCNAME:
|
||||
if (sc.ch == '`') {
|
||||
funcNameExists = false;
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
} else if (sc.atLineEnd) {
|
||||
// Prevent leaking the style to the next line if not closed
|
||||
funcNameExists = false;
|
||||
|
||||
sc.ChangeState(SCE_NIM_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_COMMENT:
|
||||
if (sc.Match(']', '#')) {
|
||||
if (commentNestLevel > 0) {
|
||||
commentNestLevel--;
|
||||
}
|
||||
|
||||
lineCurrent = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(lineCurrent, commentNestLevel);
|
||||
sc.Forward();
|
||||
|
||||
if (commentNestLevel == 0) {
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
} else if (sc.Match('#', '[')) {
|
||||
commentNestLevel++;
|
||||
lineCurrent = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(lineCurrent, commentNestLevel);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_COMMENTDOC:
|
||||
if (sc.Match("]##")) {
|
||||
if (commentNestLevel > 0) {
|
||||
commentNestLevel--;
|
||||
}
|
||||
|
||||
lineCurrent = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(lineCurrent, commentNestLevel);
|
||||
sc.Forward(2);
|
||||
|
||||
if (commentNestLevel == 0) {
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
} else if (sc.Match("##[")) {
|
||||
commentNestLevel++;
|
||||
lineCurrent = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(lineCurrent, commentNestLevel);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_COMMENTLINE:
|
||||
case SCE_NIM_COMMENTLINEDOC:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_STRING:
|
||||
if (!isStylingRawStringIdent && !isStylingRawString && sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (isStylingRawString && sc.ch == '\"' && sc.chNext == '\"') {
|
||||
// Forward in situations such as r"a""bc\" so that "bc\" wouldn't be
|
||||
// considered a string of its own
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
} else if (sc.atLineEnd) {
|
||||
sc.ChangeState(SCE_NIM_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_CHARACTER:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
} else if (sc.atLineEnd) {
|
||||
sc.ChangeState(SCE_NIM_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_BACKTICKS:
|
||||
if (sc.ch == '`' ) {
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
} else if (sc.atLineEnd) {
|
||||
sc.ChangeState(SCE_NIM_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_TRIPLEDOUBLE:
|
||||
if (sc.Match(R"(""")")) {
|
||||
|
||||
// Outright forward all " after the closing """ as a triple double
|
||||
//
|
||||
// A valid example where this is needed is: """8 double quotes->""""""""
|
||||
// You can have as many """ at the end as you wish, as long as the actual
|
||||
// closing literal is there
|
||||
while (sc.ch == '"') {
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
sc.SetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_NIM_TRIPLE:
|
||||
if (sc.Match("'''")) {
|
||||
sc.Forward(2);
|
||||
sc.ForwardSetState(SCE_NIM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc.state == SCE_NIM_DEFAULT) {
|
||||
// Number
|
||||
if (IsADigit(sc.ch)) {
|
||||
sc.SetState(SCE_NIM_NUMBER);
|
||||
|
||||
numType = NumType::Decimal;
|
||||
decimalCount = 0;
|
||||
|
||||
if (sc.ch == '0') {
|
||||
if (IsNumHex(sc)) {
|
||||
numType = NumType::Hexadecimal;
|
||||
} else if (IsNumBinary(sc)) {
|
||||
numType = NumType::Binary;
|
||||
} else if (IsNumOctal(sc)) {
|
||||
numType = NumType::Octal;
|
||||
}
|
||||
|
||||
if (numType != NumType::Decimal) {
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Raw string
|
||||
else if (IsAlphaNumeric(sc.ch) && sc.chNext == '\"') {
|
||||
isStylingRawString = true;
|
||||
|
||||
// Triple doubles can be raw strings too. How sweet
|
||||
if (styler.SafeGetCharAt(sc.currentPos + 2) == '\"' &&
|
||||
styler.SafeGetCharAt(sc.currentPos + 3) == '\"') {
|
||||
sc.SetState(SCE_NIM_TRIPLEDOUBLE);
|
||||
} else {
|
||||
sc.SetState(SCE_NIM_STRING);
|
||||
}
|
||||
|
||||
const int rawStrStyle = options.highlightRawStrIdent ? IsLetter(sc.ch) :
|
||||
(sc.ch == 'r' || sc.ch == 'R');
|
||||
|
||||
if (rawStrStyle) {
|
||||
sc.Forward();
|
||||
|
||||
if (sc.state == SCE_NIM_TRIPLEDOUBLE) {
|
||||
sc.Forward(2);
|
||||
}
|
||||
} else {
|
||||
// Anything other than r/R is considered a general raw string identifier
|
||||
isStylingRawStringIdent = true;
|
||||
sc.SetState(SCE_NIM_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
// String and triple double literal
|
||||
else if (sc.ch == '\"') {
|
||||
isStylingRawString = false;
|
||||
|
||||
if (sc.Match(R"(""")")) {
|
||||
sc.SetState(SCE_NIM_TRIPLEDOUBLE);
|
||||
|
||||
// Keep forwarding until the total opening literal count is 5
|
||||
// A valid example where this is needed is: """""<-5 double quotes"""
|
||||
while (sc.ch == '"') {
|
||||
sc.Forward();
|
||||
|
||||
if (sc.Match(R"(""")")) {
|
||||
sc.Forward();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sc.SetState(SCE_NIM_STRING);
|
||||
}
|
||||
}
|
||||
// Charecter and triple literal
|
||||
else if (sc.ch == '\'') {
|
||||
if (sc.Match("'''")) {
|
||||
sc.SetState(SCE_NIM_TRIPLE);
|
||||
} else {
|
||||
sc.SetState(SCE_NIM_CHARACTER);
|
||||
}
|
||||
}
|
||||
// Operator definition
|
||||
else if (sc.ch == '`') {
|
||||
if (funcNameExists) {
|
||||
sc.SetState(SCE_NIM_FUNCNAME);
|
||||
} else {
|
||||
sc.SetState(SCE_NIM_BACKTICKS);
|
||||
}
|
||||
}
|
||||
// Keyword
|
||||
else if (iswordstart(sc.ch)) {
|
||||
sc.SetState(SCE_NIM_IDENTIFIER);
|
||||
}
|
||||
// Comments
|
||||
else if (sc.ch == '#') {
|
||||
if (sc.Match("##[") || sc.Match("#[")) {
|
||||
commentNestLevel++;
|
||||
lineCurrent = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(lineCurrent, commentNestLevel);
|
||||
}
|
||||
|
||||
if (sc.Match("##[")) {
|
||||
sc.SetState(SCE_NIM_COMMENTDOC);
|
||||
sc.Forward();
|
||||
} else if (sc.Match("#[")) {
|
||||
sc.SetState(SCE_NIM_COMMENT);
|
||||
sc.Forward();
|
||||
} else if (sc.Match("##")) {
|
||||
sc.SetState(SCE_NIM_COMMENTLINEDOC);
|
||||
} else {
|
||||
sc.SetState(SCE_NIM_COMMENTLINE);
|
||||
}
|
||||
}
|
||||
// Operators
|
||||
else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", sc.ch)) {
|
||||
sc.SetState(SCE_NIM_OPERATOR);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.atLineEnd) {
|
||||
funcNameExists = false;
|
||||
isStylingRawString = false;
|
||||
isStylingRawStringIdent = false;
|
||||
}
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerNim::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {
|
||||
if (!options.fold) {
|
||||
return;
|
||||
}
|
||||
|
||||
Accessor styler(pAccess, nullptr);
|
||||
|
||||
const Sci_Position docLines = styler.GetLine(styler.Length());
|
||||
const Sci_Position maxPos = startPos + length;
|
||||
const Sci_Position maxLines = styler.GetLine(maxPos == styler.Length() ? maxPos : maxPos - 1);
|
||||
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int indentCurrent = IndentAmount(lineCurrent, styler);
|
||||
|
||||
while (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
indentCurrent = IndentAmount(lineCurrent, styler);
|
||||
|
||||
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
|
||||
indentCurrent = indentCurrentLevel | (indentCurrent & ~SC_FOLDLEVELNUMBERMASK);
|
||||
|
||||
while (lineCurrent <= docLines && lineCurrent <= maxLines) {
|
||||
Sci_Position lineNext = lineCurrent + 1;
|
||||
int indentNext = indentCurrent;
|
||||
int lev = indentCurrent;
|
||||
|
||||
if (lineNext <= docLines) {
|
||||
indentNext = IndentAmount(lineNext, styler);
|
||||
}
|
||||
|
||||
if (indentNext & SC_FOLDLEVELWHITEFLAG) {
|
||||
indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
|
||||
}
|
||||
|
||||
while (lineNext < docLines && (indentNext & SC_FOLDLEVELWHITEFLAG)) {
|
||||
lineNext++;
|
||||
indentNext = IndentAmount(lineNext, styler);
|
||||
}
|
||||
|
||||
const int indentNextLevel = indentNext & SC_FOLDLEVELNUMBERMASK;
|
||||
indentNext = indentNextLevel | (indentNext & ~SC_FOLDLEVELNUMBERMASK);
|
||||
|
||||
const int levelBeforeComments = std::max(indentCurrentLevel, indentNextLevel);
|
||||
|
||||
Sci_Position skipLine = lineNext;
|
||||
int skipLevel = indentNextLevel;
|
||||
|
||||
while (--skipLine > lineCurrent) {
|
||||
const int skipLineIndent = IndentAmount(skipLine, styler);
|
||||
|
||||
if (options.foldCompact) {
|
||||
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel) {
|
||||
skipLevel = levelBeforeComments;
|
||||
}
|
||||
|
||||
const int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
|
||||
styler.SetLevel(skipLine, skipLevel | whiteFlag);
|
||||
} else {
|
||||
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel &&
|
||||
!(skipLineIndent & SC_FOLDLEVELWHITEFLAG)) {
|
||||
skipLevel = levelBeforeComments;
|
||||
}
|
||||
|
||||
styler.SetLevel(skipLine, skipLevel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
|
||||
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
}
|
||||
|
||||
styler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
|
||||
|
||||
indentCurrent = indentNext;
|
||||
indentCurrentLevel = indentNextLevel;
|
||||
lineCurrent = lineNext;
|
||||
}
|
||||
}
|
||||
|
||||
LexerModule lmNim(SCLEX_NIM, LexerNim::LexerFactoryNim, "nim", nimWordListDesc);
|
||||
|
|
@ -25,9 +25,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordChar(int ch) {
|
||||
return (ch >= 0x80) || isalnum(ch) || ch == '_';
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
/*
|
||||
// located in SciLexer.h
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColouriseNullDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
|
||||
Accessor &styler) {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// -----------------------------------------
|
||||
// Functions classifying a single character.
|
||||
|
|
@ -464,7 +462,7 @@ static void FoldOScriptDoc(Sci_PositionU startPos, Sci_Position length, int init
|
|||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int style = initStyle;
|
||||
int lastStart = 0;
|
||||
Sci_Position lastStart = 0;
|
||||
|
||||
for (Sci_Position i = startPos; i < endPos; i++) {
|
||||
char ch = chNext;
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
inline static void getRange( Sci_PositionU start, Sci_PositionU end, Accessor & styler, char * s, Sci_PositionU len )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,9 +51,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsTypeCharacter(const int ch)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 1990-2007, Scientific Toolworks, Inc.
|
||||
// @file LexPLM.cxx
|
||||
// Author: Jason Haslam
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
|
|
@ -20,9 +21,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void GetRange(Sci_PositionU start,
|
||||
Sci_PositionU end,
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) {
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
|
|
|||
|
|
@ -32,9 +32,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordChar(int ch) {
|
||||
return ch < 0x80 && (isalnum(ch) || ch == '_');
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsASelfDelimitingChar(const int ch) {
|
||||
return (ch == '[' || ch == ']' || ch == '{' || ch == '}' ||
|
||||
|
|
|
|||
|
|
@ -128,9 +128,7 @@ contains requires
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void GetRangeLowered(Sci_PositionU start,
|
||||
Sci_PositionU end,
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Info for HERE document handling from perldata.pod (reformatted):
|
||||
// ----------------------------------------------------------------
|
||||
|
|
@ -38,6 +37,8 @@ using namespace Scintilla;
|
|||
// Following a << you specify a string to terminate the quoted material, and
|
||||
// all lines following the current line down to the terminating string are
|
||||
// the value of the item.
|
||||
// Prefixing the terminating string with a "~" specifies that you want to
|
||||
// use "Indented Here-docs" (see below).
|
||||
// * The terminating string may be either an identifier (a word), or some
|
||||
// quoted text.
|
||||
// * If quoted, the type of quotes you use determines the treatment of the
|
||||
|
|
@ -49,6 +50,18 @@ using namespace Scintilla;
|
|||
// (This is deprecated, -w warns of this syntax)
|
||||
// * The terminating string must appear by itself (unquoted and
|
||||
// with no surrounding whitespace) on the terminating line.
|
||||
//
|
||||
// Indented Here-docs
|
||||
// ------------------
|
||||
// The here-doc modifier "~" allows you to indent your here-docs to
|
||||
// make the code more readable.
|
||||
// The delimiter is used to determine the exact whitespace to remove
|
||||
// from the beginning of each line. All lines must have at least the
|
||||
// same starting whitespace (except lines only containing a newline)
|
||||
// or perl will croak. Tabs and spaces can be mixed, but are matched
|
||||
// exactly. One tab will not be equal to 8 spaces!
|
||||
// Additional beginning whitespace (beyond what preceded the
|
||||
// delimiter) will be preserved.
|
||||
|
||||
#define HERE_DELIM_MAX 256 // maximum length of HERE doc delimiter
|
||||
|
||||
|
|
@ -122,8 +135,8 @@ static int disambiguateBareword(LexAccessor &styler, Sci_PositionU bk, Sci_Posit
|
|||
// if ch isn't one of '[{(,' we can skip the test
|
||||
if ((ch == '{' || ch == '(' || ch == '['|| ch == ',')
|
||||
&& fw < endPos) {
|
||||
while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)),
|
||||
IsASpaceOrTab(ch) && fw < endPos) {
|
||||
while (IsASpaceOrTab(ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)))
|
||||
&& fw < endPos) {
|
||||
fw++;
|
||||
}
|
||||
if ((ch == '}' && brace)
|
||||
|
|
@ -138,10 +151,12 @@ static int disambiguateBareword(LexAccessor &styler, Sci_PositionU bk, Sci_Posit
|
|||
|
||||
static void skipWhitespaceComment(LexAccessor &styler, Sci_PositionU &p) {
|
||||
// when backtracking, we need to skip whitespace and comments
|
||||
int style;
|
||||
while ((p > 0) && (style = styler.StyleAt(p),
|
||||
style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
|
||||
while (p > 0) {
|
||||
const int style = styler.StyleAt(p);
|
||||
if (style != SCE_PL_DEFAULT && style != SCE_PL_COMMENTLINE)
|
||||
break;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
static int findPrevLexeme(LexAccessor &styler, Sci_PositionU &bk, int &style) {
|
||||
|
|
@ -398,7 +413,7 @@ struct OptionSetPerl : public OptionSet<OptionsPerl> {
|
|||
}
|
||||
};
|
||||
|
||||
class LexerPerl : public ILexer {
|
||||
class LexerPerl : public DefaultLexer {
|
||||
CharacterSet setWordStart;
|
||||
CharacterSet setWord;
|
||||
CharacterSet setSpecialVar;
|
||||
|
|
@ -408,6 +423,7 @@ class LexerPerl : public ILexer {
|
|||
OptionSetPerl osPerl;
|
||||
public:
|
||||
LexerPerl() :
|
||||
DefaultLexer("perl", SCLEX_PERL),
|
||||
setWordStart(CharacterSet::setAlpha, "_", 0x80, true),
|
||||
setWord(CharacterSet::setAlphaNum, "_", 0x80, true),
|
||||
setSpecialVar(CharacterSet::setNone, "\"$;<>&`'+,./\\%:=~!?@[]"),
|
||||
|
|
@ -415,30 +431,33 @@ public:
|
|||
}
|
||||
virtual ~LexerPerl() {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char *SCI_METHOD PropertyNames() {
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osPerl.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osPerl.PropertyType(name);
|
||||
}
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osPerl.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
const char *SCI_METHOD DescribeWordListSets() {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osPerl.PropertyGet(key);
|
||||
}
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osPerl.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void *SCI_METHOD PrivateCall(int, void *) {
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -618,12 +637,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
// 2: here doc text (lines after the delimiter)
|
||||
int Quote; // the char after '<<'
|
||||
bool Quoted; // true if Quote in ('\'','"','`')
|
||||
bool StripIndent; // true if '<<~' requested to strip leading whitespace
|
||||
int DelimiterLength; // strlen(Delimiter)
|
||||
char Delimiter[HERE_DELIM_MAX]; // the Delimiter
|
||||
HereDocCls() {
|
||||
State = 0;
|
||||
Quote = 0;
|
||||
Quoted = false;
|
||||
StripIndent = false;
|
||||
DelimiterLength = 0;
|
||||
Delimiter[0] = '\0';
|
||||
}
|
||||
|
|
@ -884,7 +905,7 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
sc.SetState(SCE_PL_DEFAULT);
|
||||
break;
|
||||
case SCE_PL_COMMENTLINE:
|
||||
if (sc.atLineEnd) {
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_PL_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
|
@ -895,8 +916,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
HereDoc.State = 1; // pre-init HERE doc class
|
||||
HereDoc.Quote = sc.chNext;
|
||||
HereDoc.Quoted = false;
|
||||
HereDoc.StripIndent = false;
|
||||
HereDoc.DelimiterLength = 0;
|
||||
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
|
||||
if (delim_ch == '~') { // was actually '<<~'
|
||||
sc.Forward();
|
||||
HereDoc.StripIndent = true;
|
||||
HereDoc.Quote = delim_ch = sc.chNext;
|
||||
}
|
||||
if (IsASpaceOrTab(delim_ch)) {
|
||||
// skip whitespace; legal only for quoted delimiters
|
||||
Sci_PositionU i = sc.currentPos + 1;
|
||||
|
|
@ -963,6 +990,11 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
case SCE_PL_HERE_QX:
|
||||
// also implies HereDoc.State == 2
|
||||
sc.Complete();
|
||||
if (HereDoc.StripIndent) {
|
||||
// skip whitespace
|
||||
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
|
||||
sc.Forward();
|
||||
}
|
||||
if (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) {
|
||||
int c = sc.GetRelative(HereDoc.DelimiterLength);
|
||||
if (c == '\r' || c == '\n') { // peek first, do not consume match
|
||||
|
|
@ -1174,6 +1206,7 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int
|
|||
break;
|
||||
}
|
||||
// (continued for ' delim)
|
||||
// Falls through.
|
||||
default: // non-interpolated path
|
||||
sc.Forward(sLen);
|
||||
}
|
||||
|
|
@ -1699,6 +1732,12 @@ void SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int
|
|||
} else if (ch == ']') {
|
||||
levelCurrent--;
|
||||
}
|
||||
} else if (style == SCE_PL_STRING_QW) {
|
||||
// qw
|
||||
if (stylePrevCh != style)
|
||||
levelCurrent++;
|
||||
else if (styleNext != style)
|
||||
levelCurrent--;
|
||||
}
|
||||
// POD folding
|
||||
if (options.foldPOD && atLineStart) {
|
||||
|
|
|
|||
|
|
@ -43,9 +43,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsStreamCommentStyle(int style) {
|
||||
return style == SCE_POWERPRO_COMMENTBLOCK;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
// Extended to accept accented characters
|
||||
static inline bool IsAWordChar(int ch) {
|
||||
|
|
@ -33,7 +31,7 @@ static inline bool IsAWordChar(int ch) {
|
|||
}
|
||||
|
||||
static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
WordList *keywordlists[], Accessor &styler) {
|
||||
WordList *keywordlists[], Accessor &styler) {
|
||||
|
||||
WordList &keywords = *keywordlists[0];
|
||||
WordList &keywords2 = *keywordlists[1];
|
||||
|
|
@ -53,8 +51,8 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
|
|||
sc.SetState(SCE_POWERSHELL_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {
|
||||
if(sc.atLineStart) {
|
||||
while(IsASpaceOrTab(sc.ch)) {
|
||||
if (sc.atLineStart) {
|
||||
while (IsASpaceOrTab(sc.ch)) {
|
||||
sc.Forward();
|
||||
}
|
||||
if (sc.ch == '.' && IsAWordChar(sc.chNext)) {
|
||||
|
|
@ -65,7 +63,7 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
|
|||
sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_POWERSHELL_COMMENTDOCKEYWORD) {
|
||||
if(!IsAWordChar(sc.ch)) {
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
char s[100];
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
if (!keywords6.InList(s + 1)) {
|
||||
|
|
@ -77,11 +75,15 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
|
|||
// This is a doubles quotes string
|
||||
if (sc.ch == '\"') {
|
||||
sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
|
||||
} else if (sc.ch == '`') {
|
||||
sc.Forward(); // skip next escaped character
|
||||
}
|
||||
} else if (sc.state == SCE_POWERSHELL_CHARACTER) {
|
||||
// This is a single quote string
|
||||
if (sc.ch == '\'') {
|
||||
sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
|
||||
} else if (sc.ch == '`') {
|
||||
sc.Forward(); // skip next escaped character
|
||||
}
|
||||
} else if (sc.state == SCE_POWERSHELL_HERE_STRING) {
|
||||
// This is a doubles quotes here-string
|
||||
|
|
@ -161,7 +163,7 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
|
|||
// 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(Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
WordList *[], Accessor &styler) {
|
||||
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;
|
||||
|
|
@ -236,7 +238,7 @@ static void FoldPowerShellDoc(Sci_PositionU startPos, Sci_Position length, int i
|
|||
}
|
||||
}
|
||||
|
||||
static const char * const powershellWordLists[] = {
|
||||
static const char *const powershellWordLists[] = {
|
||||
"Commands",
|
||||
"Cmdlets",
|
||||
"Aliases",
|
||||
|
|
|
|||
|
|
@ -38,10 +38,9 @@ Differentiate between labels and variables
|
|||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "SparseState.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
|
@ -122,7 +121,7 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
class LexerABL : public ILexer {
|
||||
class LexerABL : public DefaultLexer {
|
||||
CharacterSet setWord;
|
||||
CharacterSet setNegationOp;
|
||||
CharacterSet setArithmethicOp;
|
||||
|
|
@ -137,6 +136,7 @@ class LexerABL : public ILexer {
|
|||
OptionSetABL osABL;
|
||||
public:
|
||||
LexerABL() :
|
||||
DefaultLexer("abl", SCLEX_PROGRESS),
|
||||
setWord(CharacterSet::setAlphaNum, "_", 0x80, true),
|
||||
setNegationOp(CharacterSet::setNone, "!"),
|
||||
setArithmethicOp(CharacterSet::setNone, "+-/*%"),
|
||||
|
|
@ -145,34 +145,37 @@ public:
|
|||
}
|
||||
virtual ~LexerABL() {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
return osABL.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osABL.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osABL.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) ;
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override ;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osABL.PropertyGet(key);
|
||||
}
|
||||
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
return osABL.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
int SCI_METHOD LineEndTypesSupported() {
|
||||
int SCI_METHOD LineEndTypesSupported() override {
|
||||
return SC_LINE_END_TYPE_DEFAULT;
|
||||
}
|
||||
static ILexer *LexerFactoryABL() {
|
||||
|
|
@ -278,10 +281,15 @@ void SCI_METHOD LexerABL::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
|||
|
||||
// commentNestingLevel is a non-visible state, used to identify the nesting level of a comment
|
||||
if (checkCommentNestingLevel) {
|
||||
if (chPrev == '/' && ch == '*')
|
||||
if (chPrev == '/' && ch == '*') {
|
||||
commentNestingLevel++;
|
||||
// eat the '/' so we don't miscount a */ if we see /*/*
|
||||
--back;
|
||||
}
|
||||
if (chPrev == '*' && ch == '/') {
|
||||
commentNestingLevel--;
|
||||
// eat the '*' so we don't miscount a /* if we see */*/
|
||||
--back;
|
||||
}
|
||||
}
|
||||
--back;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
|
@ -23,9 +25,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
return (styler[i] == '\n') ||
|
||||
|
|
@ -37,7 +37,7 @@ static inline bool isassignchar(unsigned char ch) {
|
|||
}
|
||||
|
||||
static void ColourisePropsLine(
|
||||
char *lineBuffer,
|
||||
const char *lineBuffer,
|
||||
Sci_PositionU lengthLine,
|
||||
Sci_PositionU startLine,
|
||||
Sci_PositionU endPos,
|
||||
|
|
@ -81,39 +81,37 @@ static void ColourisePropsLine(
|
|||
}
|
||||
|
||||
static void ColourisePropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||||
char lineBuffer[1024];
|
||||
std::string lineBuffer;
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
Sci_PositionU linePos = 0;
|
||||
Sci_PositionU startLine = startPos;
|
||||
|
||||
// property lexer.props.allow.initial.spaces
|
||||
// For properties files, set to 0 to style all lines that start with whitespace in the default style.
|
||||
// This is not suitable for SciTE .properties files which use indentation for flow control but
|
||||
// can be used for RFC2822 text where indentation is used for continuation lines.
|
||||
bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
|
||||
const bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
|
||||
|
||||
for (Sci_PositionU i = startPos; i < startPos + length; i++) {
|
||||
lineBuffer[linePos++] = styler[i];
|
||||
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
|
||||
lineBuffer.push_back(styler[i]);
|
||||
if (AtEOL(styler, i)) {
|
||||
// End of line (or of line buffer) met, colourise it
|
||||
lineBuffer[linePos] = '\0';
|
||||
ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces);
|
||||
linePos = 0;
|
||||
ColourisePropsLine(lineBuffer.c_str(), lineBuffer.length(), startLine, i, styler, allowInitialSpaces);
|
||||
lineBuffer.clear();
|
||||
startLine = i + 1;
|
||||
}
|
||||
}
|
||||
if (linePos > 0) { // Last line does not have ending characters
|
||||
ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces);
|
||||
if (lineBuffer.length() > 0) { // Last line does not have ending characters
|
||||
ColourisePropsLine(lineBuffer.c_str(), lineBuffer.length(), startLine, startPos + length - 1, styler, allowInitialSpaces);
|
||||
}
|
||||
}
|
||||
|
||||
// adaption by ksc, using the "} else {" trick of 1.53
|
||||
// 030721
|
||||
static void FoldPropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
const Sci_PositionU endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
|
||||
|
|
@ -123,12 +121,12 @@ static void FoldPropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordL
|
|||
int lev;
|
||||
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
char ch = chNext;
|
||||
const char ch = chNext;
|
||||
chNext = styler[i+1];
|
||||
|
||||
int style = styleNext;
|
||||
const int style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
|
||||
if (style == SCE_PROPS_SECTION) {
|
||||
headerPoint = true;
|
||||
|
|
@ -138,7 +136,7 @@ static void FoldPropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordL
|
|||
lev = SC_FOLDLEVELBASE;
|
||||
|
||||
if (lineCurrent > 0) {
|
||||
int levelPrevious = styler.LevelAt(lineCurrent - 1);
|
||||
const int levelPrevious = styler.LevelAt(lineCurrent - 1);
|
||||
|
||||
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
|
||||
lev = SC_FOLDLEVELBASE + 1;
|
||||
|
|
@ -169,7 +167,7 @@ static void FoldPropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordL
|
|||
}
|
||||
|
||||
if (lineCurrent > 0) {
|
||||
int levelPrevious = styler.LevelAt(lineCurrent - 1);
|
||||
const int levelPrevious = styler.LevelAt(lineCurrent - 1);
|
||||
if (levelPrevious & SC_FOLDLEVELHEADERFLAG) {
|
||||
lev = SC_FOLDLEVELBASE + 1;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,55 +5,77 @@
|
|||
// 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 <cstdlib>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "CharacterCategory.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "SubStyles.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
/* Notes on f-strings: f-strings are strings prefixed with f (e.g. f'') that may
|
||||
have arbitrary expressions in {}. The tokens in the expressions are lexed as if
|
||||
they were outside of any string. Expressions may contain { and } characters as
|
||||
long as there is a closing } for every {, may be 2+ lines in a triple quoted
|
||||
string, and may have a formatting specifier following a ! or :, but both !
|
||||
and : are valid inside of a bracketed expression and != is a valid
|
||||
expression token even outside of a bracketed expression.
|
||||
|
||||
When in an f-string expression, the lexer keeps track of the state value of
|
||||
the f-string and the nesting count for the expression (# of [, (, { seen - # of
|
||||
}, ), ] seen). f-strings may be nested (e.g. f'{ a + f"{1+2}"') so a stack of
|
||||
states and nesting counts is kept. If a f-string expression continues beyond
|
||||
the end of a line, this stack is saved in a std::map that maps a line number to
|
||||
the stack at the end of that line. std::vector is used for the stack.
|
||||
|
||||
The PEP for f-strings is at https://www.python.org/dev/peps/pep-0498/
|
||||
*/
|
||||
struct SingleFStringExpState {
|
||||
int state;
|
||||
int nestingCount;
|
||||
};
|
||||
|
||||
/* kwCDef, kwCTypeName only used for Cython */
|
||||
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
|
||||
|
||||
enum literalsAllowed { litNone = 0, litU = 1, litB = 2 };
|
||||
enum literalsAllowed { litNone = 0, litU = 1, litB = 2, litF = 4 };
|
||||
|
||||
const int indicatorWhitespace = 1;
|
||||
constexpr int indicatorWhitespace = 1;
|
||||
|
||||
bool IsPyComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
|
||||
return len > 0 && styler[pos] == '#';
|
||||
}
|
||||
|
||||
bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
|
||||
bool IsPyStringTypeChar(int ch, literalsAllowed allowed) noexcept {
|
||||
return
|
||||
((allowed & litB) && (ch == 'b' || ch == 'B')) ||
|
||||
((allowed & litU) && (ch == 'u' || ch == 'U'));
|
||||
((allowed & litU) && (ch == 'u' || ch == 'U')) ||
|
||||
((allowed & litF) && (ch == 'f' || ch == 'F'));
|
||||
}
|
||||
|
||||
bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
|
||||
bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) noexcept {
|
||||
if (ch == '\'' || ch == '"')
|
||||
return true;
|
||||
if (IsPyStringTypeChar(ch, allowed)) {
|
||||
|
|
@ -68,12 +90,63 @@ bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IsPyFStringState(int st) noexcept {
|
||||
return ((st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING) ||
|
||||
(st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE));
|
||||
}
|
||||
|
||||
bool IsPySingleQuoteStringState(int st) noexcept {
|
||||
return ((st == SCE_P_CHARACTER) || (st == SCE_P_STRING) ||
|
||||
(st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING));
|
||||
}
|
||||
|
||||
bool IsPyTripleQuoteStringState(int st) noexcept {
|
||||
return ((st == SCE_P_TRIPLE) || (st == SCE_P_TRIPLEDOUBLE) ||
|
||||
(st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE));
|
||||
}
|
||||
|
||||
char GetPyStringQuoteChar(int st) noexcept {
|
||||
if ((st == SCE_P_CHARACTER) || (st == SCE_P_FCHARACTER) ||
|
||||
(st == SCE_P_TRIPLE) || (st == SCE_P_FTRIPLE))
|
||||
return '\'';
|
||||
if ((st == SCE_P_STRING) || (st == SCE_P_FSTRING) ||
|
||||
(st == SCE_P_TRIPLEDOUBLE) || (st == SCE_P_FTRIPLEDOUBLE))
|
||||
return '"';
|
||||
|
||||
return '\0';
|
||||
}
|
||||
|
||||
void PushStateToStack(int state, std::vector<SingleFStringExpState> &stack, SingleFStringExpState *¤tFStringExp) {
|
||||
SingleFStringExpState single = {state, 0};
|
||||
stack.push_back(single);
|
||||
|
||||
currentFStringExp = &stack.back();
|
||||
}
|
||||
|
||||
int PopFromStateStack(std::vector<SingleFStringExpState> &stack, SingleFStringExpState *¤tFStringExp) noexcept {
|
||||
int state = 0;
|
||||
|
||||
if (!stack.empty()) {
|
||||
state = stack.back().state;
|
||||
stack.pop_back();
|
||||
}
|
||||
|
||||
if (stack.empty()) {
|
||||
currentFStringExp = nullptr;
|
||||
} else {
|
||||
currentFStringExp = &stack.back();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
|
||||
int GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex, literalsAllowed allowed) {
|
||||
char ch = styler.SafeGetCharAt(i);
|
||||
char chNext = styler.SafeGetCharAt(i + 1);
|
||||
const int firstIsF = (ch == 'f' || ch == 'F');
|
||||
|
||||
// Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
|
||||
// Advance beyond r, u, or ur prefix (or r, b, or br in Python 2.7+ and r, f, or fr in Python 3.6+), but bail if there are any unexpected chars
|
||||
if (ch == 'r' || ch == 'R') {
|
||||
i++;
|
||||
ch = styler.SafeGetCharAt(i);
|
||||
|
|
@ -96,32 +169,46 @@ int GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex,
|
|||
*nextIndex = i + 3;
|
||||
|
||||
if (ch == '"')
|
||||
return SCE_P_TRIPLEDOUBLE;
|
||||
return (firstIsF ? SCE_P_FTRIPLEDOUBLE : SCE_P_TRIPLEDOUBLE);
|
||||
else
|
||||
return SCE_P_TRIPLE;
|
||||
return (firstIsF ? SCE_P_FTRIPLE : SCE_P_TRIPLE);
|
||||
} else {
|
||||
*nextIndex = i + 1;
|
||||
|
||||
if (ch == '"')
|
||||
return SCE_P_STRING;
|
||||
return (firstIsF ? SCE_P_FSTRING : SCE_P_STRING);
|
||||
else
|
||||
return SCE_P_CHARACTER;
|
||||
return (firstIsF ? SCE_P_FCHARACTER : SCE_P_CHARACTER);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsAWordChar(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
|
||||
inline bool IsAWordChar(int ch, bool unicodeIdentifiers) {
|
||||
if (IsASCII(ch))
|
||||
return (IsAlphaNumeric(ch) || ch == '.' || ch == '_');
|
||||
|
||||
if (!unicodeIdentifiers)
|
||||
return false;
|
||||
|
||||
// Python uses the XID_Continue set from Unicode data
|
||||
return IsXidContinue(ch);
|
||||
}
|
||||
|
||||
inline bool IsAWordStart(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '_');
|
||||
inline bool IsAWordStart(int ch, bool unicodeIdentifiers) {
|
||||
if (IsASCII(ch))
|
||||
return (IsUpperOrLowerCase(ch) || ch == '_');
|
||||
|
||||
if (!unicodeIdentifiers)
|
||||
return false;
|
||||
|
||||
// Python uses the XID_Start set from Unicode data
|
||||
return IsXidStart(ch);
|
||||
}
|
||||
|
||||
static bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {
|
||||
Sci_Position line = styler.GetLine(pos);
|
||||
Sci_Position start_pos = styler.LineStart(line);
|
||||
bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {
|
||||
const Sci_Position line = styler.GetLine(pos);
|
||||
const Sci_Position start_pos = styler.LineStart(line);
|
||||
for (Sci_Position i = start_pos; i < pos; i++) {
|
||||
char ch = styler[i];
|
||||
const char ch = styler[i];
|
||||
if (!(ch == ' ' || ch == '\t'))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -134,156 +221,200 @@ struct OptionsPython {
|
|||
bool base2or8Literals;
|
||||
bool stringsU;
|
||||
bool stringsB;
|
||||
bool stringsF;
|
||||
bool stringsOverNewline;
|
||||
bool keywords2NoSubIdentifiers;
|
||||
bool fold;
|
||||
bool foldQuotes;
|
||||
bool foldCompact;
|
||||
bool unicodeIdentifiers;
|
||||
|
||||
OptionsPython() {
|
||||
whingeLevel = 0;
|
||||
base2or8Literals = true;
|
||||
stringsU = true;
|
||||
stringsB = true;
|
||||
stringsF = true;
|
||||
stringsOverNewline = false;
|
||||
keywords2NoSubIdentifiers = false;
|
||||
fold = false;
|
||||
foldQuotes = false;
|
||||
foldCompact = false;
|
||||
unicodeIdentifiers = true;
|
||||
}
|
||||
|
||||
literalsAllowed AllowedLiterals() const {
|
||||
literalsAllowed AllowedLiterals() const noexcept {
|
||||
literalsAllowed allowedLiterals = stringsU ? litU : litNone;
|
||||
if (stringsB)
|
||||
allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
|
||||
if (stringsF)
|
||||
allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litF);
|
||||
return allowedLiterals;
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const pythonWordListDesc[] = {
|
||||
const char *const pythonWordListDesc[] = {
|
||||
"Keywords",
|
||||
"Highlighted identifiers",
|
||||
0
|
||||
nullptr
|
||||
};
|
||||
|
||||
struct OptionSetPython : public OptionSet<OptionsPython> {
|
||||
OptionSetPython() {
|
||||
DefineProperty("tab.timmy.whinge.level", &OptionsPython::whingeLevel,
|
||||
"For Python code, checks whether indenting is consistent. "
|
||||
"The default, 0 turns off indentation checking, "
|
||||
"1 checks whether each line is potentially inconsistent with the previous line, "
|
||||
"2 checks whether any space characters occur before a tab character in the indentation, "
|
||||
"3 checks whether any spaces are in the indentation, and "
|
||||
"4 checks for any tab characters in the indentation. "
|
||||
"1 is a good level to use.");
|
||||
"For Python code, checks whether indenting is consistent. "
|
||||
"The default, 0 turns off indentation checking, "
|
||||
"1 checks whether each line is potentially inconsistent with the previous line, "
|
||||
"2 checks whether any space characters occur before a tab character in the indentation, "
|
||||
"3 checks whether any spaces are in the indentation, and "
|
||||
"4 checks for any tab characters in the indentation. "
|
||||
"1 is a good level to use.");
|
||||
|
||||
DefineProperty("lexer.python.literals.binary", &OptionsPython::base2or8Literals,
|
||||
"Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.");
|
||||
"Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.");
|
||||
|
||||
DefineProperty("lexer.python.strings.u", &OptionsPython::stringsU,
|
||||
"Set to 0 to not recognise Python Unicode literals u\"x\" as used before Python 3.");
|
||||
"Set to 0 to not recognise Python Unicode literals u\"x\" as used before Python 3.");
|
||||
|
||||
DefineProperty("lexer.python.strings.b", &OptionsPython::stringsB,
|
||||
"Set to 0 to not recognise Python 3 bytes literals b\"x\".");
|
||||
"Set to 0 to not recognise Python 3 bytes literals b\"x\".");
|
||||
|
||||
DefineProperty("lexer.python.strings.f", &OptionsPython::stringsF,
|
||||
"Set to 0 to not recognise Python 3.6 f-string literals f\"var={var}\".");
|
||||
|
||||
DefineProperty("lexer.python.strings.over.newline", &OptionsPython::stringsOverNewline,
|
||||
"Set to 1 to allow strings to span newline characters.");
|
||||
"Set to 1 to allow strings to span newline characters.");
|
||||
|
||||
DefineProperty("lexer.python.keywords2.no.sub.identifiers", &OptionsPython::keywords2NoSubIdentifiers,
|
||||
"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.");
|
||||
"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.");
|
||||
|
||||
DefineProperty("fold", &OptionsPython::fold);
|
||||
|
||||
DefineProperty("fold.quotes.python", &OptionsPython::foldQuotes,
|
||||
"This option enables folding multi-line quoted strings when using the Python lexer.");
|
||||
"This option enables folding multi-line quoted strings when using the Python lexer.");
|
||||
|
||||
DefineProperty("fold.compact", &OptionsPython::foldCompact);
|
||||
|
||||
DefineProperty("lexer.python.unicode.identifiers", &OptionsPython::unicodeIdentifiers,
|
||||
"Set to 0 to not recognise Python 3 Unicode identifiers.");
|
||||
|
||||
DefineWordListSets(pythonWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
const char styleSubable[] = { SCE_P_IDENTIFIER, 0 };
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer Python SCLEX_PYTHON SCE_P_:
|
||||
0, "SCE_P_DEFAULT", "default", "White space",
|
||||
1, "SCE_P_COMMENTLINE", "comment line", "Comment",
|
||||
2, "SCE_P_NUMBER", "literal numeric", "Number",
|
||||
3, "SCE_P_STRING", "literal string", "String",
|
||||
4, "SCE_P_CHARACTER", "literal string", "Single quoted string",
|
||||
5, "SCE_P_WORD", "keyword", "Keyword",
|
||||
6, "SCE_P_TRIPLE", "literal string", "Triple quotes",
|
||||
7, "SCE_P_TRIPLEDOUBLE", "literal string", "Triple double quotes",
|
||||
8, "SCE_P_CLASSNAME", "identifier", "Class name definition",
|
||||
9, "SCE_P_DEFNAME", "identifier", "Function or method name definition",
|
||||
10, "SCE_P_OPERATOR", "operator", "Operators",
|
||||
11, "SCE_P_IDENTIFIER", "identifier", "Identifiers",
|
||||
12, "SCE_P_COMMENTBLOCK", "comment", "Comment-blocks",
|
||||
13, "SCE_P_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
14, "SCE_P_WORD2", "identifier", "Highlighted identifiers",
|
||||
15, "SCE_P_DECORATOR", "preprocessor", "Decorators",
|
||||
16, "SCE_P_FSTRING", "literal string interpolated", "F-String",
|
||||
17, "SCE_P_FCHARACTER", "literal string interpolated", "Single quoted f-string",
|
||||
18, "SCE_P_FTRIPLE", "literal string interpolated", "Triple quoted f-string",
|
||||
19, "SCE_P_FTRIPLEDOUBLE", "literal string interpolated", "Triple double quoted f-string",
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class LexerPython : public ILexerWithSubStyles {
|
||||
class LexerPython : public DefaultLexer {
|
||||
WordList keywords;
|
||||
WordList keywords2;
|
||||
OptionsPython options;
|
||||
OptionSetPython osPython;
|
||||
enum { ssIdentifier };
|
||||
SubStyles subStyles;
|
||||
std::map<Sci_Position, std::vector<SingleFStringExpState> > ftripleStateAtEol;
|
||||
public:
|
||||
explicit LexerPython() :
|
||||
DefaultLexer("python", SCLEX_PYTHON, lexicalClasses, ELEMENTS(lexicalClasses)),
|
||||
subStyles(styleSubable, 0x80, 0x40, 0) {
|
||||
}
|
||||
virtual ~LexerPython() {
|
||||
~LexerPython() override {
|
||||
}
|
||||
void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const {
|
||||
return lvSubStyles;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() {
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osPython.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osPython.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osPython.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
|
||||
const char * SCI_METHOD DescribeWordListSets() {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osPython.PropertyGet(key);
|
||||
}
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osPython.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) {
|
||||
return 0;
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int SCI_METHOD LineEndTypesSupported() {
|
||||
int SCI_METHOD LineEndTypesSupported() override {
|
||||
return SC_LINE_END_TYPE_UNICODE;
|
||||
}
|
||||
|
||||
int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) {
|
||||
int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) override {
|
||||
return subStyles.Allocate(styleBase, numberStyles);
|
||||
}
|
||||
int SCI_METHOD SubStylesStart(int styleBase) {
|
||||
int SCI_METHOD SubStylesStart(int styleBase) override {
|
||||
return subStyles.Start(styleBase);
|
||||
}
|
||||
int SCI_METHOD SubStylesLength(int styleBase) {
|
||||
int SCI_METHOD SubStylesLength(int styleBase) override {
|
||||
return subStyles.Length(styleBase);
|
||||
}
|
||||
int SCI_METHOD StyleFromSubStyle(int subStyle) {
|
||||
int styleBase = subStyles.BaseStyle(subStyle);
|
||||
int SCI_METHOD StyleFromSubStyle(int subStyle) override {
|
||||
const int styleBase = subStyles.BaseStyle(subStyle);
|
||||
return styleBase;
|
||||
}
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) {
|
||||
int SCI_METHOD PrimaryStyleFromStyle(int style) override {
|
||||
return style;
|
||||
}
|
||||
void SCI_METHOD FreeSubStyles() {
|
||||
void SCI_METHOD FreeSubStyles() override {
|
||||
subStyles.Free();
|
||||
}
|
||||
void SCI_METHOD SetIdentifiers(int style, const char *identifiers) {
|
||||
void SCI_METHOD SetIdentifiers(int style, const char *identifiers) override {
|
||||
subStyles.SetIdentifiers(style, identifiers);
|
||||
}
|
||||
int SCI_METHOD DistanceToSecondaryStyles() {
|
||||
int SCI_METHOD DistanceToSecondaryStyles() override {
|
||||
return 0;
|
||||
}
|
||||
const char * SCI_METHOD GetSubStyleBases() {
|
||||
const char *SCI_METHOD GetSubStyleBases() override {
|
||||
return styleSubable;
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryPython() {
|
||||
return new LexerPython();
|
||||
}
|
||||
|
||||
private:
|
||||
void ProcessLineEnd(StyleContext &sc, std::vector<SingleFStringExpState> &fstringStateStack, SingleFStringExpState *¤tFStringExp, bool &inContinuedString);
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *val) {
|
||||
|
|
@ -294,7 +425,7 @@ Sci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *va
|
|||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = 0;
|
||||
WordList *wordListN = nullptr;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywords;
|
||||
|
|
@ -315,8 +446,55 @@ Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) {
|
|||
return firstModification;
|
||||
}
|
||||
|
||||
void LexerPython::ProcessLineEnd(StyleContext &sc, std::vector<SingleFStringExpState> &fstringStateStack, SingleFStringExpState *¤tFStringExp, bool &inContinuedString) {
|
||||
long deepestSingleStateIndex = -1;
|
||||
unsigned long i;
|
||||
|
||||
// Find the deepest single quote state because that string will end; no \ continuation in f-string
|
||||
for (i = 0; i < fstringStateStack.size(); i++) {
|
||||
if (IsPySingleQuoteStringState(fstringStateStack[i].state)) {
|
||||
deepestSingleStateIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (deepestSingleStateIndex != -1) {
|
||||
sc.SetState(fstringStateStack[deepestSingleStateIndex].state);
|
||||
while (fstringStateStack.size() > static_cast<unsigned long>(deepestSingleStateIndex)) {
|
||||
PopFromStateStack(fstringStateStack, currentFStringExp);
|
||||
}
|
||||
}
|
||||
if (!fstringStateStack.empty()) {
|
||||
std::pair<Sci_Position, std::vector<SingleFStringExpState> > val;
|
||||
val.first = sc.currentLine;
|
||||
val.second = fstringStateStack;
|
||||
|
||||
ftripleStateAtEol.insert(val);
|
||||
}
|
||||
|
||||
if ((sc.state == SCE_P_DEFAULT)
|
||||
|| IsPyTripleQuoteStringState(sc.state)) {
|
||||
// Perform colourisation of white space and triple quoted strings at end of each line to allow
|
||||
// tab marking to work inside white space and triple quoted strings
|
||||
sc.SetState(sc.state);
|
||||
}
|
||||
if (IsPySingleQuoteStringState(sc.state)) {
|
||||
if (inContinuedString || options.stringsOverNewline) {
|
||||
inContinuedString = false;
|
||||
} else {
|
||||
sc.ChangeState(SCE_P_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
Accessor styler(pAccess, NULL);
|
||||
Accessor styler(pAccess, nullptr);
|
||||
|
||||
// Track whether in f-string expression; vector is used for a stack to
|
||||
// handle nested f-strings such as f"""{f'''{f"{f'{1}'}"}'''}"""
|
||||
std::vector<SingleFStringExpState> fstringStateStack;
|
||||
SingleFStringExpState *currentFStringExp = nullptr;
|
||||
|
||||
const Sci_Position endPos = startPos + length;
|
||||
|
||||
|
|
@ -327,11 +505,11 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
lineCurrent--;
|
||||
// Look for backslash-continued lines
|
||||
while (lineCurrent > 0) {
|
||||
Sci_Position eolPos = styler.LineStart(lineCurrent) - 1;
|
||||
int eolStyle = styler.StyleAt(eolPos);
|
||||
const Sci_Position eolPos = styler.LineStart(lineCurrent) - 1;
|
||||
const int eolStyle = styler.StyleAt(eolPos);
|
||||
if (eolStyle == SCE_P_STRING
|
||||
|| eolStyle == SCE_P_CHARACTER
|
||||
|| eolStyle == SCE_P_STRINGEOL) {
|
||||
|| eolStyle == SCE_P_CHARACTER
|
||||
|| eolStyle == SCE_P_STRINGEOL) {
|
||||
lineCurrent -= 1;
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -349,6 +527,18 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
initStyle = SCE_P_DEFAULT;
|
||||
}
|
||||
|
||||
// Set up fstate stack from last line and remove any subsequent ftriple at eol states
|
||||
std::map<Sci_Position, std::vector<SingleFStringExpState> >::iterator it;
|
||||
it = ftripleStateAtEol.find(lineCurrent - 1);
|
||||
if (it != ftripleStateAtEol.end() && !it->second.empty()) {
|
||||
fstringStateStack = it->second;
|
||||
currentFStringExp = &fstringStateStack.back();
|
||||
}
|
||||
it = ftripleStateAtEol.lower_bound(lineCurrent);
|
||||
if (it != ftripleStateAtEol.end()) {
|
||||
ftripleStateAtEol.erase(it, ftripleStateAtEol.end());
|
||||
}
|
||||
|
||||
kwType kwLast = kwOther;
|
||||
int spaceFlags = 0;
|
||||
styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
|
||||
|
|
@ -383,39 +573,25 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
}
|
||||
|
||||
if (sc.atLineEnd) {
|
||||
if ((sc.state == SCE_P_DEFAULT) ||
|
||||
(sc.state == SCE_P_TRIPLE) ||
|
||||
(sc.state == SCE_P_TRIPLEDOUBLE)) {
|
||||
// Perform colourisation of white space and triple quoted strings at end of each line to allow
|
||||
// tab marking to work inside white space and triple quoted strings
|
||||
sc.SetState(sc.state);
|
||||
}
|
||||
ProcessLineEnd(sc, fstringStateStack, currentFStringExp, inContinuedString);
|
||||
lineCurrent++;
|
||||
if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
|
||||
if (inContinuedString || options.stringsOverNewline) {
|
||||
inContinuedString = false;
|
||||
} else {
|
||||
sc.ChangeState(SCE_P_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
}
|
||||
}
|
||||
if (!sc.More())
|
||||
break;
|
||||
}
|
||||
|
||||
bool needEOLCheck = false;
|
||||
|
||||
// Check for a state end
|
||||
|
||||
if (sc.state == SCE_P_OPERATOR) {
|
||||
kwLast = kwOther;
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
} else if (sc.state == SCE_P_NUMBER) {
|
||||
if (!IsAWordChar(sc.ch) &&
|
||||
!(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
|
||||
if (!IsAWordChar(sc.ch, false) &&
|
||||
!(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_P_IDENTIFIER) {
|
||||
if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) {
|
||||
if ((sc.ch == '.') || (!IsAWordChar(sc.ch, options.unicodeIdentifiers))) {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
int style = SCE_P_IDENTIFIER;
|
||||
|
|
@ -449,7 +625,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
// We don't want to highlight keywords2
|
||||
// that are used as a sub-identifier,
|
||||
// i.e. not open in "foo.open".
|
||||
Sci_Position pos = styler.GetStartSegment() - 1;
|
||||
const Sci_Position pos = styler.GetStartSegment() - 1;
|
||||
if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
|
||||
style = SCE_P_WORD2;
|
||||
} else {
|
||||
|
|
@ -487,10 +663,10 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_P_DECORATOR) {
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
if (!IsAWordStart(sc.ch, options.unicodeIdentifiers)) {
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
|
||||
} else if (IsPySingleQuoteStringState(sc.state)) {
|
||||
if (sc.ch == '\\') {
|
||||
if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
|
||||
sc.Forward();
|
||||
|
|
@ -501,26 +677,23 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
// Don't roll over the newline.
|
||||
sc.Forward();
|
||||
}
|
||||
} else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
} else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
|
||||
} else if (sc.ch == GetPyStringQuoteChar(sc.state)) {
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
}
|
||||
} else if (sc.state == SCE_P_TRIPLE) {
|
||||
} else if ((sc.state == SCE_P_TRIPLE) || (sc.state == SCE_P_FTRIPLE)) {
|
||||
if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
} else if (sc.Match("\'\'\'")) {
|
||||
} else if (sc.Match(R"(''')")) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
}
|
||||
} else if (sc.state == SCE_P_TRIPLEDOUBLE) {
|
||||
} else if ((sc.state == SCE_P_TRIPLEDOUBLE) || (sc.state == SCE_P_FTRIPLEDOUBLE)) {
|
||||
if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
} else if (sc.Match("\"\"\"")) {
|
||||
} else if (sc.Match(R"(""")")) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
|
|
@ -528,6 +701,51 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
}
|
||||
}
|
||||
|
||||
// Note if used and not if else because string states also match
|
||||
// some of the above clauses
|
||||
if (IsPyFStringState(sc.state) && sc.ch == '{') {
|
||||
if (sc.chNext == '{') {
|
||||
sc.Forward();
|
||||
} else {
|
||||
PushStateToStack(sc.state, fstringStateStack, currentFStringExp);
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
}
|
||||
needEOLCheck = true;
|
||||
}
|
||||
|
||||
// If in an f-string expression, check for the ending quote(s)
|
||||
// and end f-string to handle syntactically incorrect cases like
|
||||
// f'{' and f"""{"""
|
||||
if (!fstringStateStack.empty() && (sc.ch == '\'' || sc.ch == '"')) {
|
||||
long matching_stack_i = -1;
|
||||
for (unsigned long stack_i = 0; stack_i < fstringStateStack.size() && matching_stack_i == -1; stack_i++) {
|
||||
const int stack_state = fstringStateStack[stack_i].state;
|
||||
const char quote = GetPyStringQuoteChar(stack_state);
|
||||
if (sc.ch == quote) {
|
||||
if (IsPySingleQuoteStringState(stack_state)) {
|
||||
matching_stack_i = stack_i;
|
||||
} else if (quote == '"' ? sc.Match(R"(""")") : sc.Match("'''")) {
|
||||
matching_stack_i = stack_i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matching_stack_i != -1) {
|
||||
sc.SetState(fstringStateStack[matching_stack_i].state);
|
||||
if (IsPyTripleQuoteStringState(fstringStateStack[matching_stack_i].state)) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
}
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
|
||||
while (fstringStateStack.size() > static_cast<unsigned long>(matching_stack_i)) {
|
||||
PopFromStateStack(fstringStateStack, currentFStringExp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of code to find the end of a state
|
||||
|
||||
if (!indentGood && !IsASpaceOrTab(sc.ch)) {
|
||||
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
|
||||
startIndicator = sc.currentPos;
|
||||
|
|
@ -541,12 +759,26 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
|
||||
// State exit code may have moved on to end of line
|
||||
if (needEOLCheck && sc.atLineEnd) {
|
||||
ProcessLineEnd(sc, fstringStateStack, currentFStringExp, inContinuedString);
|
||||
lineCurrent++;
|
||||
styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
|
||||
if (!sc.More())
|
||||
break;
|
||||
}
|
||||
|
||||
// If in f-string expression, check for }, :, ! to resume f-string state or update nesting count
|
||||
if (currentFStringExp && !IsPySingleQuoteStringState(sc.state) && !IsPyTripleQuoteStringState(sc.state)) {
|
||||
if (currentFStringExp->nestingCount == 0 && (sc.ch == '}' || sc.ch == ':' || (sc.ch == '!' && sc.chNext != '='))) {
|
||||
sc.SetState(PopFromStateStack(fstringStateStack, currentFStringExp));
|
||||
} else {
|
||||
if (sc.ch == '{' || sc.ch == '[' || sc.ch == '(') {
|
||||
currentFStringExp->nestingCount++;
|
||||
} else if (sc.ch == '}' || sc.ch == ']' || sc.ch == ')') {
|
||||
currentFStringExp->nestingCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a new state starting character
|
||||
if (sc.state == SCE_P_DEFAULT) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
|
|
@ -554,7 +786,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
base_n_number = true;
|
||||
sc.SetState(SCE_P_NUMBER);
|
||||
} else if (sc.ch == '0' &&
|
||||
(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
|
||||
(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
|
||||
if (options.base2or8Literals) {
|
||||
base_n_number = true;
|
||||
sc.SetState(SCE_P_NUMBER);
|
||||
|
|
@ -566,7 +798,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
base_n_number = false;
|
||||
sc.SetState(SCE_P_NUMBER);
|
||||
}
|
||||
} else if ((IsASCII(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') {
|
||||
} else if (isoperator(sc.ch) || sc.ch == '`') {
|
||||
sc.SetState(SCE_P_OPERATOR);
|
||||
} else if (sc.ch == '#') {
|
||||
sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
|
||||
|
|
@ -581,7 +813,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
while (nextIndex > (sc.currentPos + 1) && sc.More()) {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (IsAWordStart(sc.ch)) {
|
||||
} else if (IsAWordStart(sc.ch, options.unicodeIdentifiers)) {
|
||||
sc.SetState(SCE_P_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
|
|
@ -591,10 +823,10 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
|||
}
|
||||
|
||||
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
|
||||
Sci_Position pos = styler.LineStart(line);
|
||||
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
const Sci_Position pos = styler.LineStart(line);
|
||||
const Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position i = pos; i < eol_pos; i++) {
|
||||
char ch = styler[i];
|
||||
const char ch = styler[i];
|
||||
if (ch == '#')
|
||||
return true;
|
||||
else if (ch != ' ' && ch != '\t')
|
||||
|
|
@ -603,9 +835,9 @@ static bool IsCommentLine(Sci_Position line, Accessor &styler) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool IsQuoteLine(Sci_Position line, Accessor &styler) {
|
||||
int style = styler.StyleAt(styler.LineStart(line)) & 31;
|
||||
return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
|
||||
static bool IsQuoteLine(Sci_Position line, const Accessor &styler) {
|
||||
const int style = styler.StyleAt(styler.LineStart(line)) & 31;
|
||||
return IsPyTripleQuoteStringState(style);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -613,7 +845,7 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
if (!options.fold)
|
||||
return;
|
||||
|
||||
Accessor styler(pAccess, NULL);
|
||||
Accessor styler(pAccess, nullptr);
|
||||
|
||||
const Sci_Position maxPos = startPos + length;
|
||||
const Sci_Position maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line
|
||||
|
|
@ -625,13 +857,13 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
// at least one line in all cases)
|
||||
int spaceFlags = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
|
||||
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);
|
||||
while (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
|
||||
indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, nullptr);
|
||||
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
|
||||
(!IsCommentLine(lineCurrent, styler)) &&
|
||||
(!IsQuoteLine(lineCurrent, styler)))
|
||||
(!IsCommentLine(lineCurrent, styler)) &&
|
||||
(!IsQuoteLine(lineCurrent, styler)))
|
||||
break;
|
||||
}
|
||||
int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
|
||||
|
|
@ -641,7 +873,7 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
int prev_state = SCE_P_DEFAULT & 31;
|
||||
if (lineCurrent >= 1)
|
||||
prev_state = styler.StyleAt(startPos - 1) & 31;
|
||||
int prevQuote = options.foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));
|
||||
int prevQuote = options.foldQuotes && IsPyTripleQuoteStringState(prev_state);
|
||||
|
||||
// Process all characters to end of requested range or end of any triple quote
|
||||
//that hangs over the end of the range. Cap processing in all cases
|
||||
|
|
@ -655,10 +887,10 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
int quote = false;
|
||||
if (lineNext <= docLines) {
|
||||
// Information about next line is only available if not at end of document
|
||||
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
|
||||
Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
|
||||
int style = styler.StyleAt(lookAtPos) & 31;
|
||||
quote = options.foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
|
||||
indentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);
|
||||
const Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
|
||||
const int style = styler.StyleAt(lookAtPos) & 31;
|
||||
quote = options.foldQuotes && IsPyTripleQuoteStringState(style);
|
||||
}
|
||||
const int quote_start = (quote && !prevQuote);
|
||||
const int quote_continue = (quote && prevQuote);
|
||||
|
|
@ -680,19 +912,25 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
// 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.
|
||||
// than screwing up folding. If comments end file, use the min
|
||||
// comment indent as the level after
|
||||
|
||||
int minCommentLevel = indentCurrentLevel;
|
||||
while (!quote &&
|
||||
(lineNext < docLines) &&
|
||||
((indentNext & SC_FOLDLEVELWHITEFLAG) ||
|
||||
(lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
|
||||
(lineNext < docLines) &&
|
||||
((indentNext & SC_FOLDLEVELWHITEFLAG) ||
|
||||
(lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
|
||||
|
||||
if (IsCommentLine(lineNext, styler) && indentNext < minCommentLevel) {
|
||||
minCommentLevel = indentNext;
|
||||
}
|
||||
|
||||
lineNext++;
|
||||
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
|
||||
indentNext = styler.IndentAmount(lineNext, &spaceFlags, nullptr);
|
||||
}
|
||||
|
||||
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
|
||||
const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);
|
||||
const int levelAfterComments = ((lineNext < docLines) ? indentNext & SC_FOLDLEVELNUMBERMASK : minCommentLevel);
|
||||
const int levelBeforeComments = std::max(indentCurrentLevel, levelAfterComments);
|
||||
|
||||
// Now set all the indent levels on the lines we skipped
|
||||
// Do this from end to start. Once we encounter one line
|
||||
|
|
@ -703,19 +941,19 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
int skipLevel = levelAfterComments;
|
||||
|
||||
while (--skipLine > lineCurrent) {
|
||||
int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
|
||||
const int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, nullptr);
|
||||
|
||||
if (options.foldCompact) {
|
||||
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
|
||||
skipLevel = levelBeforeComments;
|
||||
|
||||
int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
|
||||
const int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
|
||||
|
||||
styler.SetLevel(skipLine, skipLevel | whiteFlag);
|
||||
} else {
|
||||
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
|
||||
!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
|
||||
!IsCommentLine(skipLine, styler))
|
||||
!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
|
||||
!IsCommentLine(skipLine, styler))
|
||||
skipLevel = levelBeforeComments;
|
||||
|
||||
styler.SetLevel(skipLine, skipLevel);
|
||||
|
|
@ -743,4 +981,4 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i
|
|||
}
|
||||
|
||||
LexerModule lmPython(SCLEX_PYTHON, LexerPython::LexerFactoryPython, "python",
|
||||
pythonWordListDesc);
|
||||
pythonWordListDesc);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file Lexr.cxx
|
||||
/** @file LexR.cxx
|
||||
** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer).
|
||||
**
|
||||
**/
|
||||
|
|
@ -24,9 +24,7 @@
|
|||
#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 == '_');
|
||||
|
|
|
|||
1605
src/stc/scintilla/lexers/LexRaku.cxx
Normal file
1605
src/stc/scintilla/lexers/LexRaku.cxx
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -29,9 +29,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static inline bool IsAWordChar(const int ch) {
|
||||
return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static const char *const RegistryWordListDesc[] = {
|
||||
0
|
||||
|
|
@ -53,7 +52,7 @@ struct OptionSetRegistry : public OptionSet<OptionsRegistry> {
|
|||
}
|
||||
};
|
||||
|
||||
class LexerRegistry : public ILexer {
|
||||
class LexerRegistry : public DefaultLexer {
|
||||
OptionsRegistry options;
|
||||
OptionSetRegistry optSetRegistry;
|
||||
|
||||
|
|
@ -162,49 +161,53 @@ class LexerRegistry : public ILexer {
|
|||
}
|
||||
|
||||
public:
|
||||
LexerRegistry() {}
|
||||
LexerRegistry() : DefaultLexer("registry", SCLEX_REGISTRY) {}
|
||||
virtual ~LexerRegistry() {}
|
||||
virtual int SCI_METHOD Version() const {
|
||||
return lvOriginal;
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvIdentity;
|
||||
}
|
||||
virtual void SCI_METHOD Release() {
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
virtual const char *SCI_METHOD PropertyNames() {
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return optSetRegistry.PropertyNames();
|
||||
}
|
||||
virtual int SCI_METHOD PropertyType(const char *name) {
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return optSetRegistry.PropertyType(name);
|
||||
}
|
||||
virtual const char *SCI_METHOD DescribeProperty(const char *name) {
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return optSetRegistry.DescribeProperty(name);
|
||||
}
|
||||
virtual Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) {
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override {
|
||||
if (optSetRegistry.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
virtual Sci_Position SCI_METHOD WordListSet(int, const char *) {
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
return optSetRegistry.PropertyGet(key);
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD WordListSet(int, const char *) override {
|
||||
return -1;
|
||||
}
|
||||
virtual void *SCI_METHOD PrivateCall(int, void *) {
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return 0;
|
||||
}
|
||||
static ILexer *LexerFactoryRegistry() {
|
||||
return new LexerRegistry;
|
||||
}
|
||||
virtual const char *SCI_METHOD DescribeWordListSets() {
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return optSetRegistry.DescribeWordListSets();
|
||||
}
|
||||
virtual void SCI_METHOD Lex(Sci_PositionU startPos,
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos,
|
||||
Sci_Position length,
|
||||
int initStyle,
|
||||
IDocument *pAccess);
|
||||
virtual void SCI_METHOD Fold(Sci_PositionU startPos,
|
||||
IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos,
|
||||
Sci_Position length,
|
||||
int initStyle,
|
||||
IDocument *pAccess);
|
||||
IDocument *pAccess) override;
|
||||
};
|
||||
|
||||
void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos,
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
//XXX Identical to Perl, put in common area
|
||||
static inline bool isEOLChar(char ch) {
|
||||
|
|
@ -346,7 +344,7 @@ static bool RE_CanFollowKeyword(const char *keyword) {
|
|||
// Look at chars up to but not including endPos
|
||||
// Don't look at styles in case we're looking forward
|
||||
|
||||
static int skipWhitespace(Sci_Position startPos,
|
||||
static Sci_Position skipWhitespace(Sci_Position startPos,
|
||||
Sci_Position endPos,
|
||||
Accessor &styler) {
|
||||
for (Sci_Position i = startPos; i < endPos; i++) {
|
||||
|
|
@ -564,7 +562,7 @@ static bool sureThisIsNotHeredoc(Sci_Position lt2StartPos,
|
|||
bool allow_indent;
|
||||
Sci_Position target_start, target_end;
|
||||
// From this point on no more styling, since we're looking ahead
|
||||
if (styler[j] == '-') {
|
||||
if (styler[j] == '-' || styler[j] == '~') {
|
||||
allow_indent = true;
|
||||
j++;
|
||||
} else {
|
||||
|
|
@ -890,7 +888,7 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init
|
|||
chNext = chNext2;
|
||||
styler.ColourTo(i, SCE_RB_OPERATOR);
|
||||
|
||||
if (!(strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) {
|
||||
if (!(strchr("\"\'`_-~", chNext2) || isSafeAlpha(chNext2))) {
|
||||
// It's definitely not a here-doc,
|
||||
// based on Ruby's lexer/parser in the
|
||||
// heredoc_identifier routine.
|
||||
|
|
@ -1236,7 +1234,7 @@ static void ColouriseRbDoc(Sci_PositionU startPos, Sci_Position length, int init
|
|||
if (HereDoc.State == 0) { // '<<' encountered
|
||||
HereDoc.State = 1;
|
||||
HereDoc.DelimiterLength = 0;
|
||||
if (ch == '-') {
|
||||
if (ch == '-' || ch == '~') {
|
||||
HereDoc.CanBeIndented = true;
|
||||
advance_char(i, ch, chNext, chNext2); // pass by ref
|
||||
} else {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue