Initial commit.

This commit is contained in:
2018-12-06 16:01:56 +01:00
parent 10867b60c2
commit 18eb3f6047
1011 changed files with 345688 additions and 10 deletions

View File

@@ -0,0 +1,26 @@
# This file is part of EPOCH.
# File: CMakeLists.txt
# Author: Florent Teichteil-Königsbuch
# Contact: florent.teichteil@onera.fr
#
# EPOCH is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# EPOCH is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with EPOCH. If not, see <http://www.gnu.org/licenses/>.
MESSAGE (STATUS "Compiling wxScintilla-1.69.2 from codelite-2.7.0.4375")
FILE (GLOB_RECURSE WXSCINTILLA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR} *.cxx *.cpp)
INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src/scintilla/include
${CMAKE_CURRENT_SOURCE_DIR}/src/scintilla/src)
ADD_DEFINITIONS (-D__WX__=1 -DSCI_LEXER -DLINK_LEXERS)
ADD_LIBRARY (epoch-wxscintilla STATIC ${WXSCINTILLA_SOURCES})

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
#ifndef PLATWX_H // [CHANGED]
#define PLATWX_H // [CHANGED]
#ifdef SCI_NAMESPACE
namespace Scintilla
{
#endif
wxRect wxRectFromPRectangle(PRectangle prc);
PRectangle PRectangleFromwxRect(wxRect rc);
wxColour wxColourFromCA(const ColourAllocated& ca);
#ifdef SCI_NAMESPACE
}
#endif
#endif // [CHANGED]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,214 @@
////////////////////////////////////////////////////////////////////////////
// Name: ScintillaWX.h
// Purpose: A wxWidgets implementation of Scintilla. A class derived
// from ScintillaBase that uses the "wx platform" defined in
// PlatWX.cpp. This class is one end of a bridge between
// the wx world and the Scintilla world. It needs a peer
// object of type wxScintilla to function.
//
// Author: Robin Dunn
//
// Created: 13-Jan-2000
// RCS-ID: $Id: ScintillaWX.h,v 1.9 2006/06/06 19:16:25 wyo Exp $
// Copyright: (c) 2000 by Total Control Software
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __ScintillaWX_h__
#define __ScintillaWX_h__
// [CHANGED] BEGIN
#include <vector>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Platform.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "Scintilla.h"
#include "ScintillaWidget.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#endif
#include "ContractionState.h"
#include "SVector.h"
#include "CellBuffer.h"
#include "CallTip.h"
#include "KeyMap.h"
#include "Indicator.h"
#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "AutoComplete.h"
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
#include "SString.h"
#include "PropSetSimple.h"
#include "ScintillaBase.h"
#include <wx/wx.h>
#include <wx/dataobj.h>
#include <wx/clipbrd.h>
#include <wx/dnd.h>
// [CHANGED] END
#ifdef WXMAKINGDLL_SCI
#define WXDLLIMPEXP_SCI WXEXPORT
#elif defined(WXUSINGDLL_SCI)
#define WXDLLIMPEXP_SCI WXIMPORT
#else // not making nor using DLL
#define WXDLLIMPEXP_SCI
#endif
class WXDLLIMPEXP_SCI wxScintilla; // forward
class ScintillaWX;
#ifndef SCI_SCOPE // begin [CHANGED]
#ifdef SCI_NAMESPACE
#define SCI_SCOPE( x ) Scintilla::x
#else
#define SCI_SCOPE( x ) x
#endif
#endif // end [CHANGED]
//----------------------------------------------------------------------
// Helper classes
#if wxUSE_DRAG_AND_DROP
class wxSCIDropTarget : public wxTextDropTarget {
public:
void SetScintilla(ScintillaWX* swx) {
this->swx = swx;
}
bool OnDropText(wxCoord x, wxCoord y, const wxString& data);
wxDragResult OnEnter(wxCoord x, wxCoord y, wxDragResult def);
wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def);
void OnLeave();
private:
ScintillaWX* swx;
};
#endif
//----------------------------------------------------------------------
class ScintillaWX : public SCI_SCOPE( ScintillaBase ) {
public:
ScintillaWX(wxScintilla* win);
~ScintillaWX();
// base class virtuals
virtual void Initialise();
virtual void Finalise();
virtual void StartDrag();
virtual bool SetIdle(bool on);
virtual void SetTicking(bool on);
virtual void SetMouseCapture(bool on);
virtual bool HaveMouseCapture();
virtual void ScrollText(int linesToMove);
virtual void SetVerticalScrollPos();
virtual void SetHorizontalScrollPos();
virtual bool ModifyScrollBars(int nMax, int nPage);
virtual void Copy();
virtual void Paste();
virtual void CopyToClipboard(const SCI_SCOPE(SelectionText) &selectedText);
virtual void CreateCallTipWindow( SCI_SCOPE(PRectangle) rc);
virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true);
virtual void ClaimSelection();
virtual long DefWndProc(unsigned int iMessage,
unsigned long wParam,
long lParam);
virtual long WndProc(unsigned int iMessage,
unsigned long wParam,
long lParam);
virtual void NotifyChange();
virtual void NotifyParent( SCI_SCOPE(SCNotification) scn);
virtual void CancelModes();
virtual void UpdateSystemCaret();
// Event delegates
void DoPaint(wxDC* dc, wxRect rect);
void DoHScroll(int type, int pos);
void DoVScroll(int type, int pos);
void DoSize(int width, int height);
void DoLoseFocus();
void DoGainFocus();
void DoSysColourChange();
void DoLeftButtonDown( SCI_SCOPE(Point) pt, unsigned int curTime, bool shift, bool ctrl, bool alt); // [CHANGED]
void DoLeftButtonUp(SCI_SCOPE(Point) pt, unsigned int curTime, bool ctrl); // [CHANGED]
void DoLeftButtonMove(SCI_SCOPE(Point) pt); // [CHANGED]
void DoMiddleButtonUp(SCI_SCOPE(Point) pt); // [CHANGED]
void DoMouseWheel(int rotation, int delta, int linesPerAction, int ctrlDown, bool isPageScroll);
void DoAddChar(int key);
int DoKeyDown(const wxKeyEvent& event, bool* consumed);
void DoTick() { Tick(); }
void DoOnIdle(wxIdleEvent& evt);
void DoStartDrag();
#if wxUSE_DRAG_AND_DROP
bool DoDropText(long x, long y, const wxString& data);
wxDragResult DoDragEnter(wxCoord x, wxCoord y, wxDragResult def);
wxDragResult DoDragOver(wxCoord x, wxCoord y, wxDragResult def);
void DoDragLeave();
#endif
void DoCommand(int ID);
void DoContextMenu(SCI_SCOPE(Point) pt); // [CHANGED]
void DoOnListBox();
// helpers
void FullPaint();
bool CanPaste();
bool GetHideSelection() { return hideSelection; }
void DoScrollToLine(int line);
void DoScrollToColumn(int column);
void ClipChildren(wxDC& dc, SCI_SCOPE(PRectangle) rect);
void SetUseAntiAliasing(bool useAA);
bool GetUseAntiAliasing();
private:
bool capturedMouse;
bool focusEvent;
wxScintilla* sci;
#if wxUSE_DRAG_AND_DROP
wxSCIDropTarget* dropTarget;
wxDragResult dragResult;
bool dragRectangle;
wxTimer* startDragTimer;
#endif
int wheelRotation;
// For use in creating a system caret
bool HasCaretSizeChanged();
bool CreateSystemCaret();
bool DestroySystemCaret();
#ifdef __WXMSW__
#if wxCHECK_VERSION(2, 5, 0)
HBITMAP sysCaretBitmap;
int sysCaretWidth;
int sysCaretHeight;
#endif
#endif
friend class wxSCICallTip;
};
//----------------------------------------------------------------------
#endif

View File

@@ -0,0 +1,39 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/gtk/private/string.h
// Purpose: MyGtkString class declaration
// Author: Vadim Zeitlin
// Created: 2006-10-19
// RCS-ID: $Id$
// Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifdef __WXGTK__
#ifndef _GTK_PRIVATE_STRING_H_
#define _GTK_PRIVATE_STRING_H_
// ----------------------------------------------------------------------------
// Convenience class for g_freeing a gchar* on scope exit automatically
// ----------------------------------------------------------------------------
#ifdef __WXGTK20__
#include <gtk-2.0/gtk/gtk.h>
#endif
class MyGtkString
{
public:
explicit MyGtkString(gchar *s) : m_str(s) { }
~MyGtkString() { g_free(m_str); }
const gchar *c_str() const { return m_str; }
operator gchar *() const { return m_str; }
private:
gchar *m_str;
DECLARE_NO_COPY_CLASS(MyGtkString)
};
#endif // _WX_GTK_PRIVATE_STRING_H_
#endif //__WXGTK__

View File

@@ -0,0 +1,20 @@
License for Scintilla and SciTE
Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
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.
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.

View File

@@ -0,0 +1,5 @@
This directory contains copies of the scintilla/src and
scintilla/include directories from the Scintilla source
distribution.
The current version of the Scintilla code is 1.62

View File

@@ -0,0 +1,79 @@
// Scintilla source code edit control
/** @file Accessor.h
** Rapid easy access to contents of a Scintilla.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
class Accessor;
typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
/**
* Interface to data in a Scintilla.
*/
class Accessor {
protected:
enum {extremePosition=0x7FFFFFFF};
/** @a bufferSize is a trade off between time taken to copy the characters
* and retrieval overhead.
* @a slopSize positions the buffer before the desired position
* in case there is some backtracking. */
enum {bufferSize=4000, slopSize=bufferSize/8};
char buf[bufferSize+1];
int startPos;
int endPos;
int codePage;
virtual bool InternalIsLeadByte(char ch)=0;
virtual void Fill(int position)=0;
public:
Accessor() : startPos(extremePosition), endPos(0), codePage(0) {}
virtual ~Accessor() {}
char operator[](int position) {
if (position < startPos || position >= endPos) {
Fill(position);
}
return buf[position - startPos];
}
/** Safe version of operator[], returning a defined value for invalid position. */
char SafeGetCharAt(int position, char chDefault=' ') {
if (position < startPos || position >= endPos) {
Fill(position);
if (position < startPos || position >= endPos) {
// Position is outside range of document
return chDefault;
}
}
return buf[position - startPos];
}
bool IsLeadByte(char ch) {
return codePage && InternalIsLeadByte(ch);
}
void SetCodePage(int codePage_) { codePage = codePage_; }
virtual bool Match(int pos, const char *s)=0;
virtual char StyleAt(int position)=0;
virtual int GetLine(int position)=0;
virtual int LineStart(int line)=0;
virtual int LevelAt(int line)=0;
virtual int Length()=0;
virtual void Flush()=0;
virtual int GetLineState(int line)=0;
virtual int SetLineState(int line, int state)=0;
virtual int GetPropertyInt(const char *key, int defaultValue=0)=0;
virtual char *GetProperties()=0;
// Style setting
virtual void StartAt(unsigned int start, char chMask=31)=0;
virtual void SetFlags(char chFlags_, char chWhile_)=0;
virtual unsigned int GetStartSegment()=0;
virtual void StartSegment(unsigned int pos)=0;
virtual void ColourTo(unsigned int pos, int chAttr)=0;
virtual void SetLevel(int line, int level)=0;
virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0;
virtual void IndicatorFill(int start, int end, int indicator, int value)=0;
};

View File

@@ -0,0 +1,110 @@
# Module for reading and parsing Scintilla.iface file
def sanitiseLine(line):
if line[-1:] == '\n': line = line[:-1]
if line.find("##") != -1:
line = line[:line.find("##")]
line = line.strip()
return line
def decodeFunction(featureVal):
retType, rest = featureVal.split(" ", 1)
nameIdent, params = rest.split("(")
name, value = nameIdent.split("=")
params, rest = params.split(")")
param1, param2 = params.split(",")[0:2]
return retType, name, value, param1, param2
def decodeEvent(featureVal):
retType, rest = featureVal.split(" ", 1)
nameIdent, params = rest.split("(")
name, value = nameIdent.split("=")
return retType, name, value
def decodeParam(p):
param = p.strip()
type = ""
name = ""
value = ""
if " " in param:
type, nv = param.split(" ")
if "=" in nv:
name, value = nv.split("=")
else:
name = nv
return type, name, value
class Face:
def __init__(self):
self.order = []
self.features = {}
self.values = {}
self.events = {}
def ReadFromFile(self, name):
currentCategory = ""
currentComment = []
currentCommentFinished = 0
file = open(name)
for line in file.readlines():
line = sanitiseLine(line)
if line:
if line[0] == "#":
if line[1] == " ":
if currentCommentFinished:
currentComment = []
currentCommentFinished = 0
currentComment.append(line[2:])
else:
currentCommentFinished = 1
featureType, featureVal = line.split(" ", 1)
if featureType in ["fun", "get", "set"]:
retType, name, value, param1, param2 = decodeFunction(featureVal)
p1 = decodeParam(param1)
p2 = decodeParam(param2)
self.features[name] = {
"FeatureType": featureType,
"ReturnType": retType,
"Value": value,
"Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2],
"Param2Type": p2[0], "Param2Name": p2[1], "Param2Value": p2[2],
"Category": currentCategory, "Comment": currentComment
}
if value in self.values:
raise "Duplicate value " + value + " " + name
self.values[value] = 1
self.order.append(name)
elif featureType == "evt":
retType, name, value = decodeEvent(featureVal)
self.features[name] = {
"FeatureType": featureType,
"ReturnType": retType,
"Value": value,
"Category": currentCategory, "Comment": currentComment
}
if value in self.events:
raise "Duplicate event " + value + " " + name
self.events[value] = 1
self.order.append(name)
elif featureType == "cat":
currentCategory = featureVal
elif featureType == "val":
try:
name, value = featureVal.split("=", 1)
except ValueError:
print("Failure %s" % featureVal)
raise
self.features[name] = {
"FeatureType": featureType,
"Category": currentCategory,
"Value": value }
self.order.append(name)
elif featureType == "enu" or featureType == "lex":
name, value = featureVal.split("=", 1)
self.features[name] = {
"FeatureType": featureType,
"Category": currentCategory,
"Value": value }
self.order.append(name)

View File

@@ -0,0 +1,75 @@
# HFacer.py - regenerate the Scintilla.h and SciLexer.h files from the Scintilla.iface interface
# definition file.
# The header files are copied to a temporary file apart from the section between a /* ++Autogenerated*/
# comment and a /* --Autogenerated*/ comment which is generated by the printHFile and printLexHFile
# functions. After the temporary file is created, it is copied back to the original file name.
import sys
import os
import Face
def Contains(s,sub):
return s.find(sub) != -1
def printLexHFile(f,out):
for name in f.order:
v = f.features[name]
if v["FeatureType"] in ["val"]:
if Contains(name, "SCE_") or Contains(name, "SCLEX_"):
out.write("#define " + name + " " + v["Value"] + "\n")
def printHFile(f,out):
for name in f.order:
v = f.features[name]
if v["Category"] != "Deprecated":
if v["FeatureType"] in ["fun", "get", "set"]:
featureDefineName = "SCI_" + name.upper()
out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
elif v["FeatureType"] in ["evt"]:
featureDefineName = "SCN_" + name.upper()
out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
elif v["FeatureType"] in ["val"]:
if not (Contains(name, "SCE_") or Contains(name, "SCLEX_")):
out.write("#define " + name + " " + v["Value"] + "\n")
def CopyWithInsertion(input, output, genfn, definition):
copying = 1
for line in input.readlines():
if copying:
output.write(line)
if Contains(line, "/* ++Autogenerated"):
copying = 0
genfn(definition, output)
if Contains(line, "/* --Autogenerated"):
copying = 1
output.write(line)
def contents(filename):
f = open(filename)
t = f.read()
f.close()
return t
def Regenerate(filename, genfn, definition):
inText = contents(filename)
tempname = "HFacer.tmp"
out = open(tempname,"w")
hfile = open(filename)
CopyWithInsertion(hfile, out, genfn, definition)
out.close()
hfile.close()
outText = contents(tempname)
if inText == outText:
os.unlink(tempname)
else:
os.unlink(filename)
os.rename(tempname, filename)
f = Face.Face()
try:
f.ReadFromFile("Scintilla.iface")
Regenerate("Scintilla.h", printHFile, f)
Regenerate("SciLexer.h", printLexHFile, f)
print("Maximum ID is %s" % max([x for x in f.values if int(x) < 3000]))
except:
raise

View File

@@ -0,0 +1,113 @@
// Scintilla source code edit control
/** @file KeyWords.h
** Colourise for particular languages.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class WordList {
public:
// Each word contains at least one character - a empty word acts as sentinel at the end.
char **words;
char *list;
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
bool sorted;
int starts[256];
WordList(bool onlyLineEnds_ = false) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
sorted(false)
{}
~WordList() { Clear(); }
operator bool() { return len ? true : false; }
void Clear();
void Set(const char *s);
bool InList(const char *s);
bool InListAbbreviated(const char *s, const char marker);
};
typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler);
/**
* A LexerModule is responsible for lexing and folding a particular language.
* The class maintains a list of LexerModules which can be searched to find a
* module appropriate to a particular language.
*/
class LexerModule {
protected:
const LexerModule *next;
int language;
LexerFunction fnLexer;
LexerFunction fnFolder;
const char * const * wordListDescriptions;
int styleBits;
static const LexerModule *base;
static int nextLanguage;
public:
const char *languageName;
LexerModule(int language_,
LexerFunction fnLexer_,
const char *languageName_=0,
LexerFunction fnFolder_=0,
const char * const wordListDescriptions_[] = NULL,
int styleBits_=5);
virtual ~LexerModule() {
}
int GetLanguage() const { return language; }
// -1 is returned if no WordList information is available
int GetNumWordLists() const;
const char *GetWordListDescription(int index) const;
int GetStyleBitsNeeded() const;
virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
static const LexerModule *Find(int language);
static const LexerModule *Find(const char *languageName);
};
#ifdef SCI_NAMESPACE
}
#endif
/**
* Check if a character is a space.
* This is ASCII specific but is safe with chars >= 0x80.
*/
inline bool isspacechar(unsigned char ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
inline bool iswordchar(char ch) {
return isascii(ch) && (isalnum(ch) || ch == '.' || ch == '_');
}
inline bool iswordstart(char ch) {
return isascii(ch) && (isalnum(ch) || ch == '_');
}
inline bool isoperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
ch == '?' || ch == '!' || ch == '.' || ch == '~')
return true;
return false;
}

View File

@@ -0,0 +1,558 @@
// Scintilla source code edit control
/** @file Platform.h
** Interface to platform facilities. Also includes some basic utilities.
** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PLATFORM_H
#define PLATFORM_H
// PLAT_GTK = GTK+ on Linux or Win32
// PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32
// PLAT_WIN = Win32 API on Win32 OS
// PLAT_WX is wxWindows on any supported platform
#define PLAT_GTK 0
#define PLAT_GTK_WIN32 0
#define PLAT_MACOSX 0
#define PLAT_WIN 0
#define PLAT_WX 0
#define PLAT_FOX 0
#if defined(FOX)
#undef PLAT_FOX
#define PLAT_FOX 1
#elif defined(__WX__)
#undef PLAT_WX
#define PLAT_WX 1
#elif defined(GTK)
#undef PLAT_GTK
#define PLAT_GTK 1
#if defined(__WIN32__) || defined(_MSC_VER)
#undef PLAT_GTK_WIN32
#define PLAT_GTK_WIN32 1
#endif
#elif defined(__APPLE__)
#undef PLAT_MACOSX
#define PLAT_MACOSX 1
#else
#undef PLAT_WIN
#define PLAT_WIN 1
#endif
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// 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
typedef void *FontID;
typedef void *SurfaceID;
typedef void *WindowID;
typedef void *MenuID;
typedef void *TickerID;
typedef void *Function;
typedef void *IdlerID;
/**
* A geometric point class.
* Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably.
*/
class Point {
public:
int x;
int y;
explicit Point(int x_=0, int y_=0) : x(x_), y(y_) {
}
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
static Point FromLong(long lpoint);
};
/**
* A geometric rectangle class.
* PRectangle is exactly the same as the Win32 RECT so can be used interchangeably.
* PRectangles contain their top and left sides, but not their right and bottom sides.
*/
class PRectangle {
public:
int left;
int top;
int right;
int bottom;
PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) :
left(left_), top(top_), right(right_), bottom(bottom_) {
}
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
bool operator==(PRectangle &rc) {
return (rc.left == left) && (rc.right == right) &&
(rc.top == top) && (rc.bottom == bottom);
}
bool Contains(Point pt) {
return (pt.x >= left) && (pt.x <= right) &&
(pt.y >= top) && (pt.y <= bottom);
}
bool Contains(PRectangle rc) {
return (rc.left >= left) && (rc.right <= right) &&
(rc.top >= top) && (rc.bottom <= bottom);
}
bool Intersects(PRectangle other) {
return (right > other.left) && (left < other.right) &&
(bottom > other.top) && (top < other.bottom);
}
void Move(int xDelta, int yDelta) {
left += xDelta;
top += yDelta;
right += xDelta;
bottom += yDelta;
}
int Width() { return right - left; }
int Height() { return bottom - top; }
bool Empty() {
return (Height() <= 0) || (Width() <= 0);
}
};
/**
* In some circumstances, including Win32 in paletted mode and GTK+, each colour
* must be allocated before use. The desired colours are held in the ColourDesired class,
* and after allocation the allocation entry is stored in the ColourAllocated class. In other
* circumstances, such as Win32 in true colour mode, the allocation process just copies
* the RGB values from the desired to the allocated class.
* As each desired colour requires allocation before it can be used, the ColourPair class
* holds both a ColourDesired and a ColourAllocated
* The Palette class is responsible for managing the palette of colours which contains a
* list of ColourPair objects and performs the allocation.
*/
/**
* Holds a desired RGB colour.
*/
class ColourDesired {
long co;
public:
ColourDesired(long lcol=0) {
co = lcol;
}
ColourDesired(unsigned int red, unsigned int green, unsigned int blue) {
Set(red, green, blue);
}
bool operator==(const ColourDesired &other) const {
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 {
return co;
}
unsigned int GetRed() {
return co & 0xff;
}
unsigned int GetGreen() {
return (co >> 8) & 0xff;
}
unsigned int GetBlue() {
return (co >> 16) & 0xff;
}
};
/**
* Holds an allocated RGB colour which may be an approximation to the desired colour.
*/
class ColourAllocated {
long coAllocated;
public:
ColourAllocated(long lcol=0) {
coAllocated = lcol;
}
void Set(long lcol) {
coAllocated = lcol;
}
long AsLong() const {
return coAllocated;
}
};
/**
* Colour pairs hold a desired colour and an allocated colour.
*/
struct ColourPair {
ColourDesired desired;
ColourAllocated allocated;
ColourPair(ColourDesired desired_=ColourDesired(0,0,0)) {
desired = desired_;
allocated.Set(desired.AsLong());
}
void Copy() {
allocated.Set(desired.AsLong());
}
};
class Window; // Forward declaration for Palette
/**
* Colour palette management.
*/
class Palette {
int used;
int size;
ColourPair *entries;
#if PLAT_GTK
void *allocatedPalette; // GdkColor *
int allocatedLen;
#endif
// Private so Palette objects can not be copied
Palette(const Palette &) {}
Palette &operator=(const Palette &) { return *this; }
public:
#if PLAT_WIN
void *hpal;
#endif
bool allowRealization;
Palette();
~Palette();
void Release();
/**
* This method either adds a colour to the list of wanted colours (want==true)
* or retrieves the allocated colour back to the ColourPair.
* This is one method to make it easier to keep the code for wanting and retrieving in sync.
*/
void WantFind(ColourPair &cp, bool want);
void Allocate(Window &w);
};
/**
* Font management.
*/
class Font {
protected:
FontID fid;
#if PLAT_WX
int ascent;
#endif
// Private so Font objects can not be copied
Font(const Font &) {}
Font &operator=(const Font &) { fid=0; return *this; }
public:
Font();
virtual ~Font();
virtual void Create(const char *faceName, int characterSet, int size,
bool bold, bool italic, int extraFontFlag=0);
virtual void Release();
FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
friend class Surface;
friend class SurfaceImpl;
};
/**
* 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() {}
virtual ~Surface() {}
static Surface *Allocate();
virtual void Init(WindowID wid)=0;
virtual void Init(SurfaceID sid, WindowID wid)=0;
virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0;
virtual void Release()=0;
virtual bool Initialised()=0;
virtual void PenColour(ColourAllocated fore)=0;
virtual int LogPixelsY()=0;
virtual int DeviceHeightFont(int points)=0;
virtual void MoveTo(int x_, int y_)=0;
virtual void LineTo(int x_, int y_)=0;
virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0;
virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0;
virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0;
virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags)=0;
virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0;
virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0;
virtual int WidthText(Font &font_, const char *s, int len)=0;
virtual int WidthChar(Font &font_, char ch)=0;
virtual int Ascent(Font &font_)=0;
virtual int Descent(Font &font_)=0;
virtual int InternalLeading(Font &font_)=0;
virtual int ExternalLeading(Font &font_)=0;
virtual int Height(Font &font_)=0;
virtual int AverageCharWidth(Font &font_)=0;
virtual int SetPalette(Palette *pal, bool inBackGround)=0;
virtual void SetClip(PRectangle rc)=0;
virtual void FlushCachedState()=0;
virtual void SetUnicodeMode(bool unicodeMode_)=0;
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.
*/
class Window {
protected:
WindowID wid;
#if PLAT_MACOSX
void *windowRef;
void *control;
#endif
public:
Window() : wid(0), cursorLast(cursorInvalid) {
#if PLAT_MACOSX
windowRef = 0;
control = 0;
#endif
}
Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
#if PLAT_MACOSX
windowRef = 0;
control = 0;
#endif
}
virtual ~Window();
Window &operator=(WindowID wid_) {
wid = wid_;
return *this;
}
WindowID GetID() const { return wid; }
bool Created() const { return wid != 0; }
void Destroy();
bool HasFocus();
PRectangle GetPosition();
void SetPosition(PRectangle rc);
void SetPositionRelative(PRectangle rc, Window relativeTo);
PRectangle GetClientPosition();
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);
#if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; };
void SetControl(void *_control) { control = _control; };
#endif
private:
Cursor cursorLast;
};
/**
* Listbox management.
*/
class ListBox : public Window {
public:
ListBox();
virtual ~ListBox();
static ListBox *Allocate();
virtual void SetFont(Font &font)=0;
virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0;
virtual void SetAverageCharWidth(int width)=0;
virtual void SetVisibleRows(int rows)=0;
virtual int GetVisibleRows() const=0;
virtual PRectangle GetDesiredRect()=0;
virtual int CaretFromEdge()=0;
virtual void Clear()=0;
virtual void Append(char *s, int type = -1)=0;
virtual int Length()=0;
virtual void Select(int n)=0;
virtual int GetSelection()=0;
virtual int Find(const char *prefix)=0;
virtual void GetValue(int n, char *value, int len)=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
virtual void SetList(const char* list, char separator, char typesep)=0;
};
/**
* Menu management.
*/
class Menu {
MenuID mid;
public:
Menu();
MenuID GetID() { 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() {}
/// @return Pointer to function "name", or NULL on failure.
virtual Function FindFunction(const char *name) = 0;
/// @return true if the library was loaded successfully.
virtual bool IsValid() = 0;
/// @return An instance of a DynamicLibrary subclass with "modulePath" loaded.
static DynamicLibrary *Load(const char *modulePath);
};
/**
* Platform class used to retrieve system wide parameters such as double click speed
* 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() {}
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) {
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);
static int Clamp(int val, int minVal, int maxVal);
};
//#ifdef NDEBUG
#if 1
#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
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4244 4309 4514 4710)
#endif
#endif

View File

@@ -0,0 +1,26 @@
// Scintilla source code edit control
/** @file PropSet.h
** An interface to the methods needed for access to property sets inside lexers.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PROPSET_H
#define PROPSET_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class PropertyGet {
public:
virtual char *ToString() const=0; // Caller must delete[] the return value
virtual int GetInt(const char *key, int defaultValue=0) const=0;
virtual ~PropertyGet() {}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,289 @@
// SciTE - Scintilla based Text Editor
/** @file SString.h
** A simple string class.
**/
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef SSTRING_H
#define SSTRING_H
// These functions are implemented because each platform calls them something different.
int CompareCaseInsensitive(const char *a, const char *b);
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
bool EqualCaseInsensitive(const char *a, const char *b);
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// Define another string class.
// While it would be 'better' to use std::string, that doubles the executable size.
// An SString may contain embedded nul characters.
/**
* Base class from which the two other classes (SBuffer & SString)
* are derived.
*/
class SContainer {
public:
/** Type of string lengths (sizes) and positions (indexes). */
typedef size_t lenpos_t;
/** Out of bounds value indicating that the string argument should be measured. */
enum { measure_length=0xffffffffU};
protected:
char *s; ///< The C string
lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
SContainer() : s(0), sSize(0) {}
~SContainer() {
delete []s; // Suppose it was allocated using StringAllocate
s = 0;
sSize = 0;
}
/** Size of buffer. */
lenpos_t size() const {
if (s) {
return sSize;
} else {
return 0;
}
}
public:
/**
* Allocate uninitialized memory big enough to fit a string of the given length.
* @return the pointer to the new string
*/
static char *StringAllocate(lenpos_t len);
/**
* Duplicate a buffer/C string.
* Allocate memory of the given size, or big enough to fit the string if length isn't given;
* then copy the given string in the allocated memory.
* @return the pointer to the new string
*/
static char *StringAllocate(
const char *s, ///< The string to duplicate
lenpos_t len=measure_length); ///< The length of memory to allocate. Optional.
};
/**
* @brief A string buffer class.
*
* Main use is to ask an API the length of a string it can provide,
* then to allocate a buffer of the given size, and to provide this buffer
* to the API to put the string.
* This class is intended to be shortlived, to be transformed as SString
* as soon as it holds the string, so it has little members.
* Note: we assume the buffer is filled by the API. If the length can be shorter,
* we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
*/
class SBuffer : protected SContainer {
public:
SBuffer(lenpos_t len) {
s = StringAllocate(len);
if (s) {
*s = '\0';
sSize = len;
} else {
sSize = 0;
}
}
private:
/// Copy constructor
// Here only to be on the safe size, user should avoid returning SBuffer values.
SBuffer(const SBuffer &source) : SContainer() {
s = StringAllocate(source.s, source.sSize);
sSize = (s) ? source.sSize : 0;
}
/// Default assignment operator
// Same here, shouldn't be used
SBuffer &operator=(const SBuffer &source) {
if (this != &source) {
delete []s;
s = StringAllocate(source.s, source.sSize);
sSize = (s) ? source.sSize : 0;
}
return *this;
}
public:
/** Provide direct read/write access to buffer. */
char *ptr() {
return s;
}
/** Ownership of the buffer have been taken, so release it. */
void reset() {
s = 0;
sSize = 0;
}
/** Size of buffer. */
lenpos_t size() const {
return SContainer::size();
}
};
/**
* @brief A simple string class.
*
* Hold the length of the string for quick operations,
* can have a buffer bigger than the string to avoid too many memory allocations and copies.
* May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
* functions to allow reliable manipulations of these strings, other than simple appends, etc.
*/
class SString : protected SContainer {
lenpos_t sLen; ///< The size of the string in s
lenpos_t sizeGrowth; ///< Minimum growth size when appending strings
enum { sizeGrowthDefault = 64 };
bool grow(lenpos_t lenNew);
SString &assign(const char *sOther, lenpos_t sSize_=measure_length);
public:
SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
s = StringAllocate(source.s, source.sLen);
sSize = sLen = (s) ? source.sLen : 0;
}
SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
s = StringAllocate(s_);
sSize = sLen = (s) ? strlen(s) : 0;
}
SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) {
s = buf.ptr();
sSize = sLen = buf.size();
// Consumes the given buffer!
buf.reset();
}
SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
// note: expects the "last" argument to point one beyond the range end (a la STL iterators)
s = StringAllocate(s_ + first, last - first);
sSize = sLen = (s) ? last - first : 0;
}
SString(int i);
SString(double d, int precision);
~SString() {
sLen = 0;
}
void clear() {
if (s) {
*s = '\0';
}
sLen = 0;
}
/** Size of buffer. */
lenpos_t size() const {
return SContainer::size();
}
/** Size of string in buffer. */
lenpos_t length() const {
return sLen;
}
/** Read access to a character of the string. */
char operator[](lenpos_t i) const {
return (s && i < sSize) ? s[i] : '\0';
}
SString &operator=(const char *source) {
return assign(source);
}
SString &operator=(const SString &source) {
if (this != &source) {
assign(source.s, source.sLen);
}
return *this;
}
bool operator==(const SString &sOther) const;
bool operator!=(const SString &sOther) const {
return !operator==(sOther);
}
bool operator==(const char *sOther) const;
bool operator!=(const char *sOther) const {
return !operator==(sOther);
}
bool contains(char ch) const {
return (s && *s) ? strchr(s, ch) != 0 : false;
}
void setsizegrowth(lenpos_t sizeGrowth_) {
sizeGrowth = sizeGrowth_;
}
const char *c_str() const {
return s ? s : "";
}
/** Give ownership of buffer to caller which must use delete[] to free buffer. */
char *detach() {
char *sRet = s;
s = 0;
sSize = 0;
sLen = 0;
return sRet;
}
SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
SString &operator+=(const char *sOther) {
return append(sOther, static_cast<lenpos_t>(measure_length));
}
SString &operator+=(const SString &sOther) {
return append(sOther.s, sOther.sLen);
}
SString &operator+=(char ch) {
return append(&ch, 1);
}
SString &appendwithseparator(const char *sOther, char sep) {
return append(sOther, strlen(sOther), sep);
}
SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);
/**
* Remove @a len characters from the @a pos position, included.
* Characters at pos + len and beyond replace characters at pos.
* If @a len is 0, or greater than the length of the string
* starting at @a pos, the string is just truncated at @a pos.
*/
void remove(lenpos_t pos, lenpos_t len);
SString &change(lenpos_t pos, char ch) {
if (pos < sLen) { // character changed must be in string bounds
*(s + pos) = ch;
}
return *this;
}
/** Read an integral numeric value from the string. */
int value() const {
return s ? atoi(s) : 0;
}
bool startswith(const char *prefix);
bool endswith(const char *suffix);
int search(const char *sFind, lenpos_t start=0) const;
bool contains(const char *sFind) const {
return search(sFind) >= 0;
}
int substitute(char chFind, char chReplace);
int substitute(const char *sFind, const char *sReplace);
int remove(const char *sFind) {
return substitute(sFind, "");
}
};
/**
* Duplicate a C string.
* Allocate memory of the given size, or big enough to fit the string if length isn't given;
* then copy the given string in the allocated memory.
* @return the pointer to the new string
*/
inline char *StringDup(
const char *s, ///< The string to duplicate
SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional.
{
return SContainer::StringAllocate(s, len);
}
#ifdef SCI_NAMESPACE
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,974 @@
/* Scintilla source code edit control */
/** @file Scintilla.h
** Interface to the edit control.
**/
/* Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
* The License.txt file describes the conditions under which this software may be distributed. */
/* Most of this file is automatically generated from the Scintilla.iface interface definition
* file which contains any comments about the definitions. HFacer.py does the generation. */
#ifndef SCINTILLA_H
#define SCINTILLA_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32)
/* Return false on failure: */
int Scintilla_RegisterClasses(void *hInstance);
int Scintilla_ReleaseResources();
#endif
int Scintilla_LinkLexers();
#ifdef __cplusplus
}
#endif
/* Here should be placed typedefs for uptr_t, an unsigned integer type large enough to
* hold a pointer and sptr_t, a signed integer large enough to hold a pointer.
* May need to be changed for 64 bit platforms. */
#if defined(_WIN32)
#include <basetsd.h>
#endif
#ifdef MAXULONG_PTR
typedef ULONG_PTR uptr_t;
typedef LONG_PTR sptr_t;
#else
typedef unsigned long uptr_t;
typedef long sptr_t;
#endif
typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
#define INVALID_POSITION -1
#define SCI_START 2000
#define SCI_OPTIONAL_START 3000
#define SCI_LEXER_START 4000
#define SCI_ADDTEXT 2001
#define SCI_ADDSTYLEDTEXT 2002
#define SCI_INSERTTEXT 2003
#define SCI_CLEARALL 2004
#define SCI_CLEARDOCUMENTSTYLE 2005
#define SCI_GETLENGTH 2006
#define SCI_GETCHARAT 2007
#define SCI_GETCURRENTPOS 2008
#define SCI_GETANCHOR 2009
#define SCI_GETSTYLEAT 2010
#define SCI_REDO 2011
#define SCI_SETUNDOCOLLECTION 2012
#define SCI_SELECTALL 2013
#define SCI_SETSAVEPOINT 2014
#define SCI_GETSTYLEDTEXT 2015
#define SCI_CANREDO 2016
#define SCI_MARKERLINEFROMHANDLE 2017
#define SCI_MARKERDELETEHANDLE 2018
#define SCI_GETUNDOCOLLECTION 2019
#define SCWS_INVISIBLE 0
#define SCWS_VISIBLEALWAYS 1
#define SCWS_VISIBLEAFTERINDENT 2
#define SCI_GETVIEWWS 2020
#define SCI_SETVIEWWS 2021
#define SCI_POSITIONFROMPOINT 2022
#define SCI_POSITIONFROMPOINTCLOSE 2023
#define SCI_GOTOLINE 2024
#define SCI_GOTOPOS 2025
#define SCI_SETANCHOR 2026
#define SCI_GETCURLINE 2027
#define SCI_GETENDSTYLED 2028
#define SC_EOL_CRLF 0
#define SC_EOL_CR 1
#define SC_EOL_LF 2
#define SCI_CONVERTEOLS 2029
#define SCI_GETEOLMODE 2030
#define SCI_SETEOLMODE 2031
#define SCI_STARTSTYLING 2032
#define SCI_SETSTYLING 2033
#define SCI_GETBUFFEREDDRAW 2034
#define SCI_SETBUFFEREDDRAW 2035
#define SCI_SETTABWIDTH 2036
#define SCI_GETTABWIDTH 2121
#define SC_CP_UTF8 65001
#define SC_CP_DBCS 1
#define SCI_SETCODEPAGE 2037
#define SCI_SETUSEPALETTE 2039
#define MARKER_MAX 31
#define SC_MARK_CIRCLE 0
#define SC_MARK_ROUNDRECT 1
#define SC_MARK_ARROW 2
#define SC_MARK_SMALLRECT 3
#define SC_MARK_SHORTARROW 4
#define SC_MARK_EMPTY 5
#define SC_MARK_ARROWDOWN 6
#define SC_MARK_MINUS 7
#define SC_MARK_PLUS 8
#define SC_MARK_VLINE 9
#define SC_MARK_LCORNER 10
#define SC_MARK_TCORNER 11
#define SC_MARK_BOXPLUS 12
#define SC_MARK_BOXPLUSCONNECTED 13
#define SC_MARK_BOXMINUS 14
#define SC_MARK_BOXMINUSCONNECTED 15
#define SC_MARK_LCORNERCURVE 16
#define SC_MARK_TCORNERCURVE 17
#define SC_MARK_CIRCLEPLUS 18
#define SC_MARK_CIRCLEPLUSCONNECTED 19
#define SC_MARK_CIRCLEMINUS 20
#define SC_MARK_CIRCLEMINUSCONNECTED 21
#define SC_MARK_BACKGROUND 22
#define SC_MARK_DOTDOTDOT 23
#define SC_MARK_ARROWS 24
#define SC_MARK_PIXMAP 25
#define SC_MARK_FULLRECT 26
#define SC_MARK_LEFTRECT 27
#define SC_MARK_AVAILABLE 28
#define SC_MARK_UNDERLINE 29
#define SC_MARK_ARROW_IN_BOX 100
#define SC_MARK_ARROWDOWN_IN_BOX 101
#define SC_MARK_FULLRECT_TAIL 102
#define SC_MARK_PLUS_IN_BOX 103
#define SC_MARK_MINUS_IN_BOX 104
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
#define SC_MARKNUM_FOLDERMIDTAIL 27
#define SC_MARKNUM_FOLDERTAIL 28
#define SC_MARKNUM_FOLDERSUB 29
#define SC_MARKNUM_FOLDER 30
#define SC_MARKNUM_FOLDEROPEN 31
#define SC_MASK_FOLDERS 0xFE000000
#define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042
#define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045
#define SCI_MARKERGET 2046
#define SCI_MARKERNEXT 2047
#define SCI_MARKERPREVIOUS 2048
#define SCI_MARKERDEFINEPIXMAP 2049
#define SCI_MARKERADDSET 2466
#define SCI_MARKERSETALPHA 2476
#define SC_MARGIN_SYMBOL 0
#define SC_MARGIN_NUMBER 1
#define SC_MARGIN_BACK 2
#define SC_MARGIN_FORE 3
#define SC_MARGIN_TEXT 4
#define SC_MARGIN_RTEXT 5
#define SCI_SETMARGINTYPEN 2240
#define SCI_GETMARGINTYPEN 2241
#define SCI_SETMARGINWIDTHN 2242
#define SCI_GETMARGINWIDTHN 2243
#define SCI_SETMARGINMASKN 2244
#define SCI_GETMARGINMASKN 2245
#define SCI_SETMARGINSENSITIVEN 2246
#define SCI_GETMARGINSENSITIVEN 2247
#define STYLE_DEFAULT 32
#define STYLE_LINENUMBER 33
#define STYLE_BRACELIGHT 34
#define STYLE_BRACEBAD 35
#define STYLE_CONTROLCHAR 36
#define STYLE_INDENTGUIDE 37
#define STYLE_CALLTIP 38
#define STYLE_LASTPREDEFINED 39
#define STYLE_MAX 255
#define SC_CHARSET_ANSI 0
#define SC_CHARSET_DEFAULT 1
#define SC_CHARSET_BALTIC 186
#define SC_CHARSET_CHINESEBIG5 136
#define SC_CHARSET_EASTEUROPE 238
#define SC_CHARSET_GB2312 134
#define SC_CHARSET_GREEK 161
#define SC_CHARSET_HANGUL 129
#define SC_CHARSET_MAC 77
#define SC_CHARSET_OEM 255
#define SC_CHARSET_RUSSIAN 204
#define SC_CHARSET_CYRILLIC 1251
#define SC_CHARSET_SHIFTJIS 128
#define SC_CHARSET_SYMBOL 2
#define SC_CHARSET_TURKISH 162
#define SC_CHARSET_JOHAB 130
#define SC_CHARSET_HEBREW 177
#define SC_CHARSET_ARABIC 178
#define SC_CHARSET_VIETNAMESE 163
#define SC_CHARSET_THAI 222
#define SC_CHARSET_8859_15 1000
#define SCI_STYLECLEARALL 2050
#define SCI_STYLESETFORE 2051
#define SCI_STYLESETBACK 2052
#define SCI_STYLESETBOLD 2053
#define SCI_STYLESETITALIC 2054
#define SCI_STYLESETSIZE 2055
#define SCI_STYLESETFONT 2056
#define SCI_STYLESETEOLFILLED 2057
#define SCI_STYLERESETDEFAULT 2058
#define SCI_STYLESETUNDERLINE 2059
#define SC_CASE_MIXED 0
#define SC_CASE_UPPER 1
#define SC_CASE_LOWER 2
#define SCI_STYLEGETFORE 2481
#define SCI_STYLEGETBACK 2482
#define SCI_STYLEGETBOLD 2483
#define SCI_STYLEGETITALIC 2484
#define SCI_STYLEGETSIZE 2485
#define SCI_STYLEGETFONT 2486
#define SCI_STYLEGETEOLFILLED 2487
#define SCI_STYLEGETUNDERLINE 2488
#define SCI_STYLEGETCASE 2489
#define SCI_STYLEGETCHARACTERSET 2490
#define SCI_STYLEGETVISIBLE 2491
#define SCI_STYLEGETCHANGEABLE 2492
#define SCI_STYLEGETHOTSPOT 2493
#define SCI_STYLESETCASE 2060
#define SCI_STYLESETCHARACTERSET 2066
#define SCI_STYLESETHOTSPOT 2409
#define SCI_SETSELFORE 2067
#define SCI_SETSELBACK 2068
#define SCI_GETSELALPHA 2477
#define SCI_SETSELALPHA 2478
#define SCI_GETSELEOLFILLED 2479
#define SCI_SETSELEOLFILLED 2480
#define SCI_SETCARETFORE 2069
#define SCI_ASSIGNCMDKEY 2070
#define SCI_CLEARCMDKEY 2071
#define SCI_CLEARALLCMDKEYS 2072
#define SCI_SETSTYLINGEX 2073
#define SCI_STYLESETVISIBLE 2074
#define SCI_GETCARETPERIOD 2075
#define SCI_SETCARETPERIOD 2076
#define SCI_SETWORDCHARS 2077
#define SCI_BEGINUNDOACTION 2078
#define SCI_ENDUNDOACTION 2079
#define INDIC_PLAIN 0
#define INDIC_SQUIGGLE 1
#define INDIC_TT 2
#define INDIC_DIAGONAL 3
#define INDIC_STRIKE 4
#define INDIC_HIDDEN 5
#define INDIC_BOX 6
#define INDIC_ROUNDBOX 7
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
#define INDIC1_MASK 0x40
#define INDIC2_MASK 0x80
#define INDICS_MASK 0xE0
#define SCI_INDICSETSTYLE 2080
#define SCI_INDICGETSTYLE 2081
#define SCI_INDICSETFORE 2082
#define SCI_INDICGETFORE 2083
#define SCI_INDICSETUNDER 2510
#define SCI_INDICGETUNDER 2511
#define SCI_SETWHITESPACEFORE 2084
#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
#define SCI_GETCARETLINEVISIBLE 2095
#define SCI_SETCARETLINEVISIBLE 2096
#define SCI_GETCARETLINEBACK 2097
#define SCI_SETCARETLINEBACK 2098
#define SCI_STYLESETCHANGEABLE 2099
#define SCI_AUTOCSHOW 2100
#define SCI_AUTOCCANCEL 2101
#define SCI_AUTOCACTIVE 2102
#define SCI_AUTOCPOSSTART 2103
#define SCI_AUTOCCOMPLETE 2104
#define SCI_AUTOCSTOPS 2105
#define SCI_AUTOCSETSEPARATOR 2106
#define SCI_AUTOCGETSEPARATOR 2107
#define SCI_AUTOCSELECT 2108
#define SCI_AUTOCSETCANCELATSTART 2110
#define SCI_AUTOCGETCANCELATSTART 2111
#define SCI_AUTOCSETFILLUPS 2112
#define SCI_AUTOCSETCHOOSESINGLE 2113
#define SCI_AUTOCGETCHOOSESINGLE 2114
#define SCI_AUTOCSETIGNORECASE 2115
#define SCI_AUTOCGETIGNORECASE 2116
#define SCI_USERLISTSHOW 2117
#define SCI_AUTOCSETAUTOHIDE 2118
#define SCI_AUTOCGETAUTOHIDE 2119
#define SCI_AUTOCSETDROPRESTOFWORD 2270
#define SCI_AUTOCGETDROPRESTOFWORD 2271
#define SCI_REGISTERIMAGE 2405
#define SCI_CLEARREGISTEREDIMAGES 2408
#define SCI_AUTOCGETTYPESEPARATOR 2285
#define SCI_AUTOCSETTYPESEPARATOR 2286
#define SCI_AUTOCSETMAXWIDTH 2208
#define SCI_AUTOCGETMAXWIDTH 2209
#define SCI_AUTOCSETMAXHEIGHT 2210
#define SCI_AUTOCGETMAXHEIGHT 2211
#define SCI_SETINDENT 2122
#define SCI_GETINDENT 2123
#define SCI_SETUSETABS 2124
#define SCI_GETUSETABS 2125
#define SCI_SETLINEINDENTATION 2126
#define SCI_GETLINEINDENTATION 2127
#define SCI_GETLINEINDENTPOSITION 2128
#define SCI_GETCOLUMN 2129
#define SCI_SETHSCROLLBAR 2130
#define SCI_GETHSCROLLBAR 2131
#define SC_IV_NONE 0
#define SC_IV_REAL 1
#define SC_IV_LOOKFORWARD 2
#define SC_IV_LOOKBOTH 3
#define SCI_SETINDENTATIONGUIDES 2132
#define SCI_GETINDENTATIONGUIDES 2133
#define SCI_SETHIGHLIGHTGUIDE 2134
#define SCI_GETHIGHLIGHTGUIDE 2135
#define SCI_GETLINEENDPOSITION 2136
#define SCI_GETCODEPAGE 2137
#define SCI_GETCARETFORE 2138
#define SCI_GETUSEPALETTE 2139
#define SCI_GETREADONLY 2140
#define SCI_SETCURRENTPOS 2141
#define SCI_SETSELECTIONSTART 2142
#define SCI_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145
#define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0
#define SC_PRINT_INVERTLIGHT 1
#define SC_PRINT_BLACKONWHITE 2
#define SC_PRINT_COLOURONWHITE 3
#define SC_PRINT_COLOURONWHITEDEFAULTBG 4
#define SCI_SETPRINTCOLOURMODE 2148
#define SCI_GETPRINTCOLOURMODE 2149
#define SCFIND_WHOLEWORD 2
#define SCFIND_MATCHCASE 4
#define SCFIND_WORDSTART 0x00100000
#define SCFIND_REGEXP 0x00200000
#define SCFIND_POSIX 0x00400000
#define SCI_FINDTEXT 2150
#define SCI_FORMATRANGE 2151
#define SCI_GETFIRSTVISIBLELINE 2152
#define SCI_GETLINE 2153
#define SCI_GETLINECOUNT 2154
#define SCI_SETMARGINLEFT 2155
#define SCI_GETMARGINLEFT 2156
#define SCI_SETMARGINRIGHT 2157
#define SCI_GETMARGINRIGHT 2158
#define SCI_GETMODIFY 2159
#define SCI_SETSEL 2160
#define SCI_GETSELTEXT 2161
#define SCI_GETTEXTRANGE 2162
#define SCI_HIDESELECTION 2163
#define SCI_POINTXFROMPOSITION 2164
#define SCI_POINTYFROMPOSITION 2165
#define SCI_LINEFROMPOSITION 2166
#define SCI_POSITIONFROMLINE 2167
#define SCI_LINESCROLL 2168
#define SCI_SCROLLCARET 2169
#define SCI_REPLACESEL 2170
#define SCI_SETREADONLY 2171
#define SCI_NULL 2172
#define SCI_CANPASTE 2173
#define SCI_CANUNDO 2174
#define SCI_EMPTYUNDOBUFFER 2175
#define SCI_UNDO 2176
#define SCI_CUT 2177
#define SCI_COPY 2178
#define SCI_PASTE 2179
#define SCI_CLEAR 2180
#define SCI_SETTEXT 2181
#define SCI_GETTEXT 2182
#define SCI_GETTEXTLENGTH 2183
#define SCI_GETDIRECTFUNCTION 2184
#define SCI_GETDIRECTPOINTER 2185
#define SCI_SETOVERTYPE 2186
#define SCI_GETOVERTYPE 2187
#define SCI_SETCARETWIDTH 2188
#define SCI_GETCARETWIDTH 2189
#define SCI_SETTARGETSTART 2190
#define SCI_GETTARGETSTART 2191
#define SCI_SETTARGETEND 2192
#define SCI_GETTARGETEND 2193
#define SCI_REPLACETARGET 2194
#define SCI_REPLACETARGETRE 2195
#define SCI_SEARCHINTARGET 2197
#define SCI_SETSEARCHFLAGS 2198
#define SCI_GETSEARCHFLAGS 2199
#define SCI_CALLTIPSHOW 2200
#define SCI_CALLTIPCANCEL 2201
#define SCI_CALLTIPACTIVE 2202
#define SCI_CALLTIPPOSSTART 2203
#define SCI_CALLTIPSETHLT 2204
#define SCI_CALLTIPSETBACK 2205
#define SCI_CALLTIPSETFORE 2206
#define SCI_CALLTIPSETFOREHLT 2207
#define SCI_CALLTIPUSESTYLE 2212
#define SCI_VISIBLEFROMDOCLINE 2220
#define SCI_DOCLINEFROMVISIBLE 2221
#define SCI_WRAPCOUNT 2235
//ERAN IFRAH
#define SCI_CALLTIPSHOWEXT 22250
// END
#define SC_FOLDLEVELBASE 0x400
#define SC_FOLDLEVELWHITEFLAG 0x1000
#define SC_FOLDLEVELHEADERFLAG 0x2000
#define SC_FOLDLEVELNUMBERMASK 0x0FFF
#define SCI_SETFOLDLEVEL 2222
#define SCI_GETFOLDLEVEL 2223
#define SCI_GETLASTCHILD 2224
#define SCI_GETFOLDPARENT 2225
#define SCI_SHOWLINES 2226
#define SCI_HIDELINES 2227
#define SCI_GETLINEVISIBLE 2228
#define SCI_SETFOLDEXPANDED 2229
#define SCI_GETFOLDEXPANDED 2230
#define SCI_TOGGLEFOLD 2231
#define SCI_ENSUREVISIBLE 2232
#define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002
#define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004
#define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
#define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
#define SC_FOLDFLAG_LEVELNUMBERS 0x0040
#define SCI_SETFOLDFLAGS 2233
#define SCI_ENSUREVISIBLEENFORCEPOLICY 2234
#define SCI_SETTABINDENTS 2260
#define SCI_GETTABINDENTS 2261
#define SCI_SETBACKSPACEUNINDENTS 2262
#define SCI_GETBACKSPACEUNINDENTS 2263
#define SC_TIME_FOREVER 10000000
#define SCI_SETMOUSEDWELLTIME 2264
#define SCI_GETMOUSEDWELLTIME 2265
#define SCI_WORDSTARTPOSITION 2266
#define SCI_WORDENDPOSITION 2267
#define SC_WRAP_NONE 0
#define SC_WRAP_WORD 1
#define SC_WRAP_CHAR 2
#define SCI_SETWRAPMODE 2268
#define SCI_GETWRAPMODE 2269
#define SC_WRAPVISUALFLAG_NONE 0x0000
#define SC_WRAPVISUALFLAG_END 0x0001
#define SC_WRAPVISUALFLAG_START 0x0002
#define SCI_SETWRAPVISUALFLAGS 2460
#define SCI_GETWRAPVISUALFLAGS 2461
#define SC_WRAPVISUALFLAGLOC_DEFAULT 0x0000
#define SC_WRAPVISUALFLAGLOC_END_BY_TEXT 0x0001
#define SC_WRAPVISUALFLAGLOC_START_BY_TEXT 0x0002
#define SCI_SETWRAPVISUALFLAGSLOCATION 2462
#define SCI_GETWRAPVISUALFLAGSLOCATION 2463
#define SCI_SETWRAPSTARTINDENT 2464
#define SCI_GETWRAPSTARTINDENT 2465
#define SC_WRAPINDENT_FIXED 0
#define SC_WRAPINDENT_SAME 1
#define SC_WRAPINDENT_INDENT 2
#define SCI_SETWRAPINDENTMODE 2472
#define SCI_GETWRAPINDENTMODE 2473
#define SC_CACHE_NONE 0
#define SC_CACHE_CARET 1
#define SC_CACHE_PAGE 2
#define SC_CACHE_DOCUMENT 3
#define SCI_SETLAYOUTCACHE 2272
#define SCI_GETLAYOUTCACHE 2273
#define SCI_SETSCROLLWIDTH 2274
#define SCI_GETSCROLLWIDTH 2275
#define SCI_SETSCROLLWIDTHTRACKING 2516
#define SCI_GETSCROLLWIDTHTRACKING 2517
#define SCI_TEXTWIDTH 2276
#define SCI_SETENDATLASTLINE 2277
#define SCI_GETENDATLASTLINE 2278
#define SCI_TEXTHEIGHT 2279
#define SCI_SETVSCROLLBAR 2280
#define SCI_GETVSCROLLBAR 2281
#define SCI_APPENDTEXT 2282
#define SCI_GETTWOPHASEDRAW 2283
#define SCI_SETTWOPHASEDRAW 2284
#define SC_EFF_QUALITY_MASK 0xF
#define SC_EFF_QUALITY_DEFAULT 0
#define SC_EFF_QUALITY_NON_ANTIALIASED 1
#define SC_EFF_QUALITY_ANTIALIASED 2
#define SC_EFF_QUALITY_LCD_OPTIMIZED 3
#define SCI_SETFONTQUALITY 2611
#define SCI_GETFONTQUALITY 2612
#define SCI_SETFIRSTVISIBLELINE 2613
#define SC_MULTIPASTE_ONCE 0
#define SC_MULTIPASTE_EACH 1
#define SCI_SETMULTIPASTE 2614
#define SCI_GETMULTIPASTE 2615
#define SCI_GETTAG 2616
#define SCI_TARGETFROMSELECTION 2287
#define SCI_LINESJOIN 2288
#define SCI_LINESSPLIT 2289
#define SCI_SETFOLDMARGINCOLOUR 2290
#define SCI_SETFOLDMARGINHICOLOUR 2291
#define SCI_LINEDOWN 2300
#define SCI_LINEDOWNEXTEND 2301
#define SCI_LINEUP 2302
#define SCI_LINEUPEXTEND 2303
#define SCI_CHARLEFT 2304
#define SCI_CHARLEFTEXTEND 2305
#define SCI_CHARRIGHT 2306
#define SCI_CHARRIGHTEXTEND 2307
#define SCI_WORDLEFT 2308
#define SCI_WORDLEFTEXTEND 2309
#define SCI_WORDRIGHT 2310
#define SCI_WORDRIGHTEXTEND 2311
#define SCI_HOME 2312
#define SCI_HOMEEXTEND 2313
#define SCI_LINEEND 2314
#define SCI_LINEENDEXTEND 2315
#define SCI_DOCUMENTSTART 2316
#define SCI_DOCUMENTSTARTEXTEND 2317
#define SCI_DOCUMENTEND 2318
#define SCI_DOCUMENTENDEXTEND 2319
#define SCI_PAGEUP 2320
#define SCI_PAGEUPEXTEND 2321
#define SCI_PAGEDOWN 2322
#define SCI_PAGEDOWNEXTEND 2323
#define SCI_EDITTOGGLEOVERTYPE 2324
#define SCI_CANCEL 2325
#define SCI_DELETEBACK 2326
#define SCI_TAB 2327
#define SCI_BACKTAB 2328
#define SCI_NEWLINE 2329
#define SCI_FORMFEED 2330
#define SCI_VCHOME 2331
#define SCI_VCHOMEEXTEND 2332
#define SCI_ZOOMIN 2333
#define SCI_ZOOMOUT 2334
#define SCI_DELWORDLEFT 2335
#define SCI_DELWORDRIGHT 2336
#define SCI_DELWORDRIGHTEND 2518
#define SCI_LINECUT 2337
#define SCI_LINEDELETE 2338
#define SCI_LINETRANSPOSE 2339
#define SCI_LINEDUPLICATE 2404
#define SCI_LOWERCASE 2340
#define SCI_UPPERCASE 2341
#define SCI_LINESCROLLDOWN 2342
#define SCI_LINESCROLLUP 2343
#define SCI_DELETEBACKNOTLINE 2344
#define SCI_HOMEDISPLAY 2345
#define SCI_HOMEDISPLAYEXTEND 2346
#define SCI_LINEENDDISPLAY 2347
#define SCI_LINEENDDISPLAYEXTEND 2348
#define SCI_HOMEWRAP 2349
#define SCI_HOMEWRAPEXTEND 2450
#define SCI_LINEENDWRAP 2451
#define SCI_LINEENDWRAPEXTEND 2452
#define SCI_VCHOMEWRAP 2453
#define SCI_VCHOMEWRAPEXTEND 2454
#define SCI_LINECOPY 2455
#define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351
#define SCI_BRACEBADLIGHT 2352
#define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356
#define SCI_GETDOCPOINTER 2357
#define SCI_SETDOCPOINTER 2358
#define SCI_SETMODEVENTMASK 2359
#define EDGE_NONE 0
#define EDGE_LINE 1
#define EDGE_BACKGROUND 2
#define SCI_GETEDGECOLUMN 2360
#define SCI_SETEDGECOLUMN 2361
#define SCI_GETEDGEMODE 2362
#define SCI_SETEDGEMODE 2363
#define SCI_GETEDGECOLOUR 2364
#define SCI_SETEDGECOLOUR 2365
#define SCI_SEARCHANCHOR 2366
#define SCI_SEARCHNEXT 2367
#define SCI_SEARCHPREV 2368
#define SCI_LINESONSCREEN 2370
#define SCI_USEPOPUP 2371
#define SCI_SELECTIONISRECTANGLE 2372
#define SCI_SETZOOM 2373
#define SCI_GETZOOM 2374
#define SCI_CREATEDOCUMENT 2375
#define SCI_ADDREFDOCUMENT 2376
#define SCI_RELEASEDOCUMENT 2377
#define SCI_GETMODEVENTMASK 2378
#define SCI_SETFOCUS 2380
#define SCI_GETFOCUS 2381
#define SC_STATUS_OK 0
#define SC_STATUS_FAILURE 1
#define SC_STATUS_BADALLOC 2
#define SCI_SETSTATUS 2382
#define SCI_GETSTATUS 2383
#define SCI_SETMOUSEDOWNCAPTURES 2384
#define SCI_GETMOUSEDOWNCAPTURES 2385
#define SC_CURSORNORMAL -1
#define SC_CURSORWAIT 4
#define SCI_SETCURSOR 2386
#define SCI_GETCURSOR 2387
#define SCI_SETCONTROLCHARSYMBOL 2388
#define SCI_GETCONTROLCHARSYMBOL 2389
#define SCI_WORDPARTLEFT 2390
#define SCI_WORDPARTLEFTEXTEND 2391
#define SCI_WORDPARTRIGHT 2392
#define SCI_WORDPARTRIGHTEXTEND 2393
#define VISIBLE_SLOP 0x01
#define VISIBLE_STRICT 0x04
#define SCI_SETVISIBLEPOLICY 2394
#define SCI_DELLINELEFT 2395
#define SCI_DELLINERIGHT 2396
#define SCI_SETXOFFSET 2397
#define SCI_GETXOFFSET 2398
#define SCI_CHOOSECARETX 2399
#define SCI_GRABFOCUS 2400
#define CARET_SLOP 0x01
#define CARET_STRICT 0x04
#define CARET_JUMPS 0x10
#define CARET_EVEN 0x08
#define SCI_SETXCARETPOLICY 2402
#define SCI_SETYCARETPOLICY 2403
#define SCI_SETPRINTWRAPMODE 2406
#define SCI_GETPRINTWRAPMODE 2407
#define SCI_SETHOTSPOTACTIVEFORE 2410
#define SCI_GETHOTSPOTACTIVEFORE 2494
#define SCI_SETHOTSPOTACTIVEBACK 2411
#define SCI_GETHOTSPOTACTIVEBACK 2495
#define SCI_SETHOTSPOTACTIVEUNDERLINE 2412
#define SCI_GETHOTSPOTACTIVEUNDERLINE 2496
#define SCI_SETHOTSPOTSINGLELINE 2421
#define SCI_GETHOTSPOTSINGLELINE 2497
#define SCI_PARADOWN 2413
#define SCI_PARADOWNEXTEND 2414
#define SCI_PARAUP 2415
#define SCI_PARAUPEXTEND 2416
#define SCI_POSITIONBEFORE 2417
#define SCI_POSITIONAFTER 2418
#define SCI_COPYRANGE 2419
#define SCI_COPYTEXT 2420
#define SC_SEL_STREAM 0
#define SC_SEL_RECTANGLE 1
#define SC_SEL_LINES 2
#define SC_SEL_THIN 3
#define SCI_SETSELECTIONMODE 2422
#define SCI_GETSELECTIONMODE 2423
#define SCI_GETLINESELSTARTPOSITION 2424
#define SCI_GETLINESELENDPOSITION 2425
#define SCI_LINEDOWNRECTEXTEND 2426
#define SCI_LINEUPRECTEXTEND 2427
#define SCI_CHARLEFTRECTEXTEND 2428
#define SCI_CHARRIGHTRECTEXTEND 2429
#define SCI_HOMERECTEXTEND 2430
#define SCI_VCHOMERECTEXTEND 2431
#define SCI_LINEENDRECTEXTEND 2432
#define SCI_PAGEUPRECTEXTEND 2433
#define SCI_PAGEDOWNRECTEXTEND 2434
#define SCI_STUTTEREDPAGEUP 2435
#define SCI_STUTTEREDPAGEUPEXTEND 2436
#define SCI_STUTTEREDPAGEDOWN 2437
#define SCI_STUTTEREDPAGEDOWNEXTEND 2438
#define SCI_WORDLEFTEND 2439
#define SCI_WORDLEFTENDEXTEND 2440
#define SCI_WORDRIGHTEND 2441
#define SCI_WORDRIGHTENDEXTEND 2442
#define SCI_SETWHITESPACECHARS 2443
#define SCI_SETCHARSDEFAULT 2444
#define SCI_AUTOCGETCURRENT 2445
#define SCI_AUTOCGETCURRENTTEXT 2610
#define SCI_ALLOCATE 2446
#define SCI_TARGETASUTF8 2447
#define SCI_SETLENGTHFORENCODE 2448
#define SCI_ENCODEDFROMUTF8 2449
#define SCI_FINDCOLUMN 2456
#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 SCI_SETCARETSTYLE 2512
#define SCI_GETCARETSTYLE 2513
#define SCI_SETINDICATORCURRENT 2500
#define SCI_GETINDICATORCURRENT 2501
#define SCI_SETINDICATORVALUE 2502
#define SCI_GETINDICATORVALUE 2503
#define SCI_INDICATORFILLRANGE 2504
#define SCI_INDICATORCLEARRANGE 2505
#define SCI_INDICATORALLONFOR 2506
#define SCI_INDICATORVALUEAT 2507
#define SCI_INDICATORSTART 2508
#define SCI_INDICATOREND 2509
#define SCI_SETPOSITIONCACHE 2514
#define SCI_GETPOSITIONCACHE 2515
#define SCI_COPYALLOWLINE 2519
#define SCI_GETCHARACTERPOINTER 2520
#define SCI_SETKEYSUNICODE 2521
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524
#define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527
#define SCI_GETEXTRADESCENT 2528
#define SCI_MARKERSYMBOLDEFINED 2529
#define SCI_MARGINSETTEXT 2530
#define SCI_MARGINGETTEXT 2531
#define SCI_MARGINSETSTYLE 2532
#define SCI_MARGINGETSTYLE 2533
#define SCI_MARGINSETSTYLES 2534
#define SCI_MARGINGETSTYLES 2535
#define SCI_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538
#define SCI_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542
#define SCI_ANNOTATIONGETSTYLE 2543
#define SCI_ANNOTATIONSETSTYLES 2544
#define SCI_ANNOTATIONGETSTYLES 2545
#define SCI_ANNOTATIONGETLINES 2546
#define SCI_ANNOTATIONCLEARALL 2547
#define ANNOTATION_HIDDEN 0
#define ANNOTATION_STANDARD 1
#define ANNOTATION_BOXED 2
#define SCI_ANNOTATIONSETVISIBLE 2548
#define SCI_ANNOTATIONGETVISIBLE 2549
#define SCI_ANNOTATIONSETSTYLEOFFSET 2550
#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
#define UNDO_MAY_COALESCE 1
#define SCI_ADDUNDOACTION 2560
#define SCI_CHARPOSITIONFROMPOINT 2561
#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562
#define SCI_SETMULTIPLESELECTION 2563
#define SCI_GETMULTIPLESELECTION 2564
#define SCI_SETADDITIONALSELECTIONTYPING 2565
#define SCI_GETADDITIONALSELECTIONTYPING 2566
#define SCI_SETADDITIONALCARETSBLINK 2567
#define SCI_GETADDITIONALCARETSBLINK 2568
#define SCI_SETADDITIONALCARETSVISIBLE 2608
#define SCI_GETADDITIONALCARETSVISIBLE 2609
#define SCI_GETSELECTIONS 2570
#define SCI_CLEARSELECTIONS 2571
#define SCI_SETSELECTION 2572
#define SCI_ADDSELECTION 2573
#define SCI_SETMAINSELECTION 2574
#define SCI_GETMAINSELECTION 2575
#define SCI_SETSELECTIONNCARET 2576
#define SCI_GETSELECTIONNCARET 2577
#define SCI_SETSELECTIONNANCHOR 2578
#define SCI_GETSELECTIONNANCHOR 2579
#define SCI_SETSELECTIONNCARETVIRTUALSPACE 2580
#define SCI_GETSELECTIONNCARETVIRTUALSPACE 2581
#define SCI_SETSELECTIONNANCHORVIRTUALSPACE 2582
#define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583
#define SCI_SETSELECTIONNSTART 2584
#define SCI_GETSELECTIONNSTART 2585
#define SCI_SETSELECTIONNEND 2586
#define SCI_GETSELECTIONNEND 2587
#define SCI_SETRECTANGULARSELECTIONCARET 2588
#define SCI_GETRECTANGULARSELECTIONCARET 2589
#define SCI_SETRECTANGULARSELECTIONANCHOR 2590
#define SCI_GETRECTANGULARSELECTIONANCHOR 2591
#define SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE 2592
#define SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE 2593
#define SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2594
#define SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2595
#define SCVS_NONE 0
#define SCVS_RECTANGULARSELECTION 1
#define SCVS_USERACCESSIBLE 2
#define SCI_SETVIRTUALSPACEOPTIONS 2596
#define SCI_GETVIRTUALSPACEOPTIONS 2597
#define SCI_SETRECTANGULARSELECTIONMODIFIER 2598
#define SCI_GETRECTANGULARSELECTIONMODIFIER 2599
#define SCI_SETADDITIONALSELFORE 2600
#define SCI_SETADDITIONALSELBACK 2601
#define SCI_SETADDITIONALSELALPHA 2602
#define SCI_GETADDITIONALSELALPHA 2603
#define SCI_SETADDITIONALCARETFORE 2604
#define SCI_GETADDITIONALCARETFORE 2605
#define SCI_ROTATESELECTION 2606
#define SCI_SWAPMAINANCHORCARET 2607
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
#define SCI_GETLEXER 4002
#define SCI_COLOURISE 4003
#define SCI_SETPROPERTY 4004
#define KEYWORDSET_MAX 8
#define SCI_SETKEYWORDS 4005
#define SCI_SETLEXERLANGUAGE 4006
#define SCI_LOADLEXERLIBRARY 4007
#define SCI_GETPROPERTY 4008
#define SCI_GETPROPERTYEXPANDED 4009
#define SCI_GETPROPERTYINT 4010
#define SCI_GETSTYLEBITSNEEDED 4011
#define SCI_GETLEXERLANGUAGE 4012
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
#define SC_MOD_CHANGEFOLD 0x8
#define SC_PERFORMED_USER 0x10
#define SC_PERFORMED_UNDO 0x20
#define SC_PERFORMED_REDO 0x40
#define SC_MULTISTEPUNDOREDO 0x80
#define SC_LASTSTEPINUNDOREDO 0x100
#define SC_MOD_CHANGEMARKER 0x200
#define SC_MOD_BEFOREINSERT 0x400
#define SC_MOD_BEFOREDELETE 0x800
#define SC_MULTILINEUNDOREDO 0x1000
#define SC_STARTACTION 0x2000
#define SC_MOD_CHANGEINDICATOR 0x4000
#define SC_MOD_CHANGELINESTATE 0x8000
#define SC_MOD_CHANGEMARGIN 0x10000
#define SC_MOD_CHANGEANNOTATION 0x20000
#define SC_MOD_CONTAINER 0x40000
#define SC_MODEVENTMASKALL 0x7FFFF
#define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256
#define SCK_DOWN 300
#define SCK_UP 301
#define SCK_LEFT 302
#define SCK_RIGHT 303
#define SCK_HOME 304
#define SCK_END 305
#define SCK_PRIOR 306
#define SCK_NEXT 307
#define SCK_DELETE 308
#define SCK_INSERT 309
#define SCK_ESCAPE 7
#define SCK_BACK 8
#define SCK_TAB 9
#define SCK_RETURN 13
#define SCK_ADD 310
#define SCK_SUBTRACT 311
#define SCK_DIVIDE 312
#define SCK_WIN 313
#define SCK_RWIN 314
#define SCK_MENU 315
#define SCMOD_NORM 0
#define SCMOD_SHIFT 1
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCMOD_SUPER 8
#define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002
#define SCN_SAVEPOINTLEFT 2003
#define SCN_MODIFYATTEMPTRO 2004
#define SCN_KEY 2005
#define SCN_DOUBLECLICK 2006
#define SCN_UPDATEUI 2007
#define SCN_MODIFIED 2008
#define SCN_MACRORECORD 2009
#define SCN_MARGINCLICK 2010
#define SCN_NEEDSHOWN 2011
#define SCN_PAINTED 2013
#define SCN_USERLISTSELECTION 2014
#define SCN_URIDROPPED 2015
#define SCN_DWELLSTART 2016
#define SCN_DWELLEND 2017
#define SCN_ZOOM 2018
#define SCN_HOTSPOTCLICK 2019
#define SCN_HOTSPOTDOUBLECLICK 2020
#define SCN_CALLTIPCLICK 2021
#define SCN_AUTOCSELECTION 2022
#define SCN_INDICATORCLICK 2023
#define SCN_INDICATORRELEASE 2024
#define SCN_AUTOCCANCELLED 2025
#define SCN_AUTOCCHARDELETED 2026
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* 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. */
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
struct Sci_CharacterRange {
long cpMin;
long cpMax;
};
struct Sci_TextRange {
struct Sci_CharacterRange chrg;
char *lpstrText;
};
struct Sci_TextToFind {
struct Sci_CharacterRange chrg;
char *lpstrText;
struct Sci_CharacterRange chrgText;
};
#define CharacterRange Sci_CharacterRange
#define TextRange Sci_TextRange
#define TextToFind Sci_TextToFind
typedef void *Sci_SurfaceID;
struct Sci_Rectangle {
int left;
int top;
int right;
int bottom;
};
/* This structure is used in printing and requires some of the graphics types
* from Platform.h. Not needed by most client code. */
struct Sci_RangeToFormat {
Sci_SurfaceID hdc;
Sci_SurfaceID hdcTarget;
struct Sci_Rectangle rc;
struct Sci_Rectangle rcPage;
struct Sci_CharacterRange chrg;
};
#define RangeToFormat Sci_RangeToFormat
struct Sci_NotifyHeader {
/* Compatible with Windows NMHDR.
* hwndFrom is really an environment specific window handle or pointer
* but most clients of Scintilla.h do not have this type visible. */
void *hwndFrom;
uptr_t idFrom;
unsigned int code;
};
#define NotifyHeader Sci_NotifyHeader
struct SCNotification {
struct Sci_NotifyHeader nmhdr;
int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
int ch; /* SCN_CHARADDED, SCN_KEY */
int modifiers; /* SCN_KEY */
int modificationType; /* SCN_MODIFIED */
const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */
uptr_t wParam; /* SCN_MACRORECORD */
sptr_t lParam; /* SCN_MACRORECORD */
int line; /* SCN_MODIFIED */
int foldLevelNow; /* SCN_MODIFIED */
int foldLevelPrev; /* SCN_MODIFIED */
int margin; /* SCN_MARGINCLICK */
int listType; /* SCN_USERLISTSELECTION */
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
/* Scintilla source code edit control */
/** @file ScintillaWidget.h
** Definition of Scintilla widget for GTK+.
** Only needed by GTK+ code but is harmless on other platforms.
**/
/* Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
* The License.txt file describes the conditions under which this software may be distributed. */
#ifndef SCINTILLAWIDGET_H
#define SCINTILLAWIDGET_H
#if defined(GTK) && !defined(__APPLE__)
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __APPLE__
#include <gtk/gtk.h>
#endif
#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject)
#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ())
typedef struct _ScintillaObject ScintillaObject;
typedef struct _ScintillaClass ScintillaClass;
struct _ScintillaObject {
GtkContainer cont;
void *pscin;
};
struct _ScintillaClass {
GtkContainerClass parent_class;
void (* command) (ScintillaObject *ttt);
void (* notify) (ScintillaObject *ttt);
};
GType scintilla_get_type (void);
GtkWidget* scintilla_new (void);
void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);
#define SCINTILLA_NOTIFY "sci-notify"
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@@ -0,0 +1,67 @@
// Scintilla source code edit control
/** @file WindowAccessor.h
** Implementation of BufferAccess and StylingAccess on a Scintilla
** rapid easy access to contents of a Scintilla.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class WindowAccessor : public Accessor {
// Private so WindowAccessor objects can not be copied
WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
WindowAccessor &operator=(const WindowAccessor &) { return *this; }
protected:
WindowID id;
PropertyGet &props;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
WindowAccessor(WindowID id_, PropertyGet &props_) :
Accessor(), id(id_), props(props_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
}
~WindowAccessor();
bool Match(int pos, const char *s);
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
void Flush();
int GetLineState(int line);
int SetLineState(int line, int state);
int GetPropertyInt(const char *key, int defaultValue=0) {
return props.GetInt(key, defaultValue);
}
char *GetProperties() {
return props.ToString();
}
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
void IndicatorFill(int start, int end, int indicator, int value);
};
#ifdef SCI_NAMESPACE
}
#endif

View File

@@ -0,0 +1,178 @@
// Scintilla source code edit control
/** @file AutoComplete.cxx
** Defines the auto completion list box.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "Platform.h"
#include "CharClassify.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
AutoComplete::AutoComplete() :
active(false),
separator(' '),
typesep('?'),
ignoreCase(false),
chooseSingle(false),
lb(0),
posStart(0),
startLen(0),
cancelAtStartPos(true),
autoHide(true),
dropRestOfWord(false) {
lb = ListBox::Allocate();
stopChars[0] = '\0';
fillUpChars[0] = '\0';
}
AutoComplete::~AutoComplete() {
if (lb) {
lb->Destroy();
delete lb;
lb = 0;
}
}
bool AutoComplete::Active() const {
return active;
}
void AutoComplete::Start(Window &parent, int ctrlID,
int position, Point location, int startLen_,
int lineHeight, bool unicodeMode) {
if (active) {
Cancel();
}
lb->Create(parent, ctrlID, location, lineHeight, unicodeMode);
lb->Clear();
active = true;
startLen = startLen_;
posStart = position;
}
void AutoComplete::SetStopChars(const char *stopChars_) {
strncpy(stopChars, stopChars_, sizeof(stopChars));
stopChars[sizeof(stopChars) - 1] = '\0';
}
bool AutoComplete::IsStopChar(char ch) {
return ch && strchr(stopChars, ch);
}
void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
fillUpChars[sizeof(fillUpChars) - 1] = '\0';
}
bool AutoComplete::IsFillUpChar(char ch) {
return ch && strchr(fillUpChars, ch);
}
void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
char AutoComplete::GetSeparator() const {
return separator;
}
void AutoComplete::SetTypesep(char separator_) {
typesep = separator_;
}
char AutoComplete::GetTypesep() const {
return typesep;
}
void AutoComplete::SetList(const char *list) {
lb->SetList(list, separator, typesep);
}
void AutoComplete::Show(bool show) {
lb->Show(show);
if (show)
lb->Select(0);
}
void AutoComplete::Cancel() {
if (lb->Created()) {
lb->Clear();
lb->Destroy();
active = false;
}
}
void AutoComplete::Move(int delta) {
int count = lb->Length();
int current = lb->GetSelection();
current += delta;
if (current >= count)
current = count - 1;
if (current < 0)
current = 0;
lb->Select(current);
}
void AutoComplete::Select(const char *word) {
size_t lenWord = strlen(word);
int location = -1;
const int maxItemLen=1000;
char item[maxItemLen];
int start = 0; // lower bound of the api array block to search
int end = lb->Length() - 1; // upper bound of the api array block to search
while ((start <= end) && (location == -1)) { // Binary searching loop
int pivot = (start + end) / 2;
lb->GetValue(pivot, item, maxItemLen);
int cond;
if (ignoreCase)
cond = CompareNCaseInsensitive(word, item, lenWord);
else
cond = strncmp(word, item, lenWord);
if (!cond) {
// Find first match
while (pivot > start) {
lb->GetValue(pivot-1, item, maxItemLen);
if (ignoreCase)
cond = CompareNCaseInsensitive(word, item, lenWord);
else
cond = strncmp(word, item, lenWord);
if (0 != cond)
break;
--pivot;
}
location = pivot;
if (ignoreCase) {
// Check for exact-case match
for (; pivot <= end; pivot++) {
lb->GetValue(pivot, item, maxItemLen);
if (!strncmp(word, item, lenWord)) {
location = pivot;
break;
}
if (CompareNCaseInsensitive(word, item, lenWord))
break;
}
}
} else if (cond < 0) {
end = pivot - 1;
} else if (cond > 0) {
start = pivot + 1;
}
}
if (location == -1 && autoHide)
Cancel();
else
lb->Select(location);
}

View File

@@ -0,0 +1,78 @@
// Scintilla source code edit control
/** @file AutoComplete.h
** Defines the auto completion list box.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef AUTOCOMPLETE_H
#define AUTOCOMPLETE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class AutoComplete {
bool active;
char stopChars[256];
char fillUpChars[256];
char separator;
char typesep; // Type seperator
public:
bool ignoreCase;
bool chooseSingle;
ListBox *lb;
int posStart;
int startLen;
/// Should autocompletion be canceled if editor's currentPos <= startPos?
bool cancelAtStartPos;
bool autoHide;
bool dropRestOfWord;
AutoComplete();
~AutoComplete();
/// Is the auto completion list displayed?
bool Active() const;
/// Display the auto completion list positioned to be near a character position
void Start(Window &parent, int ctrlID, int position, Point location,
int startLen_, int lineHeight, bool unicodeMode);
/// The stop chars are characters which, when typed, cause the auto completion list to disappear
void SetStopChars(const char *stopChars_);
bool IsStopChar(char ch);
/// The fillup chars are characters which, when typed, fill up the selected word
void SetFillUpChars(const char *fillUpChars_);
bool IsFillUpChar(char ch);
/// The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_);
char GetSeparator() const;
/// The typesep character is used for seperating the word from the type
void SetTypesep(char separator_);
char GetTypesep() const;
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
void Show(bool show);
void Cancel();
/// Move the current list element by delta, scrolling appropriately
void Move(int delta);
/// Select a list element that starts with word as the current element
void Select(const char *word);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,387 @@
// Scintilla source code edit control
/** @file CallTip.cxx
** Code for displaying call tips.
**/
// 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 "Platform.h"
#include "Scintilla.h"
#include "CallTip.h"
#include <stdio.h>
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static const int insetX = 5; // text inset in x from calltip border
static const int widthArrow = 14;
CallTip::CallTip() {
wCallTip = 0;
inCallTipMode = false;
posStartCallTip = 0;
val = 0;
rectUp = PRectangle(0,0,0,0);
rectDown = PRectangle(0,0,0,0);
lineHeight = 1;
startHighlight = 0;
endHighlight = 0;
tabSize = 0;
useStyleCallTip = false; // for backwards compatibility
#ifdef __APPLE__
// proper apple colours for the default
colourBG.desired = ColourDesired(0xff, 0xff, 0xc6);
colourUnSel.desired = ColourDesired(0, 0, 0);
#else
colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
#endif
colourSel.desired = ColourDesired(0, 0, 0x80);
colourShade.desired = ColourDesired(0, 0, 0);
colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
// ERAN IFRAH
ColourDesired c(0, 0, 255);
ColourAllocated ca(c.AsLong());
colourDoxyHighlight = ca;
colourDivider = ColourAllocated(0);
// ERAN IFRAH - END
}
CallTip::~CallTip() {
font.Release();
wCallTip.Destroy();
delete []val;
val = 0;
}
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(colourBG, want);
pal.WantFind(colourUnSel, want);
pal.WantFind(colourSel, want);
pal.WantFind(colourShade, want);
pal.WantFind(colourLight, want);
}
// Although this test includes 0, we should never see a \0 character.
static bool IsArrowCharacter(char ch) {
return (ch == 0) || (ch == '\001') || (ch == '\002');
}
// ERAN IFRAH
static bool IsDoxyKeyWord(const char* s, int &len) {
len = 0;
if(s[0] == '@' || s[0] == '\\') {
len = 1;
for(size_t i=0; i<strlen(s); i++) {
if(s[i] == ' ' || s[i] == '\t' || s[i] == '\n') {
break;
} else {
len++;
}
}
}
return len > 0;
}
// ERAN IFRAH - END
// We ignore tabs unless a tab width has been set.
bool CallTip::IsTabCharacter(char ch) const {
return (tabSize > 0) && (ch == '\t');
}
int CallTip::NextTabPos(int x) {
if (tabSize > 0) { // paranoia... not called unless this is true
x -= insetX; // position relative to text
x = (x + tabSize) / tabSize; // tab "number"
return tabSize*x + insetX; // position of next tab
} else {
return x + 1; // arbitrary
}
}
// Draw a section of the call tip that does not include \n in one colour.
// The text may include up to numEnds tabs or arrow characters.
void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw) {
s += posStart;
int len = posEnd - posStart;
// Divide the text into sections that are all text, or that are
// single arrows or single tab characters (if tabSize > 0).
int maxEnd = 0;
const int numEnds = 10;
int ends[numEnds + 2];
// ERAN IFRAH
int doxyWordLen = 0;
for (int i=0;i<len;i++) {
if ((maxEnd < numEnds) && (IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;
} else if((maxEnd < numEnds) && IsDoxyKeyWord(s+i, doxyWordLen)) {
// we found a doxygen word
if(i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i + doxyWordLen;
i += len;
}
}
// If we find this magic string, we translate it into
// a horizontal line in the tip
bool isLine (false);
if(strncmp(s, "@@LINE@@", 8) == 0) {
isLine = true;
}
// ERAN IFRAH - END
ends[maxEnd++] = len;
int startSeg = 0;
int xEnd;
for (int seg = 0; seg<maxEnd; seg++) {
int endSeg = ends[seg];
if (endSeg > startSeg) {
// ERAN IFRAH
if(isLine) {
int ww = rcClient.Width();
rcClient.left = x;
rcClient.right = rcClient.left + ww;
surface->PenColour(colourDivider);
surface->MoveTo(0, rcClient.top);
surface->LineTo(rcClient.right, rcClient.top);
xEnd = rcClient.right;
// END
} else if (IsArrowCharacter(s[startSeg])) {
bool upArrow = s[startSeg] == '\001';
rcClient.left = x;
rcClient.right = rcClient.left + widthArrow;
if (draw) {
const int halfWidth = widthArrow / 2 - 3;
const int centreX = rcClient.left + widthArrow / 2 - 1;
const int centreY = (rcClient.top + rcClient.bottom) / 2;
surface->FillRectangle(rcClient, colourBG.allocated);
PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1,
rcClient.right - 2, rcClient.bottom - 1);
surface->FillRectangle(rcClientInner, colourUnSel.allocated);
if (upArrow) { // Up arrow
Point pts[] = {
Point(centreX - halfWidth, centreY + halfWidth / 2),
Point(centreX + halfWidth, centreY + halfWidth / 2),
Point(centreX, centreY - halfWidth + halfWidth / 2),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
colourBG.allocated, colourBG.allocated);
} else { // Down arrow
Point pts[] = {
Point(centreX - halfWidth, centreY - halfWidth / 2),
Point(centreX + halfWidth, centreY - halfWidth / 2),
Point(centreX, centreY + halfWidth - halfWidth / 2),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
colourBG.allocated, colourBG.allocated);
}
}
xEnd = rcClient.right;
offsetMain = xEnd;
if (upArrow) {
rectUp = rcClient;
} else {
rectDown = rcClient;
}
} else if (IsTabCharacter(s[startSeg])) {
xEnd = NextTabPos(x);
} else {
// ERAN IFRAH
bool doxyHighlight = (s[startSeg] == '@' || s[startSeg] == '\\');
xEnd = x + surface->WidthText(font, s + startSeg, endSeg - startSeg);
if (draw)
{
rcClient.left = x;
rcClient.right = xEnd;
if(doxyHighlight) {
surface->DrawTextTransparent(rcClient, font, ytext,
s+startSeg, endSeg - startSeg,
colourDoxyHighlight);
} else {
surface->DrawTextTransparent(rcClient, font, ytext,
s+startSeg, endSeg - startSeg,
highlight ? colourSel.allocated : colourUnSel.allocated);
}
}
// ERAN IFRAH - END
}
x = xEnd;
startSeg = endSeg;
}
}
}
int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
PRectangle rcClientPos = wCallTip.GetClientPosition();
PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
rcClientPos.bottom - rcClientPos.top);
PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
// To make a nice small call tip window, it is only sized to fit most normal characters without accents
int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
// For each line...
// Draw the definition in three parts: before highlight, highlighted, after highlight
int ytext = rcClient.top + ascent + 1;
rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
char *chunkVal = val;
bool moreChunks = true;
int maxWidth = 0;
while (moreChunks) {
char *chunkEnd = strchr(chunkVal, '\n');
if (chunkEnd == NULL) {
chunkEnd = chunkVal + strlen(chunkVal);
moreChunks = false;
}
int chunkOffset = chunkVal - val;
int chunkLength = chunkEnd - chunkVal;
int chunkEndOffset = chunkOffset + chunkLength;
int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
thisStartHighlight -= chunkOffset;
int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
thisEndHighlight -= chunkOffset;
rcClient.top = ytext - ascent - 1;
int x = insetX; // start each line at this inset
DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
ytext, rcClient, false, draw);
DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
ytext, rcClient, true, draw);
DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
ytext, rcClient, false, draw);
chunkVal = chunkEnd + 1;
ytext += lineHeight;
rcClient.bottom += lineHeight;
maxWidth = Platform::Maximum(maxWidth, x);
}
return maxWidth;
}
void CallTip::PaintCT(Surface *surfaceWindow) {
if (!val)
return;
PRectangle rcClientPos = wCallTip.GetClientPosition();
PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
rcClientPos.bottom - rcClientPos.top);
PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
offsetMain = insetX; // initial alignment assuming no arrows
PaintContents(surfaceWindow, true);
// OSX doesn't put borders on "help tags"
// Draw a raised border around the edges of the window
surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
surfaceWindow->PenColour(colourShade.allocated);
surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
surfaceWindow->LineTo(rcClientSize.right - 1, 0);
surfaceWindow->PenColour(colourShade.allocated);
surfaceWindow->LineTo(0, 0);
surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
}
void CallTip::MouseClick(Point pt) {
clickPlace = 0;
if (rectUp.Contains(pt))
clickPlace = 1;
if (rectDown.Contains(pt))
clickPlace = 2;
}
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
const char *faceName, int size,
int codePage_, int characterSet, Window &wParent) {
clickPlace = 0;
delete []val;
val = 0;
val = new char[strlen(defn) + 1];
strcpy(val, defn);
codePage = codePage_;
Surface *surfaceMeasure = Surface::Allocate();
if (!surfaceMeasure)
return PRectangle();
surfaceMeasure->Init(wParent.GetID());
surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
surfaceMeasure->SetDBCSMode(codePage);
startHighlight = 0;
endHighlight = 0;
inCallTipMode = true;
posStartCallTip = pos;
int deviceHeight = surfaceMeasure->DeviceHeightFont(size);
font.Create(faceName, characterSet, deviceHeight, false, false);
// Look for multiple lines in the text
// Only support \n here - simply means container must avoid \r!
int numLines = 1;
const char *newline;
const char *look = val;
rectUp = PRectangle(0,0,0,0);
rectDown = PRectangle(0,0,0,0);
offsetMain = insetX; // changed to right edge of any arrows
int width = PaintContents(surfaceMeasure, false) + insetX;
while ((newline = strchr(look, '\n')) != NULL) {
look = newline + 1;
numLines++;
}
lineHeight = surfaceMeasure->Height(font);
// Extra line for border and an empty line at top and bottom. The returned
// rectangle is aligned to the right edge of the last arrow encountered in
// the tip text, else to the tip text left edge.
int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
delete surfaceMeasure;
return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
}
void CallTip::CallTipCancel() {
inCallTipMode = false;
if (wCallTip.Created()) {
wCallTip.Destroy();
}
}
void CallTip::SetHighlight(int start, int end) {
// Avoid flashing by checking something has really changed
if ((start != startHighlight) || (end != endHighlight)) {
startHighlight = start;
endHighlight = end;
if (wCallTip.Created()) {
wCallTip.InvalidateAll();
}
}
}
// Set the tab size (sizes > 0 enable the use of tabs). This also enables the
// use of the STYLE_CALLTIP.
void CallTip::SetTabSize(int tabSz) {
tabSize = tabSz;
useStyleCallTip = true;
}
// It might be better to have two access functions for this and to use
// them for all settings of colours.
void CallTip::SetForeBack(const ColourPair &fore, const ColourPair &back) {
colourBG = back;
colourUnSel = fore;
}

View File

@@ -0,0 +1,91 @@
// Scintilla source code edit control
/** @file CallTip.h
** Interface to the call tip control.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CALLTIP_H
#define CALLTIP_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class CallTip {
int startHighlight; // character offset to start and...
int endHighlight; // ...end of highlighted text
char *val;
Font font;
PRectangle rectUp; // rectangle of last up angle in the tip
PRectangle rectDown; // rectangle of last down arrow in the tip
int lineHeight; // vertical line spacing
int offsetMain; // The alignment point of the call tip
int tabSize; // Tab size in pixels, <=0 no TAB expand
bool useStyleCallTip; // if true, STYLE_CALLTIP should be used
// Private so CallTip objects can not be copied
CallTip(const CallTip &);
CallTip &operator=(const CallTip &);
void DrawChunk(Surface *surface, int &x, const char *s,
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw);
int PaintContents(Surface *surfaceWindow, bool draw);
bool IsTabCharacter(char c) const;
int NextTabPos(int x);
public:
Window wCallTip;
Window wDraw;
bool inCallTipMode;
int posStartCallTip;
ColourPair colourBG;
ColourPair colourUnSel;
ColourPair colourSel;
ColourPair colourShade;
ColourPair colourLight;
// ERAN IFRAH
ColourAllocated colourDivider;
ColourAllocated colourDoxyHighlight;
// ERAN IFRAH - END
int codePage;
int clickPlace;
CallTip();
~CallTip();
/// Claim or accept palette entries for the colours required to paint a calltip.
void RefreshColourPalette(Palette &pal, bool want);
void PaintCT(Surface *surfaceWindow);
void MouseClick(Point pt);
/// Setup the calltip and return a rectangle of the area required.
PRectangle CallTipStart(int pos, Point pt, const char *defn,
const char *faceName, int size, int codePage_,
int characterSet, Window &wParent);
void CallTipCancel();
/// Set a range of characters to be displayed in a highlight style.
/// Commonly used to highlight the current parameter.
void SetHighlight(int start, int end);
/// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand.
void SetTabSize(int tabSz);
/// Used to determine which STYLE_xxxx to use for call tip information
bool UseStyleCallTip() const { return useStyleCallTip;}
// Modify foreground and background colours
void SetForeBack(const ColourPair &fore, const ColourPair &back);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,656 @@
// Scintilla source code edit control
/** @file CellBuffer.cxx
** Manages a buffer of cells.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "CellBuffer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
LineVector::LineVector() : starts(256), perLine(0) {
Init();
}
LineVector::~LineVector() {
starts.DeleteAll();
}
void LineVector::Init() {
starts.DeleteAll();
if (perLine) {
perLine->Init();
}
}
void LineVector::SetPerLine(PerLine *pl) {
perLine = pl;
}
void LineVector::InsertText(int line, int delta) {
starts.InsertText(line, delta);
}
void LineVector::InsertLine(int line, int position, bool lineStart) {
starts.InsertPartition(line, position);
if (perLine) {
if ((line > 0) && lineStart)
line--;
perLine->InsertLine(line);
}
}
void LineVector::SetLineStart(int line, int position) {
starts.SetPartitionStartPosition(line, position);
}
void LineVector::RemoveLine(int line) {
starts.RemovePartition(line);
if (perLine) {
perLine->RemoveLine(line);
}
}
int LineVector::LineFromPosition(int pos) const {
return starts.PartitionFromPosition(pos);
}
Action::Action() {
at = startAction;
position = 0;
data = 0;
lenData = 0;
mayCoalesce = false;
}
Action::~Action() {
Destroy();
}
void Action::Create(actionType at_, int position_, char *data_, int lenData_, bool mayCoalesce_) {
delete []data;
position = position_;
at = at_;
data = data_;
lenData = lenData_;
mayCoalesce = mayCoalesce_;
}
void Action::Destroy() {
delete []data;
data = 0;
}
void Action::Grab(Action *source) {
delete []data;
position = source->position;
at = source->at;
data = source->data;
lenData = source->lenData;
mayCoalesce = source->mayCoalesce;
// Ownership of source data transferred to this
source->position = 0;
source->at = startAction;
source->data = 0;
source->lenData = 0;
source->mayCoalesce = true;
}
// The undo history stores a sequence of user operations that represent the user's view of the
// commands executed on the text.
// Each user operation contains a sequence of text insertion and text deletion actions.
// All the user operations are stored in a list of individual actions with 'start' actions used
// as delimiters between user operations.
// Initially there is one start action in the history.
// As each action is performed, it is recorded in the history. The action may either become
// part of the current user operation or may start a new user operation. If it is to be part of the
// current operation, then it overwrites the current last action. If it is to be part of a new
// operation, it is appended after the current last action.
// After writing the new action, a new start action is appended at the end of the history.
// The decision of whether to start a new user operation is based upon two factors. If a
// compound operation has been explicitly started by calling BeginUndoAction and no matching
// EndUndoAction (these calls nest) has been called, then the action is coalesced into the current
// operation. If there is no outstanding BeginUndoAction call then a new operation is started
// unless it looks as if the new action is caused by the user typing or deleting a stream of text.
// Sequences that look like typing or deletion are coalesced into a single user operation.
UndoHistory::UndoHistory() {
lenActions = 100;
actions = new Action[lenActions];
maxAction = 0;
currentAction = 0;
undoSequenceDepth = 0;
savePoint = 0;
actions[currentAction].Create(startAction);
}
UndoHistory::~UndoHistory() {
delete []actions;
actions = 0;
}
void UndoHistory::EnsureUndoRoom() {
// Have to test that there is room for 2 more actions in the array
// as two actions may be created by the calling function
if (currentAction >= (lenActions - 2)) {
// Run out of undo nodes so extend the array
int lenActionsNew = lenActions * 2;
Action *actionsNew = new Action[lenActionsNew];
for (int act = 0; act <= currentAction; act++)
actionsNew[act].Grab(&actions[act]);
delete []actions;
lenActions = lenActionsNew;
actions = actionsNew;
}
}
void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData,
bool &startSequence, bool mayCoalesce) {
EnsureUndoRoom();
//Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction);
//Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at,
// actions[currentAction - 1].position, actions[currentAction - 1].lenData);
if (currentAction < savePoint) {
savePoint = -1;
}
int oldCurrentAction = currentAction;
if (currentAction >= 1) {
if (0 == undoSequenceDepth) {
// Top level actions may not always be coalesced
int targetAct = -1;
const Action *actPrevious = &(actions[currentAction + targetAct]);
// Container actions may forward the coalesce state of Scintilla Actions.
while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) {
targetAct--;
actPrevious = &(actions[currentAction + targetAct]);
}
// See if current action can be coalesced into previous action
// Will work if both are inserts or deletes and position is same
if (currentAction == savePoint) {
currentAction++;
} else if (!actions[currentAction].mayCoalesce) {
// Not allowed to coalesce if this set
currentAction++;
} else if (!mayCoalesce || !actPrevious->mayCoalesce) {
currentAction++;
} else if (at == containerAction || actions[currentAction].at == containerAction) {
; // A coalescible containerAction
} else if ((at != actPrevious->at) && (actPrevious->at != startAction)) {
currentAction++;
} else if ((at == insertAction) &&
(position != (actPrevious->position + actPrevious->lenData))) {
// Insertions must be immediately after to coalesce
currentAction++;
} else if (at == removeAction) {
if ((lengthData == 1) || (lengthData == 2)){
if ((position + lengthData) == actPrevious->position) {
; // Backspace -> OK
} else if (position == actPrevious->position) {
; // Delete -> OK
} else {
// Removals must be at same position to coalesce
currentAction++;
}
} else {
// Removals must be of one character to coalesce
currentAction++;
}
} else {
// Action coalesced.
}
} else {
// Actions not at top level are always coalesced unless this is after return to top level
if (!actions[currentAction].mayCoalesce)
currentAction++;
}
} else {
currentAction++;
}
startSequence = oldCurrentAction != currentAction;
actions[currentAction].Create(at, position, data, lengthData, mayCoalesce);
currentAction++;
actions[currentAction].Create(startAction);
maxAction = currentAction;
}
void UndoHistory::BeginUndoAction() {
EnsureUndoRoom();
if (undoSequenceDepth == 0) {
if (actions[currentAction].at != startAction) {
currentAction++;
actions[currentAction].Create(startAction);
maxAction = currentAction;
}
actions[currentAction].mayCoalesce = false;
}
undoSequenceDepth++;
}
void UndoHistory::EndUndoAction() {
PLATFORM_ASSERT(undoSequenceDepth > 0);
EnsureUndoRoom();
undoSequenceDepth--;
if (0 == undoSequenceDepth) {
if (actions[currentAction].at != startAction) {
currentAction++;
actions[currentAction].Create(startAction);
maxAction = currentAction;
}
actions[currentAction].mayCoalesce = false;
}
}
void UndoHistory::DropUndoSequence() {
undoSequenceDepth = 0;
}
void UndoHistory::DeleteUndoHistory() {
for (int i = 1; i < maxAction; i++)
actions[i].Destroy();
maxAction = 0;
currentAction = 0;
actions[currentAction].Create(startAction);
savePoint = 0;
}
void UndoHistory::SetSavePoint() {
savePoint = currentAction;
}
bool UndoHistory::IsSavePoint() const {
return savePoint == currentAction;
}
bool UndoHistory::CanUndo() const {
return (currentAction > 0) && (maxAction > 0);
}
int UndoHistory::StartUndo() {
// Drop any trailing startAction
if (actions[currentAction].at == startAction && currentAction > 0)
currentAction--;
// Count the steps in this action
int act = currentAction;
while (actions[act].at != startAction && act > 0) {
act--;
}
return currentAction - act;
}
const Action &UndoHistory::GetUndoStep() const {
return actions[currentAction];
}
void UndoHistory::CompletedUndoStep() {
currentAction--;
}
bool UndoHistory::CanRedo() const {
return maxAction > currentAction;
}
int UndoHistory::StartRedo() {
// Drop any leading startAction
if (actions[currentAction].at == startAction && currentAction < maxAction)
currentAction++;
// Count the steps in this action
int act = currentAction;
while (actions[act].at != startAction && act < maxAction) {
act++;
}
return act - currentAction;
}
const Action &UndoHistory::GetRedoStep() const {
return actions[currentAction];
}
void UndoHistory::CompletedRedoStep() {
currentAction++;
}
CellBuffer::CellBuffer() {
readOnly = false;
collectingUndo = true;
}
CellBuffer::~CellBuffer() {
}
char CellBuffer::CharAt(int position) const {
return substance.ValueAt(position);
}
void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const {
if (lengthRetrieve < 0)
return;
if (position < 0)
return;
if ((position + lengthRetrieve) > substance.Length()) {
Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", position,
lengthRetrieve, substance.Length());
return;
}
for (int i=0; i<lengthRetrieve; i++) {
*buffer++ = substance.ValueAt(position + i);
}
}
char CellBuffer::StyleAt(int position) const {
return style.ValueAt(position);
}
const char *CellBuffer::BufferPointer() {
return substance.BufferPointer();
}
// The char* returned is to an allocation owned by the undo history
const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) {
char *data = 0;
// InsertString and DeleteChars are the bottleneck though which all changes occur
if (!readOnly) {
if (collectingUndo) {
// Save into the undo/redo stack, but only the characters - not the formatting
// This takes up about half load time
data = new char[insertLength];
for (int i = 0; i < insertLength; i++) {
data[i] = s[i];
}
uh.AppendAction(insertAction, position, data, insertLength, startSequence);
}
BasicInsertString(position, s, insertLength);
}
return data;
}
bool CellBuffer::SetStyleAt(int position, char styleValue, char mask) {
styleValue &= mask;
char curVal = style.ValueAt(position);
if ((curVal & mask) != styleValue) {
style.SetValueAt(position, static_cast<char>((curVal & ~mask) | styleValue));
return true;
} else {
return false;
}
}
bool CellBuffer::SetStyleFor(int position, int lengthStyle, char styleValue, char mask) {
bool changed = false;
PLATFORM_ASSERT(lengthStyle == 0 ||
(lengthStyle > 0 && lengthStyle + position <= style.Length()));
while (lengthStyle--) {
char curVal = style.ValueAt(position);
if ((curVal & mask) != styleValue) {
style.SetValueAt(position, static_cast<char>((curVal & ~mask) | styleValue));
changed = true;
}
position++;
}
return changed;
}
// The char* returned is to an allocation owned by the undo history
const char *CellBuffer::DeleteChars(int position, int deleteLength, bool &startSequence) {
// InsertString and DeleteChars are the bottleneck though which all changes occur
PLATFORM_ASSERT(deleteLength > 0);
char *data = 0;
if (!readOnly) {
if (collectingUndo) {
// Save into the undo/redo stack, but only the characters - not the formatting
data = new char[deleteLength];
for (int i = 0; i < deleteLength; i++) {
data[i] = substance.ValueAt(position + i);
}
uh.AppendAction(removeAction, position, data, deleteLength, startSequence);
}
BasicDeleteChars(position, deleteLength);
}
return data;
}
int CellBuffer::Length() const {
return substance.Length();
}
void CellBuffer::Allocate(int newSize) {
substance.ReAllocate(newSize);
style.ReAllocate(newSize);
}
void CellBuffer::SetPerLine(PerLine *pl) {
lv.SetPerLine(pl);
}
int CellBuffer::Lines() const {
return lv.Lines();
}
int CellBuffer::LineStart(int line) const {
if (line < 0)
return 0;
else if (line >= Lines())
return Length();
else
return lv.LineStart(line);
}
bool CellBuffer::IsReadOnly() const {
return readOnly;
}
void CellBuffer::SetReadOnly(bool set) {
readOnly = set;
}
void CellBuffer::SetSavePoint() {
uh.SetSavePoint();
}
bool CellBuffer::IsSavePoint() {
return uh.IsSavePoint();
}
// Without undo
void CellBuffer::InsertLine(int line, int position, bool lineStart) {
lv.InsertLine(line, position, lineStart);
}
void CellBuffer::RemoveLine(int line) {
lv.RemoveLine(line);
}
void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
if (insertLength == 0)
return;
PLATFORM_ASSERT(insertLength > 0);
substance.InsertFromArray(position, s, 0, insertLength);
style.InsertValue(position, insertLength, 0);
int lineInsert = lv.LineFromPosition(position) + 1;
bool atLineStart = lv.LineStart(lineInsert-1) == position;
// Point all the lines after the insertion point further along in the buffer
lv.InsertText(lineInsert-1, insertLength);
char chPrev = substance.ValueAt(position - 1);
char chAfter = substance.ValueAt(position + insertLength);
if (chPrev == '\r' && chAfter == '\n') {
// Splitting up a crlf pair at position
InsertLine(lineInsert, position, false);
lineInsert++;
}
char ch = ' ';
for (int i = 0; i < insertLength; i++) {
ch = s[i];
if (ch == '\r') {
InsertLine(lineInsert, (position + i) + 1, atLineStart);
lineInsert++;
} else if (ch == '\n') {
if (chPrev == '\r') {
// Patch up what was end of line
lv.SetLineStart(lineInsert - 1, (position + i) + 1);
} else {
InsertLine(lineInsert, (position + i) + 1, atLineStart);
lineInsert++;
}
}
chPrev = ch;
}
// Joining two lines where last insertion is cr and following substance starts with lf
if (chAfter == '\n') {
if (ch == '\r') {
// End of line already in buffer so drop the newly created one
RemoveLine(lineInsert - 1);
}
}
}
void CellBuffer::BasicDeleteChars(int position, int deleteLength) {
if (deleteLength == 0)
return;
if ((position == 0) && (deleteLength == substance.Length())) {
// If whole buffer is being deleted, faster to reinitialise lines data
// than to delete each line.
lv.Init();
} else {
// Have to fix up line positions before doing deletion as looking at text in buffer
// to work out which lines have been removed
int lineRemove = lv.LineFromPosition(position) + 1;
lv.InsertText(lineRemove-1, - (deleteLength));
char chPrev = substance.ValueAt(position - 1);
char chBefore = chPrev;
char chNext = substance.ValueAt(position);
bool ignoreNL = false;
if (chPrev == '\r' && chNext == '\n') {
// Move back one
lv.SetLineStart(lineRemove, position);
lineRemove++;
ignoreNL = true; // First \n is not real deletion
}
char ch = chNext;
for (int i = 0; i < deleteLength; i++) {
chNext = substance.ValueAt(position + i + 1);
if (ch == '\r') {
if (chNext != '\n') {
RemoveLine(lineRemove);
}
} else if (ch == '\n') {
if (ignoreNL) {
ignoreNL = false; // Further \n are real deletions
} else {
RemoveLine(lineRemove);
}
}
ch = chNext;
}
// May have to fix up end if last deletion causes cr to be next to lf
// or removes one of a crlf pair
char chAfter = substance.ValueAt(position + deleteLength);
if (chBefore == '\r' && chAfter == '\n') {
// Using lineRemove-1 as cr ended line before start of deletion
RemoveLine(lineRemove - 1);
lv.SetLineStart(lineRemove - 1, position + 1);
}
}
substance.DeleteRange(position, deleteLength);
style.DeleteRange(position, deleteLength);
}
bool CellBuffer::SetUndoCollection(bool collectUndo) {
collectingUndo = collectUndo;
uh.DropUndoSequence();
return collectingUndo;
}
bool CellBuffer::IsCollectingUndo() const {
return collectingUndo;
}
void CellBuffer::BeginUndoAction() {
uh.BeginUndoAction();
}
void CellBuffer::EndUndoAction() {
uh.EndUndoAction();
}
void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
bool startSequence;
uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
}
void CellBuffer::DeleteUndoHistory() {
uh.DeleteUndoHistory();
}
bool CellBuffer::CanUndo() {
return uh.CanUndo();
}
int CellBuffer::StartUndo() {
return uh.StartUndo();
}
const Action &CellBuffer::GetUndoStep() const {
return uh.GetUndoStep();
}
void CellBuffer::PerformUndoStep() {
const Action &actionStep = uh.GetUndoStep();
if (actionStep.at == insertAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData);
} else if (actionStep.at == removeAction) {
BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData);
}
uh.CompletedUndoStep();
}
bool CellBuffer::CanRedo() {
return uh.CanRedo();
}
int CellBuffer::StartRedo() {
return uh.StartRedo();
}
const Action &CellBuffer::GetRedoStep() const {
return uh.GetRedoStep();
}
void CellBuffer::PerformRedoStep() {
const Action &actionStep = uh.GetRedoStep();
if (actionStep.at == insertAction) {
BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData);
} else if (actionStep.at == removeAction) {
BasicDeleteChars(actionStep.position, actionStep.lenData);
}
uh.CompletedRedoStep();
}

View File

@@ -0,0 +1,208 @@
// Scintilla source code edit control
/** @file CellBuffer.h
** Manages the text of the document.
**/
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CELLBUFFER_H
#define CELLBUFFER_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// Interface to per-line data that wants to see each line insertion and deletion
class PerLine {
public:
virtual ~PerLine() {}
virtual void Init()=0;
virtual void InsertLine(int)=0;
virtual void RemoveLine(int)=0;
};
/**
* The line vector contains information about each of the lines in a cell buffer.
*/
class LineVector {
Partitioning starts;
PerLine *perLine;
public:
LineVector();
~LineVector();
void Init();
void SetPerLine(PerLine *pl);
void InsertText(int line, int delta);
void InsertLine(int line, int position, bool lineStart);
void SetLineStart(int line, int position);
void RemoveLine(int line);
int Lines() const {
return starts.Partitions();
}
int LineFromPosition(int pos) const;
int LineStart(int line) const {
return starts.PositionFromPartition(line);
}
int MarkValue(int line);
int AddMark(int line, int marker);
void MergeMarkers(int pos);
void DeleteMark(int line, int markerNum, bool all);
void DeleteMarkFromHandle(int markerHandle);
int LineFromHandle(int markerHandle);
void ClearLevels();
int SetLevel(int line, int level);
int GetLevel(int line);
int SetLineState(int line, int state);
int GetLineState(int line);
int GetMaxLineState();
};
enum actionType { insertAction, removeAction, startAction, containerAction };
/**
* Actions are used to store all the information required to perform one undo/redo step.
*/
class Action {
public:
actionType at;
int position;
char *data;
int lenData;
bool mayCoalesce;
Action();
~Action();
void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0, bool mayCoalesce_=true);
void Destroy();
void Grab(Action *source);
};
/**
*
*/
class UndoHistory {
Action *actions;
int lenActions;
int maxAction;
int currentAction;
int undoSequenceDepth;
int savePoint;
void EnsureUndoRoom();
public:
UndoHistory();
~UndoHistory();
void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, bool mayCoalesce=true);
void BeginUndoAction();
void EndUndoAction();
void DropUndoSequence();
void DeleteUndoHistory();
/// The save point is a marker in the undo stack where the container has stated that
/// the buffer was saved. Undo and redo can move over the save point.
void SetSavePoint();
bool IsSavePoint() const;
/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
/// called that many times. Similarly for redo.
bool CanUndo() const;
int StartUndo();
const Action &GetUndoStep() const;
void CompletedUndoStep();
bool CanRedo() const;
int StartRedo();
const Action &GetRedoStep() const;
void CompletedRedoStep();
};
/**
* Holder for an expandable array of characters that supports undo and line markers.
* Based on article "Data Structures in a Bit-Mapped Text Editor"
* by Wilfred J. Hansen, Byte January 1987, page 183.
*/
class CellBuffer {
private:
SplitVector<char> substance;
SplitVector<char> style;
bool readOnly;
bool collectingUndo;
UndoHistory uh;
LineVector lv;
public:
CellBuffer();
~CellBuffer();
/// Retrieving positions outside the range of the buffer works and returns 0
char CharAt(int position) const;
void GetCharRange(char *buffer, int position, int lengthRetrieve) const;
char StyleAt(int position) const;
const char *BufferPointer();
int Length() const;
void Allocate(int newSize);
void SetPerLine(PerLine *pl);
int Lines() const;
int LineStart(int line) const;
int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
void InsertLine(int line, int position, bool lineStart);
void RemoveLine(int line);
const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
/// Setting styles for positions outside the range of the buffer is safe and has no effect.
/// @return true if the style of a character is changed.
bool SetStyleAt(int position, char styleValue, char mask='\377');
bool SetStyleFor(int position, int length, char styleValue, char mask);
const char *DeleteChars(int position, int deleteLength, bool &startSequence);
bool IsReadOnly() const;
void SetReadOnly(bool set);
/// The save point is a marker in the undo stack where the container has stated that
/// the buffer was saved. Undo and redo can move over the save point.
void SetSavePoint();
bool IsSavePoint();
/// Actions without undo
void BasicInsertString(int position, const char *s, int insertLength);
void BasicDeleteChars(int position, int deleteLength);
bool SetUndoCollection(bool collectUndo);
bool IsCollectingUndo() const;
void BeginUndoAction();
void EndUndoAction();
void AddUndoAction(int token, bool mayCoalesce);
void DeleteUndoHistory();
/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
/// called that many times. Similarly for redo.
bool CanUndo();
int StartUndo();
const Action &GetUndoStep() const;
void PerformUndoStep();
bool CanRedo();
int StartRedo();
const Action &GetRedoStep() const;
void PerformRedoStep();
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,78 @@
// Scintilla source code edit control
/** @file CharClassify.cxx
** Character classifications used by Document and RESearch.
**/
// Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <ctype.h>
#include "CharClassify.h"
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4514)
#endif
CharClassify::CharClassify() {
SetDefaultCharClasses(true);
}
void CharClassify::SetDefaultCharClasses(bool includeWordClass) {
// Initialize all char classes to default values
for (int ch = 0; ch < 256; ch++) {
if (ch == '\r' || ch == '\n')
charClass[ch] = ccNewLine;
else if (ch < 0x20 || ch == ' ')
charClass[ch] = ccSpace;
else if (includeWordClass && (ch >= 0x80 || isalnum(ch) || ch == '_'))
charClass[ch] = ccWord;
else
charClass[ch] = ccPunctuation;
}
}
void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
// Apply the newCharClass to the specifed chars
if (chars) {
while (*chars) {
charClass[*chars] = static_cast<unsigned char>(newCharClass);
chars++;
}
}
}
int CompareCaseInsensitive(const char *a, const char *b) {
while (*a && *b) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
}
// Either *a or *b is nul
return *a - *b;
}
int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
while (*a && *b && len) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
len--;
}
if (len == 0)
return 0;
else
// Either *a or *b is nul
return *a - *b;
}

View File

@@ -0,0 +1,37 @@
// Scintilla source code edit control
/** @file CharClassify.h
** Character classifications used by Document and RESearch.
**/
// Copyright 2006-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CHARCLASSIFY_H
#define CHARCLASSIFY_H
class CharClassify {
public:
CharClassify();
enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation };
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, cc newCharClass);
cc GetClass(unsigned char ch) const { return static_cast<cc>(charClass[ch]);}
bool IsWord(unsigned char ch) const { return static_cast<cc>(charClass[ch]) == ccWord;}
private:
enum { maxChar=256 };
unsigned char charClass[maxChar]; // not type cc to save space
};
// These functions are implemented because each platform calls them something different.
int CompareCaseInsensitive(const char *a, const char *b);
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
inline char MakeUpperCase(char ch) {
if (ch < 'a' || ch > 'z')
return ch;
else
return static_cast<char>(ch - 'a' + 'A');
}
#endif

View File

@@ -0,0 +1,59 @@
// Scintilla source code edit control
/** @file CharacterSet.h
** Encapsulates a set of characters. Used to test if a character is within a set.
**/
// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
class CharacterSet {
int size;
bool valueAfter;
bool *bset;
public:
enum setBase {
setNone=0,
setLower=1,
setUpper=2,
setDigits=4,
setAlpha=setLower|setUpper,
setAlphaNum=setAlpha|setDigits
};
CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) {
size = size_;
valueAfter = valueAfter_;
bset = new bool[size];
for (int i=0; i < size; i++) {
bset[i] = false;
}
AddString(initialSet);
if (base & setLower)
AddString("abcdefghijklmnopqrstuvwxyz");
if (base & setUpper)
AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
if (base & setDigits)
AddString("0123456789");
}
~CharacterSet() {
delete []bset;
bset = 0;
size = 0;
}
void Add(int val) {
PLATFORM_ASSERT(val >= 0);
PLATFORM_ASSERT(val < size);
bset[val] = true;
}
void AddString(const char *CharacterSet) {
for (const char *cp=CharacterSet; *cp; cp++) {
int val = static_cast<unsigned char>(*cp);
PLATFORM_ASSERT(val >= 0);
PLATFORM_ASSERT(val < size);
bset[val] = true;
}
}
bool Contains(int val) const {
PLATFORM_ASSERT(val >= 0);
if (val < 0) return false;
return (val < size) ? bset[val] : valueAfter;
}
};

View File

@@ -0,0 +1,251 @@
// Scintilla source code edit control
/** @file ContractionState.cxx
** Manages visibility of lines for folding and wrapping.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
#include "Platform.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "ContractionState.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) {
//InsertLine(0);
}
ContractionState::~ContractionState() {
Clear();
}
void ContractionState::EnsureData() {
if (OneToOne()) {
visible = new RunStyles();
expanded = new RunStyles();
heights = new RunStyles();
displayLines = new Partitioning(4);
InsertLines(0, linesInDocument);
}
}
void ContractionState::Clear() {
delete visible;
visible = 0;
delete expanded;
expanded = 0;
delete heights;
heights = 0;
delete displayLines;
displayLines = 0;
linesInDocument = 1;
}
int ContractionState::LinesInDoc() const {
if (OneToOne()) {
return linesInDocument;
} else {
return displayLines->Partitions() - 1;
}
}
int ContractionState::LinesDisplayed() const {
if (OneToOne()) {
return linesInDocument;
} else {
return displayLines->PositionFromPartition(LinesInDoc());
}
}
int ContractionState::DisplayFromDoc(int lineDoc) const {
if (OneToOne()) {
return lineDoc;
} else {
if (lineDoc > displayLines->Partitions())
lineDoc = displayLines->Partitions();
return displayLines->PositionFromPartition(lineDoc);
}
}
int ContractionState::DocFromDisplay(int lineDisplay) const {
if (OneToOne()) {
return lineDisplay;
} else {
if (lineDisplay <= 0) {
return 0;
}
if (lineDisplay > LinesDisplayed()) {
return displayLines->PartitionFromPosition(LinesDisplayed());
}
int lineDoc = displayLines->PartitionFromPosition(lineDisplay);
PLATFORM_ASSERT(GetVisible(lineDoc));
return lineDoc;
}
}
void ContractionState::InsertLine(int lineDoc) {
if (OneToOne()) {
linesInDocument++;
} else {
visible->InsertSpace(lineDoc, 1);
visible->SetValueAt(lineDoc, 1);
expanded->InsertSpace(lineDoc, 1);
expanded->SetValueAt(lineDoc, 1);
heights->InsertSpace(lineDoc, 1);
heights->SetValueAt(lineDoc, 1);
int lineDisplay = DisplayFromDoc(lineDoc);
displayLines->InsertPartition(lineDoc, lineDisplay);
displayLines->InsertText(lineDoc, 1);
}
}
void ContractionState::InsertLines(int lineDoc, int lineCount) {
for (int l = 0; l < lineCount; l++) {
InsertLine(lineDoc + l);
}
Check();
}
void ContractionState::DeleteLine(int lineDoc) {
if (OneToOne()) {
linesInDocument--;
} else {
if (GetVisible(lineDoc)) {
displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc));
}
displayLines->RemovePartition(lineDoc);
visible->DeleteRange(lineDoc, 1);
expanded->DeleteRange(lineDoc, 1);
heights->DeleteRange(lineDoc, 1);
}
}
void ContractionState::DeleteLines(int lineDoc, int lineCount) {
for (int l = 0; l < lineCount; l++) {
DeleteLine(lineDoc);
}
Check();
}
bool ContractionState::GetVisible(int lineDoc) const {
if (OneToOne()) {
return true;
} else {
if (lineDoc >= visible->Length())
return true;
return visible->ValueAt(lineDoc) == 1;
}
}
bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible_) {
if (OneToOne() && visible_) {
return false;
} else {
EnsureData();
int delta = 0;
Check();
if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) {
for (int line = lineDocStart; line <= lineDocEnd; line++) {
if (GetVisible(line) != visible_) {
int difference = visible_ ? heights->ValueAt(line) : -heights->ValueAt(line);
visible->SetValueAt(line, visible_ ? 1 : 0);
displayLines->InsertText(line, difference);
delta += difference;
}
}
} else {
return false;
}
Check();
return delta != 0;
}
}
bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) {
return true;
} else {
Check();
return expanded->ValueAt(lineDoc) == 1;
}
}
bool ContractionState::SetExpanded(int lineDoc, bool expanded_) {
if (OneToOne() && expanded_) {
return false;
} else {
EnsureData();
if (expanded_ != (expanded->ValueAt(lineDoc) == 1)) {
expanded->SetValueAt(lineDoc, expanded_ ? 1 : 0);
Check();
return true;
} else {
Check();
return false;
}
}
}
int ContractionState::GetHeight(int lineDoc) const {
if (OneToOne()) {
return 1;
} else {
return heights->ValueAt(lineDoc);
}
}
// Set the number of display lines needed for this line.
// Return true if this is a change.
bool ContractionState::SetHeight(int lineDoc, int height) {
if (OneToOne() && (height == 1)) {
return false;
} else {
EnsureData();
if (GetHeight(lineDoc) != height) {
if (GetVisible(lineDoc)) {
displayLines->InsertText(lineDoc, height - GetHeight(lineDoc));
}
heights->SetValueAt(lineDoc, height);
Check();
return true;
} else {
Check();
return false;
}
}
}
void ContractionState::ShowAll() {
int lines = LinesInDoc();
Clear();
linesInDocument = lines;
}
// Debugging checks
void ContractionState::Check() const {
#ifdef CHECK_CORRECTNESS
for (int vline = 0;vline < LinesDisplayed(); vline++) {
const int lineDoc = DocFromDisplay(vline);
PLATFORM_ASSERT(GetVisible(lineDoc));
}
for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) {
const int displayThis = DisplayFromDoc(lineDoc);
const int displayNext = DisplayFromDoc(lineDoc + 1);
const int height = displayNext - displayThis;
PLATFORM_ASSERT(height >= 0);
if (GetVisible(lineDoc)) {
PLATFORM_ASSERT(GetHeight(lineDoc) == height);
} else {
PLATFORM_ASSERT(0 == height);
}
}
#endif
}

View File

@@ -0,0 +1,66 @@
// Scintilla source code edit control
/** @file ContractionState.h
** Manages visibility of lines for folding and wrapping.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CONTRACTIONSTATE_H
#define CONTRACTIONSTATE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class ContractionState {
// These contain 1 element for every document line.
RunStyles *visible;
RunStyles *expanded;
RunStyles *heights;
Partitioning *displayLines;
int linesInDocument;
void EnsureData();
bool OneToOne() const {
// True when each document line is exactly one display line so need for
// complex data structures.
return visible == 0;
}
public:
ContractionState();
virtual ~ContractionState();
void Clear();
int LinesInDoc() const;
int LinesDisplayed() const;
int DisplayFromDoc(int lineDoc) const;
int DocFromDisplay(int lineDisplay) const;
void InsertLine(int lineDoc);
void InsertLines(int lineDoc, int lineCount);
void DeleteLine(int lineDoc);
void DeleteLines(int lineDoc, int lineCount);
bool GetVisible(int lineDoc) const;
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded);
int GetHeight(int lineDoc) const;
bool SetHeight(int lineDoc, int height);
void ShowAll();
void Check() const;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,188 @@
/** @file Decoration.cxx
** Visual elements added over text.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "Decoration.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) {
}
Decoration::~Decoration() {
}
bool Decoration::Empty() {
return rs.starts->Partitions() == 1;
}
DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
lengthDocument(0), root(0), clickNotified(false) {
}
DecorationList::~DecorationList() {
Decoration *deco = root;
while (deco) {
Decoration *decoNext = deco->next;
delete deco;
deco = decoNext;
}
root = 0;
current = 0;
}
Decoration *DecorationList::DecorationFromIndicator(int indicator) {
for (Decoration *deco=root; deco; deco = deco->next) {
if (deco->indicator == indicator) {
return deco;
}
}
return 0;
}
Decoration *DecorationList::Create(int indicator, int length) {
currentIndicator = indicator;
Decoration *decoNew = new Decoration(indicator);
decoNew->rs.InsertSpace(0, length);
Decoration *decoPrev = 0;
Decoration *deco = root;
while (deco && (deco->indicator < indicator)) {
decoPrev = deco;
deco = deco->next;
}
if (decoPrev == 0) {
decoNew->next = root;
root = decoNew;
} else {
decoNew->next = deco;
decoPrev->next = decoNew;
}
return decoNew;
}
void DecorationList::Delete(int indicator) {
Decoration *decoToDelete = 0;
if (root) {
if (root->indicator == indicator) {
decoToDelete = root;
root = root->next;
} else {
Decoration *deco=root;
while (deco->next && !decoToDelete) {
if (deco->next && deco->next->indicator == indicator) {
decoToDelete = deco->next;
deco->next = decoToDelete->next;
} else {
deco = deco->next;
}
}
}
}
if (decoToDelete) {
delete decoToDelete;
current = 0;
}
}
void DecorationList::SetCurrentIndicator(int indicator) {
currentIndicator = indicator;
current = DecorationFromIndicator(indicator);
currentValue = 1;
}
void DecorationList::SetCurrentValue(int value) {
currentValue = value ? value : 1;
}
bool DecorationList::FillRange(int &position, int value, int &fillLength) {
if (!current) {
current = DecorationFromIndicator(currentIndicator);
if (!current) {
current = Create(currentIndicator, lengthDocument);
}
}
bool changed = current->rs.FillRange(position, value, fillLength);
if (current->Empty()) {
Delete(currentIndicator);
}
return changed;
}
void DecorationList::InsertSpace(int position, int insertLength) {
lengthDocument += insertLength;
for (Decoration *deco=root; deco; deco = deco->next) {
deco->rs.InsertSpace(position, insertLength);
}
}
void DecorationList::DeleteRange(int position, int deleteLength) {
lengthDocument -= deleteLength;
Decoration *deco;
for (deco=root; deco; deco = deco->next) {
deco->rs.DeleteRange(position, deleteLength);
}
DeleteAnyEmpty();
}
void DecorationList::DeleteAnyEmpty() {
Decoration *deco = root;
while (deco) {
if (deco->Empty()) {
Delete(deco->indicator);
deco = root;
} else {
deco = deco->next;
}
}
}
int DecorationList::AllOnFor(int position) {
int mask = 0;
for (Decoration *deco=root; deco; deco = deco->next) {
if (deco->rs.ValueAt(position)) {
mask |= 1 << deco->indicator;
}
}
return mask;
}
int DecorationList::ValueAt(int indicator, int position) {
Decoration *deco = DecorationFromIndicator(indicator);
if (deco) {
return deco->rs.ValueAt(position);
}
return 0;
}
int DecorationList::Start(int indicator, int position) {
Decoration *deco = DecorationFromIndicator(indicator);
if (deco) {
return deco->rs.StartRun(position);
}
return 0;
}
int DecorationList::End(int indicator, int position) {
Decoration *deco = DecorationFromIndicator(indicator);
if (deco) {
return deco->rs.EndRun(position);
}
return 0;
}

View File

@@ -0,0 +1,64 @@
/** @file Decoration.h
** Visual elements added over text.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DECORATION_H
#define DECORATION_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class Decoration {
public:
Decoration *next;
RunStyles rs;
int indicator;
Decoration(int indicator_);
~Decoration();
bool Empty();
};
class DecorationList {
int currentIndicator;
int currentValue;
Decoration *current;
int lengthDocument;
Decoration *DecorationFromIndicator(int indicator);
Decoration *Create(int indicator, int length);
void Delete(int indicator);
void DeleteAnyEmpty();
public:
Decoration *root;
bool clickNotified;
DecorationList();
~DecorationList();
void SetCurrentIndicator(int indicator);
int GetCurrentIndicator() const { return currentIndicator; }
void SetCurrentValue(int value);
int GetCurrentValue() const { return currentValue; }
// Returns true if some values may have changed
bool FillRange(int &position, int value, int &fillLength);
void InsertSpace(int position, int insertLength);
void DeleteRange(int position, int deleteLength);
int AllOnFor(int position);
int ValueAt(int indicator, int position);
int Start(int indicator, int position);
int End(int indicator, int position);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,426 @@
// Scintilla source code edit control
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
#define DOCUMENT_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
* A Position is a position within a document between two characters or at the beginning or end.
* Sometimes used as a character index where it identifies the character after the position.
*/
typedef int Position;
const Position invalidPosition = -1;
/**
* The range class represents a range of text in a document.
* The two values are not sorted as one end may be more significant than the other
* as is the case for the selection where the end position is the position of the caret.
* If either position is invalidPosition then the range is invalid and most operations will fail.
*/
class Range {
public:
Position start;
Position end;
Range(Position pos=0) :
start(pos), end(pos) {
}
Range(Position start_, Position end_) :
start(start_), end(end_) {
}
bool Valid() const {
return (start != invalidPosition) && (end != invalidPosition);
}
// Is the position within the range?
bool Contains(Position pos) const {
if (start < end) {
return (pos >= start && pos <= end);
} else {
return (pos <= start && pos >= end);
}
}
// Is the character after pos within the range?
bool ContainsCharacter(Position pos) const {
if (start < end) {
return (pos >= start && pos < end);
} else {
return (pos < start && pos >= end);
}
}
bool Contains(Range other) const {
return Contains(other.start) && Contains(other.end);
}
bool Overlaps(Range other) const {
return
Contains(other.start) ||
Contains(other.end) ||
other.Contains(start) ||
other.Contains(end);
}
};
class DocWatcher;
class DocModification;
class Document;
/**
* Interface class for regular expression searching
*/
class RegexSearchBase {
public:
virtual ~RegexSearchBase(){}
virtual long FindText(Document* doc, int minPos, int maxPos, const char *s,
bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0;
///@return String with the substitutions, must remain valid until the next call or destruction
virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length) = 0;
};
/// Factory function for RegexSearchBase
extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
struct StyledText {
size_t length;
const char *text;
bool multipleStyles;
size_t style;
const unsigned char *styles;
StyledText( size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) :
length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
}
// Return number of bytes from start to before '\n' or end of text.
// Return 1 when start is outside text
size_t LineLength(size_t start) const {
size_t cur = start;
while ((cur < length) && (text[cur] != '\n'))
cur++;
return cur-start;
}
size_t StyleAt(size_t i) const {
return multipleStyles ? styles[i] : style;
}
};
class CaseFolder {
public:
virtual ~CaseFolder() {
}
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0;
};
class CaseFolderTable : public CaseFolder {
protected:
char mapping[256];
public:
CaseFolderTable();
virtual ~CaseFolderTable();
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed);
void SetTranslation(char ch, char chTranslation);
void StandardASCII();
};
/**
*/
class Document : PerLine {
public:
/** Used to pair watcher pointer with user data. */
class WatcherWithUserData {
public:
DocWatcher *watcher;
void *userData;
WatcherWithUserData() {
watcher = 0;
userData = 0;
}
};
enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
private:
int refCount;
CellBuffer cb;
CharClassify charClass;
char stylingMask;
int endStyled;
int styleClock;
int enteredModification;
int enteredStyling;
int enteredReadOnlyCount;
WatcherWithUserData *watchers;
int lenWatchers;
// ldSize is not real data - it is for dimensions and loops
enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };
PerLine *perLineData[ldSize];
bool matchesValid;
RegexSearchBase* regex;
public:
int stylingBits;
int stylingBitsMask;
int eolMode;
/// Can also be SC_CP_UTF8 to enable UTF-8 mode
int dbcsCodePage;
int tabInChars;
int indentInChars;
int actualIndentInChars;
bool useTabs;
bool tabIndents;
bool backspaceUnindents;
DecorationList decorations;
Document();
virtual ~Document();
int AddRef();
int Release();
virtual void Init();
virtual void InsertLine(int line);
virtual void RemoveLine(int line);
int LineFromPosition(int pos) const;
int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos);
int LenChar(int pos);
bool InGoodUTF8(int pos, int &start, int &end);
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
// Gateways to modifying document
void ModifiedAt(int pos);
void CheckReadOnly();
bool DeleteChars(int pos, int len);
bool InsertString(int position, const char *s, int insertLength);
int Undo();
int Redo();
bool CanUndo() { return cb.CanUndo(); }
bool CanRedo() { return cb.CanRedo(); }
void DeleteUndoHistory() { cb.DeleteUndoHistory(); }
bool SetUndoCollection(bool collectUndo) {
return cb.SetUndoCollection(collectUndo);
}
bool IsCollectingUndo() { return cb.IsCollectingUndo(); }
void BeginUndoAction() { cb.BeginUndoAction(); }
void EndUndoAction() { cb.EndUndoAction(); }
void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); }
const char *BufferPointer() { return cb.BufferPointer(); }
int GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
int GetLineIndentPosition(int line) const;
int GetColumn(int position);
int FindColumn(int line, int column);
void Indent(bool forwards, int lineBottom, int lineTop);
static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode);
void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() { return cb.IsReadOnly(); }
bool InsertChar(int pos, char ch);
bool InsertCString(int position, const char *s);
void ChangeChar(int pos, char ch);
void DelChar(int pos);
void DelCharBack(int pos);
char CharAt(int position) { return cb.CharAt(position); }
void GetCharRange(char *buffer, int position, int lengthRetrieve) const {
cb.GetCharRange(buffer, position, lengthRetrieve);
}
char StyleAt(int position) const { return cb.StyleAt(position); }
int GetMark(int line);
int AddMark(int line, int markerNum);
void AddMarkSet(int line, int valueSet);
void DeleteMark(int line, int markerNum);
void DeleteMarkFromHandle(int markerHandle);
void DeleteAllMarks(int markerNum);
int LineFromHandle(int markerHandle);
int LineStart(int line) const;
int LineEnd(int line) const;
int LineEndPosition(int position) const;
bool IsLineEndPosition(int position) const;
int VCHomePosition(int position) const;
int SetLevel(int line, int level);
int GetLevel(int line) const;
void ClearLevels();
int GetLastChild(int lineParent, int level=-1);
int GetFoldParent(int line);
void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
int NextWordStart(int pos, int delta);
int NextWordEnd(int pos, int delta);
int Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
size_t ExtractChar(int pos, char *bytes);
bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word,
bool wordStart, bool regExp, int flags, int *length, CaseFolder *pcf);
const char *SubstituteByPosition(const char *text, int *length);
int LinesTotal() const;
void ChangeCase(Range r, bool makeUpperCase);
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
void SetStylingBits(int bits);
void StartStyling(int position, char mask);
bool SetStyleFor(int length, char style);
bool SetStyles(int length, const char *styles);
int GetEndStyled() { return endStyled; }
void EnsureStyledTo(int pos);
int GetStyleClock() { return styleClock; }
void IncrementStyleClock();
void DecorationFillRange(int position, int value, int fillLength);
int SetLineState(int line, int state);
int GetLineState(int line) const;
int GetMaxLineState();
StyledText MarginStyledText(int line);
void MarginSetStyle(int line, int style);
void MarginSetStyles(int line, const unsigned char *styles);
void MarginSetText(int line, const char *text);
int MarginLength(int line) const;
void MarginClearAll();
bool AnnotationAny() const;
StyledText AnnotationStyledText(int line);
void AnnotationSetText(int line, const char *text);
void AnnotationSetStyle(int line, int style);
void AnnotationSetStyles(int line, const unsigned char *styles);
int AnnotationLength(int line) const;
int AnnotationLines(int line) const;
void AnnotationClearAll();
bool AddWatcher(DocWatcher *watcher, void *userData);
bool RemoveWatcher(DocWatcher *watcher, void *userData);
const WatcherWithUserData *GetWatchers() const { return watchers; }
int GetLenWatchers() const { return lenWatchers; }
bool IsWordPartSeparator(char ch);
int WordPartLeft(int pos);
int WordPartRight(int pos);
int ExtendStyleRange(int pos, int delta, bool singleLine = false);
bool IsWhiteLine(int line) const;
int ParaUp(int pos);
int ParaDown(int pos);
int IndentSize() { return actualIndentInChars; }
int BraceMatch(int position, int maxReStyle);
private:
CharClassify::cc WordCharClass(unsigned char ch);
bool IsWordStartAt(int pos);
bool IsWordEndAt(int pos);
bool IsWordAt(int start, int end);
void NotifyModifyAttempt();
void NotifySavePoint(bool atSavePoint);
void NotifyModified(DocModification mh);
};
class UndoGroup {
Document *pdoc;
bool groupNeeded;
public:
UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
pdoc(pdoc_), groupNeeded(groupNeeded_) {
if (groupNeeded) {
pdoc->BeginUndoAction();
}
}
~UndoGroup() {
if (groupNeeded) {
pdoc->EndUndoAction();
}
}
bool Needed() const {
return groupNeeded;
}
};
/**
* To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
* scope of the change.
* If the DocWatcher is a document view then this can be used to optimise screen updating.
*/
class DocModification {
public:
int modificationType;
int position;
int length;
int linesAdded; /**< Negative if lines deleted. */
const char *text; /**< Only valid for changes to text, not for changes to style. */
int line;
int foldLevelNow;
int foldLevelPrev;
int annotationLinesAdded;
int token;
DocModification(int modificationType_, int position_=0, int length_=0,
int linesAdded_=0, const char *text_=0, int line_=0) :
modificationType(modificationType_),
position(position_),
length(length_),
linesAdded(linesAdded_),
text(text_),
line(line_),
foldLevelNow(0),
foldLevelPrev(0),
annotationLinesAdded(0),
token(0) {}
DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
position(act.position),
length(act.lenData),
linesAdded(linesAdded_),
text(act.data),
line(0),
foldLevelNow(0),
foldLevelPrev(0),
annotationLinesAdded(0),
token(0) {}
};
/**
* A class that wants to receive notifications from a Document must be derived from DocWatcher
* and implement the notification methods. It can then be added to the watcher list with AddWatcher.
*/
class DocWatcher {
public:
virtual ~DocWatcher() {}
virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0;
virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0;
virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
virtual void NotifyDeleted(Document *doc, void *userData) = 0;
virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,199 @@
// Scintilla source code edit control
/** @file DocumentAccessor.cxx
** Rapid easy access to contents of a Scintilla.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "CellBuffer.h"
#include "Scintilla.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
DocumentAccessor::~DocumentAccessor() {
}
bool DocumentAccessor::InternalIsLeadByte(char ch) {
if (SC_CP_UTF8 == codePage)
// For lexing, all characters >= 0x80 are treated the
// same so none is considered a lead byte.
return false;
else
return Platform::IsDBCSLeadByte(codePage, ch);
}
void DocumentAccessor::Fill(int position) {
if (lenDoc == -1)
lenDoc = pdoc->Length();
startPos = position - slopSize;
if (startPos + bufferSize > lenDoc)
startPos = lenDoc - bufferSize;
if (startPos < 0)
startPos = 0;
endPos = startPos + bufferSize;
if (endPos > lenDoc)
endPos = lenDoc;
pdoc->GetCharRange(buf, startPos, endPos-startPos);
buf[endPos-startPos] = '\0';
}
bool DocumentAccessor::Match(int pos, const char *s) {
for (int i=0; *s; i++) {
if (*s != SafeGetCharAt(pos+i))
return false;
s++;
}
return true;
}
char DocumentAccessor::StyleAt(int position) {
// Mask off all bits which aren't in the 'mask'.
return static_cast<char>(pdoc->StyleAt(position) & mask);
}
int DocumentAccessor::GetLine(int position) {
return pdoc->LineFromPosition(position);
}
int DocumentAccessor::LineStart(int line) {
return pdoc->LineStart(line);
}
int DocumentAccessor::LevelAt(int line) {
return pdoc->GetLevel(line);
}
int DocumentAccessor::Length() {
if (lenDoc == -1)
lenDoc = pdoc->Length();
return lenDoc;
}
int DocumentAccessor::GetLineState(int line) {
return pdoc->GetLineState(line);
}
int DocumentAccessor::SetLineState(int line, int state) {
return pdoc->SetLineState(line, state);
}
void DocumentAccessor::StartAt(unsigned int start, char chMask) {
// Store the mask specified for use with StyleAt.
mask = chMask;
pdoc->StartStyling(start, chMask);
startPosStyling = start;
}
void DocumentAccessor::StartSegment(unsigned int pos) {
startSeg = pos;
}
void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {
// Only perform styling if non empty range
if (pos != startSeg - 1) {
PLATFORM_ASSERT(pos >= startSeg);
if (pos < startSeg) {
return;
}
if (validLen + (pos - startSeg + 1) >= bufferSize)
Flush();
if (validLen + (pos - startSeg + 1) >= bufferSize) {
// Too big for buffer so send directly
pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
} else {
if (chAttr != chWhile)
chFlags = 0;
chAttr |= chFlags;
for (unsigned int i = startSeg; i <= pos; i++) {
PLATFORM_ASSERT((startPosStyling + validLen) < Length());
styleBuf[validLen++] = static_cast<char>(chAttr);
}
}
}
startSeg = pos+1;
}
void DocumentAccessor::SetLevel(int line, int level) {
pdoc->SetLevel(line, level);
}
void DocumentAccessor::Flush() {
startPos = extremePosition;
lenDoc = -1;
if (validLen > 0) {
pdoc->SetStyles(validLen, styleBuf);
startPosStyling += validLen;
validLen = 0;
}
}
int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
int end = Length();
int spaceFlags = 0;
// Determines the indentation level of the current line and also checks for consistent
// indentation compared to the previous line.
// Indentation is judged consistent when the indentation whitespace of each line lines
// the same or the indentation of one line is a prefix of the other.
int pos = LineStart(line);
char ch = (*this)[pos];
int indent = 0;
bool inPrevPrefix = line > 0;
int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
while ((ch == ' ' || ch == '\t') && (pos < end)) {
if (inPrevPrefix) {
char chPrev = (*this)[posPrev++];
if (chPrev == ' ' || chPrev == '\t') {
if (chPrev != ch)
spaceFlags |= wsInconsistent;
} else {
inPrevPrefix = false;
}
}
if (ch == ' ') {
spaceFlags |= wsSpace;
indent++;
} else { // Tab
spaceFlags |= wsTab;
if (spaceFlags & wsSpace)
spaceFlags |= wsSpaceTab;
indent = (indent / 8 + 1) * 8;
}
ch = (*this)[++pos];
}
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
return indent | SC_FOLDLEVELWHITEFLAG;
else
return indent;
}
void DocumentAccessor::IndicatorFill(int start, int end, int indicator, int value) {
pdoc->decorations.SetCurrentIndicator(indicator);
pdoc->DecorationFillRange(start, value, end - start);
}

View File

@@ -0,0 +1,77 @@
// Scintilla source code edit control
/** @file DocumentAccessor.h
** Implementation of BufferAccess and StylingAccess on a Scintilla
** rapid easy access to contents of a Scintilla.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class Document;
/**
*/
class DocumentAccessor : public Accessor {
// Private so DocumentAccessor objects can not be copied
DocumentAccessor(const DocumentAccessor &source);
DocumentAccessor &operator=(const DocumentAccessor &);
protected:
Document *pdoc;
PropertyGet &props;
WindowID id;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
char chFlags;
char chWhile;
unsigned int startSeg;
int startPosStyling;
int mask;
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
DocumentAccessor(Document *pdoc_, PropertyGet &props_, WindowID id_=0) :
Accessor(), pdoc(pdoc_), props(props_), id(id_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
startSeg(0), startPosStyling(0),
mask(127) { // Initialize the mask to be big enough for any lexer.
}
~DocumentAccessor();
bool Match(int pos, const char *s);
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
void Flush();
int GetLineState(int line);
int SetLineState(int line, int state);
int GetPropertyInt(const char *key, int defaultValue=0) {
return props.GetInt(key, defaultValue);
}
char *GetProperties() {
return props.ToString();
}
WindowID GetWindow() { return id; }
void StartAt(unsigned int start, char chMask=31);
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
void IndicatorFill(int start, int end, int indicator, int value);
};
#ifdef SCI_NAMESPACE
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,590 @@
// Scintilla source code edit control
/** @file Editor.h
** Defines the main editor class.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
#define EDITOR_H
// Eran Ifrah
#include <string>
// Eran Ifrah - END
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class Caret {
public:
bool active;
bool on;
int period;
Caret();
};
/**
*/
class Timer {
public:
bool ticking;
int ticksToWait;
enum {tickSize = 100};
TickerID tickerID;
Timer();
};
/**
*/
class Idler {
public:
bool state;
IdlerID idlerID;
Idler();
};
/**
* When platform has a way to generate an event before painting,
* accumulate needed styling range in StyleNeeded to avoid unnecessary work.
*/
class StyleNeeded {
public:
bool active;
Position upTo;
StyleNeeded() : active(false), upTo(0) {}
void Reset() {
active = false;
upTo = 0;
}
void NeedUpTo(Position pos) {
if (upTo < pos)
upTo = pos;
}
};
/**
* Hold a piece of text selected for copying or dragging.
* The text is expected to hold a terminating '\0' and this is counted in len.
*/
class SelectionText {
public:
char *s;
int len;
bool rectangular;
bool lineCopy;
int codePage;
int characterSet;
SelectionText() : s(0), len(0), rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
~SelectionText() {
Free();
}
void Free() {
Set(0, 0, 0, 0, false, false);
}
void Set(char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
delete []s;
s = s_;
if (s)
len = len_;
else
len = 0;
codePage = codePage_;
characterSet = characterSet_;
rectangular = rectangular_;
lineCopy = lineCopy_;
}
void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
delete []s;
s = 0;
s = new char[len_];
len = len_;
for (int i = 0; i < len_; i++) {
s[i] = s_[i];
}
codePage = codePage_;
characterSet = characterSet_;
rectangular = rectangular_;
lineCopy = lineCopy_;
}
void Copy(const SelectionText &other) {
Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular, other.lineCopy);
}
};
/**
*/
class Editor : public DocWatcher {
// Private so Editor objects can not be copied
Editor(const Editor &);
Editor &operator=(const Editor &);
protected: // ScintillaBase subclass needs access to much of Editor
/** On GTK+, Scintilla is a container widget holding two scroll bars
* whereas on Windows there is just one window with both scroll bars turned on. */
Window wMain; ///< The Scintilla parent window
/** Style resources may be expensive to allocate so are cached between uses.
* When a style attribute is changed, this cache is flushed. */
bool stylesValid;
ViewStyle vs;
Palette palette;
int printMagnification;
int printColourMode;
int printWrapState;
int cursorMode;
int controlCharSymbol;
bool hasFocus;
bool hideSelection;
bool inOverstrike;
bool mouseDownCaptures;
/** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
* the screen. This avoids flashing but is about 30% slower. */
bool bufferedDraw;
/** In twoPhaseDraw mode, drawing is performed in two phases, first the background
* and then the foreground. This avoids chopping off characters that overlap the next run. */
bool twoPhaseDraw;
int xOffset; ///< Horizontal scrolled amount in pixels
int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret
bool horizontalScrollBarVisible;
int scrollWidth;
bool trackLineWidth;
int lineWidthMaxSeen;
bool verticalScrollBarVisible;
bool endAtLastLine;
bool caretSticky;
bool multipleSelection;
bool additionalSelectionTyping;
int multiPasteMode;
bool additionalCaretsBlink;
bool additionalCaretsVisible;
int virtualSpaceOptions;
Surface *pixmapLine;
Surface *pixmapSelMargin;
Surface *pixmapSelPattern;
Surface *pixmapIndentGuide;
Surface *pixmapIndentGuideHighlight;
LineLayoutCache llc;
PositionCache posCache;
KeyMap kmap;
Caret caret;
Timer timer;
Timer autoScrollTimer;
enum { autoScrollDelay = 200 };
Idler idler;
Point lastClick;
unsigned int lastClickTime;
int dwellDelay;
int ticksToDwell;
bool dwelling;
enum { selChar, selWord, selLine } selectionType;
Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
SelectionPosition posDrag;
SelectionPosition posDrop;
int lastXChosen;
int lineAnchor;
int originalAnchorPos;
int targetStart;
int targetEnd;
int searchFlags;
int topLine;
int posTopLine;
int lengthForEncode;
bool needUpdateUI;
Position braces[2];
int bracesMatchStyle;
int highlightGuideColumn;
int theEdge;
enum { notPainting, painting, paintAbandoned } paintState;
PRectangle rcPaint;
bool paintingAllText;
StyleNeeded styleNeeded;
int modEventMask;
SelectionText drag;
Selection sel;
bool primarySelection;
int caretXPolicy;
int caretXSlop; ///< Ensure this many pixels visible on both sides of caret
int caretYPolicy;
int caretYSlop; ///< Ensure this many lines visible on both sides of caret
int visiblePolicy;
int visibleSlop;
int searchAnchor;
bool recordingMacro;
int foldFlags;
ContractionState cs;
// Hotspot support
int hsStart;
int hsEnd;
// Wrapping support
enum { eWrapNone, eWrapWord, eWrapChar } wrapState;
enum { wrapLineLarge = 0x7ffffff };
int wrapWidth;
int wrapStart;
int wrapEnd;
int wrapVisualFlags;
int wrapVisualFlagsLocation;
int wrapVisualStartIndent;
int wrapAddIndent; // This will be added to initial indent of line
int wrapIndentMode; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
bool convertPastes;
Document *pdoc;
Editor();
virtual ~Editor();
virtual void Initialise() = 0;
virtual void Finalise();
void InvalidateStyleData();
void InvalidateStyleRedraw();
virtual void RefreshColourPalette(Palette &pal, bool want);
void RefreshStyleData();
void DropGraphics();
virtual PRectangle GetClientRectangle();
PRectangle GetTextRectangle();
int LinesOnScreen();
int LinesToScroll();
int MaxScrollPos();
SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
Point LocationFromPosition(SelectionPosition pos);
Point LocationFromPosition(int pos);
int XFromPosition(int pos);
int XFromPosition(SelectionPosition sp);
SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false);
SelectionPosition SPositionFromLineX(int lineDoc, int x);
int PositionFromLineX(int line, int x);
int LineFromLocation(Point pt);
void SetTopLine(int topLineNew);
bool AbandonPaint();
void RedrawRect(PRectangle rc);
void Redraw();
void RedrawSelMargin(int line=-1, bool allAfter=false);
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
bool UserVirtualSpace() const {
return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0);
}
int CurrentPosition();
bool SelectionEmpty();
SelectionPosition SelectionStart();
SelectionPosition SelectionEnd();
void SetRectangularRange();
void ThinRectangularRange();
void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
void SetSelection(int currentPos_, int anchor_);
void SetSelection(SelectionPosition currentPos_);
void SetSelection(int currentPos_);
void SetEmptySelection(SelectionPosition currentPos_);
void SetEmptySelection(int currentPos_);
bool RangeContainsProtected(int start, int end) const;
bool SelectionContainsProtected();
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const;
SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const;
int MovePositionTo(SelectionPosition newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
int MovePositionTo(int newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir);
SelectionPosition MovePositionSoVisible(int pos, int moveDir);
Point PointMainCaret();
void SetLastXChosen();
void ScrollTo(int line, bool moveThumb=true);
virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos);
void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos);
struct XYScrollPosition {
int xOffset;
int topLine;
XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {}
};
XYScrollPosition XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz);
void SetXYScroll(XYScrollPosition newXY);
void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
void ShowCaretAtCurrentPosition();
void DropCaret();
void InvalidateCaret();
virtual void UpdateSystemCaret();
void NeedWrapping(int docLineStart = 0, int docLineEnd = wrapLineLarge);
bool WrapOneLine(Surface *surface, int lineToWrap);
bool WrapLines(bool fullWrap, int priorityWrapLineStart);
void LinesJoin();
void LinesSplit(int pixelWidth);
int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault);
void PaintSelMargin(Surface *surface, PRectangle &rc);
LineLayout *RetrieveLineLayout(int lineNumber);
void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
int width=LineLayout::wrapWidthInfinite);
ColourAllocated SelectionBackground(ViewStyle &vsDraw, bool main);
ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour);
void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
int line, int lineEnd, int xStart, int subLine, int subLineStart,
bool overrideBackground, ColourAllocated background,
bool drawWrapMark, ColourAllocated wrapColour);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour);
void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void RefreshPixMaps(Surface *surfaceWindow);
void Paint(Surface *surfaceWindow, PRectangle rcArea);
long FormatRange(bool draw, Sci_RangeToFormat *pfr);
int TextWidth(int style, const char *text);
virtual void SetVerticalScrollPos() = 0;
virtual void SetHorizontalScrollPos() = 0;
virtual bool ModifyScrollBars(int nMax, int nPage) = 0;
virtual void ReconfigureScrollBars();
void SetScrollBars();
void ChangeSize();
void FilterSelections();
int InsertSpace(int position, unsigned int spaces);
void AddChar(char ch);
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
void InsertPaste(SelectionPosition selStart, const char *text, int len);
void ClearSelection();
void ClearAll();
void ClearDocumentStyle();
void Cut();
void PasteRectangular(SelectionPosition pos, const char *ptr, int len);
virtual void Copy() = 0;
virtual void CopyAllowLine();
virtual bool CanPaste();
virtual void Paste() = 0;
void Clear();
void SelectAll();
void Undo();
void Redo();
void DelChar();
void DelCharBack(bool allowLineStartDeletion);
virtual void ClaimSelection() = 0;
virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus);
virtual int GetCtrlID() { return ctrlID; }
virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleToNeeded(int endStyleNeeded);
void NotifyChar(int ch);
void NotifySavePoint(bool isSavePoint);
void NotifyModifyAttempt();
virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyUpdateUI();
void NotifyPainted();
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
void NotifyNeedShown(int pos, int len);
void NotifyDwelling(Point pt, bool state);
void NotifyZoom();
void NotifyModifyAttempt(Document *document, void *userData);
void NotifySavePoint(Document *document, void *userData, bool atSavePoint);
void CheckModificationForWrap(DocModification mh);
void NotifyModified(Document *document, DocModification mh, void *userData);
void NotifyDeleted(Document *document, void *userData);
void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
enum { cmSame, cmUpper, cmLower } caseMap;
virtual std::string CaseMapString(const std::string &s, int caseMapping);
void ChangeCaseOfSelection(int caseMapping);
void LineTranspose();
void Duplicate(bool forLine);
virtual void CancelModes();
void NewLine();
void CursorUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
void ParaUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
int GetWhitespaceVisible();
void SetWhitespaceVisible(int view);
void Indent(bool forwards);
virtual CaseFolder *CaseFolderForEncoding();
long FindText(uptr_t wParam, sptr_t lParam);
void SearchAnchor();
long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
long SearchInTarget(const char *text, int length);
void GoToLine(int lineNo);
virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
char *CopyRange(int start, int end);
void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
void CopyRangeToClipboard(int start, int end);
void CopyText(int length, const char *text);
void SetDragPosition(SelectionPosition newPos);
virtual void DisplayCursor(Window::Cursor c);
virtual bool DragThreshold(Point ptStart, Point ptNow);
virtual void StartDrag();
void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
/** PositionInSelection returns true if position in selection. */
bool PositionInSelection(int pos);
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_);
void DwellEnd(bool mouseMoved);
void MouseLeave();
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
void ButtonMove(Point pt);
void ButtonUp(Point pt, unsigned int curTime, bool ctrl);
void Tick();
bool Idle();
virtual void SetTicking(bool on) = 0;
virtual bool SetIdle(bool) { return false; }
virtual void SetMouseCapture(bool on) = 0;
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
int PositionAfterArea(PRectangle rcArea);
void StyleToPositionInView(Position pos);
void IdleStyling();
virtual void QueueStyling(int upTo);
virtual bool PaintContains(PRectangle rc);
bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
void SetAnnotationHeights(int start, int end);
void SetDocPointer(Document *document);
void SetAnnotationVisible(int visible);
void Expand(int &line, bool doExpand);
void ToggleContraction(int line);
void EnsureLineVisible(int lineDoc, bool enforcePolicy);
int GetTag(char *tagValue, int tagNumber);
int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
bool PositionIsHotspot(int position);
bool PointIsHotspot(Point pt);
void SetHotSpotRange(Point *pt);
void GetHotSpotRange(int& hsStart, int& hsEnd);
int CodePage() const;
virtual bool ValidCodePage(int /* codePage */) const { return true; }
int WrapCount(int line);
void AddStyledText(char *buffer, int appendLength);
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
static const char *StringFromEOLMode(int eolMode);
static sptr_t StringResult(sptr_t lParam, const char *val);
public:
// Public so the COM thunks can access it.
bool IsUnicodeMode() const;
// Public so scintilla_send_message can use it.
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
// Public so scintilla_set_id can use it.
int ctrlID;
// Public so COM methods for drag and drop can set it.
int errorStatus;
friend class AutoSurface;
friend class SelectionLineIterator;
};
/**
* A smart pointer class to ensure Surfaces are set up and deleted correctly.
*/
class AutoSurface {
private:
Surface *surf;
public:
AutoSurface(Editor *ed) : surf(0) {
if (ed->wMain.GetID()) {
surf = Surface::Allocate();
if (surf) {
surf->Init(ed->wMain.GetID());
surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
surf->SetDBCSMode(ed->CodePage());
}
}
}
AutoSurface(SurfaceID sid, Editor *ed) : surf(0) {
if (ed->wMain.GetID()) {
surf = Surface::Allocate();
if (surf) {
surf->Init(sid, ed->wMain.GetID());
surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
surf->SetDBCSMode(ed->CodePage());
}
}
}
~AutoSurface() {
delete surf;
}
Surface *operator->() const {
return surf;
}
operator Surface *() const {
return surf;
}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,262 @@
// Scintilla source code edit control
/** @file ExternalLexer.cxx
** Support external lexers in DLLs.
**/
// Copyright 2001 Simon Steele <ss@pnotepad.org>, portions copyright Neil Hodgson.
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <string>
#include "Platform.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSet.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "KeyWords.h"
#include "ExternalLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
LexerManager *LexerManager::theInstance = NULL;
//------------------------------------------
//
// ExternalLexerModule
//
//------------------------------------------
char **WordListsToStrings(WordList *val[]) {
int dim = 0;
while (val[dim])
dim++;
char **wls = new char * [dim + 1];
for (int i = 0;i < dim;i++) {
std::string words;
words = "";
for (int n = 0; n < val[i]->len; n++) {
words += val[i]->words[n];
if (n != val[i]->len - 1)
words += " ";
}
wls[i] = new char[words.length() + 1];
strcpy(wls[i], words.c_str());
}
wls[dim] = 0;
return wls;
}
void DeleteWLStrings(char *strs[]) {
int dim = 0;
while (strs[dim]) {
delete strs[dim];
dim++;
}
delete [] strs;
}
void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const {
if (!fneLexer)
return ;
char **kwds = WordListsToStrings(keywordlists);
char *ps = styler.GetProperties();
// The accessor passed in is always a DocumentAccessor so this cast and the subsequent
// access will work. Can not use the stricter dynamic_cast as that requires RTTI.
DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
WindowID wID = da.GetWindow();
fneLexer(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
delete ps;
DeleteWLStrings(kwds);
}
void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const {
if (!fneFolder)
return ;
char **kwds = WordListsToStrings(keywordlists);
char *ps = styler.GetProperties();
// The accessor passed in is always a DocumentAccessor so this cast and the subsequent
// access will work. Can not use the stricter dynamic_cast as that requires RTTI.
DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
WindowID wID = da.GetWindow();
fneFolder(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
delete ps;
DeleteWLStrings(kwds);
}
void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
fneLexer = fLexer;
fneFolder = fFolder;
externalLanguage = index;
}
//------------------------------------------
//
// LexerLibrary
//
//------------------------------------------
LexerLibrary::LexerLibrary(const char* ModuleName) {
// Initialise some members...
first = NULL;
last = NULL;
// Load the DLL
lib = DynamicLibrary::Load(ModuleName);
if (lib->IsValid()) {
m_sModuleName = ModuleName;
//Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
if (GetLexerCount) {
ExternalLexerModule *lex;
LexerMinder *lm;
// Find functions in the DLL
GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
// Assign a buffer for the lexer name.
char lexname[100];
strcpy(lexname, "");
int nl = GetLexerCount();
for (int i = 0; i < nl; i++) {
GetLexerName(i, lexname, 100);
lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
// Create a LexerMinder so we don't leak the ExternalLexerModule...
lm = new LexerMinder;
lm->self = lex;
lm->next = NULL;
if (first != NULL) {
last->next = lm;
last = lm;
} else {
first = lm;
last = lm;
}
// The external lexer needs to know how to call into its DLL to
// do its lexing and folding, we tell it here. Folder may be null.
lex->SetExternal(Lexer, Folder, i);
}
}
}
next = NULL;
}
LexerLibrary::~LexerLibrary() {
Release();
delete lib;
}
void LexerLibrary::Release() {
//TODO maintain a list of lexers created, and delete them!
LexerMinder *lm;
LexerMinder *lmNext;
lm = first;
while (NULL != lm) {
lmNext = lm->next;
delete lm->self;
delete lm;
lm = lmNext;
}
first = NULL;
last = NULL;
}
//------------------------------------------
//
// LexerManager
//
//------------------------------------------
/// Return the single LexerManager instance...
LexerManager *LexerManager::GetInstance() {
if(!theInstance)
theInstance = new LexerManager;
return theInstance;
}
/// Delete any LexerManager instance...
void LexerManager::DeleteInstance() {
delete theInstance;
theInstance = NULL;
}
/// protected constructor - this is a singleton...
LexerManager::LexerManager() {
first = NULL;
last = NULL;
}
LexerManager::~LexerManager() {
Clear();
}
void LexerManager::Load(const char *path) {
LoadLexerLibrary(path);
}
void LexerManager::LoadLexerLibrary(const char *module) {
for (LexerLibrary *ll = first; ll; ll= ll->next) {
if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
return;
}
LexerLibrary *lib = new LexerLibrary(module);
if (NULL != first) {
last->next = lib;
last = lib;
} else {
first = lib;
last = lib;
}
}
void LexerManager::Clear() {
if (NULL != first) {
LexerLibrary *cur = first;
LexerLibrary *next;
while (cur) {
next = cur->next;
delete cur;
cur = next;
}
first = NULL;
last = NULL;
}
}
//------------------------------------------
//
// LexerManager
//
//------------------------------------------
LMMinder::~LMMinder() {
LexerManager::DeleteInstance();
}
LMMinder minder;

View File

@@ -0,0 +1,104 @@
// Scintilla source code edit control
/** @file ExternalLexer.h
** Support external lexers in DLLs.
**/
// Copyright 2001 Simon Steele <ss@pnotepad.org>, portions copyright Neil Hodgson.
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EXTERNALLEXER_H
#define EXTERNALLEXER_H
#if PLAT_WIN
#define EXT_LEXER_DECL __stdcall
#else
#define EXT_LEXER_DECL
#endif
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// External Lexer function definitions...
typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
char *words[], WindowID window, char *props);
typedef void (EXT_LEXER_DECL *ExtFoldFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
char *words[], WindowID window, char *props);
typedef void* (EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
typedef int (EXT_LEXER_DECL *GetLexerCountFn)();
typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);
//class DynamicLibrary;
/// Sub-class of LexerModule to use an external lexer.
class ExternalLexerModule : protected LexerModule {
protected:
ExtLexerFunction fneLexer;
ExtFoldFunction fneFolder;
int externalLanguage;
char name[100];
public:
ExternalLexerModule(int language_, LexerFunction fnLexer_,
const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){
strncpy(name, languageName_, sizeof(name));
name[sizeof(name)-1] = '\0';
languageName = name;
}
virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index);
};
/// LexerMinder points to an ExternalLexerModule - so we don't leak them.
class LexerMinder {
public:
ExternalLexerModule *self;
LexerMinder *next;
};
/// LexerLibrary exists for every External Lexer DLL, contains LexerMinders.
class LexerLibrary {
DynamicLibrary *lib;
LexerMinder *first;
LexerMinder *last;
public:
LexerLibrary(const char* ModuleName);
~LexerLibrary();
void Release();
LexerLibrary *next;
std::string m_sModuleName;
};
/// LexerManager manages external lexers, contains LexerLibrarys.
class LexerManager {
public:
~LexerManager();
static LexerManager *GetInstance();
static void DeleteInstance();
void Load(const char* path);
void Clear();
private:
LexerManager();
static LexerManager *theInstance;
void LoadLexerLibrary(const char* module);
LexerLibrary *first;
LexerLibrary *last;
};
class LMMinder {
public:
~LMMinder();
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,12 @@
// Scintilla source code edit control
/** @file FontQuality.h
** Definitions to control font anti-aliasing.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#define SC_EFF_QUALITY_MASK 0xF
#define SC_EFF_QUALITY_DEFAULT 0
#define SC_EFF_QUALITY_NON_ANTIALIASED 1
#define SC_EFF_QUALITY_ANTIALIASED 2
#define SC_EFF_QUALITY_LCD_OPTIMIZED 3

View File

@@ -0,0 +1,81 @@
// Scintilla source code edit control
/** @file Indicator.cxx
** Defines the style of indicators which are text decorations such as underlining.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include "Platform.h"
#include "Scintilla.h"
#include "Indicator.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) {
surface->PenColour(fore.allocated);
int ymid = (rc.bottom + rc.top) / 2;
if (style == INDIC_SQUIGGLE) {
surface->MoveTo(rc.left, rc.top);
int x = rc.left + 2;
int y = 2;
while (x < rc.right) {
surface->LineTo(x, rc.top + y);
x += 2;
y = 2 - y;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid);
int x = rc.left + 5;
while (x < rc.right) {
surface->LineTo(x, ymid);
surface->MoveTo(x-3, ymid);
surface->LineTo(x-3, ymid+2);
x++;
surface->MoveTo(x, ymid);
x += 5;
}
surface->LineTo(rc.right, ymid); // Finish the line
if (x - 3 <= rc.right) {
surface->MoveTo(x-3, ymid);
surface->LineTo(x-3, ymid+2);
}
} else if (style == INDIC_DIAGONAL) {
int x = rc.left;
while (x < rc.right) {
surface->MoveTo(x, rc.top+2);
int endX = x+3;
int endY = rc.top - 1;
if (endX > rc.right) {
endY += endX - rc.right;
endX = rc.right;
}
surface->LineTo(endX, endY);
x += 4;
}
} else if (style == INDIC_STRIKE) {
surface->MoveTo(rc.left, rc.top - 4);
surface->LineTo(rc.right, rc.top - 4);
} else if (style == INDIC_HIDDEN) {
// Draw nothing
} else if (style == INDIC_BOX) {
surface->MoveTo(rc.left, ymid+1);
surface->LineTo(rc.right, ymid+1);
surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1);
} else if (style == INDIC_ROUNDBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid);
}
}

View File

@@ -0,0 +1,32 @@
// Scintilla source code edit control
/** @file Indicator.h
** Defines the style of indicators which are text decorations such as underlining.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef INDICATOR_H
#define INDICATOR_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class Indicator {
public:
int style;
bool under;
ColourPair fore;
int fillAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
}
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,152 @@
// Scintilla source code edit control
/** @file KeyMap.cxx
** Defines a mapping between keystrokes and commands.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include "Platform.h"
#include "Scintilla.h"
#include "KeyMap.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
KeyMap::KeyMap() : kmap(0), len(0), alloc(0) {
for (int i = 0; MapDefault[i].key; i++) {
AssignCmdKey(MapDefault[i].key,
MapDefault[i].modifiers,
MapDefault[i].msg);
}
}
KeyMap::~KeyMap() {
Clear();
}
void KeyMap::Clear() {
delete []kmap;
kmap = 0;
len = 0;
alloc = 0;
}
void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) {
if ((len+1) >= alloc) {
KeyToCommand *ktcNew = new KeyToCommand[alloc + 5];
if (!ktcNew)
return;
for (int k = 0; k < len; k++)
ktcNew[k] = kmap[k];
alloc += 5;
delete []kmap;
kmap = ktcNew;
}
for (int keyIndex = 0; keyIndex < len; keyIndex++) {
if ((key == kmap[keyIndex].key) && (modifiers == kmap[keyIndex].modifiers)) {
kmap[keyIndex].msg = msg;
return;
}
}
kmap[len].key = key;
kmap[len].modifiers = modifiers;
kmap[len].msg = msg;
len++;
}
unsigned int KeyMap::Find(int key, int modifiers) {
for (int i = 0; i < len; i++) {
if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) {
return kmap[i].msg;
}
}
return 0;
}
const KeyToCommand KeyMap::MapDefault[] = {
{SCK_DOWN, SCI_NORM, SCI_LINEDOWN},
{SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
{SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND},
{SCK_UP, SCI_NORM, SCI_LINEUP},
{SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
{SCK_UP, SCI_CTRL, SCI_LINESCROLLUP},
{SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND},
{'[', SCI_CTRL, SCI_PARAUP},
{'[', SCI_CSHIFT, SCI_PARAUPEXTEND},
{']', SCI_CTRL, SCI_PARADOWN},
{']', SCI_CSHIFT, SCI_PARADOWNEXTEND},
{SCK_LEFT, SCI_NORM, SCI_CHARLEFT},
{SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_WORDLEFT},
{SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND},
{SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
{SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND},
{'/', SCI_CTRL, SCI_WORDPARTLEFT},
{'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND},
{'\\', SCI_CTRL, SCI_WORDPARTRIGHT},
{'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND},
{SCK_HOME, SCI_NORM, SCI_VCHOME},
{SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND},
{SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY},
// {SCK_HOME, SCI_ASHIFT, SCI_HOMEDISPLAYEXTEND},
{SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND},
{SCK_END, SCI_NORM, SCI_LINEEND},
{SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
{SCK_END, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_END, SCI_ALT, SCI_LINEENDDISPLAY},
// {SCK_END, SCI_ASHIFT, SCI_LINEENDDISPLAYEXTEND},
{SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND},
{SCK_PRIOR, SCI_NORM, SCI_PAGEUP},
{SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
{SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND},
{SCK_NEXT, SCI_NORM, SCI_PAGEDOWN},
{SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND},
{SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND},
{SCK_DELETE, SCI_NORM, SCI_CLEAR},
{SCK_DELETE, SCI_SHIFT, SCI_CUT},
{SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT},
{SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT},
{SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE},
{SCK_INSERT, SCI_SHIFT, SCI_PASTE},
{SCK_INSERT, SCI_CTRL, SCI_COPY},
{SCK_ESCAPE, SCI_NORM, SCI_CANCEL},
{SCK_BACK, SCI_NORM, SCI_DELETEBACK},
{SCK_BACK, SCI_SHIFT, SCI_DELETEBACK},
{SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT},
{SCK_BACK, SCI_ALT, SCI_UNDO},
{SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT},
{'Z', SCI_CTRL, SCI_UNDO},
{'Y', SCI_CTRL, SCI_REDO},
{'X', SCI_CTRL, SCI_CUT},
{'C', SCI_CTRL, SCI_COPY},
{'V', SCI_CTRL, SCI_PASTE},
{'A', SCI_CTRL, SCI_SELECTALL},
{SCK_TAB, SCI_NORM, SCI_TAB},
{SCK_TAB, SCI_SHIFT, SCI_BACKTAB},
{SCK_RETURN, SCI_NORM, SCI_NEWLINE},
{SCK_RETURN, SCI_SHIFT, SCI_NEWLINE},
{SCK_ADD, SCI_CTRL, SCI_ZOOMIN},
{SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
{SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM},
//'L', SCI_CTRL, SCI_FORMFEED,
{'L', SCI_CTRL, SCI_LINECUT},
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},
{'T', SCI_CTRL, SCI_LINETRANSPOSE},
{'D', SCI_CTRL, SCI_SELECTIONDUPLICATE},
{'U', SCI_CTRL, SCI_LOWERCASE},
{'U', SCI_CSHIFT, SCI_UPPERCASE},
{0,0,0},
};

View File

@@ -0,0 +1,51 @@
// Scintilla source code edit control
/** @file KeyMap.h
** Defines a mapping between keystrokes and commands.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef KEYTOCOMMAND_H
#define KEYTOCOMMAND_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
#define SCI_NORM 0
#define SCI_SHIFT SCMOD_SHIFT
#define SCI_CTRL SCMOD_CTRL
#define SCI_ALT SCMOD_ALT
#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT)
#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT)
/**
*/
class KeyToCommand {
public:
int key;
int modifiers;
unsigned int msg;
};
/**
*/
class KeyMap {
KeyToCommand *kmap;
int len;
int alloc;
static const KeyToCommand MapDefault[];
public:
KeyMap();
~KeyMap();
void Clear();
void AssignCmdKey(int key, int modifiers, unsigned int msg);
unsigned int Find(int key, int modifiers); // 0 returned on failure
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@@ -0,0 +1,441 @@
// Scintilla source code edit control
/** @file KeyWords.cxx
** Colourise for particular languages.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/**
* Creates an array that points into each word in the string and puts \0 terminators
* after each word.
*/
static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
int prev = '\n';
int words = 0;
// For rapid determination of whether a character is a separator, build
// a look up table.
bool wordSeparator[256];
for (int i=0;i<256; i++) {
wordSeparator[i] = false;
}
wordSeparator['\r'] = true;
wordSeparator['\n'] = true;
if (!onlyLineEnds) {
wordSeparator[' '] = true;
wordSeparator['\t'] = true;
}
for (int j = 0; wordlist[j]; j++) {
int curr = static_cast<unsigned char>(wordlist[j]);
if (!wordSeparator[curr] && wordSeparator[prev])
words++;
prev = curr;
}
char **keywords = new char *[words + 1];
if (keywords) {
words = 0;
prev = '\0';
size_t slen = strlen(wordlist);
for (size_t k = 0; k < slen; k++) {
if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
if (!prev) {
keywords[words] = &wordlist[k];
words++;
}
} else {
wordlist[k] = '\0';
}
prev = wordlist[k];
}
keywords[words] = &wordlist[slen];
*len = words;
} else {
*len = 0;
}
return keywords;
}
void WordList::Clear() {
if (words) {
delete []list;
delete []words;
}
words = 0;
list = 0;
len = 0;
sorted = false;
}
void WordList::Set(const char *s) {
list = new char[strlen(s) + 1];
strcpy(list, s);
sorted = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
}
extern "C" int cmpString(const void *a1, const void *a2) {
// Can't work out the correct incantation to use modern casts here
return strcmp(*(char**)(a1), *(char**)(a2));
}
static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
cmpString);
}
bool WordList::InList(const char *s) {
if (0 == words)
return false;
if (!sorted) {
sorted = true;
SortWordList(words, len);
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while ((unsigned char)words[j][0] == firstChar) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a && !*b)
return true;
}
j++;
}
}
j = starts['^'];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
/** similar to InList, but word s can be a substring of keyword.
* eg. the keyword define is defined as def~ine. This means the word must start
* with def to be a keyword, but also defi, defin and define are valid.
* The marker is ~ in this case.
*/
bool WordList::InListAbbreviated(const char *s, const char marker) {
if (0 == words)
return false;
if (!sorted) {
sorted = true;
SortWordList(words, len);
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {
isSubword = true;
start++;
}
if (s[1] == words[j][start]) {
const char *a = words[j] + start;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
if (*a == marker) {
isSubword = true;
a++;
}
b++;
}
if ((!*a || isSubword) && !*b)
return true;
}
j++;
}
}
j = starts['^'];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
const LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
LexerModule::LexerModule(int language_,
LexerFunction fnLexer_,
const char *languageName_,
LexerFunction fnFolder_,
const char * const wordListDescriptions_[],
int styleBits_) :
language(language_),
fnLexer(fnLexer_),
fnFolder(fnFolder_),
wordListDescriptions(wordListDescriptions_),
styleBits(styleBits_),
languageName(languageName_) {
next = base;
base = this;
if (language == SCLEX_AUTOMATIC) {
language = nextLanguage;
nextLanguage++;
}
}
int LexerModule::GetNumWordLists() const {
if (wordListDescriptions == NULL) {
return -1;
} else {
int numWordLists = 0;
while (wordListDescriptions[numWordLists]) {
++numWordLists;
}
return numWordLists;
}
}
const char *LexerModule::GetWordListDescription(int index) const {
static const char *emptyStr = "";
PLATFORM_ASSERT(index < GetNumWordLists());
if (index >= GetNumWordLists()) {
return emptyStr;
} else {
return wordListDescriptions[index];
}
}
int LexerModule::GetStyleBitsNeeded() const {
return styleBits;
}
const LexerModule *LexerModule::Find(int language) {
const LexerModule *lm = base;
while (lm) {
if (lm->language == language) {
return lm;
}
lm = lm->next;
}
return 0;
}
const LexerModule *LexerModule::Find(const char *languageName) {
if (languageName) {
const LexerModule *lm = base;
while (lm) {
if (lm->languageName && 0 == strcmp(lm->languageName, languageName)) {
return lm;
}
lm = lm->next;
}
}
return 0;
}
void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const {
if (fnLexer)
fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
}
void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const {
if (fnFolder) {
int lineCurrent = styler.GetLine(startPos);
// Move back one line in case deletion wrecked current line fold state
if (lineCurrent > 0) {
lineCurrent--;
int newStartPos = styler.LineStart(lineCurrent);
lengthDoc += startPos - newStartPos;
startPos = newStartPos;
initStyle = 0;
if (startPos > 0) {
initStyle = styler.StyleAt(startPos - 1);
}
}
fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
}
}
// Alternative historical name for Scintilla_LinkLexers
int wxForceScintillaLexers(void) {
return Scintilla_LinkLexers();
}
// To add or remove a lexer, add or remove its file and run LexGen.py.
// Force a reference to all of the Scintilla lexers so that the linker will
// not remove the code of the lexers.
int Scintilla_LinkLexers() {
static int forcer = 0;
// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
#define LINK_LEXER(lexer) extern LexerModule lexer; forcer += lexer.GetLanguage();
//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
LINK_LEXER(lmAbaqus);
LINK_LEXER(lmAda);
LINK_LEXER(lmAns1);
LINK_LEXER(lmAPDL);
LINK_LEXER(lmAsm);
LINK_LEXER(lmASY);
LINK_LEXER(lmAU3);
LINK_LEXER(lmAVE);
LINK_LEXER(lmBaan);
LINK_LEXER(lmBash);
LINK_LEXER(lmBatch);
LINK_LEXER(lmBlitzBasic);
LINK_LEXER(lmBullant);
LINK_LEXER(lmCaml);
LINK_LEXER(lmClw);
LINK_LEXER(lmClwNoCase);
LINK_LEXER(lmCmake);
LINK_LEXER(lmCOBOL);
LINK_LEXER(lmConf);
LINK_LEXER(lmCPP);
LINK_LEXER(lmCPPNoCase);
LINK_LEXER(lmCsound);
LINK_LEXER(lmCss);
LINK_LEXER(lmD);
LINK_LEXER(lmDiff);
LINK_LEXER(lmEiffel);
LINK_LEXER(lmEiffelkw);
LINK_LEXER(lmErlang);
LINK_LEXER(lmErrorList);
LINK_LEXER(lmESCRIPT);
LINK_LEXER(lmF77);
LINK_LEXER(lmFlagShip);
LINK_LEXER(lmForth);
LINK_LEXER(lmFortran);
LINK_LEXER(lmFreeBasic);
LINK_LEXER(lmGAP);
LINK_LEXER(lmGui4Cli);
LINK_LEXER(lmHaskell);
LINK_LEXER(lmHTML);
LINK_LEXER(lmInno);
LINK_LEXER(lmKix);
LINK_LEXER(lmLatex);
LINK_LEXER(lmLISP);
LINK_LEXER(lmLot);
LINK_LEXER(lmLout);
LINK_LEXER(lmLua);
LINK_LEXER(lmMagikSF);
LINK_LEXER(lmMake);
LINK_LEXER(lmMarkdown);
LINK_LEXER(lmMatlab);
LINK_LEXER(lmMETAPOST);
LINK_LEXER(lmMMIXAL);
LINK_LEXER(lmMSSQL);
LINK_LEXER(lmMySQL);
LINK_LEXER(lmNimrod);
LINK_LEXER(lmNncrontab);
LINK_LEXER(lmNsis);
LINK_LEXER(lmNull);
LINK_LEXER(lmOctave);
LINK_LEXER(lmOpal);
LINK_LEXER(lmPascal);
LINK_LEXER(lmPB);
LINK_LEXER(lmPerl);
LINK_LEXER(lmPHPSCRIPT);
LINK_LEXER(lmPLM);
LINK_LEXER(lmPo);
LINK_LEXER(lmPOV);
LINK_LEXER(lmPowerPro);
LINK_LEXER(lmPowerShell);
LINK_LEXER(lmProgress);
LINK_LEXER(lmProps);
LINK_LEXER(lmPS);
LINK_LEXER(lmPureBasic);
LINK_LEXER(lmPython);
LINK_LEXER(lmR);
LINK_LEXER(lmREBOL);
LINK_LEXER(lmRuby);
LINK_LEXER(lmScriptol);
LINK_LEXER(lmSmalltalk);
LINK_LEXER(lmSML);
LINK_LEXER(lmSorc);
LINK_LEXER(lmSpecman);
LINK_LEXER(lmSpice);
LINK_LEXER(lmSQL);
LINK_LEXER(lmTACL);
LINK_LEXER(lmTADS3);
LINK_LEXER(lmTAL);
LINK_LEXER(lmTCL);
LINK_LEXER(lmTeX);
LINK_LEXER(lmVB);
LINK_LEXER(lmVBScript);
LINK_LEXER(lmVerilog);
LINK_LEXER(lmVHDL);
LINK_LEXER(lmXML);
LINK_LEXER(lmYAML);
//ERAN - START
LINK_LEXER(lmGcc);
LINK_LEXER(lmFif);
LINK_LEXER(lmSvn);
LINK_LEXER(lmCppCheck);
//ERAN - END
// EPOCH - START
LINK_LEXER(lmAltaRica);
LINK_LEXER(lmPrism);
// EPOCH - END
//--Autogenerated -- end of automatically generated section
return 1;
}

View File

@@ -0,0 +1,256 @@
// Scintilla source code edit control
/** @file LexAPDL.cxx
** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
** By Hadar Raz.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || ch == '_'));
}
static inline bool IsAnOperator(char ch) {
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
ch == '$' || ch == ':' || ch == '%')
return true;
return false;
}
static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
int stringStart = ' ';
WordList &processors = *keywordlists[0];
WordList &commands = *keywordlists[1];
WordList &slashcommands = *keywordlists[2];
WordList &starcommands = *keywordlists[3];
WordList &arguments = *keywordlists[4];
WordList &functions = *keywordlists[5];
// Do not leak onto next line
initStyle = SCE_APDL_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
// Determine if the current state should terminate.
if (sc.state == SCE_APDL_NUMBER) {
if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
sc.SetState(SCE_APDL_DEFAULT);
}
} else if (sc.state == SCE_APDL_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_APDL_DEFAULT);
}
} else if (sc.state == SCE_APDL_COMMENTBLOCK) {
if (sc.atLineEnd) {
if (sc.ch == '\r') {
sc.Forward();
}
sc.ForwardSetState(SCE_APDL_DEFAULT);
}
} else if (sc.state == SCE_APDL_STRING) {
if (sc.atLineEnd) {
sc.SetState(SCE_APDL_DEFAULT);
} else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
sc.ForwardSetState(SCE_APDL_DEFAULT);
}
} else if (sc.state == SCE_APDL_WORD) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (processors.InList(s)) {
sc.ChangeState(SCE_APDL_PROCESSOR);
} else if (slashcommands.InList(s)) {
sc.ChangeState(SCE_APDL_SLASHCOMMAND);
} else if (starcommands.InList(s)) {
sc.ChangeState(SCE_APDL_STARCOMMAND);
} else if (commands.InList(s)) {
sc.ChangeState(SCE_APDL_COMMAND);
} else if (arguments.InList(s)) {
sc.ChangeState(SCE_APDL_ARGUMENT);
} else if (functions.InList(s)) {
sc.ChangeState(SCE_APDL_FUNCTION);
}
sc.SetState(SCE_APDL_DEFAULT);
}
} else if (sc.state == SCE_APDL_OPERATOR) {
if (!IsAnOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_APDL_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_APDL_DEFAULT) {
if (sc.ch == '!' && sc.chNext == '!') {
sc.SetState(SCE_APDL_COMMENTBLOCK);
} else if (sc.ch == '!') {
sc.SetState(SCE_APDL_COMMENT);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_APDL_NUMBER);
} else if (sc.ch == '\'' || sc.ch == '\"') {
sc.SetState(SCE_APDL_STRING);
stringStart = sc.ch;
} else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
sc.SetState(SCE_APDL_WORD);
} else if (IsAnOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_APDL_OPERATOR);
}
}
}
sc.Complete();
}
//------------------------------------------------------------------------------
// 06-27-07 Sergio Lucato
// - Included code folding for Ansys APDL lexer
// - Copyied from LexBasic.cxx and modified for APDL
//------------------------------------------------------------------------------
/* Bits:
* 1 - whitespace
* 2 - operator
* 4 - identifier
* 8 - decimal digit
* 16 - hex digit
* 32 - bin digit
*/
static int character_classification[128] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
};
static bool IsSpace(int c) {
return c < 128 && (character_classification[c] & 1);
}
static bool IsIdentifier(int c) {
return c < 128 && (character_classification[c] & 4);
}
static int LowerCase(int c)
{
if (c >= 'A' && c <= 'Z')
return 'a' + c - 'A';
return c;
}
static int CheckAPDLFoldPoint(char const *token, int &level) {
if (!strcmp(token, "*if") ||
!strcmp(token, "*do") ||
!strcmp(token, "*dowhile") ) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "*endif") ||
!strcmp(token, "*enddo") ) {
return -1;
}
return 0;
}
static void FoldAPDLDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
int line = styler.GetLine(startPos);
int level = styler.LevelAt(line);
int go = 0, done = 0;
int endPos = startPos + length;
char word[256];
int wordlen = 0;
int i;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
// Scan for tokens at the start of the line (they may include
// whitespace, for tokens like "End Function"
for (i = startPos; i < endPos; i++) {
int c = styler.SafeGetCharAt(i);
if (!done && !go) {
if (wordlen) { // are we scanning a token already?
word[wordlen] = static_cast<char>(LowerCase(c));
if (!IsIdentifier(c)) { // done with token
word[wordlen] = '\0';
go = CheckAPDLFoldPoint(word, level);
if (!go) {
// Treat any whitespace as single blank, for
// things like "End Function".
if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
word[wordlen] = ' ';
if (wordlen < 255)
wordlen++;
}
else // done with this line
done = 1;
}
} else if (wordlen < 255) {
wordlen++;
}
} else { // start scanning at first non-whitespace character
if (!IsSpace(c)) {
if (IsIdentifier(c)) {
word[0] = static_cast<char>(LowerCase(c));
wordlen = 1;
} else // done with this line
done = 1;
}
}
}
if (c == '\n') { // line end
if (!done && wordlen == 0 && foldCompact) // line was only space
level |= SC_FOLDLEVELWHITEFLAG;
if (level != styler.LevelAt(line))
styler.SetLevel(line, level);
level += go;
line++;
// reset state
wordlen = 0;
level &= ~SC_FOLDLEVELHEADERFLAG;
level &= ~SC_FOLDLEVELWHITEFLAG;
go = 0;
done = 0;
}
}
}
static const char * const apdlWordListDesc[] = {
"processors",
"commands",
"slashommands",
"starcommands",
"arguments",
"functions",
0
};
LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);

View File

@@ -0,0 +1,270 @@
// Scintilla source code edit control
//Author: instanton (email: soft_share<at>126<dot>com)
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
int visibleChars = 0;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart) {
if (sc.state == SCE_ASY_STRING) {
sc.SetState(SCE_ASY_STRING);
}
visibleChars = 0;
}
if (sc.ch == '\\') {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
// continuationLine = true;
continue;
}
}
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_ASY_OPERATOR:
sc.SetState(SCE_ASY_DEFAULT);
break;
case SCE_ASY_NUMBER:
if (!setWord.Contains(sc.ch)) {
sc.SetState(SCE_ASY_DEFAULT);
}
break;
case SCE_ASY_IDENTIFIER:
if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
char s[1000];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_ASY_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_ASY_WORD2);
}
sc.SetState(SCE_ASY_DEFAULT);
}
break;
case SCE_ASY_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_ASY_DEFAULT);
}
break;
case SCE_ASY_COMMENTLINE:
if (sc.atLineStart) {
sc.SetState(SCE_ASY_DEFAULT);
}
break;
case SCE_ASY_STRING:
if (sc.atLineEnd) {
sc.ChangeState(SCE_ASY_STRINGEOL);
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_ASY_DEFAULT);
}
break;
case SCE_ASY_CHARACTER:
if (sc.atLineEnd) {
sc.ChangeState(SCE_ASY_STRINGEOL);
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_ASY_DEFAULT);
}
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_ASY_DEFAULT) {
if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
sc.SetState(SCE_ASY_IDENTIFIER);
} else if (sc.Match('/', '*')) {
sc.SetState(SCE_ASY_COMMENT);
sc.Forward(); //
} else if (sc.Match('/', '/')) {
sc.SetState(SCE_ASY_COMMENTLINE);
} else if (sc.ch == '\"') {
sc.SetState(SCE_ASY_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_ASY_CHARACTER);
} else if (sc.ch == '#' && visibleChars == 0) {
do {
sc.Forward();
} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
if (sc.atLineEnd) {
sc.SetState(SCE_ASY_DEFAULT);
}
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_ASY_OPERATOR);
}
}
}
sc.Complete();
}
static bool IsAsyCommentStyle(int style) {
return style == SCE_ASY_COMMENT;
}
static inline bool isASYidentifier(int ch) {
return
((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ;
}
static int ParseASYWord(unsigned int pos, Accessor &styler, char *word)
{
int length=0;
char ch=styler.SafeGetCharAt(pos);
*word=0;
while(isASYidentifier(ch) && length<100){
word[length]=ch;
length++;
ch=styler.SafeGetCharAt(pos+length);
}
word[length]=0;
return length;
}
static bool IsASYDrawingLine(int line, Accessor &styler) {
int pos = styler.LineStart(line);
int eol_pos = styler.LineStart(line + 1) - 1;
int startpos = pos;
char buffer[100]="";
while (startpos<eol_pos){
char ch = styler[startpos];
ParseASYWord(startpos,styler,buffer);
bool drawcommands = strncmp(buffer,"draw",4)==0||
strncmp(buffer,"pair",4)==0||strncmp(buffer,"label",5)==0;
if (!drawcommands && ch!=' ') return false;
else if (drawcommands) return true;
startpos++;
}
return false;
}
static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment && IsAsyCommentStyle(style)) {
if (!IsAsyCommentStyle(stylePrev) && (stylePrev != SCE_ASY_COMMENTLINEDOC)) {
levelNext++;
} else if (!IsAsyCommentStyle(styleNext) && (styleNext != SCE_ASY_COMMENTLINEDOC) && !atEOL) {
levelNext--;
}
}
if (style == SCE_ASY_OPERATOR) {
if (ch == '{') {
if (levelMinCurrent > levelNext) {
levelMinCurrent = levelNext;
}
levelNext++;
} else if (ch == '}') {
levelNext--;
}
}
if (atEOL && IsASYDrawingLine(lineCurrent, styler)){
if (lineCurrent==0 && IsASYDrawingLine(lineCurrent + 1, styler))
levelNext++;
else if (lineCurrent!=0 && !IsASYDrawingLine(lineCurrent - 1, styler)
&& IsASYDrawingLine(lineCurrent + 1, styler)
)
levelNext++;
else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&
!IsASYDrawingLine(lineCurrent+1, styler))
levelNext--;
}
if (atEOL) {
int levelUse = levelCurrent;
if (foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
visibleChars = 0;
}
if (!IsASpace(ch))
visibleChars++;
}
}
static const char * const asyWordLists[] = {
"Primary keywords and identifiers",
"Secondary keywords and identifiers",
0,
};
LexerModule lmASY(SCLEX_ASYMPTOTE, ColouriseAsyDoc, "asy", FoldAsyDoc, asyWordLists);

View File

@@ -0,0 +1,907 @@
// Scintilla source code edit control
// @file LexAU3.cxx
// Lexer for AutoIt3 http://www.hiddensoft.com/autoit3
// by Jos van der Zande, jvdzande@yahoo.com
//
// Changes:
// March 28, 2004 - Added the standard Folding code
// April 21, 2004 - Added Preprosessor Table + Syntax Highlighting
// Fixed Number highlighting
// Changed default isoperator to IsAOperator to have a better match to AutoIt3
// Fixed "#comments_start" -> "#comments-start"
// Fixed "#comments_end" -> "#comments-end"
// Fixed Sendkeys in Strings when not terminated with }
// Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
// Added logic for #include <xyz.au3> to treat the <> as string
// Added underscore to IsAOperator.
// May 17, 2004 - Changed the folding logic from indent to keyword folding.
// Added Folding logic for blocks of single-commentlines or commentblock.
// triggered by: fold.comment=1
// Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1
// Added Special for #region - #endregion syntax highlight and folding.
// May 30, 2004 - Fixed issue with continuation lines on If statements.
// June 5, 2004 - Added comma to Operators for better readability.
// Added fold.compact support set with fold.compact=1
// Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
// it will now only happen when fold.comment=2.
// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
// Typed Characters now show as "default" till they match any table.
// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
// Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
// Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
// Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator.
// Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account
// - Added folding support for With...EndWith
// - Added support for a DOT in variable names
// - Fixed Underscore in CommentBlock
// May 23, 2005 - Fixed the SentKey lexing in case of a missing }
// Aug 11, 2005 - Fixed possible bug with s_save length > 100.
// Aug 23, 2005 - Added Switch/endswitch support to the folding logic.
// Sep 27, 2005 - Fixed the SentKey lexing logic in case of multiple sentkeys.
// Mar 12, 2006 - Fixed issue with <> coloring as String in stead of Operator in rare occasions.
// Apr 8, 2006 - Added support for AutoIt3 Standard UDF library (SCE_AU3_UDF)
// Mar 9, 2007 - Fixed bug with + following a String getting the wrong Color.
// Jun 20, 2007 - Fixed Commentblock issue when LF's are used as EOL.
// Jul 26, 2007 - Fixed #endregion undetected bug.
//
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Scintilla source code edit control
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsTypeCharacter(const int ch)
{
return ch == '$';
}
static inline bool IsAWordChar(const int ch)
{
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAWordStart(const int ch)
{
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
}
static inline bool IsAOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' ||
ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' )
return true;
return false;
}
///////////////////////////////////////////////////////////////////////////////
// GetSendKey() filters the portion before and after a/multiple space(s)
// and return the first portion to be looked-up in the table
// also check if the second portion is valid... (up,down.on.off,toggle or a number)
///////////////////////////////////////////////////////////////////////////////
static int GetSendKey(const char *szLine, char *szKey)
{
int nFlag = 0;
int nStartFound = 0;
int nKeyPos = 0;
int nSpecPos= 0;
int nSpecNum= 1;
int nPos = 0;
char cTemp;
char szSpecial[100];
// split the portion of the sendkey in the part before and after the spaces
while ( ( (cTemp = szLine[nPos]) != '\0'))
{
// skip leading Ctrl/Shift/Alt state
if (cTemp == '{') {
nStartFound = 1;
}
//
if (nStartFound == 1) {
if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
{
nFlag = 1;
// Add } to the end of the first bit for table lookup later.
szKey[nKeyPos++] = '}';
}
else if (cTemp == ' ')
{
// skip other spaces
}
else if (nFlag == 0)
{
// save first portion into var till space or } is hit
szKey[nKeyPos++] = cTemp;
}
else if ((nFlag == 1) && (cTemp != '}'))
{
// Save second portion into var...
szSpecial[nSpecPos++] = cTemp;
// check if Second portion is all numbers for repeat fuction
if (isdigit(cTemp) == false) {nSpecNum = 0;}
}
}
nPos++; // skip to next char
} // End While
// Check if the second portion is either a number or one of these keywords
szKey[nKeyPos] = '\0';
szSpecial[nSpecPos] = '\0';
if (strcmp(szSpecial,"down")== 0 || strcmp(szSpecial,"up")== 0 ||
strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 ||
strcmp(szSpecial,"toggle")== 0 || nSpecNum == 1 )
{
nFlag = 0;
}
else
{
nFlag = 1;
}
return nFlag; // 1 is bad, 0 is good
} // GetSendKey()
//
// Routine to check the last "none comment" character on a line to see if its a continuation
//
static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
{
int nsPos = styler.LineStart(szLine);
int nePos = styler.LineStart(szLine+1) - 2;
//int stylech = styler.StyleAt(nsPos);
while (nsPos < nePos)
{
//stylech = styler.StyleAt(nePos);
int stylech = styler.StyleAt(nsPos);
if (!(stylech == SCE_AU3_COMMENT)) {
char ch = styler.SafeGetCharAt(nePos);
if (!isspacechar(ch)) {
if (ch == '_')
return true;
else
return false;
}
}
nePos--; // skip to next char
} // End While
return false;
} // IsContinuationLine()
//
// syntax highlighting logic
static void ColouriseAU3Doc(unsigned int startPos,
int length, int initStyle,
WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
WordList &keywords7 = *keywordlists[6];
WordList &keywords8 = *keywordlists[7];
// find the first previous line without continuation character at the end
int lineCurrent = styler.GetLine(startPos);
int s_startPos = startPos;
// When not inside a Block comment: find First line without _
if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
(lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent); // get start position
initStyle = 0; // reset the start style to 0
}
}
// Set the new length to include it from the start and set the start position
length = length + s_startPos - startPos; // correct the total length to process
styler.StartAt(startPos);
StyleContext sc(startPos, length, initStyle, styler);
char si; // string indicator "=1 '=2
char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
char ci; // comment indicator 0=not linecomment(;)
char s_save[100];
si=0;
ni=0;
ci=0;
//$$$
for (; sc.More(); sc.Forward()) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
// **********************************************
// save the total current word for eof processing
if (IsAWordChar(sc.ch) || sc.ch == '}')
{
strcpy(s_save,s);
int tp = strlen(s_save);
if (tp < 99) {
s_save[tp] = static_cast<char>(tolower(sc.ch));
s_save[tp+1] = '\0';
}
}
// **********************************************
//
switch (sc.state)
{
case SCE_AU3_COMMENTBLOCK:
{
//Reset at line end
if (sc.atLineEnd) {
ci=0;
if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
if (sc.atLineEnd)
sc.SetState(SCE_AU3_DEFAULT);
else
sc.SetState(SCE_AU3_COMMENTBLOCK);
}
break;
}
//skip rest of line when a ; is encountered
if (sc.chPrev == ';') {
ci=2;
sc.SetState(SCE_AU3_COMMENTBLOCK);
}
// skip rest of the line
if (ci==2)
break;
// check when first character is detected on the line
if (ci==0) {
if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
ci=1;
sc.SetState(SCE_AU3_COMMENTBLOCK);
}
break;
}
if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line
else
ci=2; // line doesn't begin with #CE so skip the rest of the line
}
break;
}
case SCE_AU3_COMMENT:
{
if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
break;
}
case SCE_AU3_OPERATOR:
{
// check if its a COMobject
if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
sc.SetState(SCE_AU3_COMOBJ);
}
else {
sc.SetState(SCE_AU3_DEFAULT);
}
break;
}
case SCE_AU3_SPECIAL:
{
if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
break;
}
case SCE_AU3_KEYWORD:
{
if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0))))
{
if (!IsTypeCharacter(sc.ch))
{
if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 )
{
sc.ChangeState(SCE_AU3_COMMENTBLOCK);
sc.SetState(SCE_AU3_COMMENTBLOCK);
break;
}
else if (keywords.InList(s)) {
sc.ChangeState(SCE_AU3_KEYWORD);
sc.SetState(SCE_AU3_DEFAULT);
}
else if (keywords2.InList(s)) {
sc.ChangeState(SCE_AU3_FUNCTION);
sc.SetState(SCE_AU3_DEFAULT);
}
else if (keywords3.InList(s)) {
sc.ChangeState(SCE_AU3_MACRO);
sc.SetState(SCE_AU3_DEFAULT);
}
else if (keywords5.InList(s)) {
sc.ChangeState(SCE_AU3_PREPROCESSOR);
sc.SetState(SCE_AU3_DEFAULT);
if (strcmp(s, "#include")== 0)
{
si = 3; // use to determine string start for #inlude <>
}
}
else if (keywords6.InList(s)) {
sc.ChangeState(SCE_AU3_SPECIAL);
sc.SetState(SCE_AU3_SPECIAL);
}
else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
sc.ChangeState(SCE_AU3_EXPAND);
sc.SetState(SCE_AU3_DEFAULT);
}
else if (keywords8.InList(s)) {
sc.ChangeState(SCE_AU3_UDF);
sc.SetState(SCE_AU3_DEFAULT);
}
else if (strcmp(s, "_") == 0) {
sc.ChangeState(SCE_AU3_OPERATOR);
sc.SetState(SCE_AU3_DEFAULT);
}
else if (!IsAWordChar(sc.ch)) {
sc.ChangeState(SCE_AU3_DEFAULT);
sc.SetState(SCE_AU3_DEFAULT);
}
}
}
if (sc.atLineEnd) {
sc.SetState(SCE_AU3_DEFAULT);}
break;
}
case SCE_AU3_NUMBER:
{
// Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
//
// test for Hex notation
if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
{
ni = 2;
break;
}
// test for E notation
if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
{
ni = 3;
break;
}
// Allow Hex characters inside hex numeric strings
if ((ni == 2) &&
(sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
{
break;
}
// test for 1 dec point only
if (sc.ch == '.')
{
if (ni==0)
{
ni=1;
}
else
{
ni=9;
}
break;
}
// end of numeric string ?
if (!(IsADigit(sc.ch)))
{
if (ni==9)
{
sc.ChangeState(SCE_AU3_DEFAULT);
}
sc.SetState(SCE_AU3_DEFAULT);
}
break;
}
case SCE_AU3_VARIABLE:
{
// Check if its a COMObject
if (sc.ch == '.' && !IsADigit(sc.chNext)) {
sc.SetState(SCE_AU3_OPERATOR);
}
else if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_AU3_DEFAULT);
}
break;
}
case SCE_AU3_COMOBJ:
{
if (!(IsAWordChar(sc.ch))) {
sc.SetState(SCE_AU3_DEFAULT);
}
break;
}
case SCE_AU3_STRING:
{
// check for " to end a double qouted string or
// check for ' to end a single qouted string
if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
{
sc.ForwardSetState(SCE_AU3_DEFAULT);
si=0;
break;
}
if (sc.atLineEnd)
{
si=0;
// at line end and not found a continuation char then reset to default
int lineCurrent = styler.GetLine(sc.currentPos);
if (!IsContinuationLine(lineCurrent,styler))
{
sc.SetState(SCE_AU3_DEFAULT);
break;
}
}
// find Sendkeys in a STRING
if (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) {
sc.SetState(SCE_AU3_SENT);}
break;
}
case SCE_AU3_SENT:
{
// Send key string ended
if (sc.chPrev == '}' && sc.ch != '}')
{
// set color to SENDKEY when valid sendkey .. else set back to regular string
char sk[100];
// split {111 222} and return {111} and check if 222 is valid.
// if return code = 1 then invalid 222 so must be string
if (GetSendKey(s,sk))
{
sc.ChangeState(SCE_AU3_STRING);
}
// if single char between {?} then its ok as sendkey for a single character
else if (strlen(sk) == 3)
{
sc.ChangeState(SCE_AU3_SENT);
}
// if sendkey {111} is in table then ok as sendkey
else if (keywords4.InList(sk))
{
sc.ChangeState(SCE_AU3_SENT);
}
else
{
sc.ChangeState(SCE_AU3_STRING);
}
sc.SetState(SCE_AU3_STRING);
}
else
{
// check if the start is a valid SendKey start
int nPos = 0;
int nState = 1;
char cTemp;
while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
{
if (cTemp == '{' && nState == 1)
{
nState = 2;
}
if (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' ))
{
nState = 0;
}
nPos++;
}
//Verify characters infront of { ... if not assume regular string
if (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) {
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_STRING);
}
// If invalid character found then assume its a regular string
if (nState == 0) {
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_STRING);
}
}
// check if next portion is again a sendkey
if (sc.atLineEnd)
{
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_DEFAULT);
si = 0; // reset string indicator
}
//* check in next characters following a sentkey are again a sent key
// Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{}
if (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) {
sc.SetState(SCE_AU3_SENT);}
// check to see if the string ended...
// Sendkey string isn't complete but the string ended....
if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\''))
{
sc.ChangeState(SCE_AU3_STRING);
sc.ForwardSetState(SCE_AU3_DEFAULT);
}
break;
}
} //switch (sc.state)
// Determine if a new state should be entered:
if (sc.state == SCE_AU3_DEFAULT)
{
if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
//else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
else if (sc.ch == '\"') {
sc.SetState(SCE_AU3_STRING);
si = 1; }
else if (sc.ch == '\'') {
sc.SetState(SCE_AU3_STRING);
si = 2; }
else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
{
sc.SetState(SCE_AU3_NUMBER);
ni = 0;
}
else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
}
} //for (; sc.More(); sc.Forward())
//*************************************
// Colourize the last word correctly
//*************************************
if (sc.state == SCE_AU3_KEYWORD)
{
if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
{
sc.ChangeState(SCE_AU3_COMMENTBLOCK);
sc.SetState(SCE_AU3_COMMENTBLOCK);
}
else if (keywords.InList(s_save)) {
sc.ChangeState(SCE_AU3_KEYWORD);
sc.SetState(SCE_AU3_KEYWORD);
}
else if (keywords2.InList(s_save)) {
sc.ChangeState(SCE_AU3_FUNCTION);
sc.SetState(SCE_AU3_FUNCTION);
}
else if (keywords3.InList(s_save)) {
sc.ChangeState(SCE_AU3_MACRO);
sc.SetState(SCE_AU3_MACRO);
}
else if (keywords5.InList(s_save)) {
sc.ChangeState(SCE_AU3_PREPROCESSOR);
sc.SetState(SCE_AU3_PREPROCESSOR);
}
else if (keywords6.InList(s_save)) {
sc.ChangeState(SCE_AU3_SPECIAL);
sc.SetState(SCE_AU3_SPECIAL);
}
else if (keywords7.InList(s_save) && sc.atLineEnd) {
sc.ChangeState(SCE_AU3_EXPAND);
sc.SetState(SCE_AU3_EXPAND);
}
else if (keywords8.InList(s_save)) {
sc.ChangeState(SCE_AU3_UDF);
sc.SetState(SCE_AU3_UDF);
}
else {
sc.ChangeState(SCE_AU3_DEFAULT);
sc.SetState(SCE_AU3_DEFAULT);
}
}
if (sc.state == SCE_AU3_SENT)
{
// Send key string ended
if (sc.chPrev == '}' && sc.ch != '}')
{
// set color to SENDKEY when valid sendkey .. else set back to regular string
char sk[100];
// split {111 222} and return {111} and check if 222 is valid.
// if return code = 1 then invalid 222 so must be string
if (GetSendKey(s_save,sk))
{
sc.ChangeState(SCE_AU3_STRING);
}
// if single char between {?} then its ok as sendkey for a single character
else if (strlen(sk) == 3)
{
sc.ChangeState(SCE_AU3_SENT);
}
// if sendkey {111} is in table then ok as sendkey
else if (keywords4.InList(sk))
{
sc.ChangeState(SCE_AU3_SENT);
}
else
{
sc.ChangeState(SCE_AU3_STRING);
}
sc.SetState(SCE_AU3_STRING);
}
// check if next portion is again a sendkey
if (sc.atLineEnd)
{
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_DEFAULT);
}
}
//*************************************
sc.Complete();
}
//
static bool IsStreamCommentStyle(int style) {
return style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK;
}
//
// Routine to find first none space on the current line and return its Style
// needed for comment lines not starting on pos 1
static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
{
int nsPos = styler.LineStart(szLine);
int nePos = styler.LineStart(szLine+1) - 1;
while (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)
{
nsPos++; // skip to next char
} // End While
return styler.StyleAt(nsPos);
} // GetStyleFirstWord()
//
static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
{
int endPos = startPos + length;
// get settings from the config files for folding comments and preprocessor lines
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
}
// vars for style of previous/current/next lines
int style = GetStyleFirstWord(lineCurrent,styler);
int stylePrev = 0;
// find the first previous line without continuation character at the end
while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
(lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
if (lineCurrent > 0) {
stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
}
// vars for getting first word to check for keywords
bool FirstWordStart = false;
bool FirstWordEnd = false;
char szKeyword[11]="";
int szKeywordlen = 0;
char szThen[5]="";
int szThenlen = 0;
bool ThenFoundLast = false;
// var for indentlevel
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
//
int visibleChars = 0;
char chNext = styler.SafeGetCharAt(startPos);
char chPrev = ' ';
//
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (IsAWordChar(ch)) {
visibleChars++;
}
// get the syle for the current character neede to check in comment
int stylech = styler.StyleAt(i);
// get first word for the line for indent check max 9 characters
if (FirstWordStart && (!(FirstWordEnd))) {
if (!IsAWordChar(ch)) {
FirstWordEnd = true;
szKeyword[szKeywordlen] = '\0';
}
else {
if (szKeywordlen < 10) {
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
}
}
}
// start the capture of the first word
if (!(FirstWordStart)) {
if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
FirstWordStart = true;
szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
}
}
// only process this logic when not in comment section
if (!(stylech == SCE_AU3_COMMENT)) {
if (ThenFoundLast) {
if (IsAWordChar(ch)) {
ThenFoundLast = false;
}
}
// find out if the word "then" is the last on a "if" line
if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
if (szThenlen == 4) {
szThen[0] = szThen[1];
szThen[1] = szThen[2];
szThen[2] = szThen[3];
szThen[3] = static_cast<char>(tolower(ch));
if (strcmp(szThen,"then") == 0 ) {
ThenFoundLast = true;
}
}
else {
szThen[szThenlen++] = static_cast<char>(tolower(ch));
if (szThenlen == 5) {
szThen[4] = '\0';
}
}
}
}
// End of Line found so process the information
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
// **************************
// Folding logic for Keywords
// **************************
// if a keyword is found on the current line and the line doesn't end with _ (continuation)
// and we are not inside a commentblock.
if (szKeywordlen > 0 && (!(chPrev == '_')) &&
((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
szKeyword[szKeywordlen] = '\0';
// only fold "if" last keyword is "then" (else its a one line if)
if (strcmp(szKeyword,"if") == 0 && ThenFoundLast) {
levelNext++;
}
// create new fold for these words
if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
levelNext++;
}
// create double Fold for select&switch because Case will subtract one of the current level
if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
levelNext++;
levelNext++;
}
// end the fold for these words before the current line
if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
levelNext--;
levelCurrent--;
}
// end the fold for these words before the current line and Start new fold
if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 ||
strcmp(szKeyword,"elseif") == 0 ) {
levelCurrent--;
}
// end the double fold for this word before the current line
if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
levelNext--;
levelNext--;
levelCurrent--;
levelCurrent--;
}
// end the fold for these words on the current line
if (strcmp(szKeyword,"#endregion") == 0 ) {
levelNext--;
}
}
// Preprocessor and Comment folding
int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
// *************************************
// Folding logic for preprocessor blocks
// *************************************
// process preprosessor line
if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {
if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {
levelNext++;
}
// fold till the last line for normal comment lines
else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {
levelNext--;
}
}
// *********************************
// Folding logic for Comment blocks
// *********************************
if (foldComment && IsStreamCommentStyle(style)) {
// Start of a comment block
if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
levelNext++;
}
// fold till the last line for normal comment lines
else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_AU3_COMMENT)
&& stylePrev == SCE_AU3_COMMENT
&& style == SCE_AU3_COMMENT) {
levelNext--;
}
// fold till the one but last line for Blockcomment lines
else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_AU3_COMMENTBLOCK)
&& style == SCE_AU3_COMMENTBLOCK) {
levelNext--;
levelCurrent--;
}
}
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
// reset values for the next line
lineCurrent++;
stylePrev = style;
style = styleNext;
levelCurrent = levelNext;
visibleChars = 0;
// if the last character is an Underscore then don't reset since the line continues on the next line.
if (!(chPrev == '_')) {
szKeywordlen = 0;
szThenlen = 0;
FirstWordStart = false;
FirstWordEnd = false;
ThenFoundLast = false;
}
}
// save the last processed character
if (!isspacechar(ch)) {
chPrev = ch;
visibleChars++;
}
}
}
//
static const char * const AU3WordLists[] = {
"#autoit keywords",
"#autoit functions",
"#autoit macros",
"#autoit Sent keys",
"#autoit Pre-processors",
"#autoit Special",
"#autoit Expand",
"#autoit UDF",
0
};
LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);

View File

@@ -0,0 +1,228 @@
// SciTE - Scintilla based Text Editor
/** @file LexAVE.cxx
** Lexer for Avenue.
**
** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
static inline bool IsEnumChar(const int ch) {
return (ch < 0x80) && (isalnum(ch)|| ch == '_');
}
static inline bool IsANumberChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' );
}
inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
inline bool isAveOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' ||
ch == '{' || ch == '}' ||
ch == '[' || ch == ']' || ch == ';' ||
ch == '<' || ch == '>' || ch == ',' ||
ch == '.' )
return true;
return false;
}
static void ColouriseAveDoc(
unsigned int startPos,
int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
// Do not leak onto next line
if (initStyle == SCE_AVE_STRINGEOL) {
initStyle = SCE_AVE_DEFAULT;
}
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.atLineEnd) {
// Update the line state, so it can be seen by next line
int currentLine = styler.GetLine(sc.currentPos);
styler.SetLineState(currentLine, 0);
}
if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
// Prevent SCE_AVE_STRINGEOL from leaking back to previous line
sc.SetState(SCE_AVE_STRING);
}
// Determine if the current state should terminate.
if (sc.state == SCE_AVE_OPERATOR) {
sc.SetState(SCE_AVE_DEFAULT);
} else if (sc.state == SCE_AVE_NUMBER) {
if (!IsANumberChar(sc.ch)) {
sc.SetState(SCE_AVE_DEFAULT);
}
} else if (sc.state == SCE_AVE_ENUM) {
if (!IsEnumChar(sc.ch)) {
sc.SetState(SCE_AVE_DEFAULT);
}
} else if (sc.state == SCE_AVE_IDENTIFIER) {
if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
char s[100];
//sc.GetCurrent(s, sizeof(s));
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_AVE_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_AVE_WORD2);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_AVE_WORD3);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_AVE_WORD4);
} else if (keywords5.InList(s)) {
sc.ChangeState(SCE_AVE_WORD5);
} else if (keywords6.InList(s)) {
sc.ChangeState(SCE_AVE_WORD6);
}
sc.SetState(SCE_AVE_DEFAULT);
}
} else if (sc.state == SCE_AVE_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_AVE_DEFAULT);
}
} else if (sc.state == SCE_AVE_STRING) {
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_AVE_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_AVE_STRINGEOL);
sc.ForwardSetState(SCE_AVE_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_AVE_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_AVE_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_AVE_IDENTIFIER);
} else if (sc.Match('\"')) {
sc.SetState(SCE_AVE_STRING);
} else if (sc.Match('\'')) {
sc.SetState(SCE_AVE_COMMENT);
sc.Forward();
} else if (isAveOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_AVE_OPERATOR);
} else if (sc.Match('#')) {
sc.SetState(SCE_AVE_ENUM);
sc.Forward();
}
}
}
sc.Complete();
}
static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = static_cast<char>(tolower(styler[startPos]));
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
int styleNext = styler.StyleAt(startPos);
char s[10];
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = static_cast<char>(tolower(chNext));
chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_AVE_WORD) {
if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
for (unsigned int j = 0; j < 6; j++) {
if (!iswordchar(styler[i + j])) {
break;
}
s[j] = static_cast<char>(tolower(styler[i + j]));
s[j + 1] = '\0';
}
if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
levelCurrent++;
}
if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
// Normally "elseif" and "then" will be on the same line and will cancel
// each other out. // As implemented, this does not support fold.at.else.
levelCurrent--;
}
}
} else if (style == SCE_AVE_OPERATOR) {
if (ch == '{' || ch == '(') {
levelCurrent++;
} else if (ch == '}' || ch == ')') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact) {
lev |= SC_FOLDLEVELWHITEFLAG;
}
if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch)) {
visibleChars++;
}
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);

View File

@@ -0,0 +1,617 @@
// Scintilla source code edit control
/** @file LexABAQUS.cxx
** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
** By Sergio Lucato.
** Sort of completely rewritten by Gertjan Kloosterman
**/
// The License.txt file describes the conditions under which this software may be distributed.
// Code folding copyied and modified from LexBasic.cxx
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || (ch == '_')));
}
static inline bool IsAKeywordChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
}
static inline bool IsASetChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
}
static inline bool IsAnOperator(char ch) {
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
ch == '$' || ch == ':' || ch == '%')
return true;
return false;
}
static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */,
Accessor &styler) {
enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
DAT_LINE_VAL, DAT_LINE_COMMA,\
COMMENT_LINE,\
ST_ERROR, LINE_END } state ;
// Do not leak onto next line
state = LINE_END ;
initStyle = SCE_ABAQUS_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler);
// Things are actually quite simple
// we have commentlines
// keywordlines and datalines
// On a data line there will only be colouring of numbers
// a keyword line is constructed as
// *word,[ paramname[=paramvalue]]*
// if the line ends with a , the keyword line continues onto the new line
for (; sc.More(); sc.Forward()) {
switch ( state ) {
case KW_LINE_KW :
if ( sc.atLineEnd ) {
// finished the line in keyword state, switch to LINE_END
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
} else if ( IsAKeywordChar(sc.ch) ) {
// nothing changes
state = KW_LINE_KW ;
} else if ( sc.ch == ',' ) {
// Well well we say a comma, arguments *MUST* follow
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = KW_LINE_COMMA ;
} else {
// Flag an error
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
// Done with processing
break ;
case KW_LINE_COMMA :
// acomma on a keywordline was seen
if ( IsAKeywordChar(sc.ch)) {
sc.SetState(SCE_ABAQUS_ARGUMENT) ;
state = KW_LINE_PAR ;
} else if ( sc.atLineEnd || (sc.ch == ',') ) {
// we remain in keyword mode
state = KW_LINE_COMMA ;
} else if ( sc.ch == ' ' ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = KW_LINE_COMMA ;
} else {
// Anything else constitutes an error
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
break ;
case KW_LINE_PAR :
if ( sc.atLineEnd ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
} else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
// remain in this state
state = KW_LINE_PAR ;
} else if ( sc.ch == ',' ) {
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = KW_LINE_COMMA ;
} else if ( sc.ch == '=' ) {
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = KW_LINE_EQ ;
} else {
// Anything else constitutes an error
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
break ;
case KW_LINE_EQ :
if ( sc.ch == ' ' ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
// remain in this state
state = KW_LINE_EQ ;
} else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
sc.SetState(SCE_ABAQUS_NUMBER) ;
state = KW_LINE_VAL ;
} else if ( IsAKeywordChar(sc.ch) ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = KW_LINE_VAL ;
} else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
sc.SetState(SCE_ABAQUS_STRING) ;
state = KW_LINE_VAL ;
} else {
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
break ;
case KW_LINE_VAL :
if ( sc.atLineEnd ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
} else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
// nothing changes
state = KW_LINE_VAL ;
} else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
(sc.state == SCE_ABAQUS_NUMBER)) {
// remain in number mode
state = KW_LINE_VAL ;
} else if (sc.state == SCE_ABAQUS_STRING) {
// accept everything until a closing quote
if ( sc.ch == '\'' || sc.ch == '\"' ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = KW_LINE_VAL ;
}
} else if ( sc.ch == ',' ) {
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = KW_LINE_COMMA ;
} else {
// anything else is an error
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
break ;
case DAT_LINE_VAL :
if ( sc.atLineEnd ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
} else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
// nothing changes
state = DAT_LINE_VAL ;
} else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
(sc.state == SCE_ABAQUS_NUMBER)) {
// remain in number mode
state = DAT_LINE_VAL ;
} else if (sc.state == SCE_ABAQUS_STRING) {
// accept everything until a closing quote
if ( sc.ch == '\'' || sc.ch == '\"' ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = DAT_LINE_VAL ;
}
} else if ( sc.ch == ',' ) {
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = DAT_LINE_COMMA ;
} else {
// anything else is an error
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
break ;
case DAT_LINE_COMMA :
// a comma on a data line was seen
if ( sc.atLineEnd ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
} else if ( sc.ch == ' ' ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = DAT_LINE_COMMA ;
} else if (sc.ch == ',') {
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = DAT_LINE_COMMA ;
} else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
sc.SetState(SCE_ABAQUS_NUMBER) ;
state = DAT_LINE_VAL ;
} else if ( IsAKeywordChar(sc.ch) ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = DAT_LINE_VAL ;
} else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
sc.SetState(SCE_ABAQUS_STRING) ;
state = DAT_LINE_VAL ;
} else {
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
break ;
case COMMENT_LINE :
if ( sc.atLineEnd ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
}
break ;
case ST_ERROR :
if ( sc.atLineEnd ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = LINE_END ;
}
break ;
case LINE_END :
if ( sc.atLineEnd || sc.ch == ' ' ) {
// nothing changes
state = LINE_END ;
} else if ( sc.ch == '*' ) {
if ( sc.chNext == '*' ) {
state = COMMENT_LINE ;
sc.SetState(SCE_ABAQUS_COMMENT) ;
} else {
state = KW_LINE_KW ;
sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
}
} else {
// it must be a data line, things are as if we are in DAT_LINE_COMMA
if ( sc.ch == ',' ) {
sc.SetState(SCE_ABAQUS_OPERATOR) ;
state = DAT_LINE_COMMA ;
} else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
sc.SetState(SCE_ABAQUS_NUMBER) ;
state = DAT_LINE_VAL ;
} else if ( IsAKeywordChar(sc.ch) ) {
sc.SetState(SCE_ABAQUS_DEFAULT) ;
state = DAT_LINE_VAL ;
} else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
sc.SetState(SCE_ABAQUS_STRING) ;
state = DAT_LINE_VAL ;
} else {
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
state = ST_ERROR ;
}
}
break ;
}
}
sc.Complete();
}
//------------------------------------------------------------------------------
// This copyied and modified from LexBasic.cxx
//------------------------------------------------------------------------------
/* Bits:
* 1 - whitespace
* 2 - operator
* 4 - identifier
* 8 - decimal digit
* 16 - hex digit
* 32 - bin digit
*/
static int character_classification[128] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
};
static bool IsSpace(int c) {
return c < 128 && (character_classification[c] & 1);
}
static bool IsIdentifier(int c) {
return c < 128 && (character_classification[c] & 4);
}
static int LowerCase(int c)
{
if (c >= 'A' && c <= 'Z')
return 'a' + c - 'A';
return c;
}
static int LineEnd(int line, Accessor &styler)
{
const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
int eol_pos ;
// if the line is the last line, the eol_pos is styler.Length()
// eol will contain a new line, or a virtual new line
if ( docLines == line )
eol_pos = styler.Length() ;
else
eol_pos = styler.LineStart(line + 1) - 1;
return eol_pos ;
}
static int LineStart(int line, Accessor &styler)
{
return styler.LineStart(line) ;
}
// LineType
//
// bits determines the line type
// 1 : data line
// 2 : only whitespace
// 3 : data line with only whitespace
// 4 : keyword line
// 5 : block open keyword line
// 6 : block close keyword line
// 7 : keyword line in error
// 8 : comment line
static int LineType(int line, Accessor &styler) {
int pos = LineStart(line, styler) ;
int eol_pos = LineEnd(line, styler) ;
int c ;
char ch = ' ';
int i = pos ;
while ( i < eol_pos ) {
c = styler.SafeGetCharAt(i);
ch = static_cast<char>(LowerCase(c));
// We can say something as soon as no whitespace
// was encountered
if ( !IsSpace(c) )
break ;
i++ ;
}
if ( i >= eol_pos ) {
// This is a whitespace line, currently
// classifies as data line
return 3 ;
}
if ( ch != '*' ) {
// This is a data line
return 1 ;
}
if ( i == eol_pos - 1 ) {
// Only a single *, error but make keyword line
return 4+3 ;
}
// This means we can have a second character
// if that is also a * this means a comment
// otherwise it is a keyword.
c = styler.SafeGetCharAt(i+1);
ch = static_cast<char>(LowerCase(c));
if ( ch == '*' ) {
return 8 ;
}
// At this point we know this is a keyword line
// the character at position i is a *
// it is not a comment line
char word[256] ;
int wlen = 0;
word[wlen] = '*' ;
wlen++ ;
i++ ;
while ( (i < eol_pos) && (wlen < 255) ) {
c = styler.SafeGetCharAt(i);
ch = static_cast<char>(LowerCase(c));
if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
break ;
if ( IsIdentifier(c) ) {
word[wlen] = ch ;
wlen++ ;
}
i++ ;
}
word[wlen] = 0 ;
// Make a comparison
if ( !strcmp(word, "*step") ||
!strcmp(word, "*part") ||
!strcmp(word, "*instance") ||
!strcmp(word, "*assembly")) {
return 4+1 ;
}
if ( !strcmp(word, "*endstep") ||
!strcmp(word, "*endpart") ||
!strcmp(word, "*endinstance") ||
!strcmp(word, "*endassembly")) {
return 4+2 ;
}
return 4 ;
}
static void SafeSetLevel(int line, int level, Accessor &styler)
{
if ( line < 0 )
return ;
int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
if ( (level & mask) < 0 )
return ;
if ( styler.LevelAt(line) != level )
styler.SetLevel(line, level) ;
}
static void FoldABAQUSDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
int startLine = styler.GetLine(startPos) ;
int endLine = styler.GetLine(startPos+length-1) ;
// bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
// We want to deal with all the cases
// To know the correct indentlevel, we need to look back to the
// previous command line indentation level
// order of formatting keyline datalines commentlines
int beginData = -1 ;
int beginComment = -1 ;
int prvKeyLine = startLine ;
int prvKeyLineTp = 0 ;
// Scan until we find the previous keyword line
// this will give us the level reference that we need
while ( prvKeyLine > 0 ) {
prvKeyLine-- ;
prvKeyLineTp = LineType(prvKeyLine, styler) ;
if ( prvKeyLineTp & 4 )
break ;
}
// Determine the base line level of all lines following
// the previous keyword
// new keyword lines are placed on this level
//if ( prvKeyLineTp & 4 ) {
int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
//}
// uncomment line below if weird behaviour continues
prvKeyLine = -1 ;
// Now start scanning over the lines.
for ( int line = startLine; line <= endLine; line++ ) {
int lineType = LineType(line, styler) ;
// Check for comment line
if ( lineType == 8 ) {
if ( beginComment < 0 ) {
beginComment = line ;
}
}
// Check for data line
if ( (lineType == 1) || (lineType == 3) ) {
if ( beginData < 0 ) {
if ( beginComment >= 0 ) {
beginData = beginComment ;
} else {
beginData = line ;
}
}
beginComment = -1 ;
}
// Check for keywordline.
// As soon as a keyword line is encountered, we can set the
// levels of everything from the previous keyword line to this one
if ( lineType & 4 ) {
// this is a keyword, we can now place the previous keyword
// all its data lines and the remainder
// Write comments and data line
if ( beginComment < 0 ) {
beginComment = line ;
}
if ( beginData < 0 ) {
beginData = beginComment ;
if ( prvKeyLineTp != 5 )
SafeSetLevel(prvKeyLine, level, styler) ;
else
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
} else {
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
}
int datLevel = level + 1 ;
if ( !(prvKeyLineTp & 4) ) {
datLevel = level ;
}
for ( int ll = beginData; ll < beginComment; ll++ )
SafeSetLevel(ll, datLevel, styler) ;
// The keyword we just found is going to be written at another level
// if we have a type 5 and type 6
if ( prvKeyLineTp == 5 ) {
level += 1 ;
}
if ( prvKeyLineTp == 6 ) {
level -= 1 ;
if ( level < 0 ) {
level = 0 ;
}
}
for ( int lll = beginComment; lll < line; lll++ )
SafeSetLevel(lll, level, styler) ;
// wrap and reset
beginComment = -1 ;
beginData = -1 ;
prvKeyLine = line ;
prvKeyLineTp = lineType ;
}
}
if ( beginComment < 0 ) {
beginComment = endLine + 1 ;
} else {
// We need to find out whether this comment block is followed by
// a data line or a keyword line
const int docLines = styler.GetLine(styler.Length() - 1);
for ( int line = endLine + 1; line <= docLines; line++ ) {
int lineType = LineType(line, styler) ;
if ( lineType != 8 ) {
if ( !(lineType & 4) ) {
beginComment = endLine + 1 ;
}
break ;
}
}
}
if ( beginData < 0 ) {
beginData = beginComment ;
if ( prvKeyLineTp != 5 )
SafeSetLevel(prvKeyLine, level, styler) ;
else
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
} else {
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
}
int datLevel = level + 1 ;
if ( !(prvKeyLineTp & 4) ) {
datLevel = level ;
}
for ( int ll = beginData; ll < beginComment; ll++ )
SafeSetLevel(ll, datLevel, styler) ;
if ( prvKeyLineTp == 5 ) {
level += 1 ;
}
if ( prvKeyLineTp == 6 ) {
level -= 1 ;
}
for ( int m = beginComment; m <= endLine; m++ )
SafeSetLevel(m, level, styler) ;
}
static const char * const abaqusWordListDesc[] = {
"processors",
"commands",
"slashommands",
"starcommands",
"arguments",
"functions",
0
};
LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);

View File

@@ -0,0 +1,525 @@
// Scintilla source code edit control
/** @file LexAda.cxx
** Lexer for Ada 95
**/
// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include "Platform.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "PropSet.h"
#include "KeyWords.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/*
* Interface
*/
static void ColouriseDocument(
unsigned int startPos,
int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler);
static const char * const adaWordListDesc[] = {
"Keywords",
0
};
LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
/*
* Implementation
*/
// Functions that have apostropheStartsAttribute as a parameter set it according to whether
// an apostrophe encountered after processing the current token will start an attribute or
// a character literal.
static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
static inline bool IsDelimiterCharacter(int ch);
static inline bool IsNumberStartCharacter(int ch);
static inline bool IsNumberCharacter(int ch);
static inline bool IsSeparatorOrDelimiterCharacter(int ch);
static bool IsValidIdentifier(const std::string& identifier);
static bool IsValidNumber(const std::string& number);
static inline bool IsWordStartCharacter(int ch);
static inline bool IsWordCharacter(int ch);
static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = true;
sc.SetState(SCE_ADA_CHARACTER);
// Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
// is handled correctly)
sc.Forward();
sc.Forward();
ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
}
static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
while (!sc.atLineEnd && !sc.Match(chEnd)) {
sc.Forward();
}
if (!sc.atLineEnd) {
sc.ForwardSetState(SCE_ADA_DEFAULT);
} else {
sc.ChangeState(stateEOL);
}
}
static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
// Apostrophe meaning is not changed, but the parameter is present for uniformity
sc.SetState(SCE_ADA_COMMENTLINE);
while (!sc.atLineEnd) {
sc.Forward();
}
}
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = sc.Match (')');
sc.SetState(SCE_ADA_DELIMITER);
sc.ForwardSetState(SCE_ADA_DEFAULT);
}
static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = false;
sc.SetState(SCE_ADA_LABEL);
// Skip "<<"
sc.Forward();
sc.Forward();
std::string identifier;
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
identifier += static_cast<char>(tolower(sc.ch));
sc.Forward();
}
// Skip ">>"
if (sc.Match('>', '>')) {
sc.Forward();
sc.Forward();
} else {
sc.ChangeState(SCE_ADA_ILLEGAL);
}
// If the name is an invalid identifier or a keyword, then make it invalid label
if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
sc.ChangeState(SCE_ADA_ILLEGAL);
}
sc.SetState(SCE_ADA_DEFAULT);
}
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = true;
std::string number;
sc.SetState(SCE_ADA_NUMBER);
// Get all characters up to a delimiter or a separator, including points, but excluding
// double points (ranges).
while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
number += static_cast<char>(sc.ch);
sc.Forward();
}
// Special case: exponent with sign
if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
(sc.ch == '+' || sc.ch == '-')) {
number += static_cast<char>(sc.ch);
sc.Forward ();
while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
number += static_cast<char>(sc.ch);
sc.Forward();
}
}
if (!IsValidNumber(number)) {
sc.ChangeState(SCE_ADA_ILLEGAL);
}
sc.SetState(SCE_ADA_DEFAULT);
}
static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = true;
sc.SetState(SCE_ADA_STRING);
sc.Forward();
ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
}
static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
// Apostrophe meaning is not changed, but the parameter is present for uniformity
sc.SetState(SCE_ADA_DEFAULT);
sc.ForwardSetState(SCE_ADA_DEFAULT);
}
static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = true;
sc.SetState(SCE_ADA_IDENTIFIER);
std::string word;
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
word += static_cast<char>(tolower(sc.ch));
sc.Forward();
}
if (!IsValidIdentifier(word)) {
sc.ChangeState(SCE_ADA_ILLEGAL);
} else if (keywords.InList(word.c_str())) {
sc.ChangeState(SCE_ADA_WORD);
if (word != "all") {
apostropheStartsAttribute = false;
}
}
sc.SetState(SCE_ADA_DEFAULT);
}
//
// ColouriseDocument
//
static void ColouriseDocument(
unsigned int startPos,
int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
StyleContext sc(startPos, length, initStyle, styler);
int lineCurrent = styler.GetLine(startPos);
bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
while (sc.More()) {
if (sc.atLineEnd) {
// Go to the next line
sc.Forward();
lineCurrent++;
// Remember the line state for future incremental lexing
styler.SetLineState(lineCurrent, apostropheStartsAttribute);
// Don't continue any styles on the next line
sc.SetState(SCE_ADA_DEFAULT);
}
// Comments
if (sc.Match('-', '-')) {
ColouriseComment(sc, apostropheStartsAttribute);
// Strings
} else if (sc.Match('"')) {
ColouriseString(sc, apostropheStartsAttribute);
// Characters
} else if (sc.Match('\'') && !apostropheStartsAttribute) {
ColouriseCharacter(sc, apostropheStartsAttribute);
// Labels
} else if (sc.Match('<', '<')) {
ColouriseLabel(sc, keywords, apostropheStartsAttribute);
// Whitespace
} else if (IsASpace(sc.ch)) {
ColouriseWhiteSpace(sc, apostropheStartsAttribute);
// Delimiters
} else if (IsDelimiterCharacter(sc.ch)) {
ColouriseDelimiter(sc, apostropheStartsAttribute);
// Numbers
} else if (IsADigit(sc.ch) || sc.ch == '#') {
ColouriseNumber(sc, apostropheStartsAttribute);
// Keywords or identifiers
} else {
ColouriseWord(sc, keywords, apostropheStartsAttribute);
}
}
sc.Complete();
}
static inline bool IsDelimiterCharacter(int ch) {
switch (ch) {
case '&':
case '\'':
case '(':
case ')':
case '*':
case '+':
case ',':
case '-':
case '.':
case '/':
case ':':
case ';':
case '<':
case '=':
case '>':
case '|':
return true;
default:
return false;
}
}
static inline bool IsNumberCharacter(int ch) {
return IsNumberStartCharacter(ch) ||
ch == '_' ||
ch == '.' ||
ch == '#' ||
(ch >= 'a' && ch <= 'f') ||
(ch >= 'A' && ch <= 'F');
}
static inline bool IsNumberStartCharacter(int ch) {
return IsADigit(ch);
}
static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
return IsASpace(ch) || IsDelimiterCharacter(ch);
}
static bool IsValidIdentifier(const std::string& identifier) {
// First character can't be '_', so initialize the flag to true
bool lastWasUnderscore = true;
size_t length = identifier.length();
// Zero-length identifiers are not valid (these can occur inside labels)
if (length == 0) {
return false;
}
// Check for valid character at the start
if (!IsWordStartCharacter(identifier[0])) {
return false;
}
// Check for only valid characters and no double underscores
for (size_t i = 0; i < length; i++) {
if (!IsWordCharacter(identifier[i]) ||
(identifier[i] == '_' && lastWasUnderscore)) {
return false;
}
lastWasUnderscore = identifier[i] == '_';
}
// Check for underscore at the end
if (lastWasUnderscore == true) {
return false;
}
// All checks passed
return true;
}
static bool IsValidNumber(const std::string& number) {
size_t hashPos = number.find("#");
bool seenDot = false;
size_t i = 0;
size_t length = number.length();
if (length == 0)
return false; // Just in case
// Decimal number
if (hashPos == std::string::npos) {
bool canBeSpecial = false;
for (; i < length; i++) {
if (number[i] == '_') {
if (!canBeSpecial) {
return false;
}
canBeSpecial = false;
} else if (number[i] == '.') {
if (!canBeSpecial || seenDot) {
return false;
}
canBeSpecial = false;
seenDot = true;
} else if (IsADigit(number[i])) {
canBeSpecial = true;
} else {
break;
}
}
if (!canBeSpecial)
return false;
} else {
// Based number
bool canBeSpecial = false;
int base = 0;
// Parse base
for (; i < length; i++) {
int ch = number[i];
if (ch == '_') {
if (!canBeSpecial)
return false;
canBeSpecial = false;
} else if (IsADigit(ch)) {
base = base * 10 + (ch - '0');
if (base > 16)
return false;
canBeSpecial = true;
} else if (ch == '#' && canBeSpecial) {
break;
} else {
return false;
}
}
if (base < 2)
return false;
if (i == length)
return false;
i++; // Skip over '#'
// Parse number
canBeSpecial = false;
for (; i < length; i++) {
int ch = tolower(number[i]);
if (ch == '_') {
if (!canBeSpecial) {
return false;
}
canBeSpecial = false;
} else if (ch == '.') {
if (!canBeSpecial || seenDot) {
return false;
}
canBeSpecial = false;
seenDot = true;
} else if (IsADigit(ch)) {
if (ch - '0' >= base) {
return false;
}
canBeSpecial = true;
} else if (ch >= 'a' && ch <= 'f') {
if (ch - 'a' + 10 >= base) {
return false;
}
canBeSpecial = true;
} else if (ch == '#' && canBeSpecial) {
break;
} else {
return false;
}
}
if (i == length) {
return false;
}
i++;
}
// Exponent (optional)
if (i < length) {
if (number[i] != 'e' && number[i] != 'E')
return false;
i++; // Move past 'E'
if (i == length) {
return false;
}
if (number[i] == '+')
i++;
else if (number[i] == '-') {
if (seenDot) {
i++;
} else {
return false; // Integer literals should not have negative exponents
}
}
if (i == length) {
return false;
}
bool canBeSpecial = false;
for (; i < length; i++) {
if (number[i] == '_') {
if (!canBeSpecial) {
return false;
}
canBeSpecial = false;
} else if (IsADigit(number[i])) {
canBeSpecial = true;
} else {
return false;
}
}
if (!canBeSpecial)
return false;
}
// if i == length, number was parsed successfully.
return i == length;
}
static inline bool IsWordCharacter(int ch) {
return IsWordStartCharacter(ch) || IsADigit(ch);
}
static inline bool IsWordStartCharacter(int ch) {
return (isascii(ch) && isalpha(ch)) || ch == '_';
}

View File

@@ -0,0 +1,412 @@
// Scintilla source code edit control
/** @file LexAltaRica.cxx
** Lexers for the AltaRica language.
**/
// Copyright 2010 by Florent Teichteil-Königsbuch <florent.teichteil@onera.fr>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#include "CharClassify.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool isAltaRicaOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
if ((ch == '?') || (ch == '{') || (ch == '}') || (ch == '<') || (ch == '>') ||
(ch == '=') || (ch == '|') || (ch == '&') || (ch == ';') || (ch == ',') ||
(ch == '.') || (ch == '(') || (ch == ')') || (ch == '[') || (ch == ']') ||
(ch == '+') || (ch == '-') || (ch == '*') || (ch == '~') || (ch == '/') ||
(ch == '!') || (ch == ':'))
return true;
return false;
}
static inline bool isAltaRicaForbidden(char ch) {
return !isascii(ch) || (ch == '\"') || (ch == '#') || (ch == '$') || (ch == '%') ||
(ch == '\'') || (ch == '@') || (ch == '^') || (ch == '`');
}
static inline bool isAltaRicaWordStart(char ch) {
return isascii(ch) && !isspacechar(ch) && !isAltaRicaOperator(ch) &&
!isAltaRicaForbidden(ch) && (ch != '\n') && (ch != '\r');
}
static void classifyWordAltaRica(unsigned int start, unsigned int end, WordList &keywords,
WordList &types, Accessor &styler) {
PLATFORM_ASSERT(end >= start);
char s[100];
for (unsigned int i = 0; (i < end - start + 1) && (i < 99); i++) {
s[i] = MakeUpperCase(styler[start + i]);
s[i + 1] = '\0';
}
if (keywords.InList(s))
styler.ColourTo(end, SCE_ALTARICA_KEYWORD);
else if (types.InList(s))
styler.ColourTo(end, SCE_ALTARICA_TYPE);
else
styler.ColourTo(end, SCE_ALTARICA_IDENTIFIER);
}
static void ColouriseAltaRicaDoc(
unsigned int startPos,
int length,
int initStyle,
WordList* keywordlists[],
Accessor& styler)
{
WordList &keywords = *keywordlists[0];
WordList &types = *keywordlists[1];
styler.StartAt(startPos);
int state = initStyle;
char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length;
styler.StartSegment(startPos);
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i += 1;
continue;
}
if (state == SCE_ALTARICA_DEFAULT) {
if ((ch == '/') && (chNext == '/')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i - 2, state);
state = SCE_ALTARICA_COMMENTLINE;
}
else if ((ch == '/') && (chNext == '*')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i - 2, state);
state = SCE_ALTARICA_COMMENT;
}
else if (isAltaRicaOperator(ch)) {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_ALTARICA_OPERATOR);
}
else if (isAltaRicaWordStart(ch) && !isdigit(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_ALTARICA_IDENTIFIER;
}
else if (isdigit(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_ALTARICA_NUMBER;
}
else if (isAltaRicaForbidden(ch)) {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_ALTARICA_FORBIDDEN);
}
}
else if (state == SCE_ALTARICA_COMMENTLINE) {
if (atEOL) {
styler.ColourTo(i - 1, state);
state = SCE_ALTARICA_DEFAULT;
}
}
else if (state == SCE_ALTARICA_COMMENT) {
if ((ch == '*') && (chNext == '/')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i, state);
state = SCE_ALTARICA_DEFAULT;
}
}
else if (state == SCE_ALTARICA_IDENTIFIER) {
if (!isAltaRicaWordStart(ch)) {
classifyWordAltaRica(styler.GetStartSegment(), i - 1, keywords, types, styler);
if ((ch == '/') && (chNext == '/')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i - 2, state);
state = SCE_ALTARICA_COMMENTLINE;
}
else if ((ch == '/') && (chNext == '*')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i - 2, state);
state = SCE_ALTARICA_COMMENT;
}
else if (isAltaRicaOperator(ch)) {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_ALTARICA_OPERATOR);
state = SCE_ALTARICA_DEFAULT;
}
else if (isAltaRicaForbidden(ch)) {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_ALTARICA_FORBIDDEN);
state = SCE_ALTARICA_DEFAULT;
}
else
state = SCE_ALTARICA_DEFAULT;
}
}
else if (state == SCE_ALTARICA_NUMBER) {
if (!isdigit(ch)) {
styler.ColourTo(i - 1, state);
if ((ch == '/') && (chNext == '/')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i - 2, state);
state = SCE_ALTARICA_COMMENTLINE;
}
else if ((ch == '/') && (chNext == '*')) {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i - 2, state);
state = SCE_ALTARICA_COMMENT;
}
else if (isAltaRicaOperator(ch)) {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_ALTARICA_OPERATOR);
state = SCE_ALTARICA_DEFAULT;
}
else if (isAltaRicaForbidden(ch)) {
styler.ColourTo(i, SCE_ALTARICA_FORBIDDEN);
state = SCE_ALTARICA_DEFAULT;
}
else
state = SCE_ALTARICA_DEFAULT;
}
}
}
styler.ColourTo(lengthDoc - 1, state);
}
static bool IsCommentLine(int line, Accessor& styler) {
unsigned int pos = styler.LineStart(line);
unsigned int eol_pos = styler.LineStart(line + 1) - 1;
if (pos == eol_pos) {
int style = styler.StyleAt(pos);
return (style == SCE_ALTARICA_COMMENT);
}
for (unsigned int i = pos; i < eol_pos; i++) {
int style = styler.StyleAt(i);
if (style == SCE_ALTARICA_COMMENTLINE)
return true;
else if (style == SCE_ALTARICA_COMMENT) {
if (i+1 == eol_pos) {
return true;
}
} else {
char ch = styler[i];
if ((ch != ' ') && (ch != '\t')) {
return false;
}
}
}
return false;
}
static bool PreviousFoldKeywordIsInsideNode(unsigned int endPos, Accessor& styler) {
unsigned int pos = endPos;
bool wordEnd = false;
unsigned int posWordEnd = 0;
char s[10]; // AltaRica keywords have atmost 9 characters
while (pos > 0) {
int style = styler.StyleAt(pos-1);
if (!wordEnd && (style == SCE_ALTARICA_KEYWORD)) {
posWordEnd = pos;
wordEnd = true;
}
else if (wordEnd && ((style != SCE_ALTARICA_KEYWORD) || (pos == 1))) {
if (style == SCE_ALTARICA_KEYWORD) { // keyword begins at position 0
pos--;
}
for (unsigned int i = 0; i < posWordEnd - pos && i < 9; i++) { // AltaRica keywords have atmost 9 characters
s[i] = static_cast<char>(styler[ pos + i ]);
s[i + 1] = '\0';
}
if ((CompareCaseInsensitive(s, "node") == 0) ||
(CompareCaseInsensitive(s, "edon") == 0) ||
(CompareCaseInsensitive(s, "struct") == 0) ||
(CompareCaseInsensitive(s, "tcurts") == 0) ||
(CompareCaseInsensitive(s, "domain") == 0) ||
(CompareCaseInsensitive(s, "const") == 0)) {
return false;
}
else if ((CompareCaseInsensitive(s, "sub") == 0) ||
(CompareCaseInsensitive(s, "flow") == 0) ||
(CompareCaseInsensitive(s, "state") == 0) ||
(CompareCaseInsensitive(s, "event") == 0) ||
(CompareCaseInsensitive(s, "trans") == 0) ||
(CompareCaseInsensitive(s, "assert") == 0) ||
(CompareCaseInsensitive(s, "init") == 0)) {
return true;
} else { // not a fold keyword so continue searching backward
wordEnd = false;
}
}
pos--;
}
return false;
}
static bool NextLineIsFoldKeyword(int line, Accessor& styler) {
unsigned int pos = styler.LineStart(line + 1);
unsigned int eol_pos = styler.LineStart(line + 2) - 1;
bool wordStart = false;
unsigned int posWordStart = 0;
char s[10]; // AltaRica keywords have atmost 9 characters
for (unsigned int i = pos; i <= eol_pos; i++) {
int style = styler.StyleAt(i);
if (!wordStart && (style == SCE_ALTARICA_KEYWORD)) {
posWordStart = i;
wordStart = true;
}
else if (wordStart && ((style != SCE_ALTARICA_KEYWORD) || (i == eol_pos))) {
for (unsigned int j = 0; j < i - posWordStart && j < 9; j++) { // AltaRica keywords have atmost 9 characters
s[j] = static_cast<char>(styler[ posWordStart + j ]);
s[j + 1] = '\0';
}
if ((CompareCaseInsensitive(s, "node") == 0) ||
(CompareCaseInsensitive(s, "edon") == 0) ||
(CompareCaseInsensitive(s, "struct") == 0) ||
(CompareCaseInsensitive(s, "tcurts") == 0) ||
(CompareCaseInsensitive(s, "sub") == 0) ||
(CompareCaseInsensitive(s, "flow") == 0) ||
(CompareCaseInsensitive(s, "state") == 0) ||
(CompareCaseInsensitive(s, "event") == 0) ||
(CompareCaseInsensitive(s, "trans") == 0) ||
(CompareCaseInsensitive(s, "assert") == 0) ||
(CompareCaseInsensitive(s, "init") == 0) ||
(CompareCaseInsensitive(s, "domain") == 0) ||
(CompareCaseInsensitive(s, "const") == 0)) {
return true;
}
else
return false;
}
else if(!wordStart) {
char ch = styler[i];
if ((ch != ' ') && (ch != '\t')) {
return false;
}
}
}
return false;
}
static void FoldAltaRicaDoc(unsigned int startPos, int length, int initStyle,
WordList* keywordlists[], Accessor& styler) {
if (styler.GetPropertyInt("fold") == 0) return;
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
unsigned int endPos = startPos + length;
char chNext = styler[startPos];
bool wordStart = false;
unsigned int posWordStart = 0;
char altaricaKeyword[10]; // AltaRica keywords have atmost 9 characters
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styler.StyleAt(i);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (!wordStart && (style == SCE_ALTARICA_KEYWORD)) {
posWordStart = i;
wordStart = true;
}
else if (wordStart && (style != SCE_ALTARICA_KEYWORD)) {
for (unsigned int j = 0; j < i - posWordStart && j < 9; j++) { // AltaRica keywords have atmost 9 characters
altaricaKeyword[j] = static_cast<char>(styler[ posWordStart + j ]);
altaricaKeyword[j + 1] = '\0';
}
if (CompareCaseInsensitive(altaricaKeyword, "node") == 0) {
levelCurrent++;
}
else if (CompareCaseInsensitive(altaricaKeyword, "edon") == 0) {
levelCurrent--;
}
else if (CompareCaseInsensitive(altaricaKeyword, "struct") == 0) {
levelCurrent++;
}
else if (CompareCaseInsensitive(altaricaKeyword, "tcurts") == 0) {
levelCurrent--;
}
else if ((CompareCaseInsensitive(altaricaKeyword, "sub") == 0) ||
(CompareCaseInsensitive(altaricaKeyword, "flow") == 0) ||
(CompareCaseInsensitive(altaricaKeyword, "state") == 0) ||
(CompareCaseInsensitive(altaricaKeyword, "event") == 0) ||
(CompareCaseInsensitive(altaricaKeyword, "trans") == 0) ||
(CompareCaseInsensitive(altaricaKeyword, "assert") == 0) ||
(CompareCaseInsensitive(altaricaKeyword, "init") == 0)) {
levelCurrent++;
}
wordStart = false;
}
if (atEOL) {
// Comment folding
if (foldComment && IsCommentLine(lineCurrent, styler)) {
if (((lineCurrent == 0) || !IsCommentLine(lineCurrent - 1, styler))
&& IsCommentLine(lineCurrent + 1, styler))
levelCurrent++;
else if ((lineCurrent > 0) && IsCommentLine(lineCurrent - 1, styler)
&& !IsCommentLine(lineCurrent + 1, styler))
levelCurrent--;
}
else if (NextLineIsFoldKeyword(lineCurrent, styler) && PreviousFoldKeywordIsInsideNode(i, styler)) {
levelCurrent--;
}
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const altaricaWordListDesc[] = {
"keywords",
"types",
0,
};
LexerModule lmAltaRica(SCLEX_ALTARICA, ColouriseAltaRicaDoc, "altarica", FoldAltaRicaDoc, altaricaWordListDesc);

View File

@@ -0,0 +1,180 @@
// Scintilla source code edit control
/** @file LexAsm.cxx
** Lexer for Assembler, just for the MASM syntax
** Written by The Black Horus
** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
ch == '_' || ch == '?');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
ch == '%' || ch == '@' || ch == '$' || ch == '?');
}
static inline bool IsAsmOperator(const int ch) {
if ((ch < 0x80) && (isalnum(ch)))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
ch == '%' || ch == ':')
return true;
return false;
}
static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &cpuInstruction = *keywordlists[0];
WordList &mathInstruction = *keywordlists[1];
WordList &registers = *keywordlists[2];
WordList &directive = *keywordlists[3];
WordList &directiveOperand = *keywordlists[4];
WordList &extInstruction = *keywordlists[5];
// Do not leak onto next line
if (initStyle == SCE_ASM_STRINGEOL)
initStyle = SCE_ASM_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
// Prevent SCE_ASM_STRINGEOL from leaking back to previous line
if (sc.atLineStart && (sc.state == SCE_ASM_STRING)) {
sc.SetState(SCE_ASM_STRING);
} else if (sc.atLineStart && (sc.state == SCE_ASM_CHARACTER)) {
sc.SetState(SCE_ASM_CHARACTER);
}
// Handle line continuation generically.
if (sc.ch == '\\') {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continue;
}
}
// Determine if the current state should terminate.
if (sc.state == SCE_ASM_OPERATOR) {
if (!IsAsmOperator(sc.ch)) {
sc.SetState(SCE_ASM_DEFAULT);
}
}else if (sc.state == SCE_ASM_NUMBER) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_IDENTIFIER) {
if (!IsAWordChar(sc.ch) ) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (cpuInstruction.InList(s)) {
sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
} else if (mathInstruction.InList(s)) {
sc.ChangeState(SCE_ASM_MATHINSTRUCTION);
} else if (registers.InList(s)) {
sc.ChangeState(SCE_ASM_REGISTER);
} else if (directive.InList(s)) {
sc.ChangeState(SCE_ASM_DIRECTIVE);
} else if (directiveOperand.InList(s)) {
sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
} else if (extInstruction.InList(s)) {
sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
}
sc.SetState(SCE_ASM_DEFAULT);
}
}
else if (sc.state == SCE_ASM_COMMENT ) {
if (sc.atLineEnd) {
sc.SetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_ASM_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_ASM_STRINGEOL);
sc.ForwardSetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_CHARACTER) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_ASM_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_ASM_STRINGEOL);
sc.ForwardSetState(SCE_ASM_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_ASM_DEFAULT) {
if (sc.ch == ';'){
sc.SetState(SCE_ASM_COMMENT);
} else if (isascii(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && isascii(sc.chNext) && isdigit(sc.chNext)))) {
sc.SetState(SCE_ASM_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_ASM_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_ASM_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_ASM_CHARACTER);
} else if (IsAsmOperator(sc.ch)) {
sc.SetState(SCE_ASM_OPERATOR);
}
}
}
sc.Complete();
}
static const char * const asmWordListDesc[] = {
"CPU instructions",
"FPU instructions",
"Registers",
"Directives",
"Directive operands",
"Extended instructions",
0
};
LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);

View File

@@ -0,0 +1,185 @@
// Scintilla source code edit control
/** @file LexAsn1.cxx
** Lexer for ASN.1
**/
// Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de
// Last Updated: 20/07/2004
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// Some char test functions
static bool isAsn1Number(int ch)
{
return (ch >= '0' && ch <= '9');
}
static bool isAsn1Letter(int ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static bool isAsn1Char(int ch)
{
return (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch);
}
//
// Function determining the color of a given code portion
// Based on a "state"
//
static void ColouriseAsn1Doc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[], Accessor &styler)
{
// The keywords
WordList &Keywords = *keywordLists[0];
WordList &Attributes = *keywordLists[1];
WordList &Descriptors = *keywordLists[2];
WordList &Types = *keywordLists[3];
// Parse the whole buffer character by character using StyleContext
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
// The state engine
switch (sc.state)
{
case SCE_ASN1_DEFAULT: // Plain characters
asn1_default:
if (sc.ch == '-' && sc.chNext == '-')
// A comment begins here
sc.SetState(SCE_ASN1_COMMENT);
else if (sc.ch == '"')
// A string begins here
sc.SetState(SCE_ASN1_STRING);
else if (isAsn1Number (sc.ch))
// A number starts here (identifier should start with a letter in ASN.1)
sc.SetState(SCE_ASN1_SCALAR);
else if (isAsn1Char (sc.ch))
// An identifier starts here (identifier always start with a letter)
sc.SetState(SCE_ASN1_IDENTIFIER);
else if (sc.ch == ':')
// A ::= operator starts here
sc.SetState(SCE_ASN1_OPERATOR);
break;
case SCE_ASN1_COMMENT: // A comment
if (sc.ch == '\r' || sc.ch == '\n')
// A comment ends here
sc.SetState(SCE_ASN1_DEFAULT);
break;
case SCE_ASN1_IDENTIFIER: // An identifier (keyword, attribute, descriptor or type)
if (!isAsn1Char (sc.ch))
{
// The end of identifier is here: we can look for it in lists by now and change its state
char s[100];
sc.GetCurrent(s, sizeof(s));
if (Keywords.InList(s))
// It's a keyword, change its state
sc.ChangeState(SCE_ASN1_KEYWORD);
else if (Attributes.InList(s))
// It's an attribute, change its state
sc.ChangeState(SCE_ASN1_ATTRIBUTE);
else if (Descriptors.InList(s))
// It's a descriptor, change its state
sc.ChangeState(SCE_ASN1_DESCRIPTOR);
else if (Types.InList(s))
// It's a type, change its state
sc.ChangeState(SCE_ASN1_TYPE);
// Set to default now
sc.SetState(SCE_ASN1_DEFAULT);
}
break;
case SCE_ASN1_STRING: // A string delimited by ""
if (sc.ch == '"')
{
// A string ends here
sc.ForwardSetState(SCE_ASN1_DEFAULT);
// To correctly manage a char sticking to the string quote
goto asn1_default;
}
break;
case SCE_ASN1_SCALAR: // A plain number
if (!isAsn1Number (sc.ch))
// A number ends here
sc.SetState(SCE_ASN1_DEFAULT);
break;
case SCE_ASN1_OPERATOR: // The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap)
if (sc.ch == '{')
{
// An OID definition starts here: enter the sub loop
for (; sc.More(); sc.Forward())
{
if (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev)))
// The OID number is highlighted
sc.SetState(SCE_ASN1_OID);
else if (isAsn1Char (sc.ch))
// The OID parent identifier is plain
sc.SetState(SCE_ASN1_IDENTIFIER);
else
sc.SetState(SCE_ASN1_DEFAULT);
if (sc.ch == '}')
// Here ends the OID and the operator sub loop: go back to main loop
break;
}
}
else if (isAsn1Number (sc.ch))
{
// A trap number definition starts here: enter the sub loop
for (; sc.More(); sc.Forward())
{
if (isAsn1Number (sc.ch))
// The trap number is highlighted
sc.SetState(SCE_ASN1_OID);
else
{
// The number ends here: go back to main loop
sc.SetState(SCE_ASN1_DEFAULT);
break;
}
}
}
else if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ')
// The operator doesn't imply an OID definition nor a trap, back to main loop
goto asn1_default; // To be sure to handle actually the state change
break;
}
}
sc.Complete();
}
static void FoldAsn1Doc(unsigned int, int, int, WordList *[], Accessor &styler)
{
// No folding enabled, no reason to continue...
if( styler.GetPropertyInt("fold") == 0 )
return;
// No folding implemented: doesn't make sense for ASN.1
}
static const char * const asn1WordLists[] = {
"Keywords",
"Attributes",
"Descriptors",
"Types",
0, };
LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);

View File

@@ -0,0 +1,193 @@
// Scintilla source code edit control
/** @file LexBaan.cxx
** Lexer for Baan.
** Based heavily on LexCPP.cxx
**/
// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$' || ch == ':');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static void ColouriseBaanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
if (initStyle == SCE_BAAN_STRINGEOL) // Does not leak onto next line
initStyle = SCE_BAAN_DEFAULT;
int visibleChars = 0;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.state == SCE_BAAN_OPERATOR) {
sc.SetState(SCE_BAAN_DEFAULT);
} else if (sc.state == SCE_BAAN_NUMBER) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_BAAN_DEFAULT);
}
} else if (sc.state == SCE_BAAN_IDENTIFIER) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_BAAN_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_BAAN_WORD2);
}
sc.SetState(SCE_BAAN_DEFAULT);
}
} else if (sc.state == SCE_BAAN_PREPROCESSOR) {
if (stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
sc.SetState(SCE_BAAN_DEFAULT);
}
} else {
if (sc.atLineEnd && (sc.chNext != '^')) {
sc.SetState(SCE_BAAN_DEFAULT);
}
}
} else if (sc.state == SCE_BAAN_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_BAAN_DEFAULT);
}
} else if (sc.state == SCE_BAAN_COMMENTDOC) {
if (sc.MatchIgnoreCase("enddllusage")) {
for (unsigned int i = 0; i < 10; i++){
sc.Forward();
}
sc.ForwardSetState(SCE_BAAN_DEFAULT);
}
} else if (sc.state == SCE_BAAN_STRING) {
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_BAAN_DEFAULT);
} else if ((sc.atLineEnd) && (sc.chNext != '^')) {
sc.ChangeState(SCE_BAAN_STRINGEOL);
sc.ForwardSetState(SCE_C_DEFAULT);
visibleChars = 0;
}
}
if (sc.state == SCE_BAAN_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_BAAN_NUMBER);
} else if (sc.MatchIgnoreCase("dllusage")){
sc.SetState(SCE_BAAN_COMMENTDOC);
do {
sc.Forward();
} while ((!sc.atLineEnd) && sc.More());
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_BAAN_IDENTIFIER);
} else if (sc.Match('|')){
sc.SetState(SCE_BAAN_COMMENT);
} else if (sc.ch == '\"') {
sc.SetState(SCE_BAAN_STRING);
} else if (sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
sc.SetState(SCE_BAAN_PREPROCESSOR);
// Skip whitespace between # and preprocessor word
do {
sc.Forward();
} while (IsASpace(sc.ch) && sc.More());
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_BAAN_OPERATOR);
}
}
if (sc.atLineEnd) {
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
visibleChars = 0;
}
if (!IsASpace(sc.ch)) {
visibleChars++;
}
}
sc.Complete();
}
static void FoldBaanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment &&
(style == SCE_BAAN_COMMENT || style == SCE_BAAN_COMMENTDOC)) {
if (style != stylePrev) {
levelCurrent++;
} else if ((style != styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelCurrent--;
}
}
if (style == SCE_BAAN_OPERATOR) {
if (ch == '{') {
levelCurrent++;
} else if (ch == '}') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
LexerModule lmBaan(SCLEX_BAAN, ColouriseBaanDoc, "baan", FoldBaanDoc);

View File

@@ -0,0 +1,521 @@
// Scintilla source code edit control
/** @file LexBash.cxx
** Lexer for Bash.
**/
// Copyright 2004-2008 by Neil Hodgson <neilh@scintilla.org>
// Adapted from LexPerl by Kein-Hong Man 2004
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#define HERE_DELIM_MAX 256
// define this if you want 'invalid octals' to be marked as errors
// usually, this is not a good idea, permissive lexing is better
#undef PEDANTIC_OCTAL
#define BASH_BASE_ERROR 65
#define BASH_BASE_DECIMAL 66
#define BASH_BASE_HEX 67
#ifdef PEDANTIC_OCTAL
#define BASH_BASE_OCTAL 68
#define BASH_BASE_OCTAL_ERROR 69
#endif
static inline int translateBashDigit(int ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
} else if (ch >= 'a' && ch <= 'z') {
return ch - 'a' + 10;
} else if (ch >= 'A' && ch <= 'Z') {
return ch - 'A' + 36;
} else if (ch == '@') {
return 62;
} else if (ch == '_') {
return 63;
}
return BASH_BASE_ERROR;
}
static inline int getBashNumberBase(char *s) {
int i = 0;
int base = 0;
while (*s) {
base = base * 10 + (*s++ - '0');
i++;
}
if (base > 64 || i > 2) {
return BASH_BASE_ERROR;
}
return base;
}
static int opposite(int ch) {
if (ch == '(') return ')';
if (ch == '[') return ']';
if (ch == '{') return '}';
if (ch == '<') return '>';
return ch;
}
static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
CharacterSet setWordStart(CharacterSet::setAlpha, "_");
// note that [+-] are often parts of identifiers in shell scripts
CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
CharacterSet setBashOperator(CharacterSet::setNone, "^&\\%()-+=|{}[]:;>,*/<?!.~@");
CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!");
CharacterSet setLeftShift(CharacterSet::setDigits, "=$");
class HereDocCls { // Class to manage HERE document elements
public:
int State; // 0: '<<' encountered
// 1: collect the delimiter
// 2: here doc text (lines after the delimiter)
int Quote; // the char after '<<'
bool Quoted; // true if Quote in ('\'','"','`')
bool Indent; // indented delimiter (for <<-)
int DelimiterLength; // strlen(Delimiter)
char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
HereDocCls() {
State = 0;
Quote = 0;
Quoted = false;
Indent = 0;
DelimiterLength = 0;
Delimiter = new char[HERE_DELIM_MAX];
Delimiter[0] = '\0';
}
void Append(int ch) {
Delimiter[DelimiterLength++] = static_cast<char>(ch);
Delimiter[DelimiterLength] = '\0';
}
~HereDocCls() {
delete []Delimiter;
}
};
HereDocCls HereDoc;
class QuoteCls { // Class to manage quote pairs (simplified vs LexPerl)
public:
int Count;
int Up, Down;
QuoteCls() {
Count = 0;
Up = '\0';
Down = '\0';
}
void Open(int u) {
Count++;
Up = u;
Down = opposite(Up);
}
void Start(int u) {
Count = 0;
Open(u);
}
};
QuoteCls Quote;
int numBase = 0;
int digit;
unsigned int endPos = startPos + length;
// Backtrack to beginning of style if required...
// If in a long distance lexical state, backtrack to find quote characters
if (initStyle == SCE_SH_HERE_Q) {
while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_SH_HERE_DELIM)) {
startPos--;
}
startPos = styler.LineStart(styler.GetLine(startPos));
initStyle = styler.StyleAt(startPos - 1);
}
// Bash strings can be multi-line with embedded newlines, so backtrack.
// Bash numbers have additional state during lexing, so backtrack too.
if (initStyle == SCE_SH_STRING
|| initStyle == SCE_SH_BACKTICKS
|| initStyle == SCE_SH_CHARACTER
|| initStyle == SCE_SH_NUMBER
|| initStyle == SCE_SH_IDENTIFIER
|| initStyle == SCE_SH_COMMENTLINE) {
while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
startPos--;
}
initStyle = SCE_SH_DEFAULT;
}
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
for (; sc.More(); sc.Forward()) {
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_SH_OPERATOR:
sc.SetState(SCE_SH_DEFAULT);
break;
case SCE_SH_WORD:
// "." never used in Bash variable names but used in file names
if (!setWord.Contains(sc.ch)) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (s[0] != '-' && // for file operators
!keywords.InList(s)) {
sc.ChangeState(SCE_SH_IDENTIFIER);
}
sc.SetState(SCE_SH_DEFAULT);
}
break;
case SCE_SH_IDENTIFIER:
if (sc.chPrev == '\\') { // for escaped chars
sc.ForwardSetState(SCE_SH_DEFAULT);
} else if (!setWord.Contains(sc.ch)) {
sc.SetState(SCE_SH_DEFAULT);
}
break;
case SCE_SH_NUMBER:
digit = translateBashDigit(sc.ch);
if (numBase == BASH_BASE_DECIMAL) {
if (sc.ch == '#') {
char s[10];
sc.GetCurrent(s, sizeof(s));
numBase = getBashNumberBase(s);
if (numBase != BASH_BASE_ERROR)
break;
} else if (IsADigit(sc.ch))
break;
} else if (numBase == BASH_BASE_HEX) {
if (IsADigit(sc.ch, 16))
break;
#ifdef PEDANTIC_OCTAL
} else if (numBase == BASH_BASE_OCTAL ||
numBase == BASH_BASE_OCTAL_ERROR) {
if (digit <= 7)
break;
if (digit <= 9) {
numBase = BASH_BASE_OCTAL_ERROR;
break;
}
#endif
} else if (numBase == BASH_BASE_ERROR) {
if (digit <= 9)
break;
} else { // DD#DDDD number style handling
if (digit != BASH_BASE_ERROR) {
if (numBase <= 36) {
// case-insensitive if base<=36
if (digit >= 36) digit -= 26;
}
if (digit < numBase)
break;
if (digit <= 9) {
numBase = BASH_BASE_ERROR;
break;
}
}
}
// fallthrough when number is at an end or error
if (numBase == BASH_BASE_ERROR
#ifdef PEDANTIC_OCTAL
|| numBase == BASH_BASE_OCTAL_ERROR
#endif
) {
sc.ChangeState(SCE_SH_ERROR);
}
sc.SetState(SCE_SH_DEFAULT);
break;
case SCE_SH_COMMENTLINE:
if (sc.atLineEnd && sc.chPrev != '\\') {
sc.SetState(SCE_SH_DEFAULT);
}
break;
case SCE_SH_HERE_DELIM:
// From Bash info:
// ---------------
// Specifier format is: <<[-]WORD
// Optional '-' is for removal of leading tabs from here-doc.
// Whitespace acceptable after <<[-] operator
//
if (HereDoc.State == 0) { // '<<' encountered
HereDoc.Quote = sc.chNext;
HereDoc.Quoted = false;
HereDoc.DelimiterLength = 0;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
if (sc.chNext == '\'' || sc.chNext == '\"') { // a quoted here-doc delimiter (' or ")
sc.Forward();
HereDoc.Quoted = true;
HereDoc.State = 1;
} else if (!HereDoc.Indent && sc.chNext == '-') { // <<- indent case
HereDoc.Indent = true;
} else if (setHereDoc.Contains(sc.chNext)) {
// an unquoted here-doc delimiter, no special handling
// TODO check what exactly bash considers part of the delim
HereDoc.State = 1;
} else if (sc.chNext == '<') { // HERE string <<<
sc.Forward();
sc.ForwardSetState(SCE_SH_DEFAULT);
} else if (IsASpace(sc.chNext)) {
// eat whitespace
} else if (setLeftShift.Contains(sc.chNext)) {
// left shift << or <<= operator cases
sc.ChangeState(SCE_SH_OPERATOR);
sc.ForwardSetState(SCE_SH_DEFAULT);
} else {
// symbols terminates; deprecated zero-length delimiter
HereDoc.State = 1;
}
} else if (HereDoc.State == 1) { // collect the delimiter
if (setHereDoc2.Contains(sc.ch) || sc.chPrev == '\\') {
HereDoc.Append(sc.ch);
} else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
sc.ForwardSetState(SCE_SH_DEFAULT);
} else if (sc.ch == '\\') {
// skip escape prefix
} else {
sc.SetState(SCE_SH_DEFAULT);
}
if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup
sc.SetState(SCE_SH_ERROR);
HereDoc.State = 0;
}
}
break;
case SCE_SH_HERE_Q:
// HereDoc.State == 2
if (sc.atLineStart) {
sc.SetState(SCE_SH_HERE_Q);
int prefixws = 0;
while (IsASpace(sc.ch) && !sc.atLineEnd) { // whitespace prefix
sc.Forward();
prefixws++;
}
if (prefixws > 0)
sc.SetState(SCE_SH_HERE_Q);
while (!sc.atLineEnd) {
sc.Forward();
}
char s[HERE_DELIM_MAX];
sc.GetCurrent(s, sizeof(s));
if (sc.LengthCurrent() == 0)
break;
if (s[strlen(s) - 1] == '\r')
s[strlen(s) - 1] = '\0';
if (strcmp(HereDoc.Delimiter, s) == 0) {
if ((prefixws > 0 && HereDoc.Indent) || // indentation rule
(prefixws == 0 && !HereDoc.Indent)) {
sc.SetState(SCE_SH_DEFAULT);
break;
}
}
}
break;
case SCE_SH_SCALAR: // variable names
if (!setParam.Contains(sc.ch)) {
if (sc.LengthCurrent() == 1) {
// Special variable: $(, $_ etc.
sc.ForwardSetState(SCE_SH_DEFAULT);
} else {
sc.SetState(SCE_SH_DEFAULT);
}
}
break;
case SCE_SH_STRING: // delimited styles
case SCE_SH_CHARACTER:
case SCE_SH_BACKTICKS:
case SCE_SH_PARAM:
if (sc.ch == '\\' && Quote.Up != '\\') {
sc.Forward();
} else if (sc.ch == Quote.Down) {
Quote.Count--;
if (Quote.Count == 0) {
sc.ForwardSetState(SCE_SH_DEFAULT);
}
} else if (sc.ch == Quote.Up) {
Quote.Count++;
}
break;
}
// Must check end of HereDoc state 1 before default state is handled
if (HereDoc.State == 1 && sc.atLineEnd) {
// Begin of here-doc (the line after the here-doc delimiter):
// Lexically, the here-doc starts from the next line after the >>, but the
// first line of here-doc seem to follow the style of the last EOL sequence
HereDoc.State = 2;
if (HereDoc.Quoted) {
if (sc.state == SCE_SH_HERE_DELIM) {
// Missing quote at end of string! We are stricter than bash.
// Colour here-doc anyway while marking this bit as an error.
sc.ChangeState(SCE_SH_ERROR);
}
// HereDoc.Quote always == '\''
}
sc.SetState(SCE_SH_HERE_Q);
}
// Determine if a new state should be entered.
if (sc.state == SCE_SH_DEFAULT) {
if (sc.ch == '\\') { // escaped character
sc.SetState(SCE_SH_IDENTIFIER);
} else if (IsADigit(sc.ch)) {
sc.SetState(SCE_SH_NUMBER);
numBase = BASH_BASE_DECIMAL;
if (sc.ch == '0') { // hex,octal
if (sc.chNext == 'x' || sc.chNext == 'X') {
numBase = BASH_BASE_HEX;
sc.Forward();
} else if (IsADigit(sc.chNext)) {
#ifdef PEDANTIC_OCTAL
numBase = BASH_BASE_OCTAL;
#else
numBase = BASH_BASE_HEX;
#endif
}
}
} else if (setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_SH_WORD);
} else if (sc.ch == '#') {
sc.SetState(SCE_SH_COMMENTLINE);
} else if (sc.ch == '\"') {
sc.SetState(SCE_SH_STRING);
Quote.Start(sc.ch);
} else if (sc.ch == '\'') {
sc.SetState(SCE_SH_CHARACTER);
Quote.Start(sc.ch);
} else if (sc.ch == '`') {
sc.SetState(SCE_SH_BACKTICKS);
Quote.Start(sc.ch);
} else if (sc.ch == '$') {
sc.SetState(SCE_SH_SCALAR);
sc.Forward();
if (sc.ch == '{') {
sc.ChangeState(SCE_SH_PARAM);
} else if (sc.ch == '\'') {
sc.ChangeState(SCE_SH_CHARACTER);
} else if (sc.ch == '"') {
sc.ChangeState(SCE_SH_STRING);
} else if (sc.ch == '(' || sc.ch == '`') {
sc.ChangeState(SCE_SH_BACKTICKS);
if (sc.chNext == '(') { // $(( is lexed as operator
sc.ChangeState(SCE_SH_OPERATOR);
}
} else {
continue; // scalar has no delimiter pair
}
// fallthrough, open delim for $[{'"(`]
Quote.Start(sc.ch);
} else if (sc.Match('<', '<')) {
sc.SetState(SCE_SH_HERE_DELIM);
HereDoc.State = 0;
HereDoc.Indent = false;
} else if (sc.ch == '-' && // one-char file test operators
setSingleCharOp.Contains(sc.chNext) &&
!setWord.Contains(sc.GetRelative(2)) &&
IsASpace(sc.chPrev)) {
sc.SetState(SCE_SH_WORD);
sc.Forward();
} else if (setBashOperator.Contains(sc.ch)) {
sc.SetState(SCE_SH_OPERATOR);
}
}
}
sc.Complete();
}
static bool IsCommentLine(int line, Accessor &styler) {
int pos = styler.LineStart(line);
int eol_pos = styler.LineStart(line + 1) - 1;
for (int i = pos; i < eol_pos; i++) {
char ch = styler[i];
if (ch == '#')
return true;
else if (ch != ' ' && ch != '\t')
return false;
}
return false;
}
static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
// Comment folding
if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
{
if (!IsCommentLine(lineCurrent - 1, styler)
&& IsCommentLine(lineCurrent + 1, styler))
levelCurrent++;
else if (IsCommentLine(lineCurrent - 1, styler)
&& !IsCommentLine(lineCurrent + 1, styler))
levelCurrent--;
}
if (style == SCE_SH_OPERATOR) {
if (ch == '{') {
levelCurrent++;
} else if (ch == '}') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const bashWordListDesc[] = {
"Keywords",
0
};
LexerModule lmBash(SCLEX_BASH, ColouriseBashDoc, "bash", FoldBashDoc, bashWordListDesc);

View File

@@ -0,0 +1,373 @@
// Scintilla source code edit control
/** @file LexBasic.cxx
** Lexer for BlitzBasic and PureBasic.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics
// and derivatives. Once they diverge enough, might want to split it into multiple
// lexers for more code clearity.
//
// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.
// Folding only works for simple things like functions or types.
// You may want to have a look at my ctags lexer as well, if you additionally to coloring
// and folding need to extract things like label tags in your editor.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/* Bits:
* 1 - whitespace
* 2 - operator
* 4 - identifier
* 8 - decimal digit
* 16 - hex digit
* 32 - bin digit
*/
static int character_classification[128] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
};
static bool IsSpace(int c) {
return c < 128 && (character_classification[c] & 1);
}
static bool IsOperator(int c) {
return c < 128 && (character_classification[c] & 2);
}
static bool IsIdentifier(int c) {
return c < 128 && (character_classification[c] & 4);
}
static bool IsDigit(int c) {
return c < 128 && (character_classification[c] & 8);
}
static bool IsHexDigit(int c) {
return c < 128 && (character_classification[c] & 16);
}
static bool IsBinDigit(int c) {
return c < 128 && (character_classification[c] & 32);
}
static int LowerCase(int c)
{
if (c >= 'A' && c <= 'Z')
return 'a' + c - 'A';
return c;
}
static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, char comment_char) {
bool wasfirst = true, isfirst = true; // true if first token in a line
styler.StartAt(startPos);
StyleContext sc(startPos, length, initStyle, styler);
// Can't use sc.More() here else we miss the last character
for (; ; sc.Forward()) {
if (sc.state == SCE_B_IDENTIFIER) {
if (!IsIdentifier(sc.ch)) {
// Labels
if (wasfirst && sc.Match(':')) {
sc.ChangeState(SCE_B_LABEL);
sc.ForwardSetState(SCE_B_DEFAULT);
} else {
char s[100];
int kstates[4] = {
SCE_B_KEYWORD,
SCE_B_KEYWORD2,
SCE_B_KEYWORD3,
SCE_B_KEYWORD4,
};
sc.GetCurrentLowered(s, sizeof(s));
for (int i = 0; i < 4; i++) {
if (keywordlists[i]->InList(s)) {
sc.ChangeState(kstates[i]);
}
}
// Types, must set them as operator else they will be
// matched as number/constant
if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||
sc.Match('#')) {
sc.SetState(SCE_B_OPERATOR);
} else {
sc.SetState(SCE_B_DEFAULT);
}
}
}
} else if (sc.state == SCE_B_OPERATOR) {
if (!IsOperator(sc.ch) || sc.Match('#'))
sc.SetState(SCE_B_DEFAULT);
} else if (sc.state == SCE_B_LABEL) {
if (!IsIdentifier(sc.ch))
sc.SetState(SCE_B_DEFAULT);
} else if (sc.state == SCE_B_CONSTANT) {
if (!IsIdentifier(sc.ch))
sc.SetState(SCE_B_DEFAULT);
} else if (sc.state == SCE_B_NUMBER) {
if (!IsDigit(sc.ch))
sc.SetState(SCE_B_DEFAULT);
} else if (sc.state == SCE_B_HEXNUMBER) {
if (!IsHexDigit(sc.ch))
sc.SetState(SCE_B_DEFAULT);
} else if (sc.state == SCE_B_BINNUMBER) {
if (!IsBinDigit(sc.ch))
sc.SetState(SCE_B_DEFAULT);
} else if (sc.state == SCE_B_STRING) {
if (sc.ch == '"') {
sc.ForwardSetState(SCE_B_DEFAULT);
}
if (sc.atLineEnd) {
sc.ChangeState(SCE_B_ERROR);
sc.SetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) {
if (sc.atLineEnd) {
sc.SetState(SCE_B_DEFAULT);
}
}
if (sc.atLineStart)
isfirst = true;
if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
if (isfirst && sc.Match('.')) {
sc.SetState(SCE_B_LABEL);
} else if (isfirst && sc.Match('#')) {
wasfirst = isfirst;
sc.SetState(SCE_B_IDENTIFIER);
} else if (sc.Match(comment_char)) {
// Hack to make deprecated QBASIC '$Include show
// up in freebasic with SCE_B_PREPROCESSOR.
if (comment_char == '\'' && sc.Match(comment_char, '$'))
sc.SetState(SCE_B_PREPROCESSOR);
else
sc.SetState(SCE_B_COMMENT);
} else if (sc.Match('"')) {
sc.SetState(SCE_B_STRING);
} else if (IsDigit(sc.ch)) {
sc.SetState(SCE_B_NUMBER);
} else if (sc.Match('$')) {
sc.SetState(SCE_B_HEXNUMBER);
} else if (sc.Match('%')) {
sc.SetState(SCE_B_BINNUMBER);
} else if (sc.Match('#')) {
sc.SetState(SCE_B_CONSTANT);
} else if (IsOperator(sc.ch)) {
sc.SetState(SCE_B_OPERATOR);
} else if (IsIdentifier(sc.ch)) {
wasfirst = isfirst;
sc.SetState(SCE_B_IDENTIFIER);
} else if (!IsSpace(sc.ch)) {
sc.SetState(SCE_B_ERROR);
}
}
if (!IsSpace(sc.ch))
isfirst = false;
if (!sc.More())
break;
}
sc.Complete();
}
static int CheckBlitzFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "sub") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static void FoldBasicDoc(unsigned int startPos, int length,
Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
int line = styler.GetLine(startPos);
int level = styler.LevelAt(line);
int go = 0, done = 0;
int endPos = startPos + length;
char word[256];
int wordlen = 0;
int i;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
// Scan for tokens at the start of the line (they may include
// whitespace, for tokens like "End Function"
for (i = startPos; i < endPos; i++) {
int c = styler.SafeGetCharAt(i);
if (!done && !go) {
if (wordlen) { // are we scanning a token already?
word[wordlen] = static_cast<char>(LowerCase(c));
if (!IsIdentifier(c)) { // done with token
word[wordlen] = '\0';
go = CheckFoldPoint(word, level);
if (!go) {
// Treat any whitespace as single blank, for
// things like "End Function".
if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
word[wordlen] = ' ';
if (wordlen < 255)
wordlen++;
}
else // done with this line
done = 1;
}
} else if (wordlen < 255) {
wordlen++;
}
} else { // start scanning at first non-whitespace character
if (!IsSpace(c)) {
if (IsIdentifier(c)) {
word[0] = static_cast<char>(LowerCase(c));
wordlen = 1;
} else // done with this line
done = 1;
}
}
}
if (c == '\n') { // line end
if (!done && wordlen == 0 && foldCompact) // line was only space
level |= SC_FOLDLEVELWHITEFLAG;
if (level != styler.LevelAt(line))
styler.SetLevel(line, level);
level += go;
line++;
// reset state
wordlen = 0;
level &= ~SC_FOLDLEVELHEADERFLAG;
level &= ~SC_FOLDLEVELWHITEFLAG;
go = 0;
done = 0;
}
}
}
static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
}
static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
}
static void FoldPureBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
}
static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
}
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
FoldBlitzBasicDoc, blitzbasicWordListDesc);
LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
FoldPureBasicDoc, purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
FoldFreeBasicDoc, freebasicWordListDesc);

View File

@@ -0,0 +1,229 @@
// SciTE - Scintilla based Text Editor
// LexBullant.cxx - lexer for Bullant
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100];
s[0] = '\0';
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0';
}
int lev= 0;
char chAttr = SCE_C_IDENTIFIER;
if (isdigit(s[0]) || (s[0] == '.')){
chAttr = SCE_C_NUMBER;
}
else {
if (keywords.InList(s)) {
chAttr = SCE_C_WORD;
if (strcmp(s, "end") == 0)
lev = -1;
else if (strcmp(s, "method") == 0 ||
strcmp(s, "case") == 0 ||
strcmp(s, "class") == 0 ||
strcmp(s, "debug") == 0 ||
strcmp(s, "test") == 0 ||
strcmp(s, "if") == 0 ||
strcmp(s, "lock") == 0 ||
strcmp(s, "transaction") == 0 ||
strcmp(s, "trap") == 0 ||
strcmp(s, "until") == 0 ||
strcmp(s, "while") == 0)
lev = 1;
}
}
styler.ColourTo(end, chAttr);
return lev;
}
static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
styler.StartAt(startPos);
bool fold = styler.GetPropertyInt("fold") != 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
int state = initStyle;
if (state == SCE_C_STRINGEOL) // Does not leak onto next line
state = SCE_C_DEFAULT;
char chPrev = ' ';
char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
styler.StartSegment(startPos);
int endFoundThisLine = 0;
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
// Avoid triggering two times on Dos/Win
// End of line
endFoundThisLine = 0;
if (state == SCE_C_STRINGEOL) {
styler.ColourTo(i, state);
state = SCE_C_DEFAULT;
}
if (fold) {
int lev = levelPrev;
if (visibleChars == 0)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
levelPrev = levelCurrent;
}
visibleChars = 0;
/* int indentBlock = GetLineIndentation(lineCurrent);
if (blockChange==1){
lineCurrent++;
int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize);
} else if (blockChange==-1) {
indentBlock -= indentSize;
if (indentBlock < 0)
indentBlock = 0;
SetLineIndentation(lineCurrent, indentBlock);
lineCurrent++;
}
blockChange=0;
*/ }
if (!(isascii(ch) && isspace(ch)))
visibleChars++;
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
chPrev = ' ';
i += 1;
continue;
}
if (state == SCE_C_DEFAULT) {
if (iswordstart(ch)) {
styler.ColourTo(i-1, state);
state = SCE_C_IDENTIFIER;
} else if (ch == '@' && chNext == 'o') {
if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) {
styler.ColourTo(i-1, state);
state = SCE_C_COMMENT;
}
} else if (ch == '#') {
styler.ColourTo(i-1, state);
state = SCE_C_COMMENTLINE;
} else if (ch == '\"') {
styler.ColourTo(i-1, state);
state = SCE_C_STRING;
} else if (ch == '\'') {
styler.ColourTo(i-1, state);
state = SCE_C_CHARACTER;
} else if (isoperator(ch)) {
styler.ColourTo(i-1, state);
styler.ColourTo(i, SCE_C_OPERATOR);
}
} else if (state == SCE_C_IDENTIFIER) {
if (!iswordchar(ch)) {
int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler);
state = SCE_C_DEFAULT;
chNext = styler.SafeGetCharAt(i + 1);
if (ch == '#') {
state = SCE_C_COMMENTLINE;
} else if (ch == '\"') {
state = SCE_C_STRING;
} else if (ch == '\'') {
state = SCE_C_CHARACTER;
} else if (isoperator(ch)) {
styler.ColourTo(i, SCE_C_OPERATOR);
}
if (endFoundThisLine == 0)
levelCurrent+=levelChange;
if (levelChange == -1)
endFoundThisLine=1;
}
} else if (state == SCE_C_COMMENT) {
if (ch == '@' && chNext == 'o') {
if (styler.SafeGetCharAt(i+2) == 'n') {
styler.ColourTo(i+2, state);
state = SCE_C_DEFAULT;
i+=2;
}
}
} else if (state == SCE_C_COMMENTLINE) {
if (ch == '\r' || ch == '\n') {
endFoundThisLine = 0;
styler.ColourTo(i-1, state);
state = SCE_C_DEFAULT;
}
} else if (state == SCE_C_STRING) {
if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
}
} else if (ch == '\"') {
styler.ColourTo(i, state);
state = SCE_C_DEFAULT;
} else if (chNext == '\r' || chNext == '\n') {
endFoundThisLine = 0;
styler.ColourTo(i-1, SCE_C_STRINGEOL);
state = SCE_C_STRINGEOL;
}
} else if (state == SCE_C_CHARACTER) {
if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
endFoundThisLine = 0;
styler.ColourTo(i-1, SCE_C_STRINGEOL);
state = SCE_C_STRINGEOL;
} else if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
}
} else if (ch == '\'') {
styler.ColourTo(i, state);
state = SCE_C_DEFAULT;
}
}
chPrev = ch;
}
styler.ColourTo(lengthDoc - 1, state);
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
if (fold) {
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
//styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
}
static const char * const bullantWordListDesc[] = {
"Keywords",
0
};
LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);

View File

@@ -0,0 +1,679 @@
// Scintilla source code edit control
/** @file LexClw.cxx
** Lexer for Clarion.
** 2004/12/17 Updated Lexer
**/
// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// Is an end of line character
inline bool IsEOL(const int ch) {
return(ch == '\n');
}
// Convert character to uppercase
static char CharacterUpper(char chChar) {
if (chChar < 'a' || chChar > 'z') {
return(chChar);
}
else {
return(static_cast<char>(chChar - 'a' + 'A'));
}
}
// Convert string to uppercase
static void StringUpper(char *szString) {
while (*szString) {
*szString = CharacterUpper(*szString);
szString++;
}
}
// Is a label start character
inline bool IsALabelStart(const int iChar) {
return(isalpha(iChar) || iChar == '_');
}
// Is a label character
inline bool IsALabelCharacter(const int iChar) {
return(isalnum(iChar) || iChar == '_' || iChar == ':');
}
// Is the character is a ! and the the next character is not a !
inline bool IsACommentStart(const int iChar) {
return(iChar == '!');
}
// Is the character a Clarion hex character (ABCDEF)
inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
// Case insensitive.
if (!bCaseSensitive) {
if (strchr("ABCDEFabcdef", iChar) != NULL) {
return(true);
}
}
// Case sensitive
else {
if (strchr("ABCDEF", iChar) != NULL) {
return(true);
}
}
return(false);
}
// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
// Case insensitive.
if (!bCaseSensitive) {
// If character is a numeric base character
if (strchr("BOHboh", iChar) != NULL) {
return(true);
}
}
// Case sensitive
else {
// If character is a numeric base character
if (strchr("BOH", iChar) != NULL) {
return(true);
}
}
return(false);
}
// Set the correct numeric constant state
inline bool SetNumericConstantState(StyleContext &scDoc) {
int iPoints = 0; // Point counter
char cNumericString[512]; // Numeric string buffer
// Buffer the current numberic string
scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
// Loop through the string until end of string (NULL termination)
for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) {
// Depending on the character
switch (cNumericString[iIndex]) {
// Is a . (point)
case '.' :
// Increment point counter
iPoints++;
break;
default :
break;
}
}
// If points found (can be more than one for improper formatted number
if (iPoints > 0) {
return(true);
}
// Else no points found
else {
return(false);
}
}
// Get the next word in uppercase from the current position (keyword lookahead)
inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
unsigned int iIndex = 0; // Buffer Index
// Loop through the remaining string from the current position
for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
// Get the character from the buffer using the offset
char cCharacter = styler[iOffset];
if (IsEOL(cCharacter)) {
break;
}
// If the character is alphabet character
if (isalpha(cCharacter)) {
// Add UPPERCASE character to the word buffer
cWord[iIndex++] = CharacterUpper(cCharacter);
}
}
// Add null termination
cWord[iIndex] = '\0';
// If no word was found
if (iIndex == 0) {
// Return failure
return(false);
}
// Else word was found
else {
// Return success
return(true);
}
}
// Clarion Language Colouring Procedure
static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
int iParenthesesLevel = 0; // Parenthese Level
int iColumn1Label = false; // Label starts in Column 1
WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
const char wlProcReservedKeywordList[] =
"PROCEDURE FUNCTION";
WordList wlProcReservedKeywords;
wlProcReservedKeywords.Set(wlProcReservedKeywordList);
const char wlCompilerKeywordList[] =
"COMPILE OMIT";
WordList wlCompilerKeywords;
wlCompilerKeywords.Set(wlCompilerKeywordList);
const char wlLegacyStatementsList[] =
"BOF EOF FUNCTION POINTER SHARE";
WordList wlLegacyStatements;
wlLegacyStatements.Set(wlLegacyStatementsList);
StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
// lex source code
for (; scDoc.More(); scDoc.Forward())
{
//
// Determine if the current state should terminate.
//
// Label State Handling
if (scDoc.state == SCE_CLW_LABEL) {
// If the character is not a valid label
if (!IsALabelCharacter(scDoc.ch)) {
// If the character is a . (dot syntax)
if (scDoc.ch == '.') {
// Turn off column 1 label flag as label now cannot be reserved work
iColumn1Label = false;
// Uncolour the . (dot) to default state, move forward one character,
// and change back to the label state.
scDoc.SetState(SCE_CLW_DEFAULT);
scDoc.Forward();
scDoc.SetState(SCE_CLW_LABEL);
}
// Else check label
else {
char cLabel[512]; // Label buffer
// Buffer the current label string
scDoc.GetCurrent(cLabel,sizeof(cLabel));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
StringUpper(cLabel);
}
// Else if UPPERCASE label string is in the Clarion compiler keyword list
if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
// change the label to error state
scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
}
// Else if UPPERCASE label string is in the Clarion reserved keyword list
else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
// change the label to error state
scDoc.ChangeState(SCE_CLW_ERROR);
}
// Else if UPPERCASE label string is
else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
char cWord[512]; // Word buffer
// Get the next word from the current position
if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
// If the next word is a procedure reserved word
if (wlProcReservedKeywords.InList(cWord)) {
// Change the label to error state
scDoc.ChangeState(SCE_CLW_ERROR);
}
}
}
// Else if label string is in the compiler directive keyword list
else if (wlCompilerDirectives.InList(cLabel)) {
// change the state to compiler directive state
scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
}
// Terminate the label state and set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
}
}
// Keyword State Handling
else if (scDoc.state == SCE_CLW_KEYWORD) {
// If character is : (colon)
if (scDoc.ch == ':') {
char cEquate[512]; // Equate buffer
// Move forward to include : (colon) in buffer
scDoc.Forward();
// Buffer the equate string
scDoc.GetCurrent(cEquate,sizeof(cEquate));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
StringUpper(cEquate);
}
// If statement string is in the equate list
if (wlStandardEquates.InList(cEquate)) {
// Change to equate state
scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
}
}
// If the character is not a valid label character
else if (!IsALabelCharacter(scDoc.ch)) {
char cStatement[512]; // Statement buffer
// Buffer the statement string
scDoc.GetCurrent(cStatement,sizeof(cStatement));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
StringUpper(cStatement);
}
// If statement string is in the Clarion keyword list
if (wlClarionKeywords.InList(cStatement)) {
// Change the statement string to the Clarion keyword state
scDoc.ChangeState(SCE_CLW_KEYWORD);
}
// Else if statement string is in the compiler directive keyword list
else if (wlCompilerDirectives.InList(cStatement)) {
// Change the statement string to the compiler directive state
scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
}
// Else if statement string is in the runtime expressions keyword list
else if (wlRuntimeExpressions.InList(cStatement)) {
// Change the statement string to the runtime expressions state
scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
}
// Else if statement string is in the builtin procedures and functions keyword list
else if (wlBuiltInProcsFuncs.InList(cStatement)) {
// Change the statement string to the builtin procedures and functions state
scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
}
// Else if statement string is in the tructures and data types keyword list
else if (wlStructsDataTypes.InList(cStatement)) {
// Change the statement string to the structures and data types state
scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
}
// Else if statement string is in the procedure attribute keyword list
else if (wlAttributes.InList(cStatement)) {
// Change the statement string to the procedure attribute state
scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
}
// Else if statement string is in the standard equate keyword list
else if (wlStandardEquates.InList(cStatement)) {
// Change the statement string to the standard equate state
scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
}
// Else if statement string is in the deprecated or legacy keyword list
else if (wlLegacyStatements.InList(cStatement)) {
// Change the statement string to the standard equate state
scDoc.ChangeState(SCE_CLW_DEPRECATED);
}
// Else the statement string doesn't match any work list
else {
// Change the statement string to the default state
scDoc.ChangeState(SCE_CLW_DEFAULT);
}
// Terminate the keyword state and set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
}
// String State Handling
else if (scDoc.state == SCE_CLW_STRING) {
// If the character is an ' (single quote)
if (scDoc.ch == '\'') {
// Set the state to default and move forward colouring
// the ' (single quote) as default state
// terminating the string state
scDoc.SetState(SCE_CLW_DEFAULT);
scDoc.Forward();
}
// If the next character is an ' (single quote)
if (scDoc.chNext == '\'') {
// Move forward one character and set to default state
// colouring the next ' (single quote) as default state
// terminating the string state
scDoc.ForwardSetState(SCE_CLW_DEFAULT);
scDoc.Forward();
}
}
// Picture String State Handling
else if (scDoc.state == SCE_CLW_PICTURE_STRING) {
// If the character is an ( (open parenthese)
if (scDoc.ch == '(') {
// Increment the parenthese level
iParenthesesLevel++;
}
// Else if the character is a ) (close parenthese)
else if (scDoc.ch == ')') {
// If the parenthese level is set to zero
// parentheses matched
if (!iParenthesesLevel) {
scDoc.SetState(SCE_CLW_DEFAULT);
}
// Else parenthese level is greater than zero
// still looking for matching parentheses
else {
// Decrement the parenthese level
iParenthesesLevel--;
}
}
}
// Standard Equate State Handling
else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) {
if (!isalnum(scDoc.ch)) {
scDoc.SetState(SCE_CLW_DEFAULT);
}
}
// Integer Constant State Handling
else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) {
// If the character is not a digit (0-9)
// or character is not a hexidecimal character (A-F)
// or character is not a . (point)
// or character is not a numberic base character (B,O,H)
if (!(isdigit(scDoc.ch)
|| IsAHexCharacter(scDoc.ch, bCaseSensitive)
|| scDoc.ch == '.'
|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
// If the number was a real
if (SetNumericConstantState(scDoc)) {
// Colour the matched string to the real constant state
scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
}
// Else the number was an integer
else {
// Colour the matched string to an integer constant state
scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT);
}
// Terminate the integer constant state and set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
}
//
// Determine if a new state should be entered.
//
// Beginning of Line Handling
if (scDoc.atLineStart) {
// Reset the column 1 label flag
iColumn1Label = false;
// If column 1 character is a label start character
if (IsALabelStart(scDoc.ch)) {
// Label character is found in column 1
// so set column 1 label flag and clear last column 1 label
iColumn1Label = true;
// Set the state to label
scDoc.SetState(SCE_CLW_LABEL);
}
// else if character is a space or tab
else if (IsASpace(scDoc.ch)){
// Set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
// else if comment start (!) or is an * (asterisk)
else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
}
// else the character is a ? (question mark)
else if (scDoc.ch == '?') {
// Change to the compiler directive state, move forward,
// colouring the ? (question mark), change back to default state.
scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
scDoc.Forward();
scDoc.SetState(SCE_CLW_DEFAULT);
}
// else an invalid character in column 1
else {
// Set to error state
scDoc.SetState(SCE_CLW_ERROR);
}
}
// End of Line Handling
else if (scDoc.atLineEnd) {
// Reset to the default state at the end of each line.
scDoc.SetState(SCE_CLW_DEFAULT);
}
// Default Handling
else {
// If in default state
if (scDoc.state == SCE_CLW_DEFAULT) {
// If is a letter could be a possible statement
if (isalpha(scDoc.ch)) {
// Set the state to Clarion Keyword and verify later
scDoc.SetState(SCE_CLW_KEYWORD);
}
// else is a number
else if (isdigit(scDoc.ch)) {
// Set the state to Integer Constant and verify later
scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
}
// else if the start of a comment or a | (line continuation)
else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
}
// else if the character is a ' (single quote)
else if (scDoc.ch == '\'') {
// If the character is also a ' (single quote)
// Embedded Apostrophe
if (scDoc.chNext == '\'') {
// Move forward colouring it as default state
scDoc.ForwardSetState(SCE_CLW_DEFAULT);
}
else {
// move to the next character and then set the state to comment.
scDoc.ForwardSetState(SCE_CLW_STRING);
}
}
// else the character is an @ (ampersand)
else if (scDoc.ch == '@') {
// Case insensitive.
if (!bCaseSensitive) {
// If character is a valid picture token character
if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) {
// Set to the picture string state
scDoc.SetState(SCE_CLW_PICTURE_STRING);
}
}
// Case sensitive
else {
// If character is a valid picture token character
if (strchr("DEKNPST", scDoc.chNext) != NULL) {
// Set the picture string state
scDoc.SetState(SCE_CLW_PICTURE_STRING);
}
}
}
}
}
}
// lexing complete
scDoc.Complete();
}
// Clarion Language Case Sensitive Colouring Procedure
static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
}
// Clarion Language Case Insensitive Colouring Procedure
static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
}
// Fill Buffer
static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
unsigned int uiPos = 0;
while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
uiPos++;
}
szBuffer[uiPos] = '\0';
}
// Classify Clarion Fold Point
static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
if (strcmp(szString, "PROCEDURE") == 0) {
// iLevel = SC_FOLDLEVELBASE + 1;
}
else if (strcmp(szString, "MAP") == 0 ||
strcmp(szString,"ACCEPT") == 0 ||
strcmp(szString,"BEGIN") == 0 ||
strcmp(szString,"CASE") == 0 ||
strcmp(szString,"EXECUTE") == 0 ||
strcmp(szString,"IF") == 0 ||
strcmp(szString,"ITEMIZE") == 0 ||
strcmp(szString,"INTERFACE") == 0 ||
strcmp(szString,"JOIN") == 0 ||
strcmp(szString,"LOOP") == 0 ||
strcmp(szString,"MODULE") == 0 ||
strcmp(szString,"RECORD") == 0) {
iLevel++;
}
else if (strcmp(szString, "APPLICATION") == 0 ||
strcmp(szString, "CLASS") == 0 ||
strcmp(szString, "DETAIL") == 0 ||
strcmp(szString, "FILE") == 0 ||
strcmp(szString, "FOOTER") == 0 ||
strcmp(szString, "FORM") == 0 ||
strcmp(szString, "GROUP") == 0 ||
strcmp(szString, "HEADER") == 0 ||
strcmp(szString, "INTERFACE") == 0 ||
strcmp(szString, "MENU") == 0 ||
strcmp(szString, "MENUBAR") == 0 ||
strcmp(szString, "OLE") == 0 ||
strcmp(szString, "OPTION") == 0 ||
strcmp(szString, "QUEUE") == 0 ||
strcmp(szString, "REPORT") == 0 ||
strcmp(szString, "SHEET") == 0 ||
strcmp(szString, "TAB") == 0 ||
strcmp(szString, "TOOLBAR") == 0 ||
strcmp(szString, "VIEW") == 0 ||
strcmp(szString, "WINDOW") == 0) {
iLevel++;
}
else if (strcmp(szString, "END") == 0 ||
strcmp(szString, "UNTIL") == 0 ||
strcmp(szString, "WHILE") == 0) {
iLevel--;
}
}
return(iLevel);
}
// Clarion Language Folding Procedure
static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
unsigned int uiEndPos = uiStartPos + iLength;
int iLineCurrent = accStyler.GetLine(uiStartPos);
int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
int iLevelCurrent = iLevelPrev;
char chNext = accStyler[uiStartPos];
int iStyle = iInitStyle;
int iStyleNext = accStyler.StyleAt(uiStartPos);
int iVisibleChars = 0;
int iLastStart = 0;
for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
char chChar = chNext;
chNext = accStyler.SafeGetCharAt(uiPos + 1);
int iStylePrev = iStyle;
iStyle = iStyleNext;
iStyleNext = accStyler.StyleAt(uiPos + 1);
bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
if (iStylePrev == SCE_CLW_DEFAULT) {
if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
// Store last word start point.
iLastStart = uiPos;
}
}
if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
if(iswordchar(chChar) && !iswordchar(chNext)) {
char chBuffer[100];
FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
// if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
// accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
// iLevelPrev = SC_FOLDLEVELBASE;
// }
}
}
if (bEOL) {
int iLevel = iLevelPrev;
if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
iLevel |= SC_FOLDLEVELHEADERFLAG;
if (iLevel != accStyler.LevelAt(iLineCurrent)) {
accStyler.SetLevel(iLineCurrent,iLevel);
}
iLineCurrent++;
iLevelPrev = iLevelCurrent;
iVisibleChars = 0;
}
if (!isspacechar(chChar))
iVisibleChars++;
}
// Fill in the real level of the next line, keeping the current flags
// as they will be filled in later.
int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
}
// Word List Descriptions
static const char * const rgWordListDescriptions[] = {
"Clarion Keywords",
"Compiler Directives",
"Built-in Procedures and Functions",
"Runtime Expressions",
"Structure and Data Types",
"Attributes",
"Standard Equates",
"Reserved Words (Labels)",
"Reserved Words (Procedure Labels)",
0,
};
// Case Sensitive Clarion Language Lexer
LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
// Case Insensitive Clarion Language Lexer
LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);

View File

@@ -0,0 +1,368 @@
// Scintilla source code edit control
/** @file LexCOBOL.cxx
** Lexer for COBOL
** Based on LexPascal.cxx
** Written by Laurent le Tynevez
** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
** Updated by Rod Falck, Aug 2006 Converted to COBOL
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StyleContext.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#define IN_DIVISION 0x01
#define IN_DECLARATIVES 0x02
#define IN_SECTION 0x04
#define IN_PARAGRAPH 0x08
#define IN_FLAGS 0xF
#define NOT_HEADER 0x10
inline bool isCOBOLoperator(char ch)
{
return isoperator(ch);
}
inline bool isCOBOLwordchar(char ch)
{
return isascii(ch) && (isalnum(ch) || ch == '-');
}
inline bool isCOBOLwordstart(char ch)
{
return isascii(ch) && isalnum(ch);
}
static int CountBits(int nBits)
{
int count = 0;
for (int i = 0; i < 32; ++i)
{
count += nBits & 1;
nBits >>= 1;
}
return count;
}
static void getRange(unsigned int start,
unsigned int end,
Accessor &styler,
char *s,
unsigned int len) {
unsigned int i = 0;
while ((i < end - start + 1) && (i < len-1)) {
s[i] = static_cast<char>(tolower(styler[start + i]));
i++;
}
s[i] = '\0';
}
static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr) {
styler.ColourTo(end, attr);
}
static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
int ret = 0;
WordList& a_keywords = *keywordlists[0];
WordList& b_keywords = *keywordlists[1];
WordList& c_keywords = *keywordlists[2];
char s[100];
getRange(start, end, styler, s, sizeof(s));
char chAttr = SCE_C_IDENTIFIER;
if (isdigit(s[0]) || (s[0] == '.')) {
chAttr = SCE_C_NUMBER;
char *p = s + 1;
while (*p) {
if (!isdigit(*p) && isCOBOLwordchar(*p)) {
chAttr = SCE_C_IDENTIFIER;
break;
}
++p;
}
}
else {
if (a_keywords.InList(s)) {
chAttr = SCE_C_WORD;
}
else if (b_keywords.InList(s)) {
chAttr = SCE_C_WORD2;
}
else if (c_keywords.InList(s)) {
chAttr = SCE_C_UUID;
}
}
if (*bAarea) {
if (strcmp(s, "division") == 0) {
ret = IN_DIVISION;
// we've determined the containment, anything else is just ignored for those purposes
*bAarea = false;
} else if (strcmp(s, "declaratives") == 0) {
ret = IN_DIVISION | IN_DECLARATIVES;
if (nContainment & IN_DECLARATIVES)
ret |= NOT_HEADER | IN_SECTION;
// we've determined the containment, anything else is just ignored for those purposes
*bAarea = false;
} else if (strcmp(s, "section") == 0) {
ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;
// we've determined the containment, anything else is just ignored for those purposes
*bAarea = false;
} else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) {
ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;
} else {
ret = nContainment | IN_PARAGRAPH;
}
}
ColourTo(styler, end, chAttr);
return ret;
}
static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
styler.StartAt(startPos);
int state = initStyle;
if (state == SCE_C_CHARACTER) // Does not leak onto next line
state = SCE_C_DEFAULT;
char chPrev = ' ';
char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length;
int nContainment;
int currentLine = styler.GetLine(startPos);
if (currentLine > 0) {
styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
nContainment = styler.GetLineState(currentLine);
nContainment &= ~NOT_HEADER;
} else {
styler.SetLineState(currentLine, 0);
nContainment = 0;
}
styler.StartSegment(startPos);
bool bNewLine = true;
bool bAarea = !isspacechar(chNext);
int column = 0;
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
++column;
if (bNewLine) {
column = 0;
}
if (column <= 1 && !bAarea) {
bAarea = !isspacechar(ch);
}
bool bSetNewLine = false;
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
// Avoid triggering two times on Dos/Win
// End of line
if (state == SCE_C_CHARACTER) {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
}
styler.SetLineState(currentLine, nContainment);
currentLine++;
bSetNewLine = true;
if (nContainment & NOT_HEADER)
nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);
}
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
chPrev = ' ';
i += 1;
continue;
}
if (state == SCE_C_DEFAULT) {
if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER;
} else if (column == 0 && ch == '*' && chNext != '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (column == 0 && ch == '/' && chNext != '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext == '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTDOC;
} else if (column == 0 && ch == '/' && chNext == '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTDOC;
} else if (ch == '"') {
ColourTo(styler, i-1, state);
state = SCE_C_STRING;
} else if (ch == '\'') {
ColourTo(styler, i-1, state);
state = SCE_C_CHARACTER;
} else if (ch == '?' && column == 0) {
ColourTo(styler, i-1, state);
state = SCE_C_PREPROCESSOR;
} else if (isCOBOLoperator(ch)) {
ColourTo(styler, i-1, state);
ColourTo(styler, i, SCE_C_OPERATOR);
}
} else if (state == SCE_C_IDENTIFIER) {
if (!isCOBOLwordchar(ch)) {
int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
if(lStateChange != 0) {
styler.SetLineState(currentLine, lStateChange);
nContainment = lStateChange;
}
state = SCE_C_DEFAULT;
chNext = styler.SafeGetCharAt(i + 1);
if (ch == '"') {
state = SCE_C_STRING;
} else if (ch == '\'') {
state = SCE_C_CHARACTER;
} else if (isCOBOLoperator(ch)) {
ColourTo(styler, i, SCE_C_OPERATOR);
}
}
} else {
if (state == SCE_C_PREPROCESSOR) {
if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT;
}
} else if (state == SCE_C_COMMENT) {
if (ch == '\r' || ch == '\n') {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
}
} else if (state == SCE_C_COMMENTDOC) {
if (ch == '\r' || ch == '\n') {
if (((i > styler.GetStartSegment() + 2) || (
(initStyle == SCE_C_COMMENTDOC) &&
(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
}
}
} else if (state == SCE_C_COMMENTLINE) {
if (ch == '\r' || ch == '\n') {
ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT;
}
} else if (state == SCE_C_STRING) {
if (ch == '"') {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
}
} else if (state == SCE_C_CHARACTER) {
if (ch == '\'') {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
}
}
}
chPrev = ch;
bNewLine = bSetNewLine;
if (bNewLine)
{
bAarea = false;
}
}
ColourTo(styler, lengthDoc - 1, state);
}
static void FoldCOBOLDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;
char chNext = styler[startPos];
bool bNewLine = true;
bool bAarea = !isspacechar(chNext);
int column = 0;
bool bComment = false;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
++column;
if (bNewLine) {
column = 0;
bComment = (ch == '*' || ch == '/' || ch == '?');
}
if (column <= 1 && !bAarea) {
bAarea = !isspacechar(ch);
}
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (atEOL) {
int nContainment = styler.GetLineState(lineCurrent);
int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;
if (bAarea && !bComment)
--lev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {
// this level is at the same level or less than the previous line
// therefore these is nothing for the previous header to collapse, so remove the header
styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
}
levelPrev = lev;
visibleChars = 0;
bAarea = false;
bNewLine = true;
lineCurrent++;
} else {
bNewLine = false;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const COBOLWordListDesc[] = {
"A Keywords",
"B Keywords",
"Extended Keywords",
0
};
LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);

View File

@@ -0,0 +1,519 @@
// Scintilla source code edit control
/** @file LexCPP.cxx
** Lexer for C++, C, Java, and JavaScript.
**/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static bool IsSpaceEquiv(int state) {
return (state <= SCE_C_COMMENTDOC) ||
// including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
(state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
(state == SCE_C_COMMENTDOCKEYWORDERROR);
}
// Preconditions: sc.currentPos points to a character after '+' or '-'.
// The test for pos reaching 0 should be redundant,
// and is in only for safety measures.
// Limitation: this code will give the incorrect answer for code like
// a = b+++/ptn/...
// Putting a space between the '++' post-inc operator and the '+' binary op
// fixes this, and is highly recommended for readability anyway.
static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
int pos = (int) sc.currentPos;
while (--pos > 0) {
char ch = styler[pos];
if (ch == '+' || ch == '-') {
return styler[pos - 1] == ch;
}
}
return false;
}
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler, bool caseSensitive) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
// property styling.within.preprocessor
// For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default)
// or only from the initial # to the end of the command word(1).
bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
// property lexer.cpp.allow.dollars
// Set to 0 to disallow the '$' character in identifiers with the cpp lexer.
if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
setWordStart.Add('$');
setWord.Add('$');
}
int chPrevNonWhite = ' ';
int visibleChars = 0;
bool lastWordWasUUID = false;
bool lastOpSetScope = false;
int styleBeforeDCKeyword = SCE_C_DEFAULT;
bool continuationLine = false;
bool isIncludePreprocessor = false;
if (initStyle == SCE_C_PREPROCESSOR) {
// Set continuationLine if last character of previous line is '\'
int lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0) {
int chBack = styler.SafeGetCharAt(startPos-1, 0);
int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
int lineEndChar = '!';
if (chBack2 == '\r' && chBack == '\n') {
lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
} else if (chBack == '\n' || chBack == '\r') {
lineEndChar = chBack2;
}
continuationLine = lineEndChar == '\\';
}
}
// look back to set chPrevNonWhite properly for better regex colouring
if (startPos > 0) {
int back = startPos;
while (--back && IsSpaceEquiv(styler.StyleAt(back)))
;
if (styler.StyleAt(back) == SCE_C_OPERATOR) {
chPrevNonWhite = styler.SafeGetCharAt(back);
}
}
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart) {
if (sc.state == SCE_C_STRING) {
// Prevent SCE_C_STRINGEOL from leaking back to previous line which
// ends with a line continuation by locking in the state upto this position.
sc.SetState(SCE_C_STRING);
}
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
visibleChars = 0;
lastWordWasUUID = false;
isIncludePreprocessor = false;
}
// Handle line continuation generically.
if (sc.ch == '\\') {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continuationLine = true;
continue;
}
}
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT);
break;
case SCE_C_NUMBER:
// We accept almost anything because of hex. and number suffixes
if (!setWord.Contains(sc.ch)) {
sc.SetState(SCE_C_DEFAULT);
}
break;
case SCE_C_IDENTIFIER:
if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
char s[1000];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
if (keywords.InList(s)) {
lastWordWasUUID = strcmp(s, "uuid") == 0;
sc.ChangeState(SCE_C_WORD);
} else if (!lastOpSetScope && keywords4.InList(s)) {
sc.ChangeState(SCE_C_GLOBALCLASS);
} else if (!lastOpSetScope && keywords2.InList(s)) {
sc.ChangeState(SCE_C_WORD2);
} else {
lastOpSetScope = false;
}
sc.SetState(SCE_C_DEFAULT);
}
break;
case SCE_C_PREPROCESSOR:
if (sc.atLineStart && !continuationLine) {
sc.SetState(SCE_C_DEFAULT);
} else if (stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
sc.SetState(SCE_C_DEFAULT);
}
} else {
if (sc.Match('/', '*') || sc.Match('/', '/')) {
sc.SetState(SCE_C_DEFAULT);
}
}
break;
case SCE_C_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT);
}
break;
case SCE_C_COMMENTDOC:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_C_COMMENTDOC;
sc.SetState(SCE_C_COMMENTDOCKEYWORD);
}
}
break;
case SCE_C_COMMENTLINE:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
}
break;
case SCE_C_COMMENTLINEDOC:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;
sc.SetState(SCE_C_COMMENTDOCKEYWORD);
}
}
break;
case SCE_C_COMMENTDOCKEYWORD:
if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT);
} else if (!setDoxygen.Contains(sc.ch)) {
char s[100];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
}
sc.SetState(styleBeforeDCKeyword);
}
break;
case SCE_C_STRING:
if (sc.atLineEnd) {
sc.ChangeState(SCE_C_STRINGEOL);
} else if (isIncludePreprocessor) {
if (sc.ch == '>') {
sc.ForwardSetState(SCE_C_DEFAULT);
isIncludePreprocessor = false;
}
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_C_DEFAULT);
}
break;
case SCE_C_CHARACTER:
if (sc.atLineEnd) {
sc.ChangeState(SCE_C_STRINGEOL);
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_C_DEFAULT);
}
break;
case SCE_C_REGEX:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
} else if (sc.ch == '/') {
sc.Forward();
while ((sc.ch < 0x80) && islower(sc.ch))
sc.Forward(); // gobble regex flags
sc.SetState(SCE_C_DEFAULT);
} else if (sc.ch == '\\') {
// Gobble up the quoted character
if (sc.chNext == '\\' || sc.chNext == '/') {
sc.Forward();
}
}
break;
case SCE_C_STRINGEOL:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT);
}
break;
case SCE_C_VERBATIM:
if (sc.ch == '\"') {
if (sc.chNext == '\"') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_C_DEFAULT);
}
}
break;
case SCE_C_UUID:
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
sc.SetState(SCE_C_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM);
sc.Forward();
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
if (lastWordWasUUID) {
sc.SetState(SCE_C_UUID);
lastWordWasUUID = false;
} else {
sc.SetState(SCE_C_NUMBER);
}
} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
if (lastWordWasUUID) {
sc.SetState(SCE_C_UUID);
lastWordWasUUID = false;
} else {
sc.SetState(SCE_C_IDENTIFIER);
}
} else if (sc.Match('/', '*')) {
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
sc.SetState(SCE_C_COMMENTDOC);
} else {
sc.SetState(SCE_C_COMMENT);
}
sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('/', '/')) {
if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
// Support of Qt/Doxygen doc. style
sc.SetState(SCE_C_COMMENTLINEDOC);
else
sc.SetState(SCE_C_COMMENTLINE);
} else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite) &&
(!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) {
sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
} else if (sc.ch == '\"') {
sc.SetState(SCE_C_STRING);
isIncludePreprocessor = false; // ensure that '>' won't end the string
} else if (isIncludePreprocessor && sc.ch == '<') {
sc.SetState(SCE_C_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_C_CHARACTER);
} else if (sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
sc.SetState(SCE_C_PREPROCESSOR);
// Skip whitespace between # and preprocessor word
do {
sc.Forward();
} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
if (sc.atLineEnd) {
sc.SetState(SCE_C_DEFAULT);
} else if (sc.Match("include")) {
isIncludePreprocessor = true;
}
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_C_OPERATOR);
lastOpSetScope = false;
if (sc.Match('.') || sc.Match(':', ':') || sc.Match('-', '>') || sc.Match(':', '~')) {
// check for operators '.', '::', and '->' (but not '.*', '::*', or '->*')
if (sc.ch != '.') sc.Forward();
if (sc.chNext != '*')
lastOpSetScope = true;
else
sc.Forward();
}
}
}
if (sc.state != SCE_C_OPERATOR && sc.state != SCE_C_IDENTIFIER) lastOpSetScope = false;
if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
chPrevNonWhite = sc.ch;
visibleChars++;
}
continuationLine = false;
}
sc.Complete();
}
static bool IsStreamCommentStyle(int style) {
return style == SCE_C_COMMENT ||
style == SCE_C_COMMENTDOC ||
style == SCE_C_COMMENTDOCKEYWORD ||
style == SCE_C_COMMENTDOCKEYWORDERROR;
}
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
// property fold.comment
// This option enables folding multi-line comments and explicit fold points when using the C++ lexer.
// Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //}
// at the end of a section that should fold.
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
// property fold.preprocessor
// This option enables folding preprocessor directives when using the C++ lexer.
// Includes C#'s explicit #region and #endregion folding directives.
bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
// property fold.at.else
// This option enables C++ folding on a "} else {" line of an if statement.
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelNext--;
}
}
if (foldComment && (style == SCE_C_COMMENTLINE)) {
if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
if (chNext2 == '{') {
levelNext++;
} else if (chNext2 == '}') {
levelNext--;
}
}
}
if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
if (ch == '#') {
unsigned int j = i + 1;
while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
j++;
}
if (styler.Match(j, "region") || styler.Match(j, "if")) {
levelNext++;
} else if (styler.Match(j, "end")) {
levelNext--;
}
}
}
if (style == SCE_C_OPERATOR) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
if (levelMinCurrent > levelNext) {
levelMinCurrent = levelNext;
}
levelNext++;
} else if (ch == '}') {
levelNext--;
}
}
if (!IsASpace(ch))
visibleChars++;
if (atEOL || (i == endPos-1)) {
int levelUse = levelCurrent;
if (foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
// There is an empty line at end of file so give it same level and empty
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
}
visibleChars = 0;
}
}
}
static const char * const cppWordLists[] = {
"Primary keywords and identifiers",
"Secondary keywords and identifiers",
"Documentation comment keywords",
"Unused",
"Global classes and typedefs",
0,
};
static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
}
static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
}
LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);

View File

@@ -0,0 +1,371 @@
// Scintilla source code edit control
/** @file LexCSS.cxx
** Lexer for Cascading Style Sheets
** Written by Jakub Vr<56>na
** Improved by Philippe Lhoste (CSS2)
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const unsigned int ch) {
/* FIXME:
* The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars.
* Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee
* that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher
*/
return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
}
inline bool IsCssOperator(const int ch) {
if (!((ch < 0x80) && isalnum(ch)) &&
(ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' ||
ch == '.' || ch == '#' || ch == '!' || ch == '@' ||
/* CSS2 */
ch == '*' || ch == '>' || ch == '+' || ch == '=' || ch == '~' || ch == '|' ||
ch == '[' || ch == ']' || ch == '(' || ch == ')')) {
return true;
}
return false;
}
static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
WordList &css1Props = *keywordlists[0];
WordList &pseudoClasses = *keywordlists[1];
WordList &css2Props = *keywordlists[2];
WordList &css3Props = *keywordlists[3];
WordList &pseudoElements = *keywordlists[4];
WordList &exProps = *keywordlists[5];
WordList &exPseudoClasses = *keywordlists[6];
WordList &exPseudoElements = *keywordlists[7];
StyleContext sc(startPos, length, initStyle, styler);
int lastState = -1; // before operator
int lastStateC = -1; // before comment
int lastStateS = -1; // before single-quoted/double-quoted string
int op = ' '; // last operator
int opPrev = ' '; // last operator
for (; sc.More(); sc.Forward()) {
if (sc.state == SCE_CSS_COMMENT && sc.Match('*', '/')) {
if (lastStateC == -1) {
// backtrack to get last state:
// comments are like whitespace, so we must return to the previous state
unsigned int i = startPos;
for (; i > 0; i--) {
if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
if (lastStateC == SCE_CSS_OPERATOR) {
op = styler.SafeGetCharAt(i-1);
opPrev = styler.SafeGetCharAt(i-2);
while (--i) {
lastState = styler.StyleAt(i-1);
if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
break;
}
if (i == 0)
lastState = SCE_CSS_DEFAULT;
}
break;
}
}
if (i == 0)
lastStateC = SCE_CSS_DEFAULT;
}
sc.Forward();
sc.ForwardSetState(lastStateC);
}
if (sc.state == SCE_CSS_COMMENT)
continue;
if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {
if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
continue;
unsigned int i = sc.currentPos;
while (i && styler[i-1] == '\\')
i--;
if ((sc.currentPos - i) % 2 == 1)
continue;
sc.ForwardSetState(lastStateS);
}
if (sc.state == SCE_CSS_OPERATOR) {
if (op == ' ') {
unsigned int i = startPos;
op = styler.SafeGetCharAt(i-1);
opPrev = styler.SafeGetCharAt(i-2);
while (--i) {
lastState = styler.StyleAt(i-1);
if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
break;
}
}
switch (op) {
case '@':
if (lastState == SCE_CSS_DEFAULT)
sc.SetState(SCE_CSS_DIRECTIVE);
break;
case '>':
case '+':
if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
sc.SetState(SCE_CSS_DEFAULT);
break;
case '[':
if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
sc.SetState(SCE_CSS_ATTRIBUTE);
break;
case ']':
if (lastState == SCE_CSS_ATTRIBUTE)
sc.SetState(SCE_CSS_TAG);
break;
case '{':
if (lastState == SCE_CSS_MEDIA)
sc.SetState(SCE_CSS_DEFAULT);
else if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DIRECTIVE)
sc.SetState(SCE_CSS_IDENTIFIER);
break;
case '}':
if (lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT ||
lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 || lastState == SCE_CSS_IDENTIFIER3)
sc.SetState(SCE_CSS_DEFAULT);
break;
case '(':
if (lastState == SCE_CSS_PSEUDOCLASS)
sc.SetState(SCE_CSS_TAG);
else if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)
sc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS);
break;
case ')':
if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
sc.SetState(SCE_CSS_TAG);
break;
case ':':
if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
sc.SetState(SCE_CSS_PSEUDOCLASS);
else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 ||
lastState == SCE_CSS_IDENTIFIER3 || lastState == SCE_CSS_EXTENDED_IDENTIFIER ||
lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
sc.SetState(SCE_CSS_VALUE);
break;
case '.':
if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
sc.SetState(SCE_CSS_CLASS);
break;
case '#':
if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
sc.SetState(SCE_CSS_ID);
break;
case ',':
case '|':
case '~':
if (lastState == SCE_CSS_TAG)
sc.SetState(SCE_CSS_DEFAULT);
break;
case ';':
if (lastState == SCE_CSS_DIRECTIVE)
sc.SetState(SCE_CSS_DEFAULT);
else if (lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT)
sc.SetState(SCE_CSS_IDENTIFIER);
break;
case '!':
if (lastState == SCE_CSS_VALUE)
sc.SetState(SCE_CSS_IMPORTANT);
break;
}
}
if (IsAWordChar(sc.ch)) {
if (sc.state == SCE_CSS_DEFAULT)
sc.SetState(SCE_CSS_TAG);
continue;
}
if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
sc.SetState(SCE_CSS_TAG);
continue;
}
if (IsAWordChar(sc.chPrev) && (
sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 ||
sc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER ||
sc.state == SCE_CSS_UNKNOWN_IDENTIFIER ||
sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
sc.state == SCE_CSS_IMPORTANT ||
sc.state == SCE_CSS_DIRECTIVE
)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
char *s2 = s;
while (*s2 && !IsAWordChar(*s2))
s2++;
switch (sc.state) {
case SCE_CSS_IDENTIFIER:
case SCE_CSS_IDENTIFIER2:
case SCE_CSS_IDENTIFIER3:
case SCE_CSS_EXTENDED_IDENTIFIER:
case SCE_CSS_UNKNOWN_IDENTIFIER:
if (css1Props.InList(s2))
sc.ChangeState(SCE_CSS_IDENTIFIER);
else if (css2Props.InList(s2))
sc.ChangeState(SCE_CSS_IDENTIFIER2);
else if (css3Props.InList(s2))
sc.ChangeState(SCE_CSS_IDENTIFIER3);
else if (exProps.InList(s2))
sc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER);
else
sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
break;
case SCE_CSS_PSEUDOCLASS:
case SCE_CSS_PSEUDOELEMENT:
case SCE_CSS_EXTENDED_PSEUDOCLASS:
case SCE_CSS_EXTENDED_PSEUDOELEMENT:
case SCE_CSS_UNKNOWN_PSEUDOCLASS:
if (op == ':' && opPrev != ':' && pseudoClasses.InList(s2))
sc.ChangeState(SCE_CSS_PSEUDOCLASS);
else if (opPrev == ':' && pseudoElements.InList(s2))
sc.ChangeState(SCE_CSS_PSEUDOELEMENT);
else if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2))
sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS);
else if (opPrev == ':' && exPseudoElements.InList(s2))
sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT);
else
sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
break;
case SCE_CSS_IMPORTANT:
if (strcmp(s2, "important") != 0)
sc.ChangeState(SCE_CSS_VALUE);
break;
case SCE_CSS_DIRECTIVE:
if (op == '@' && strcmp(s2, "media") == 0)
sc.ChangeState(SCE_CSS_MEDIA);
break;
}
}
if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (
sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID ||
(sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */
sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
))
))
sc.SetState(SCE_CSS_TAG);
if (sc.Match('/', '*')) {
lastStateC = sc.state;
sc.SetState(SCE_CSS_COMMENT);
sc.Forward();
} else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE)
&& (sc.ch == '\"' || sc.ch == '\'')) {
lastStateS = sc.state;
sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
} else if (IsCssOperator(sc.ch)
&& (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
&& ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_MEDIA) || sc.ch == ';' || sc.ch == '{')
) {
if (sc.state != SCE_CSS_OPERATOR)
lastState = sc.state;
sc.SetState(SCE_CSS_OPERATOR);
op = sc.ch;
opPrev = sc.chPrev;
}
}
sc.Complete();
}
static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styler.StyleAt(i);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment) {
if (!inComment && (style == SCE_CSS_COMMENT))
levelCurrent++;
else if (inComment && (style != SCE_CSS_COMMENT))
levelCurrent--;
inComment = (style == SCE_CSS_COMMENT);
}
if (style == SCE_CSS_OPERATOR) {
if (ch == '{') {
levelCurrent++;
} else if (ch == '}') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const cssWordListDesc[] = {
"CSS1 Properties",
"Pseudo-classes",
"CSS2 Properties",
"CSS3 Properties",
"Pseudo-elements",
"Browser-Specific CSS Properties",
"Browser-Specific Pseudo-classes",
"Browser-Specific Pseudo-elements",
0
};
LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);

View File

@@ -0,0 +1,449 @@
// Scintilla source code edit control
/** @file LexCaml.cxx
** Lexer for Objective Caml.
**/
// Copyright 2005-2009 by Robert Roessler <robertr@rftp.com>
// The License.txt file describes the conditions under which this software may be distributed.
/* Release History
20050204 Initial release.
20050205 Quick compiler standards/"cleanliness" adjustment.
20050206 Added cast for IsLeadByte().
20050209 Changes to "external" build support.
20050306 Fix for 1st-char-in-doc "corner" case.
20050502 Fix for [harmless] one-past-the-end coloring.
20050515 Refined numeric token recognition logic.
20051125 Added 2nd "optional" keywords class.
20051129 Support "magic" (read-only) comments for RCaml.
20051204 Swtich to using StyleContext infrastructure.
20090629 Add full Standard ML '97 support.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
// Since the Microsoft __iscsym[f] funcs are not ANSI...
inline int iscaml(int c) {return isalnum(c) || c == '_';}
inline int iscamlf(int c) {return isalpha(c) || c == '_';}
static const int baseT[24] = {
0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A - L */
0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
};
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#ifdef BUILD_AS_EXTERNAL_LEXER
/*
(actually seems to work!)
*/
#include "WindowAccessor.h"
#include "ExternalLexer.h"
#if PLAT_WIN
#include <windows.h>
#endif
static void ColouriseCamlDoc(
unsigned int startPos, int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler);
static void FoldCamlDoc(
unsigned int startPos, int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler);
static void InternalLexOrFold(int lexOrFold, unsigned int startPos, int length,
int initStyle, char *words[], WindowID window, char *props);
static const char* LexerName = "caml";
#ifdef TRACE
void Platform::DebugPrintf(const char *format, ...) {
char buffer[2000];
va_list pArguments;
va_start(pArguments, format);
vsprintf(buffer,format,pArguments);
va_end(pArguments);
Platform::DebugDisplay(buffer);
}
#else
void Platform::DebugPrintf(const char *, ...) {
}
#endif
bool Platform::IsDBCSLeadByte(int codePage, char ch) {
return ::IsDBCSLeadByteEx(codePage, ch) != 0;
}
long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam);
}
long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) {
return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam,
reinterpret_cast<LPARAM>(lParam));
}
void EXT_LEXER_DECL Fold(unsigned int lexer, unsigned int startPos, int length,
int initStyle, char *words[], WindowID window, char *props)
{
// below useless evaluation(s) to supress "not used" warnings
lexer;
// build expected data structures and do the Fold
InternalLexOrFold(1, startPos, length, initStyle, words, window, props);
}
int EXT_LEXER_DECL GetLexerCount()
{
return 1; // just us [Objective] Caml lexers here!
}
void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
{
// below useless evaluation(s) to supress "not used" warnings
Index;
// return as much of our lexer name as will fit (what's up with Index?)
if (buflength > 0) {
buflength--;
int n = strlen(LexerName);
if (n > buflength)
n = buflength;
memcpy(name, LexerName, n), name[n] = '\0';
}
}
void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length,
int initStyle, char *words[], WindowID window, char *props)
{
// below useless evaluation(s) to supress "not used" warnings
lexer;
// build expected data structures and do the Lex
InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
}
static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
int initStyle, char *words[], WindowID window, char *props)
{
// create and initialize a WindowAccessor (including contained PropSet)
PropSetSimple ps;
ps.SetMultiple(props);
WindowAccessor wa(window, ps);
// create and initialize WordList(s)
int nWL = 0;
for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed
WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs
int i = 0;
for (; i < nWL; i++) {
wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION)
wl[i]->Set(words[i]);
}
wl[i] = 0;
// call our "internal" folder/lexer (... then do Flush!)
if (foldOrLex)
FoldCamlDoc(startPos, length, initStyle, wl, wa);
else
ColouriseCamlDoc(startPos, length, initStyle, wl, wa);
wa.Flush();
// clean up before leaving
for (i = nWL - 1; i >= 0; i--)
delete wl[i];
delete [] wl;
}
static
#endif /* BUILD_AS_EXTERNAL_LEXER */
void ColouriseCamlDoc(
unsigned int startPos, int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler)
{
// initialize styler
StyleContext sc(startPos, length, initStyle, styler);
int chBase = 0, chToken = 0, chLit = 0;
WordList& keywords = *keywordlists[0];
WordList& keywords2 = *keywordlists[1];
WordList& keywords3 = *keywordlists[2];
const bool isSML = keywords.InList("andalso");
const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
// set up [initial] state info (terminating states that shouldn't "bleed")
const int state_ = sc.state & 0x0f;
if (state_ <= SCE_CAML_CHAR
|| (isSML && state_ == SCE_CAML_STRING))
sc.state = SCE_CAML_DEFAULT;
int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;
// foreach char in range...
while (sc.More()) {
// set up [per-char] state info
int state2 = -1; // (ASSUME no state change)
int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
bool advance = true; // (ASSUME scanner "eats" 1 char)
// step state machine
switch (sc.state & 0x0f) {
case SCE_CAML_DEFAULT:
chToken = sc.currentPos; // save [possible] token start (JIC)
// it's wide open; what do we have?
if (iscamlf(sc.ch))
state2 = SCE_CAML_IDENTIFIER;
else if (!isSML && sc.Match('`') && iscamlf(sc.chNext))
state2 = SCE_CAML_TAGNAME;
else if (!isSML && sc.Match('#') && isdigit(sc.chNext))
state2 = SCE_CAML_LINENUM;
else if (isdigit(sc.ch)) {
// it's a number, assume base 10
state2 = SCE_CAML_NUMBER, chBase = 10;
if (sc.Match('0')) {
// there MAY be a base specified...
const char* baseC = "bBoOxX";
if (isSML) {
if (sc.chNext == 'w')
sc.Forward(); // (consume SML "word" indicator)
baseC = "x";
}
// ... change to specified base AS REQUIRED
if (strchr(baseC, sc.chNext))
chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
}
} else if (!isSML && sc.Match('\'')) // (Caml char literal?)
state2 = SCE_CAML_CHAR, chLit = 0;
else if (isSML && sc.Match('#', '"')) // (SML char literal?)
state2 = SCE_CAML_CHAR, sc.Forward();
else if (sc.Match('"'))
state2 = SCE_CAML_STRING;
else if (sc.Match('(', '*'))
state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...
else if (strchr("!?~" /* Caml "prefix-symbol" */
"=<>@^|&+-*/$%" /* Caml "infix-symbol" */
"()[]{};,:.#", sc.ch) // Caml "bracket" or ;,:.#
// SML "extra" ident chars
|| (isSML && (sc.Match('\\') || sc.Match('`'))))
state2 = SCE_CAML_OPERATOR;
break;
case SCE_CAML_IDENTIFIER:
// [try to] interpret as [additional] identifier char
if (!(iscaml(sc.ch) || sc.Match('\''))) {
const int n = sc.currentPos - chToken;
if (n < 24) {
// length is believable as keyword, [re-]construct token
char t[24];
for (int i = -n; i < 0; i++)
t[n + i] = static_cast<char>(sc.GetRelative(i));
t[n] = '\0';
// special-case "_" token as KEYWORD
if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
sc.ChangeState(SCE_CAML_KEYWORD);
else if (keywords2.InList(t))
sc.ChangeState(SCE_CAML_KEYWORD2);
else if (keywords3.InList(t))
sc.ChangeState(SCE_CAML_KEYWORD3);
}
state2 = SCE_CAML_DEFAULT, advance = false;
}
break;
case SCE_CAML_TAGNAME:
// [try to] interpret as [additional] tagname char
if (!(iscaml(sc.ch) || sc.Match('\'')))
state2 = SCE_CAML_DEFAULT, advance = false;
break;
/*case SCE_CAML_KEYWORD:
case SCE_CAML_KEYWORD2:
case SCE_CAML_KEYWORD3:
// [try to] interpret as [additional] keyword char
if (!iscaml(ch))
state2 = SCE_CAML_DEFAULT, advance = false;
break;*/
case SCE_CAML_LINENUM:
// [try to] interpret as [additional] linenum directive char
if (!isdigit(sc.ch))
state2 = SCE_CAML_DEFAULT, advance = false;
break;
case SCE_CAML_OPERATOR: {
// [try to] interpret as [additional] operator char
const char* o = 0;
if (iscaml(sc.ch) || isspace(sc.ch) // ident or whitespace
|| (o = strchr(")]};,\'\"#", sc.ch),o) // "termination" chars
|| (!isSML && sc.Match('`')) // Caml extra term char
|| (!strchr("!$%&*+-./:<=>?@^|~", sc.ch)// "operator" chars
// SML extra ident chars
&& !(isSML && (sc.Match('\\') || sc.Match('`'))))) {
// check for INCLUSIVE termination
if (o && strchr(")]};,", sc.ch)) {
if ((sc.Match(')') && sc.chPrev == '(')
|| (sc.Match(']') && sc.chPrev == '['))
// special-case "()" and "[]" tokens as KEYWORDS
sc.ChangeState(SCE_CAML_KEYWORD);
chColor++;
} else
advance = false;
state2 = SCE_CAML_DEFAULT;
}
break;
}
case SCE_CAML_NUMBER:
// [try to] interpret as [additional] numeric literal char
if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))
break;
// how about an integer suffix?
if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))
&& (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))
break;
// or a floating-point literal?
if (chBase == 10) {
// with a decimal point?
if (sc.Match('.')
&& ((!isSML && sc.chPrev == '_')
|| IsADigit(sc.chPrev, chBase)))
break;
// with an exponent? (I)
if ((sc.Match('e') || sc.Match('E'))
&& ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))
|| IsADigit(sc.chPrev, chBase)))
break;
// with an exponent? (II)
if (((!isSML && (sc.Match('+') || sc.Match('-')))
|| (isSML && sc.Match('~')))
&& (sc.chPrev == 'e' || sc.chPrev == 'E'))
break;
}
// it looks like we have run out of number
state2 = SCE_CAML_DEFAULT, advance = false;
break;
case SCE_CAML_CHAR:
if (!isSML) {
// [try to] interpret as [additional] char literal char
if (sc.Match('\\')) {
chLit = 1; // (definitely IS a char literal)
if (sc.chPrev == '\\')
sc.ch = ' '; // (...\\')
// should we be terminating - one way or another?
} else if ((sc.Match('\'') && sc.chPrev != '\\')
|| sc.atLineEnd) {
state2 = SCE_CAML_DEFAULT;
if (sc.Match('\''))
chColor++;
else
sc.ChangeState(SCE_CAML_IDENTIFIER);
// ... maybe a char literal, maybe not
} else if (chLit < 1 && sc.currentPos - chToken >= 2)
sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
break;
}/* else
// fall through for SML char literal (handle like string) */
case SCE_CAML_STRING:
// [try to] interpret as [additional] [SML char/] string literal char
if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext))
state2 = SCE_CAML_WHITE;
else if (sc.Match('\\') && sc.chPrev == '\\')
sc.ch = ' '; // (...\\")
// should we be terminating - one way or another?
else if ((sc.Match('"') && sc.chPrev != '\\')
|| (isSML && sc.atLineEnd)) {
state2 = SCE_CAML_DEFAULT;
if (sc.Match('"'))
chColor++;
}
break;
case SCE_CAML_WHITE:
// [try to] interpret as [additional] SML embedded whitespace char
if (sc.Match('\\')) {
// style this puppy NOW...
state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++,
styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();
// ... then backtrack to determine original SML literal type
int p = chColor - 2;
for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;
if (p >= 0)
state2 = static_cast<int>(styler.StyleAt(p));
// take care of state change NOW
sc.ChangeState(state2), state2 = -1;
}
break;
case SCE_CAML_COMMENT:
case SCE_CAML_COMMENT1:
case SCE_CAML_COMMENT2:
case SCE_CAML_COMMENT3:
// we're IN a comment - does this start a NESTED comment?
if (sc.Match('(', '*'))
state2 = sc.state + 1, chToken = sc.currentPos,
sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;
// [try to] interpret as [additional] comment char
else if (sc.Match(')') && sc.chPrev == '*') {
if (nesting)
state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
else
state2 = SCE_CAML_DEFAULT;
chColor++;
// enable "magic" (read-only) comment AS REQUIRED
} else if (useMagic && sc.currentPos - chToken == 4
&& sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
sc.state |= 0x10; // (switch to read-only comment style)
break;
}
// handle state change and char coloring AS REQUIRED
if (state2 >= 0)
styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
// move to next char UNLESS re-scanning current char
if (advance)
sc.Forward();
}
// do any required terminal char coloring (JIC)
sc.Complete();
}
#ifdef BUILD_AS_EXTERNAL_LEXER
static
#endif /* BUILD_AS_EXTERNAL_LEXER */
void FoldCamlDoc(
unsigned int, int,
int,
WordList *[],
Accessor &)
{
}
static const char * const camlWordListDesc[] = {
"Keywords", // primary Objective Caml keywords
"Keywords2", // "optional" keywords (typically from Pervasives)
"Keywords3", // "optional" keywords (typically typenames)
0
};
#ifndef BUILD_AS_EXTERNAL_LEXER
LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc);
#endif /* BUILD_AS_EXTERNAL_LEXER */

View File

@@ -0,0 +1,457 @@
// Scintilla source code edit control
/** @file LexCmake.cxx
** Lexer for Cmake
**/
// Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
// based on the NSIS lexer
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static bool isCmakeNumber(char ch)
{
return(ch >= '0' && ch <= '9');
}
static bool isCmakeChar(char ch)
{
return(ch == '.' ) || (ch == '_' ) || isCmakeNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static bool isCmakeLetter(char ch)
{
return(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static bool CmakeNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
{
int nNextLine = -1;
for ( unsigned int i = start; i < end; i++ ) {
char cNext = styler.SafeGetCharAt( i );
if ( cNext == '\n' ) {
nNextLine = i+1;
break;
}
}
if ( nNextLine == -1 ) // We never foudn the next line...
return false;
for ( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ ) {
char cNext = styler.SafeGetCharAt( firstChar );
if ( cNext == ' ' )
continue;
if ( cNext == '\t' )
continue;
if ( styler.Match(firstChar, "ELSE") || styler.Match(firstChar, "else"))
return true;
break;
}
return false;
}
static int calculateFoldCmake(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse)
{
// If the word is too long, it is not what we are looking for
if ( end - start > 20 )
return foldlevel;
int newFoldlevel = foldlevel;
char s[20]; // The key word we are looking for has atmost 13 characters
for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) {
s[i] = static_cast<char>( styler[ start + i ] );
s[i + 1] = '\0';
}
if ( CompareCaseInsensitive(s, "IF") == 0 || CompareCaseInsensitive(s, "WHILE") == 0
|| CompareCaseInsensitive(s, "MACRO") == 0 || CompareCaseInsensitive(s, "FOREACH") == 0
|| CompareCaseInsensitive(s, "ELSEIF") == 0 )
newFoldlevel++;
else if ( CompareCaseInsensitive(s, "ENDIF") == 0 || CompareCaseInsensitive(s, "ENDWHILE") == 0
|| CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0)
newFoldlevel--;
else if ( bElse && CompareCaseInsensitive(s, "ELSEIF") == 0 )
newFoldlevel++;
else if ( bElse && CompareCaseInsensitive(s, "ELSE") == 0 )
newFoldlevel++;
return newFoldlevel;
}
static int classifyWordCmake(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
{
char word[100] = {0};
char lowercaseWord[100] = {0};
WordList &Commands = *keywordLists[0];
WordList &Parameters = *keywordLists[1];
WordList &UserDefined = *keywordLists[2];
for (unsigned int i = 0; i < end - start + 1 && i < 99; i++) {
word[i] = static_cast<char>( styler[ start + i ] );
lowercaseWord[i] = static_cast<char>(tolower(word[i]));
}
// Check for special words...
if ( CompareCaseInsensitive(word, "MACRO") == 0 || CompareCaseInsensitive(word, "ENDMACRO") == 0 )
return SCE_CMAKE_MACRODEF;
if ( CompareCaseInsensitive(word, "IF") == 0 || CompareCaseInsensitive(word, "ENDIF") == 0 )
return SCE_CMAKE_IFDEFINEDEF;
if ( CompareCaseInsensitive(word, "ELSEIF") == 0 || CompareCaseInsensitive(word, "ELSE") == 0 )
return SCE_CMAKE_IFDEFINEDEF;
if ( CompareCaseInsensitive(word, "WHILE") == 0 || CompareCaseInsensitive(word, "ENDWHILE") == 0)
return SCE_CMAKE_WHILEDEF;
if ( CompareCaseInsensitive(word, "FOREACH") == 0 || CompareCaseInsensitive(word, "ENDFOREACH") == 0)
return SCE_CMAKE_FOREACHDEF;
if ( Commands.InList(lowercaseWord) )
return SCE_CMAKE_COMMANDS;
if ( Parameters.InList(word) )
return SCE_CMAKE_PARAMETERS;
if ( UserDefined.InList(word) )
return SCE_CMAKE_USERDEFINED;
if ( strlen(word) > 3 ) {
if ( word[1] == '{' && word[strlen(word)-1] == '}' )
return SCE_CMAKE_VARIABLE;
}
// To check for numbers
if ( isCmakeNumber( word[0] ) ) {
bool bHasSimpleCmakeNumber = true;
for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) {
if ( !isCmakeNumber( word[j] ) ) {
bHasSimpleCmakeNumber = false;
break;
}
}
if ( bHasSimpleCmakeNumber )
return SCE_CMAKE_NUMBER;
}
return SCE_CMAKE_DEFAULT;
}
static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_CMAKE_DEFAULT;
if ( startPos > 0 )
state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
styler.StartAt( startPos );
styler.GetLine( startPos );
unsigned int nLengthDoc = startPos + length;
styler.StartSegment( startPos );
char cCurrChar;
bool bVarInString = false;
bool bClassicVarInString = false;
unsigned int i;
for ( i = startPos; i < nLengthDoc; i++ ) {
cCurrChar = styler.SafeGetCharAt( i );
char cNextChar = styler.SafeGetCharAt(i+1);
switch (state) {
case SCE_CMAKE_DEFAULT:
if ( cCurrChar == '#' ) { // we have a comment line
styler.ColourTo(i-1, state );
state = SCE_CMAKE_COMMENT;
break;
}
if ( cCurrChar == '"' ) {
styler.ColourTo(i-1, state );
state = SCE_CMAKE_STRINGDQ;
bVarInString = false;
bClassicVarInString = false;
break;
}
if ( cCurrChar == '\'' ) {
styler.ColourTo(i-1, state );
state = SCE_CMAKE_STRINGRQ;
bVarInString = false;
bClassicVarInString = false;
break;
}
if ( cCurrChar == '`' ) {
styler.ColourTo(i-1, state );
state = SCE_CMAKE_STRINGLQ;
bVarInString = false;
bClassicVarInString = false;
break;
}
// CMake Variable
if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) {
styler.ColourTo(i-1,state);
state = SCE_CMAKE_VARIABLE;
// If it is a number, we must check and set style here first...
if ( isCmakeNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
styler.ColourTo( i, SCE_CMAKE_NUMBER);
break;
}
break;
case SCE_CMAKE_COMMENT:
if ( cNextChar == '\n' || cNextChar == '\r' ) {
// Special case:
if ( cCurrChar == '\\' ) {
styler.ColourTo(i-2,state);
styler.ColourTo(i,SCE_CMAKE_DEFAULT);
}
else {
styler.ColourTo(i,state);
state = SCE_CMAKE_DEFAULT;
}
}
break;
case SCE_CMAKE_STRINGDQ:
case SCE_CMAKE_STRINGLQ:
case SCE_CMAKE_STRINGRQ:
if ( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
break; // Ignore the next character, even if it is a quote of some sort
if ( cCurrChar == '"' && state == SCE_CMAKE_STRINGDQ ) {
styler.ColourTo(i,state);
state = SCE_CMAKE_DEFAULT;
break;
}
if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) {
styler.ColourTo(i,state);
state = SCE_CMAKE_DEFAULT;
break;
}
if ( cCurrChar == '\'' && state == SCE_CMAKE_STRINGRQ ) {
styler.ColourTo(i,state);
state = SCE_CMAKE_DEFAULT;
break;
}
if ( cNextChar == '\r' || cNextChar == '\n' ) {
int nCurLine = styler.GetLine(i+1);
int nBack = i;
// We need to check if the previous line has a \ in it...
bool bNextLine = false;
while ( nBack > 0 ) {
if ( styler.GetLine(nBack) != nCurLine )
break;
char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
if ( cTemp == '\\' ) {
bNextLine = true;
break;
}
if ( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
break;
nBack--;
}
if ( bNextLine ) {
styler.ColourTo(i+1,state);
}
if ( bNextLine == false ) {
styler.ColourTo(i,state);
state = SCE_CMAKE_DEFAULT;
}
}
break;
case SCE_CMAKE_VARIABLE:
// CMake Variable:
if ( cCurrChar == '$' )
state = SCE_CMAKE_DEFAULT;
else if ( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
state = SCE_CMAKE_DEFAULT;
else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) {
state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler );
styler.ColourTo( i, state);
state = SCE_CMAKE_DEFAULT;
}
else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) {
if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER )
styler.ColourTo( i-1, SCE_CMAKE_NUMBER );
state = SCE_CMAKE_DEFAULT;
if ( cCurrChar == '"' ) {
state = SCE_CMAKE_STRINGDQ;
bVarInString = false;
bClassicVarInString = false;
}
else if ( cCurrChar == '`' ) {
state = SCE_CMAKE_STRINGLQ;
bVarInString = false;
bClassicVarInString = false;
}
else if ( cCurrChar == '\'' ) {
state = SCE_CMAKE_STRINGRQ;
bVarInString = false;
bClassicVarInString = false;
}
else if ( cCurrChar == '#' ) {
state = SCE_CMAKE_COMMENT;
}
}
break;
}
if ( state == SCE_CMAKE_COMMENT) {
styler.ColourTo(i,state);
}
else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {
bool bIngoreNextDollarSign = false;
if ( bVarInString && cCurrChar == '$' ) {
bVarInString = false;
bIngoreNextDollarSign = true;
}
else if ( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) {
styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
bVarInString = false;
bIngoreNextDollarSign = false;
}
else if ( bVarInString && !isCmakeChar(cNextChar) ) {
int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler);
if ( nWordState == SCE_CMAKE_VARIABLE )
styler.ColourTo( i, SCE_CMAKE_STRINGVAR);
bVarInString = false;
}
// Covers "${TEST}..."
else if ( bClassicVarInString && cNextChar == '}' ) {
styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR);
bClassicVarInString = false;
}
// Start of var in string
if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) {
styler.ColourTo( i-1, state);
bClassicVarInString = true;
bVarInString = false;
}
else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) {
styler.ColourTo( i-1, state);
bVarInString = true;
bClassicVarInString = false;
}
}
}
// Colourise remaining document
styler.ColourTo(nLengthDoc-1,state);
}
static void FoldCmakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
{
// No folding enabled, no reason to continue...
if ( styler.GetPropertyInt("fold") == 0 )
return;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
int lineCurrent = styler.GetLine(startPos);
unsigned int safeStartPos = styler.LineStart( lineCurrent );
bool bArg1 = true;
int nWordStart = -1;
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
for (unsigned int i = safeStartPos; i < startPos + length; i++) {
char chCurr = styler.SafeGetCharAt(i);
if ( bArg1 ) {
if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) {
nWordStart = i;
}
else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) {
int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse);
if ( newLevel == levelNext ) {
if ( foldAtElse ) {
if ( CmakeNextLineHasElse(i, startPos + length, styler) )
levelNext--;
}
}
else
levelNext = newLevel;
bArg1 = false;
}
}
if ( chCurr == '\n' ) {
if ( bArg1 && foldAtElse) {
if ( CmakeNextLineHasElse(i, startPos + length, styler) )
levelNext--;
}
// If we are on a new line...
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (levelUse < levelNext )
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
levelCurrent = levelNext;
bArg1 = true; // New line, lets look at first argument again
nWordStart = -1;
}
}
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
}
static const char * const cmakeWordLists[] = {
"Commands",
"Parameters",
"UserDefined",
0,
0,};
LexerModule lmCmake(SCLEX_CMAKE, ColouriseCmakeDoc, "cmake", FoldCmakeDoc, cmakeWordLists);

View File

@@ -0,0 +1,188 @@
// Scintilla source code edit control
/** @file LexConf.cxx
** Lexer for Apache Configuration Files.
**
** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
** i created this lexer because i needed something pretty when dealing
** when Apache Configuration files...
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_CONF_DEFAULT;
char chNext = styler[startPos];
int lengthDoc = startPos + length;
// create a buffer large enough to take the largest chunk...
char *buffer = new char[length];
int bufferCount = 0;
// this assumes that we have 2 keyword list in conf.properties
WordList &directives = *keywordLists[0];
WordList &params = *keywordLists[1];
// go through all provided text segment
// using the hand-written state machine shown below
styler.StartAt(startPos);
styler.StartSegment(startPos);
for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
continue;
}
switch(state) {
case SCE_CONF_DEFAULT:
if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
// whitespace is simply ignored here...
styler.ColourTo(i,SCE_CONF_DEFAULT);
break;
} else if( ch == '#' ) {
// signals the start of a comment...
state = SCE_CONF_COMMENT;
styler.ColourTo(i,SCE_CONF_COMMENT);
} else if( ch == '.' /*|| ch == '/'*/) {
// signals the start of a file...
state = SCE_CONF_EXTENSION;
styler.ColourTo(i,SCE_CONF_EXTENSION);
} else if( ch == '"') {
state = SCE_CONF_STRING;
styler.ColourTo(i,SCE_CONF_STRING);
} else if( isascii(ch) && ispunct(ch) ) {
// signals an operator...
// no state jump necessary for this
// simple case...
styler.ColourTo(i,SCE_CONF_OPERATOR);
} else if( isascii(ch) && isalpha(ch) ) {
// signals the start of an identifier
bufferCount = 0;
buffer[bufferCount++] = static_cast<char>(tolower(ch));
state = SCE_CONF_IDENTIFIER;
} else if( isascii(ch) && isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
//styler.ColourTo(i,SCE_CONF_NUMBER);
state = SCE_CONF_NUMBER;
} else {
// style it the default style..
styler.ColourTo(i,SCE_CONF_DEFAULT);
}
break;
case SCE_CONF_COMMENT:
// if we find a newline here,
// we simply go to default state
// else continue to work on it...
if( ch == '\n' || ch == '\r' ) {
state = SCE_CONF_DEFAULT;
} else {
styler.ColourTo(i,SCE_CONF_COMMENT);
}
break;
case SCE_CONF_EXTENSION:
// if we find a non-alphanumeric char,
// we simply go to default state
// else we're still dealing with an extension...
if( (isascii(ch) && isalnum(ch)) || (ch == '_') ||
(ch == '-') || (ch == '$') ||
(ch == '/') || (ch == '.') || (ch == '*') )
{
styler.ColourTo(i,SCE_CONF_EXTENSION);
} else {
state = SCE_CONF_DEFAULT;
chNext = styler[i--];
}
break;
case SCE_CONF_STRING:
// if we find the end of a string char, we simply go to default state
// else we're still dealing with an string...
if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
state = SCE_CONF_DEFAULT;
}
styler.ColourTo(i,SCE_CONF_STRING);
break;
case SCE_CONF_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
buffer[bufferCount++] = static_cast<char>(tolower(ch));
} else {
state = SCE_CONF_DEFAULT;
buffer[bufferCount] = '\0';
// check if the buffer contains a keyword, and highlight it if it is a keyword...
if(directives.InList(buffer)) {
styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
} else if(params.InList(buffer)) {
styler.ColourTo(i-1,SCE_CONF_PARAMETER );
} else if(strchr(buffer,'/') || strchr(buffer,'.')) {
styler.ColourTo(i-1,SCE_CONF_EXTENSION);
} else {
styler.ColourTo(i-1,SCE_CONF_DEFAULT);
}
// push back the faulty character
chNext = styler[i--];
}
break;
case SCE_CONF_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
if( (isascii(ch) && isdigit(ch)) || ch == '.') {
buffer[bufferCount++] = ch;
} else {
state = SCE_CONF_DEFAULT;
buffer[bufferCount] = '\0';
// Colourize here...
if( strchr(buffer,'.') ) {
// it is an IP address...
styler.ColourTo(i-1,SCE_CONF_IP);
} else {
// normal number
styler.ColourTo(i-1,SCE_CONF_NUMBER);
}
// push back a character
chNext = styler[i--];
}
break;
}
}
delete []buffer;
}
static const char * const confWordListDesc[] = {
"Directives",
"Parameters",
0
};
LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);

View File

@@ -0,0 +1,119 @@
// Scintilla source code edit control
/** @file LexOthers.cxx
** Lexers for batch files, diff results, properties files, make files and error lists.
** Also lexer for LaTeX documents.
**/
// Copyright 1998-2001 by Eran Ifrah <eran.ifrah@gmail.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <string>
#include <wx/string.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StyleContext.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
typedef int (*CPPCHECK_COLOUR_FUNC_PTR)(int, const char*, size_t&, size_t&);
static CPPCHECK_COLOUR_FUNC_PTR s_cppcheckColourFunc = NULL;
void SetCppCheckColourFunction(CPPCHECK_COLOUR_FUNC_PTR func)
{
s_cppcheckColourFunc = func;
}
static inline bool AtEOL(Accessor &styler, unsigned int i)
{
return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
}
static void ColouriseCppCheckDoc(
unsigned int pos,
int length,
int /*initStyle*/,
WordList * /*keywordlists*/[],
Accessor &styler)
{
std::string line;
line.reserve(2048);
styler.StartAt(pos);
styler.StartSegment(pos);
for (; length > 0; pos++, length--) {
line += styler[pos];
if (AtEOL(styler, pos)) {
// End of line met, colourise it
int style = SCLEX_GCC_OUTPUT;
if (s_cppcheckColourFunc) {
size_t start(0);
size_t len(0);
int startLine = pos-line.size()+1;
style = s_cppcheckColourFunc(startLine, line.c_str(), start, len);
if(len != 0) {
styler.ColourTo(startLine + start - 1, style);
styler.ColourTo(startLine + start + len - 1, SCLEX_GCC_FILE_LINK);
}
}
styler.ColourTo(pos, style);
line.clear();
}
}
}
static void FoldCppCheckDoc(unsigned int pos, int length, int,
WordList*[], Accessor &styler)
{
int curLine = styler.GetLine(pos);
int prevLevel = curLine > 0 ? styler.LevelAt(curLine-1) : SC_FOLDLEVELBASE;
unsigned int end = pos+length;
pos = styler.LineStart(curLine);
do {
int nextLevel;
switch (styler.StyleAt(pos)) {
case SCLEX_GCC_BUILDING:
nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
break;
default:
nextLevel = prevLevel & SC_FOLDLEVELHEADERFLAG ? (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1 : prevLevel;
break;
}
if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && nextLevel == prevLevel) {
styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
}
styler.SetLevel(curLine, nextLevel);
curLine++;
prevLevel = nextLevel;
pos = styler.LineStart(curLine);
} while (pos < end);
}
static const char * const cppcheckWordListDesc[] = {
"Internal Commands",
"External Commands",
0
};
static const char * const emptyWordListDesc[] = {
0
};
LexerModule lmCppCheck(SCLEX_CPPCHECK, ColouriseCppCheckDoc, "cppcheck", FoldCppCheckDoc, cppcheckWordListDesc);

View File

@@ -0,0 +1,222 @@
// Scintilla source code edit control
/** @file LexCrontab.cxx
** Lexer to use with extended crontab files used by a powerful
** Windows scheduler/event monitor/automation manager nnCron.
** (http://nemtsev.eserv.ru/)
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordList
*keywordLists[], Accessor &styler)
{
int state = SCE_NNCRONTAB_DEFAULT;
char chNext = styler[startPos];
int lengthDoc = startPos + length;
// create a buffer large enough to take the largest chunk...
char *buffer = new char[length];
int bufferCount = 0;
// used when highliting environment variables inside quoted string:
bool insideString = false;
// this assumes that we have 3 keyword list in conf.properties
WordList &section = *keywordLists[0];
WordList &keyword = *keywordLists[1];
WordList &modifier = *keywordLists[2];
// go through all provided text segment
// using the hand-written state machine shown below
styler.StartAt(startPos);
styler.StartSegment(startPos);
for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
continue;
}
switch(state) {
case SCE_NNCRONTAB_DEFAULT:
if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
// whitespace is simply ignored here...
styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
break;
} else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') {
// signals the start of a task...
state = SCE_NNCRONTAB_TASK;
styler.ColourTo(i,SCE_NNCRONTAB_TASK);
}
else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
styler.SafeGetCharAt(i+1) == '\t')) {
// signals the start of an extended comment...
state = SCE_NNCRONTAB_COMMENT;
styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
} else if( ch == '#' ) {
// signals the start of a plain comment...
state = SCE_NNCRONTAB_COMMENT;
styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
} else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') {
// signals the end of a task...
state = SCE_NNCRONTAB_TASK;
styler.ColourTo(i,SCE_NNCRONTAB_TASK);
} else if( ch == '"') {
state = SCE_NNCRONTAB_STRING;
styler.ColourTo(i,SCE_NNCRONTAB_STRING);
} else if( ch == '%') {
// signals environment variables
state = SCE_NNCRONTAB_ENVIRONMENT;
styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
} else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') {
// signals environment variables
state = SCE_NNCRONTAB_ENVIRONMENT;
styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
} else if( ch == '*' ) {
// signals an asterisk
// no state jump necessary for this simple case...
styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
} else if( (isascii(ch) && isalpha(ch)) || ch == '<' ) {
// signals the start of an identifier
bufferCount = 0;
buffer[bufferCount++] = ch;
state = SCE_NNCRONTAB_IDENTIFIER;
} else if( isascii(ch) && isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
state = SCE_NNCRONTAB_NUMBER;
} else {
// style it the default style..
styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
}
break;
case SCE_NNCRONTAB_COMMENT:
// if we find a newline here,
// we simply go to default state
// else continue to work on it...
if( ch == '\n' || ch == '\r' ) {
state = SCE_NNCRONTAB_DEFAULT;
} else {
styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
}
break;
case SCE_NNCRONTAB_TASK:
// if we find a newline here,
// we simply go to default state
// else continue to work on it...
if( ch == '\n' || ch == '\r' ) {
state = SCE_NNCRONTAB_DEFAULT;
} else {
styler.ColourTo(i,SCE_NNCRONTAB_TASK);
}
break;
case SCE_NNCRONTAB_STRING:
if( ch == '%' ) {
state = SCE_NNCRONTAB_ENVIRONMENT;
insideString = true;
styler.ColourTo(i-1,SCE_NNCRONTAB_STRING);
break;
}
// if we find the end of a string char, we simply go to default state
// else we're still dealing with an string...
if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') ||
(ch == '\n') || (ch == '\r') ) {
state = SCE_NNCRONTAB_DEFAULT;
}
styler.ColourTo(i,SCE_NNCRONTAB_STRING);
break;
case SCE_NNCRONTAB_ENVIRONMENT:
// if we find the end of a string char, we simply go to default state
// else we're still dealing with an string...
if( ch == '%' && insideString ) {
state = SCE_NNCRONTAB_STRING;
insideString = false;
break;
}
if( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\')
|| (ch == '\n') || (ch == '\r') || (ch == '>') ) {
state = SCE_NNCRONTAB_DEFAULT;
styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
break;
}
styler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT);
break;
case SCE_NNCRONTAB_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||
(ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
(ch == '@') ) {
buffer[bufferCount++] = ch;
} else {
state = SCE_NNCRONTAB_DEFAULT;
buffer[bufferCount] = '\0';
// check if the buffer contains a keyword,
// and highlight it if it is a keyword...
if(section.InList(buffer)) {
styler.ColourTo(i,SCE_NNCRONTAB_SECTION );
} else if(keyword.InList(buffer)) {
styler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD );
} // else if(strchr(buffer,'/') || strchr(buffer,'.')) {
// styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);
// }
else if(modifier.InList(buffer)) {
styler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER );
} else {
styler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT);
}
// push back the faulty character
chNext = styler[i--];
}
break;
case SCE_NNCRONTAB_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
if( isascii(ch) && isdigit(ch) /* || ch == '.' */ ) {
buffer[bufferCount++] = ch;
} else {
state = SCE_NNCRONTAB_DEFAULT;
buffer[bufferCount] = '\0';
// Colourize here... (normal number)
styler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER);
// push back a character
chNext = styler[i--];
}
break;
}
}
delete []buffer;
}
static const char * const cronWordListDesc[] = {
"Section keywords and Forth words",
"nnCrontab keywords",
"Modifiers",
0
};
LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);

View File

@@ -0,0 +1,210 @@
// Scintilla source code edit control
/** @file LexCsound.cxx
** Lexer for Csound (Orchestra & Score)
** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
ch == '_' || ch == '?');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
ch == '%' || ch == '@' || ch == '$' || ch == '?');
}
static inline bool IsCsoundOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
ch == '%' || ch == ':')
return true;
return false;
}
static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &opcode = *keywordlists[0];
WordList &headerStmt = *keywordlists[1];
WordList &otherKeyword = *keywordlists[2];
// Do not leak onto next line
if (initStyle == SCE_CSOUND_STRINGEOL)
initStyle = SCE_CSOUND_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
// Handle line continuation generically.
if (sc.ch == '\\') {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continue;
}
}
// Determine if the current state should terminate.
if (sc.state == SCE_CSOUND_OPERATOR) {
if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_CSOUND_DEFAULT);
}
}else if (sc.state == SCE_CSOUND_NUMBER) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_CSOUND_DEFAULT);
}
} else if (sc.state == SCE_CSOUND_IDENTIFIER) {
if (!IsAWordChar(sc.ch) ) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (opcode.InList(s)) {
sc.ChangeState(SCE_CSOUND_OPCODE);
} else if (headerStmt.InList(s)) {
sc.ChangeState(SCE_CSOUND_HEADERSTMT);
} else if (otherKeyword.InList(s)) {
sc.ChangeState(SCE_CSOUND_USERKEYWORD);
} else if (s[0] == 'p') {
sc.ChangeState(SCE_CSOUND_PARAM);
} else if (s[0] == 'a') {
sc.ChangeState(SCE_CSOUND_ARATE_VAR);
} else if (s[0] == 'k') {
sc.ChangeState(SCE_CSOUND_KRATE_VAR);
} else if (s[0] == 'i') { // covers both i-rate variables and i-statements
sc.ChangeState(SCE_CSOUND_IRATE_VAR);
} else if (s[0] == 'g') {
sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
}
sc.SetState(SCE_CSOUND_DEFAULT);
}
}
else if (sc.state == SCE_CSOUND_COMMENT ) {
if (sc.atLineEnd) {
sc.SetState(SCE_CSOUND_DEFAULT);
}
}
else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
(sc.state == SCE_CSOUND_KRATE_VAR) ||
(sc.state == SCE_CSOUND_IRATE_VAR)) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_CSOUND_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_CSOUND_DEFAULT) {
if (sc.ch == ';'){
sc.SetState(SCE_CSOUND_COMMENT);
} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
sc.SetState(SCE_CSOUND_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_CSOUND_IDENTIFIER);
} else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_CSOUND_OPERATOR);
} else if (sc.ch == 'p') {
sc.SetState(SCE_CSOUND_PARAM);
} else if (sc.ch == 'a') {
sc.SetState(SCE_CSOUND_ARATE_VAR);
} else if (sc.ch == 'k') {
sc.SetState(SCE_CSOUND_KRATE_VAR);
} else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
sc.SetState(SCE_CSOUND_IRATE_VAR);
} else if (sc.ch == 'g') {
sc.SetState(SCE_CSOUND_GLOBAL_VAR);
}
}
}
sc.Complete();
}
static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int stylePrev = 0;
int styleNext = styler.StyleAt(startPos);
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
char s[20];
unsigned int j = 0;
while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
s[j] = styler[i + j];
j++;
}
s[j] = '\0';
if (strcmp(s, "instr") == 0)
levelCurrent++;
if (strcmp(s, "endin") == 0)
levelCurrent--;
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
stylePrev = style;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const csoundWordListDesc[] = {
"Opcodes",
"Header Statements",
"User keywords",
0
};
LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);

View File

@@ -0,0 +1,399 @@
/** @file LexD.cxx
** Lexer for D.
**
** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com>
**/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/* Nested comments require keeping the value of the nesting level for every
position in the document. But since scintilla always styles line by line,
we only need to store one value per line. The non-negative number indicates
nesting level at the end of the line.
*/
// Underscore, letter, digit and universal alphas from C99 Appendix D.
static bool IsWordStart(int ch) {
return (isascii(ch) && (isalpha(ch) || ch == '_')) || !isascii(ch);
}
static bool IsWord(int ch) {
return (isascii(ch) && (isalnum(ch) || ch == '_')) || !isascii(ch);
}
static bool IsDoxygen(int ch) {
if (isascii(ch) && islower(ch))
return true;
if (ch == '$' || ch == '@' || ch == '\\' ||
ch == '&' || ch == '#' || ch == '<' || ch == '>' ||
ch == '{' || ch == '}' || ch == '[' || ch == ']')
return true;
return false;
}
static bool IsStringSuffix(int ch) {
return ch == 'c' || ch == 'w' || ch == 'd';
}
static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2]; //doxygen
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
WordList &keywords7 = *keywordlists[6];
int styleBeforeDCKeyword = SCE_D_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler);
int curLine = styler.GetLine(startPos);
int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
bool numFloat = false; // Float literals have '+' and '-' signs
bool numHex = false;
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart) {
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, curNcLevel);
}
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_D_OPERATOR:
sc.SetState(SCE_D_DEFAULT);
break;
case SCE_D_NUMBER:
// We accept almost anything because of hex. and number suffixes
if (isascii(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {
continue;
} else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {
// Don't parse 0..2 as number.
numFloat=true;
continue;
} else if ( ( sc.ch == '-' || sc.ch == '+' ) && ( /*sign and*/
( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/
( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) { /*hex*/
// Parse exponent sign in float literals: 2e+10 0x2e+10
continue;
} else {
sc.SetState(SCE_D_DEFAULT);
}
break;
case SCE_D_IDENTIFIER:
if (!IsWord(sc.ch)) {
char s[1000];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
if (keywords.InList(s)) {
sc.ChangeState(SCE_D_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_D_WORD2);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_D_TYPEDEF);
} else if (keywords5.InList(s)) {
sc.ChangeState(SCE_D_WORD5);
} else if (keywords6.InList(s)) {
sc.ChangeState(SCE_D_WORD6);
} else if (keywords7.InList(s)) {
sc.ChangeState(SCE_D_WORD7);
}
sc.SetState(SCE_D_DEFAULT);
}
break;
case SCE_D_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_D_DEFAULT);
}
break;
case SCE_D_COMMENTDOC:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_D_DEFAULT);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_D_COMMENTDOC;
sc.SetState(SCE_D_COMMENTDOCKEYWORD);
}
}
break;
case SCE_D_COMMENTLINE:
if (sc.atLineStart) {
sc.SetState(SCE_D_DEFAULT);
}
break;
case SCE_D_COMMENTLINEDOC:
if (sc.atLineStart) {
sc.SetState(SCE_D_DEFAULT);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
sc.SetState(SCE_D_COMMENTDOCKEYWORD);
}
}
break;
case SCE_D_COMMENTDOCKEYWORD:
if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
sc.Forward();
sc.ForwardSetState(SCE_D_DEFAULT);
} else if (!IsDoxygen(sc.ch)) {
char s[100];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
}
sc.SetState(styleBeforeDCKeyword);
}
break;
case SCE_D_COMMENTNESTED:
if (sc.Match('+', '/')) {
if (curNcLevel > 0)
curNcLevel -= 1;
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, curNcLevel);
sc.Forward();
if (curNcLevel == 0) {
sc.ForwardSetState(SCE_D_DEFAULT);
}
} else if (sc.Match('/','+')) {
curNcLevel += 1;
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, curNcLevel);
sc.Forward();
}
break;
case SCE_D_STRING:
if (sc.ch == '\\') {
if (sc.chNext == '"' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '"') {
if(IsStringSuffix(sc.chNext))
sc.Forward();
sc.ForwardSetState(SCE_D_DEFAULT);
}
break;
case SCE_D_CHARACTER:
if (sc.atLineEnd) {
sc.ChangeState(SCE_D_STRINGEOL);
} else if (sc.ch == '\\') {
if (sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
// Char has no suffixes
sc.ForwardSetState(SCE_D_DEFAULT);
}
break;
case SCE_D_STRINGEOL:
if (sc.atLineStart) {
sc.SetState(SCE_D_DEFAULT);
}
break;
case SCE_D_STRINGB:
if (sc.ch == '`') {
if(IsStringSuffix(sc.chNext))
sc.Forward();
sc.ForwardSetState(SCE_D_DEFAULT);
}
break;
case SCE_D_STRINGR:
if (sc.ch == '"') {
if(IsStringSuffix(sc.chNext))
sc.Forward();
sc.ForwardSetState(SCE_D_DEFAULT);
}
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_D_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_D_NUMBER);
numFloat = sc.ch == '.';
// Remember hex literal
numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );
} else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')
&& sc.chNext == '"' ) {
// Limited support for hex and delimited strings: parse as r""
sc.SetState(SCE_D_STRINGR);
sc.Forward();
} else if (IsWordStart(sc.ch) || sc.ch == '$') {
sc.SetState(SCE_D_IDENTIFIER);
} else if (sc.Match('/','+')) {
curNcLevel += 1;
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, curNcLevel);
sc.SetState(SCE_D_COMMENTNESTED);
sc.Forward();
} else if (sc.Match('/', '*')) {
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
sc.SetState(SCE_D_COMMENTDOC);
} else {
sc.SetState(SCE_D_COMMENT);
}
sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('/', '/')) {
if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
// Support of Qt/Doxygen doc. style
sc.SetState(SCE_D_COMMENTLINEDOC);
else
sc.SetState(SCE_D_COMMENTLINE);
} else if (sc.ch == '"') {
sc.SetState(SCE_D_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_D_CHARACTER);
} else if (sc.ch == '`') {
sc.SetState(SCE_D_STRINGB);
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_D_OPERATOR);
if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator
}
}
}
sc.Complete();
}
static bool IsStreamCommentStyle(int style) {
return style == SCE_D_COMMENT ||
style == SCE_D_COMMENTDOC ||
style == SCE_D_COMMENTDOCKEYWORD ||
style == SCE_D_COMMENTDOCKEYWORDERROR;
}
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
// property lexer.d.fold.at.else
// This option enables D folding on a "} else {" line of an if statement.
bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
styler.GetPropertyInt("fold.at.else", 0)) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelNext--;
}
}
if (style == SCE_D_OPERATOR) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
if (levelMinCurrent > levelNext) {
levelMinCurrent = levelNext;
}
levelNext++;
} else if (ch == '}') {
levelNext--;
}
}
if (atEOL) {
if (foldComment) { // Handle nested comments
int nc;
nc = styler.GetLineState(lineCurrent);
nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
levelNext += nc;
}
int levelUse = levelCurrent;
if (foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
visibleChars = 0;
}
if (!IsASpace(ch))
visibleChars++;
}
}
static void FoldDDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
FoldDoc(startPos, length, initStyle, styler);
}
static const char * const dWordLists[] = {
"Primary keywords and identifiers",
"Secondary keywords and identifiers",
"Documentation comment keywords",
"Type definitions and aliases",
"Keywords 5",
"Keywords 6",
"Keywords 7",
0,
};
static void ColouriseDDoc(unsigned int startPos, int length,
int initStyle, WordList *keywordlists[], Accessor &styler) {
ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
}
LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);

View File

@@ -0,0 +1,273 @@
// Scintilla source code edit control
/** @file LexESCRIPT.cxx
** Lexer for ESCRIPT
**/
// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static void ColouriseESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
// Do not leak onto next line
/*if (initStyle == SCE_ESCRIPT_STRINGEOL)
initStyle = SCE_ESCRIPT_DEFAULT;*/
StyleContext sc(startPos, length, initStyle, styler);
bool caseSensitive = styler.GetPropertyInt("escript.case.sensitive", 0) != 0;
for (; sc.More(); sc.Forward()) {
/*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) {
// Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line
sc.SetState(SCE_ESCRIPT_STRING);
}*/
// Handle line continuation generically.
if (sc.ch == '\\') {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continue;
}
}
// Determine if the current state should terminate.
if (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) {
sc.SetState(SCE_ESCRIPT_DEFAULT);
} else if (sc.state == SCE_ESCRIPT_NUMBER) {
if (!IsADigit(sc.ch) || sc.ch != '.') {
sc.SetState(SCE_ESCRIPT_DEFAULT);
}
} else if (sc.state == SCE_ESCRIPT_IDENTIFIER) {
if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
char s[100];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
// sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_ESCRIPT_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_ESCRIPT_WORD2);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_ESCRIPT_WORD3);
// sc.state = SCE_ESCRIPT_IDENTIFIER;
}
sc.SetState(SCE_ESCRIPT_DEFAULT);
}
} else if (sc.state == SCE_ESCRIPT_COMMENT) {
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
}
} else if (sc.state == SCE_ESCRIPT_COMMENTDOC) {
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
}
} else if (sc.state == SCE_ESCRIPT_COMMENTLINE) {
if (sc.atLineEnd) {
sc.SetState(SCE_ESCRIPT_DEFAULT);
}
} else if (sc.state == SCE_ESCRIPT_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_ESCRIPT_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_ESCRIPT_NUMBER);
} else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
sc.SetState(SCE_ESCRIPT_IDENTIFIER);
} else if (sc.Match('/', '*')) {
sc.SetState(SCE_ESCRIPT_COMMENT);
sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('/', '/')) {
sc.SetState(SCE_ESCRIPT_COMMENTLINE);
} else if (sc.ch == '\"') {
sc.SetState(SCE_ESCRIPT_STRING);
//} else if (isoperator(static_cast<char>(sc.ch))) {
} else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
sc.SetState(SCE_ESCRIPT_OPERATOR);
} else if (sc.ch == '{' || sc.ch == '}') {
sc.SetState(SCE_ESCRIPT_BRACE);
}
}
}
sc.Complete();
}
static int classifyFoldPointESCRIPT(const char* s, const char* prevWord) {
int lev = 0;
if (strcmp(prevWord, "end") == 0) return lev;
if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
return -1;
if (strcmp(s, "for") == 0 || strcmp(s, "foreach") == 0
|| strcmp(s, "program") == 0 || strcmp(s, "function") == 0
|| strcmp(s, "while") == 0 || strcmp(s, "case") == 0
|| strcmp(s, "if") == 0 ) {
lev = 1;
} else if ( strcmp(s, "endfor") == 0 || strcmp(s, "endforeach") == 0
|| strcmp(s, "endprogram") == 0 || strcmp(s, "endfunction") == 0
|| strcmp(s, "endwhile") == 0 || strcmp(s, "endcase") == 0
|| strcmp(s, "endif") == 0 ) {
lev = -1;
}
return lev;
}
static bool IsStreamCommentStyle(int style) {
return style == SCE_ESCRIPT_COMMENT ||
style == SCE_ESCRIPT_COMMENTDOC ||
style == SCE_ESCRIPT_COMMENTLINE;
}
static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
//~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
// Do not know how to fold the comment at the moment.
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldComment = true;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int lastStart = 0;
char prevWord[32] = "";
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelCurrent++;
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelCurrent--;
}
}
if (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) {
if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
if (chNext2 == '{') {
levelCurrent++;
} else if (chNext2 == '}') {
levelCurrent--;
}
}
}
if (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3)
{
// Store last word start point.
lastStart = i;
}
if (style == SCE_ESCRIPT_WORD3) {
if(iswordchar(ch) && !iswordchar(chNext)) {
char s[32];
unsigned int j;
for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
s[j] = static_cast<char>(tolower(styler[lastStart + j]));
}
s[j] = '\0';
levelCurrent += classifyFoldPointESCRIPT(s, prevWord);
strcpy(prevWord, s);
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
strcpy(prevWord, "");
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const ESCRIPTWordLists[] = {
"Primary keywords and identifiers",
"Intrinsic functions",
"Extended and user defined functions",
0,
};
LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, "escript", FoldESCRIPTDoc, ESCRIPTWordLists);

View File

@@ -0,0 +1,238 @@
// Scintilla source code edit control
/** @file LexEiffel.cxx
** Lexer for Eiffel.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool isEiffelOperator(unsigned int ch) {
// '.' left out as it is used to make up numbers
return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' ||
ch == '{' || ch == '}' || ch == '~' ||
ch == '[' || ch == ']' || ch == ';' ||
ch == '<' || ch == '>' || ch == ',' ||
ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
ch == '!' || ch == '@' || ch == '?';
}
static inline bool IsAWordChar(unsigned int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAWordStart(unsigned int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static void ColouriseEiffelDoc(unsigned int startPos,
int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.state == SCE_EIFFEL_STRINGEOL) {
if (sc.ch != '\r' && sc.ch != '\n') {
sc.SetState(SCE_EIFFEL_DEFAULT);
}
} else if (sc.state == SCE_EIFFEL_OPERATOR) {
sc.SetState(SCE_EIFFEL_DEFAULT);
} else if (sc.state == SCE_EIFFEL_WORD) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (!keywords.InList(s)) {
sc.ChangeState(SCE_EIFFEL_IDENTIFIER);
}
sc.SetState(SCE_EIFFEL_DEFAULT);
}
} else if (sc.state == SCE_EIFFEL_NUMBER) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_EIFFEL_DEFAULT);
}
} else if (sc.state == SCE_EIFFEL_COMMENTLINE) {
if (sc.ch == '\r' || sc.ch == '\n') {
sc.SetState(SCE_EIFFEL_DEFAULT);
}
} else if (sc.state == SCE_EIFFEL_STRING) {
if (sc.ch == '%') {
sc.Forward();
} else if (sc.ch == '\"') {
sc.Forward();
sc.SetState(SCE_EIFFEL_DEFAULT);
}
} else if (sc.state == SCE_EIFFEL_CHARACTER) {
if (sc.ch == '\r' || sc.ch == '\n') {
sc.SetState(SCE_EIFFEL_STRINGEOL);
} else if (sc.ch == '%') {
sc.Forward();
} else if (sc.ch == '\'') {
sc.Forward();
sc.SetState(SCE_EIFFEL_DEFAULT);
}
}
if (sc.state == SCE_EIFFEL_DEFAULT) {
if (sc.ch == '-' && sc.chNext == '-') {
sc.SetState(SCE_EIFFEL_COMMENTLINE);
} else if (sc.ch == '\"') {
sc.SetState(SCE_EIFFEL_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_EIFFEL_CHARACTER);
} else if (IsADigit(sc.ch) || (sc.ch == '.')) {
sc.SetState(SCE_EIFFEL_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_EIFFEL_WORD);
} else if (isEiffelOperator(sc.ch)) {
sc.SetState(SCE_EIFFEL_OPERATOR);
}
}
}
sc.Complete();
}
static bool IsEiffelComment(Accessor &styler, int pos, int len) {
return len>1 && styler[pos]=='-' && styler[pos+1]=='-';
}
static void FoldEiffelDocIndent(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
int lengthDoc = startPos + length;
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
}
int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment);
char chNext = styler[startPos];
for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
int lev = indentCurrent;
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment);
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
// Line after is blank so check the next - maybe should continue further?
int spaceFlags2 = 0;
int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment);
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
}
}
indentCurrent = indentNext;
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
}
}
}
static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int stylePrev = 0;
int styleNext = styler.StyleAt(startPos);
// lastDeferred should be determined by looking back to last keyword in case
// the "deferred" is on a line before "class"
bool lastDeferred = false;
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) {
char s[20];
unsigned int j = 0;
while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
s[j] = styler[i + j];
j++;
}
s[j] = '\0';
if (
(strcmp(s, "check") == 0) ||
(strcmp(s, "debug") == 0) ||
(strcmp(s, "deferred") == 0) ||
(strcmp(s, "do") == 0) ||
(strcmp(s, "from") == 0) ||
(strcmp(s, "if") == 0) ||
(strcmp(s, "inspect") == 0) ||
(strcmp(s, "once") == 0)
)
levelCurrent++;
if (!lastDeferred && (strcmp(s, "class") == 0))
levelCurrent++;
if (strcmp(s, "end") == 0)
levelCurrent--;
lastDeferred = strcmp(s, "deferred") == 0;
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
stylePrev = style;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const eiffelWordListDesc[] = {
"Keywords",
0
};
LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc);
LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc);

View File

@@ -0,0 +1,619 @@
// Scintilla source code edit control
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
/** @file LexErlang.cxx
** Lexer for Erlang.
** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
** Originally wrote by Peter-Henry Mander,
** based on Matlab lexer by Jos<6F> Fonseca.
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static int is_radix(int radix, int ch) {
int digit;
if (36 < radix || 2 > radix)
return 0;
if (isdigit(ch)) {
digit = ch - '0';
} else if (isalnum(ch)) {
digit = toupper(ch) - 'A' + 10;
} else {
return 0;
}
return (digit < radix);
}
typedef enum {
STATE_NULL,
COMMENT,
COMMENT_FUNCTION,
COMMENT_MODULE,
COMMENT_DOC,
COMMENT_DOC_MACRO,
ATOM_UNQUOTED,
ATOM_QUOTED,
NODE_NAME_UNQUOTED,
NODE_NAME_QUOTED,
MACRO_START,
MACRO_UNQUOTED,
MACRO_QUOTED,
RECORD_START,
RECORD_UNQUOTED,
RECORD_QUOTED,
NUMERAL_START,
NUMERAL_BASE_VALUE,
NUMERAL_FLOAT,
NUMERAL_EXPONENT,
PREPROCESSOR
} atom_parse_state_t;
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');
}
static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
StyleContext sc(startPos, length, initStyle, styler);
WordList &reservedWords = *keywordlists[0];
WordList &erlangBIFs = *keywordlists[1];
WordList &erlangPreproc = *keywordlists[2];
WordList &erlangModulesAtt = *keywordlists[3];
WordList &erlangDoc = *keywordlists[4];
WordList &erlangDocMacro = *keywordlists[5];
int radix_digits = 0;
int exponent_digits = 0;
atom_parse_state_t parse_state = STATE_NULL;
atom_parse_state_t old_parse_state = STATE_NULL;
bool to_late_to_comment = false;
char cur[100];
int old_style = SCE_ERLANG_DEFAULT;
styler.StartAt(startPos);
for (; sc.More(); sc.Forward()) {
int style = SCE_ERLANG_DEFAULT;
if (STATE_NULL != parse_state) {
switch (parse_state) {
case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;
/* COMMENTS ------------------------------------------------------*/
case COMMENT : {
if (sc.ch != '%') {
to_late_to_comment = true;
} else if (!to_late_to_comment && sc.ch == '%') {
// Switch to comment level 2 (Function)
sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
old_style = SCE_ERLANG_COMMENT_FUNCTION;
parse_state = COMMENT_FUNCTION;
sc.Forward();
}
}
// V--- Falling through!
case COMMENT_FUNCTION : {
if (sc.ch != '%') {
to_late_to_comment = true;
} else if (!to_late_to_comment && sc.ch == '%') {
// Switch to comment level 3 (Module)
sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
old_style = SCE_ERLANG_COMMENT_MODULE;
parse_state = COMMENT_MODULE;
sc.Forward();
}
}
// V--- Falling through!
case COMMENT_MODULE : {
if (parse_state != COMMENT) {
// Search for comment documentation
if (sc.chNext == '@') {
old_parse_state = parse_state;
parse_state = ('{' == sc.ch)
? COMMENT_DOC_MACRO
: COMMENT_DOC;
sc.ForwardSetState(sc.state);
}
}
// All comments types fall here.
if (sc.atLineEnd) {
to_late_to_comment = false;
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case COMMENT_DOC :
// V--- Falling through!
case COMMENT_DOC_MACRO : {
if (!isalnum(sc.ch)) {
// Try to match documentation comment
sc.GetCurrent(cur, sizeof(cur));
if (parse_state == COMMENT_DOC_MACRO
&& erlangDocMacro.InList(cur)) {
sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
while (sc.ch != '}' && !sc.atLineEnd)
sc.Forward();
} else if (erlangDoc.InList(cur)) {
sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
} else {
sc.ChangeState(old_style);
}
// Switch back to old state
sc.SetState(old_style);
parse_state = old_parse_state;
}
if (sc.atLineEnd) {
to_late_to_comment = false;
sc.ChangeState(old_style);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* -------------------------------------------------------------- */
/* Atoms ---------------------------------------------------------*/
case ATOM_UNQUOTED : {
if ('@' == sc.ch){
parse_state = NODE_NAME_UNQUOTED;
} else if (sc.ch == ':') {
// Searching for module name
if (sc.chNext == ' ') {
// error
sc.ChangeState(SCE_ERLANG_UNKNOWN);
parse_state = STATE_NULL;
} else {
sc.Forward();
if (isalnum(sc.ch)) {
sc.GetCurrent(cur, sizeof(cur));
sc.ChangeState(SCE_ERLANG_MODULES);
sc.SetState(SCE_ERLANG_MODULES);
}
}
} else if (!IsAWordChar(sc.ch)) {
sc.GetCurrent(cur, sizeof(cur));
if (reservedWords.InList(cur)) {
style = SCE_ERLANG_KEYWORD;
} else if (erlangBIFs.InList(cur)
&& strcmp(cur,"erlang:")){
style = SCE_ERLANG_BIFS;
} else if (sc.ch == '(' || '/' == sc.ch){
style = SCE_ERLANG_FUNCTION_NAME;
} else {
style = SCE_ERLANG_ATOM;
}
sc.ChangeState(style);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case ATOM_QUOTED : {
if ( '@' == sc.ch ){
parse_state = NODE_NAME_QUOTED;
} else if ('\'' == sc.ch && '\\' != sc.chPrev) {
sc.ChangeState(SCE_ERLANG_ATOM);
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* -------------------------------------------------------------- */
/* Node names ----------------------------------------------------*/
case NODE_NAME_UNQUOTED : {
if ('@' == sc.ch) {
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
} else if (!IsAWordChar(sc.ch)) {
sc.ChangeState(SCE_ERLANG_NODE_NAME);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case NODE_NAME_QUOTED : {
if ('@' == sc.ch) {
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
} else if ('\'' == sc.ch && '\\' != sc.chPrev) {
sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* -------------------------------------------------------------- */
/* Records -------------------------------------------------------*/
case RECORD_START : {
if ('\'' == sc.ch) {
parse_state = RECORD_QUOTED;
} else if (isalpha(sc.ch) && islower(sc.ch)) {
parse_state = RECORD_UNQUOTED;
} else { // error
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case RECORD_UNQUOTED : {
if (!IsAWordChar(sc.ch)) {
sc.ChangeState(SCE_ERLANG_RECORD);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case RECORD_QUOTED : {
if ('\'' == sc.ch && '\\' != sc.chPrev) {
sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* -------------------------------------------------------------- */
/* Macros --------------------------------------------------------*/
case MACRO_START : {
if ('\'' == sc.ch) {
parse_state = MACRO_QUOTED;
} else if (isalpha(sc.ch)) {
parse_state = MACRO_UNQUOTED;
} else { // error
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case MACRO_UNQUOTED : {
if (!IsAWordChar(sc.ch)) {
sc.ChangeState(SCE_ERLANG_MACRO);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
case MACRO_QUOTED : {
if ('\'' == sc.ch && '\\' != sc.chPrev) {
sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* -------------------------------------------------------------- */
/* Numerics ------------------------------------------------------*/
/* Simple integer */
case NUMERAL_START : {
if (isdigit(sc.ch)) {
radix_digits *= 10;
radix_digits += sc.ch - '0'; // Assuming ASCII here!
} else if ('#' == sc.ch) {
if (2 > radix_digits || 36 < radix_digits) {
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
} else {
parse_state = NUMERAL_BASE_VALUE;
}
} else if ('.' == sc.ch && isdigit(sc.chNext)) {
radix_digits = 0;
parse_state = NUMERAL_FLOAT;
} else if ('e' == sc.ch || 'E' == sc.ch) {
exponent_digits = 0;
parse_state = NUMERAL_EXPONENT;
} else {
radix_digits = 0;
sc.ChangeState(SCE_ERLANG_NUMBER);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* Integer in other base than 10 (x#yyy) */
case NUMERAL_BASE_VALUE : {
if (!is_radix(radix_digits,sc.ch)) {
radix_digits = 0;
if (!isalnum(sc.ch))
sc.ChangeState(SCE_ERLANG_NUMBER);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* Float (x.yyy) */
case NUMERAL_FLOAT : {
if ('e' == sc.ch || 'E' == sc.ch) {
exponent_digits = 0;
parse_state = NUMERAL_EXPONENT;
} else if (!isdigit(sc.ch)) {
sc.ChangeState(SCE_ERLANG_NUMBER);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
/* Exponent, either integer or float (xEyy, x.yyEzzz) */
case NUMERAL_EXPONENT : {
if (('-' == sc.ch || '+' == sc.ch)
&& (isdigit(sc.chNext))) {
sc.Forward();
} else if (!isdigit(sc.ch)) {
if (0 < exponent_digits)
sc.ChangeState(SCE_ERLANG_NUMBER);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
} else {
++exponent_digits;
}
} break;
/* -------------------------------------------------------------- */
/* Preprocessor --------------------------------------------------*/
case PREPROCESSOR : {
if (!IsAWordChar(sc.ch)) {
sc.GetCurrent(cur, sizeof(cur));
if (erlangPreproc.InList(cur)) {
style = SCE_ERLANG_PREPROC;
} else if (erlangModulesAtt.InList(cur)) {
style = SCE_ERLANG_MODULES_ATT;
}
sc.ChangeState(style);
sc.SetState(SCE_ERLANG_DEFAULT);
parse_state = STATE_NULL;
}
} break;
}
} /* End of : STATE_NULL != parse_state */
else
{
switch (sc.state) {
case SCE_ERLANG_VARIABLE : {
if (!IsAWordChar(sc.ch))
sc.SetState(SCE_ERLANG_DEFAULT);
} break;
case SCE_ERLANG_STRING : {
if (sc.ch == '\"' && sc.chPrev != '\\')
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
} break;
case SCE_ERLANG_COMMENT : {
if (sc.atLineEnd)
sc.SetState(SCE_ERLANG_DEFAULT);
} break;
case SCE_ERLANG_CHARACTER : {
if (sc.chPrev == '\\') {
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
} else if (sc.ch != '\\') {
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
}
} break;
case SCE_ERLANG_OPERATOR : {
if (sc.chPrev == '.') {
if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
|| sc.ch == '^') {
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
} else {
sc.SetState(SCE_ERLANG_DEFAULT);
}
} else {
sc.SetState(SCE_ERLANG_DEFAULT);
}
} break;
}
}
if (sc.state == SCE_ERLANG_DEFAULT) {
bool no_new_state = false;
switch (sc.ch) {
case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
case '%' : {
parse_state = COMMENT;
sc.SetState(SCE_ERLANG_COMMENT);
} break;
case '#' : {
parse_state = RECORD_START;
sc.SetState(SCE_ERLANG_UNKNOWN);
} break;
case '?' : {
parse_state = MACRO_START;
sc.SetState(SCE_ERLANG_UNKNOWN);
} break;
case '\'' : {
parse_state = ATOM_QUOTED;
sc.SetState(SCE_ERLANG_UNKNOWN);
} break;
case '+' :
case '-' : {
if (IsADigit(sc.chNext)) {
parse_state = NUMERAL_START;
radix_digits = 0;
sc.SetState(SCE_ERLANG_UNKNOWN);
} else if (sc.ch != '+') {
parse_state = PREPROCESSOR;
sc.SetState(SCE_ERLANG_UNKNOWN);
}
} break;
default : no_new_state = true;
}
if (no_new_state) {
if (isdigit(sc.ch)) {
parse_state = NUMERAL_START;
radix_digits = sc.ch - '0';
sc.SetState(SCE_ERLANG_UNKNOWN);
} else if (isupper(sc.ch) || '_' == sc.ch) {
sc.SetState(SCE_ERLANG_VARIABLE);
} else if (isalpha(sc.ch)) {
parse_state = ATOM_UNQUOTED;
sc.SetState(SCE_ERLANG_UNKNOWN);
} else if (isoperator(static_cast<char>(sc.ch))
|| sc.ch == '\\') {
sc.SetState(SCE_ERLANG_OPERATOR);
}
}
}
}
sc.Complete();
}
static int ClassifyErlangFoldPoint(
Accessor &styler,
int styleNext,
int keyword_start
) {
int lev = 0;
if (styler.Match(keyword_start,"case")
|| (
styler.Match(keyword_start,"fun")
&& (SCE_ERLANG_FUNCTION_NAME != styleNext)
)
|| styler.Match(keyword_start,"if")
|| styler.Match(keyword_start,"query")
|| styler.Match(keyword_start,"receive")
) {
++lev;
} else if (styler.Match(keyword_start,"end")) {
--lev;
}
return lev;
}
static void FoldErlangDoc(
unsigned int startPos, int length, int initStyle,
WordList** /*keywordlists*/, Accessor &styler
) {
unsigned int endPos = startPos + length;
int currentLine = styler.GetLine(startPos);
int lev;
int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
int currentLevel = previousLevel;
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int stylePrev;
int keyword_start = 0;
char ch;
char chNext = styler.SafeGetCharAt(startPos);
bool atEOL;
for (unsigned int i = startPos; i < endPos; i++) {
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
// Get styles
stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');
if (stylePrev != SCE_ERLANG_KEYWORD
&& style == SCE_ERLANG_KEYWORD) {
keyword_start = i;
}
// Fold on keywords
if (stylePrev == SCE_ERLANG_KEYWORD
&& style != SCE_ERLANG_KEYWORD
&& style != SCE_ERLANG_ATOM
) {
currentLevel += ClassifyErlangFoldPoint(styler,
styleNext,
keyword_start);
}
// Fold on comments
if (style == SCE_ERLANG_COMMENT
|| style == SCE_ERLANG_COMMENT_MODULE
|| style == SCE_ERLANG_COMMENT_FUNCTION) {
if (ch == '%' && chNext == '{') {
currentLevel++;
} else if (ch == '%' && chNext == '}') {
currentLevel--;
}
}
// Fold on braces
if (style == SCE_ERLANG_OPERATOR) {
if (ch == '{' || ch == '(' || ch == '[') {
currentLevel++;
} else if (ch == '}' || ch == ')' || ch == ']') {
currentLevel--;
}
}
if (atEOL) {
lev = previousLevel;
if (currentLevel > previousLevel)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(currentLine))
styler.SetLevel(currentLine, lev);
currentLine++;
previousLevel = currentLevel;
}
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
styler.SetLevel(currentLine,
previousLevel
| (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
}
static const char * const erlangWordListDesc[] = {
"Erlang Reserved words",
"Erlang BIFs",
"Erlang Preprocessor",
"Erlang Module Attributes",
"Erlang Documentation",
"Erlang Documentation Macro",
0
};
LexerModule lmErlang(
SCLEX_ERLANG,
ColouriseErlangDoc,
"erlang",
FoldErlangDoc,
erlangWordListDesc);

View File

@@ -0,0 +1,130 @@
// Scintilla source code edit control
/** @file LexFIF.cxx
** Lexers for Find In Files output format
**/
// Copyright 1998-2001 by Eran Ifrah <eran.ifrah@gmail.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include <string>
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool AtEOL(Accessor &styler, unsigned int i)
{
return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
}
static void ColouriseFifDoc(unsigned int pos, int length, int /*initStyle*/,
WordList *[], Accessor &styler)
{
styler.StartAt(pos);
styler.StartSegment(pos);
for (int firstchar = -1; length > 0; pos++, length--) {
if (firstchar == -1) {
firstchar = styler[pos]; // first char of each line
}
if (styler[pos] == ':' && firstchar == ' ') {
if (length > 1 && styler[pos+1] == ' ') {
// include the following space
pos++;
length--;
}
styler.ColourTo(pos, SCLEX_FIF_FILE_SHORT);
firstchar = ':'; // first colon only
if (length > 1 && styler[pos+1] == '[') {
firstchar = '[';
}
} else if (styler[pos] == ']' && firstchar == '['){
if (length > 1 && styler[pos+1] == ' ') {
// include the following space
pos++;
length--;
}
styler.ColourTo(pos, SCLEX_FIF_SCOPE);
firstchar = ']'; // first ']' only
} else if (AtEOL(styler, pos)) {
switch (firstchar) {
case ' ':
case ':':
case '[':
case ']':
styler.ColourTo(pos, SCLEX_FIF_MATCH);
break;
case '=':
styler.ColourTo(pos, SCLEX_FIF_DEFAULT);
break;
case '-':
styler.ColourTo(pos, SCLEX_FIF_PROJECT);
break;
default:
styler.ColourTo(pos, SCLEX_FIF_FILE);
break;
}
firstchar = -1;
}
}
}
static void FoldFifDoc(unsigned int pos, int length, int,
WordList*[], Accessor &styler)
{
int curLine = styler.GetLine(pos);
int prevLevel = curLine > 0 ? styler.LevelAt(curLine-1) : SC_FOLDLEVELBASE;
unsigned int end = pos+length;
pos = styler.LineStart(curLine);
do {
int nextLevel;
switch (styler.StyleAt(pos)) {
case SCLEX_FIF_DEFAULT:
nextLevel = SC_FOLDLEVELBASE;
break;
case SCLEX_FIF_PROJECT:
nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
break;
case SCLEX_FIF_FILE:
nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
break;
default:
nextLevel = prevLevel & SC_FOLDLEVELHEADERFLAG ? (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1 : prevLevel;
break;
}
if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && nextLevel == prevLevel) {
styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
}
styler.SetLevel(curLine, nextLevel);
curLine++;
prevLevel = nextLevel;
pos = styler.LineStart(curLine);
} while (pos < end);
}
static const char * const fifWordListDesc[] = {
"Internal Commands",
"External Commands",
0
};
static const char * const emptyWordListDesc[] = {
0
};
LexerModule lmFif(SCLEX_FIF, ColouriseFifDoc, "fif", FoldFifDoc, fifWordListDesc);

View File

@@ -0,0 +1,352 @@
// Scintilla source code edit control
/** @file LexFlagShip.cxx
** Lexer for Harbour and FlagShip.
** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)
**/
// Copyright 2005 by Randy Butler
// Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour)
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// Extended to accept accented characters
static inline bool IsAWordChar(int ch)
{
return ch >= 0x80 ||
(isalnum(ch) || ch == '_');
}
static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler)
{
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
// property lexer.flagship.styling.within.preprocessor
// For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the
// initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.
bool stylingWithinPreprocessor = styler.GetPropertyInt("lexer.flagship.styling.within.preprocessor", 1) != 0;
CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
int visibleChars = 0;
int closeStringChar = 0;
int styleBeforeDCKeyword = SCE_FS_DEFAULT;
bool bEnableCode = initStyle < SCE_FS_DISABLEDCODE;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_FS_OPERATOR:
case SCE_FS_OPERATOR_C:
case SCE_FS_WORDOPERATOR:
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
break;
case SCE_FS_IDENTIFIER:
case SCE_FS_IDENTIFIER_C:
if (!IsAWordChar(sc.ch)) {
char s[64];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C);
} else if (keywords2.InList(s)) {
sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C);
} else if (bEnableCode && keywords3.InList(s)) {
sc.ChangeState(SCE_FS_KEYWORD3);
} else if (bEnableCode && keywords4.InList(s)) {
sc.ChangeState(SCE_FS_KEYWORD4);
}// Else, it is really an identifier...
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
}
break;
case SCE_FS_NUMBER:
if (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_FS_DEFAULT);
}
break;
case SCE_FS_NUMBER_C:
if (!IsAWordChar(sc.ch) && sc.ch != '.') {
sc.SetState(SCE_FS_DEFAULT_C);
}
break;
case SCE_FS_CONSTANT:
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_FS_DEFAULT);
}
break;
case SCE_FS_STRING:
case SCE_FS_STRING_C:
if (sc.ch == closeStringChar) {
sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
} else if (sc.atLineEnd) {
sc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C);
}
break;
case SCE_FS_STRINGEOL:
case SCE_FS_STRINGEOL_C:
if (sc.atLineStart) {
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
}
break;
case SCE_FS_COMMENTDOC:
case SCE_FS_COMMENTDOC_C:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C;
sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
}
}
break;
case SCE_FS_COMMENT:
case SCE_FS_COMMENTLINE:
if (sc.atLineStart) {
sc.SetState(SCE_FS_DEFAULT);
}
break;
case SCE_FS_COMMENTLINEDOC:
case SCE_FS_COMMENTLINEDOC_C:
if (sc.atLineStart) {
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C;
sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
}
}
break;
case SCE_FS_COMMENTDOCKEYWORD:
if ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) &&
sc.Match('*', '/')) {
sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
sc.Forward();
sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
} else if (!setDoxygen.Contains(sc.ch)) {
char s[64];
sc.GetCurrentLowered(s, sizeof(s));
if (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) {
sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
}
sc.SetState(styleBeforeDCKeyword);
}
break;
case SCE_FS_PREPROCESSOR:
case SCE_FS_PREPROCESSOR_C:
if (sc.atLineEnd) {
if (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) {
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
}
} else if (stylingWithinPreprocessor) {
if (IsASpaceOrTab(sc.ch)) {
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
}
} else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) {
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
}
break;
case SCE_FS_DISABLEDCODE:
if (sc.ch == '#' && visibleChars == 0) {
sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
do { // Skip whitespace between # and preprocessor word
sc.Forward();
} while (IsASpaceOrTab(sc.ch) && sc.More());
if (sc.MatchIgnoreCase("pragma")) {
sc.Forward(6);
do { // Skip more whitespace until keyword
sc.Forward();
} while (IsASpaceOrTab(sc.ch) && sc.More());
if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
bEnableCode = true;
sc.SetState(SCE_FS_DISABLEDCODE);
sc.Forward(sc.ch == '_' ? 8 : 6);
sc.ForwardSetState(SCE_FS_DEFAULT);
} else {
sc.ChangeState(SCE_FS_DISABLEDCODE);
}
} else {
sc.ChangeState(SCE_FS_DISABLEDCODE);
}
}
break;
case SCE_FS_DATE:
if (sc.ch == '}') {
sc.ForwardSetState(SCE_FS_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_FS_STRINGEOL);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) {
if (bEnableCode &&
(sc.MatchIgnoreCase(".and.") || sc.MatchIgnoreCase(".not."))) {
sc.SetState(SCE_FS_WORDOPERATOR);
sc.Forward(4);
} else if (bEnableCode && sc.MatchIgnoreCase(".or.")) {
sc.SetState(SCE_FS_WORDOPERATOR);
sc.Forward(3);
} else if (bEnableCode &&
(sc.MatchIgnoreCase(".t.") || sc.MatchIgnoreCase(".f.") ||
(!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase("nil")))) {
sc.SetState(SCE_FS_CONSTANT);
sc.Forward(2);
} else if (sc.Match('/', '*')) {
sc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C);
sc.Forward();
} else if (bEnableCode && sc.Match('&', '&')) {
sc.SetState(SCE_FS_COMMENTLINE);
sc.Forward();
} else if (sc.Match('/', '/')) {
sc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C);
sc.Forward();
} else if (bEnableCode && sc.ch == '*' && visibleChars == 0) {
sc.SetState(SCE_FS_COMMENT);
} else if (sc.ch == '\"' || sc.ch == '\'') {
sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
closeStringChar = sc.ch;
} else if (closeStringChar == '>' && sc.ch == '<') {
sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
} else if (sc.ch == '#' && visibleChars == 0) {
sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
do { // Skip whitespace between # and preprocessor word
sc.Forward();
} while (IsASpaceOrTab(sc.ch) && sc.More());
if (sc.atLineEnd) {
sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
} else if (sc.MatchIgnoreCase("include")) {
if (stylingWithinPreprocessor) {
closeStringChar = '>';
}
} else if (sc.MatchIgnoreCase("pragma")) {
sc.Forward(6);
do { // Skip more whitespace until keyword
sc.Forward();
} while (IsASpaceOrTab(sc.ch) && sc.More());
if (sc.MatchIgnoreCase("begindump") || sc.MatchIgnoreCase("__cstream")) {
bEnableCode = false;
if (stylingWithinPreprocessor) {
sc.SetState(SCE_FS_DISABLEDCODE);
sc.Forward(8);
sc.ForwardSetState(SCE_FS_DEFAULT_C);
} else {
sc.SetState(SCE_FS_DISABLEDCODE);
}
} else if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
bEnableCode = true;
sc.SetState(SCE_FS_DISABLEDCODE);
sc.Forward(sc.ch == '_' ? 8 : 6);
sc.ForwardSetState(SCE_FS_DEFAULT);
}
}
} else if (bEnableCode && sc.ch == '{') {
int p = 0;
int chSeek;
unsigned int endPos(startPos + length);
do { // Skip whitespace
chSeek = sc.GetRelative(++p);
} while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos));
if (chSeek == '^') {
sc.SetState(SCE_FS_DATE);
} else {
sc.SetState(SCE_FS_OPERATOR);
}
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C);
} else if (IsAWordChar(sc.ch)) {
sc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C);
} else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) {
sc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C);
}
}
if (sc.atLineEnd) {
visibleChars = 0;
closeStringChar = 0;
}
if (!IsASpace(sc.ch)) {
visibleChars++;
}
}
sc.Complete();
}
static void FoldFlagShipDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler)
{
int endPos = startPos + length;
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0 && lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
char chNext = styler[startPos];
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) {
int lev = indentCurrent;
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
int spaceFlags2 = 0;
int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2);
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
}
}
indentCurrent = indentNext;
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
}
}
}
static const char * const FSWordListDesc[] = {
"Keywords Commands",
"Std Library Functions",
"Procedure, return, exit",
"Class (oop)",
"Doxygen keywords",
0
};
LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);

View File

@@ -0,0 +1,176 @@
// Scintilla source code edit control
/** @file LexForth.cxx
** Lexer for FORTH
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
ch == ')' );
}
static inline bool IsAWordStart(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
}
static inline bool IsANumChar(int ch) {
return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
}
static inline bool IsASpaceChar(int ch) {
return (ch < 0x80) && isspace(ch);
}
static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
Accessor &styler) {
WordList &control = *keywordLists[0];
WordList &keyword = *keywordLists[1];
WordList &defword = *keywordLists[2];
WordList &preword1 = *keywordLists[3];
WordList &preword2 = *keywordLists[4];
WordList &strings = *keywordLists[5];
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
// Determine if the current state should terminate.
if (sc.state == SCE_FORTH_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_FORTH_DEFAULT);
}
}else if (sc.state == SCE_FORTH_COMMENT_ML) {
if (sc.ch == ')') {
sc.ForwardSetState(SCE_FORTH_DEFAULT);
}
}else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
// handle numbers here too, because what we thought was a number might
// turn out to be a keyword e.g. 2DUP
if (IsASpaceChar(sc.ch) ) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
if (control.InList(s)) {
sc.ChangeState(SCE_FORTH_CONTROL);
} else if (keyword.InList(s)) {
sc.ChangeState(SCE_FORTH_KEYWORD);
} else if (defword.InList(s)) {
sc.ChangeState(SCE_FORTH_DEFWORD);
} else if (preword1.InList(s)) {
sc.ChangeState(SCE_FORTH_PREWORD1);
} else if (preword2.InList(s)) {
sc.ChangeState(SCE_FORTH_PREWORD2);
} else if (strings.InList(s)) {
sc.ChangeState(SCE_FORTH_STRING);
newState = SCE_FORTH_STRING;
}
sc.SetState(newState);
}
if (sc.state == SCE_FORTH_NUMBER) {
if (IsASpaceChar(sc.ch)) {
sc.SetState(SCE_FORTH_DEFAULT);
} else if (!IsANumChar(sc.ch)) {
sc.ChangeState(SCE_FORTH_IDENTIFIER);
}
}
}else if (sc.state == SCE_FORTH_STRING) {
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_FORTH_DEFAULT);
}
}else if (sc.state == SCE_FORTH_LOCALE) {
if (sc.ch == '}') {
sc.ForwardSetState(SCE_FORTH_DEFAULT);
}
}else if (sc.state == SCE_FORTH_DEFWORD) {
if (IsASpaceChar(sc.ch)) {
sc.SetState(SCE_FORTH_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_FORTH_DEFAULT) {
if (sc.ch == '\\'){
sc.SetState(SCE_FORTH_COMMENT);
} else if (sc.ch == '(' &&
(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
(sc.atLineEnd || IsASpaceChar(sc.chNext))) {
sc.SetState(SCE_FORTH_COMMENT_ML);
} else if ( (sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
// number starting with $ is a hex number
sc.SetState(SCE_FORTH_NUMBER);
while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
sc.Forward();
} else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
// number starting with % is binary
sc.SetState(SCE_FORTH_NUMBER);
while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
sc.Forward();
} else if ( isascii(sc.ch) &&
(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
){
sc.SetState(SCE_FORTH_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_FORTH_IDENTIFIER);
} else if (sc.ch == '{') {
sc.SetState(SCE_FORTH_LOCALE);
} else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
// highlight word definitions e.g. : GCD ( n n -- n ) ..... ;
// ^ ^^^
sc.SetState(SCE_FORTH_DEFWORD);
while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
sc.Forward();
} else if (sc.ch == ';' &&
(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
(sc.atLineEnd || IsASpaceChar(sc.chNext)) ) {
// mark the ';' that ends a word
sc.SetState(SCE_FORTH_DEFWORD);
sc.ForwardSetState(SCE_FORTH_DEFAULT);
}
}
}
sc.Complete();
}
static void FoldForthDoc(unsigned int, int, int, WordList *[],
Accessor &) {
}
static const char * const forthWordLists[] = {
"control keywords",
"keywords",
"definition words",
"prewords with one argument",
"prewords with two arguments",
"string definition keywords",
0,
};
LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);

View File

@@ -0,0 +1,466 @@
// Scintilla source code edit control
/** @file LexFortran.cxx
** Lexer for Fortran.
** Writen by Chuan-jian Shen, Last changed Sep. 2003
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
/***************************************/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
/***************************************/
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/***********************************************/
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
}
/**********************************************/
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch));
}
/***************************************/
inline bool IsABlank(unsigned int ch) {
return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
}
/***************************************/
inline bool IsALineEnd(char ch) {
return ((ch == '\n') || (ch == '\r')) ;
}
/***************************************/
unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) {
while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;
if (styler.SafeGetCharAt(pos) == '\n') pos++;
while (IsABlank(styler.SafeGetCharAt(pos++))) continue;
char chCur = styler.SafeGetCharAt(pos);
if (chCur == '&') {
while (IsABlank(styler.SafeGetCharAt(++pos))) continue;
return pos;
} else {
return pos;
}
}
/***************************************/
static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, bool isFixFormat) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
/***************************************/
int posLineStart = 0, numNonBlank = 0, prevState = 0;
int endPos = startPos + length;
/***************************************/
// backtrack to the nearest keyword
while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
startPos--;
}
startPos = styler.LineStart(styler.GetLine(startPos));
initStyle = styler.StyleAt(startPos - 1);
StyleContext sc(startPos, endPos-startPos, initStyle, styler);
/***************************************/
for (; sc.More(); sc.Forward()) {
// remember the start position of the line
if (sc.atLineStart) {
posLineStart = sc.currentPos;
numNonBlank = 0;
sc.SetState(SCE_F_DEFAULT);
}
if (!IsASpaceOrTab(sc.ch)) numNonBlank ++;
/***********************************************/
// Handle the fix format generically
int toLineStart = sc.currentPos - posLineStart;
if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") ||
sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR);
} else {
sc.SetState(SCE_F_COMMENT);
}
while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
} else if (toLineStart > 72) {
sc.SetState(SCE_F_COMMENT);
while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
} else if (toLineStart < 5) {
if (IsADigit(sc.ch))
sc.SetState(SCE_F_LABEL);
else
sc.SetState(SCE_F_DEFAULT);
} else if (toLineStart == 5) {
if (!IsASpace(sc.ch) && sc.ch != '0') {
sc.SetState(SCE_F_CONTINUATION);
sc.ForwardSetState(prevState);
} else
sc.SetState(SCE_F_DEFAULT);
}
continue;
}
/***************************************/
// Handle line continuation generically.
if (!isFixFormat && sc.ch == '&') {
char chTemp = ' ';
int j = 1;
while (IsABlank(chTemp) && j<132) {
chTemp = static_cast<char>(sc.GetRelative(j));
j++;
}
if (chTemp == '!') {
sc.SetState(SCE_F_CONTINUATION);
if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
} else if (chTemp == '\r' || chTemp == '\n') {
int currentState = sc.state;
sc.SetState(SCE_F_CONTINUATION);
sc.ForwardSetState(SCE_F_DEFAULT);
while (IsASpace(sc.ch) && sc.More()) sc.Forward();
if (sc.ch == '&') {
sc.SetState(SCE_F_CONTINUATION);
sc.Forward();
}
sc.SetState(currentState);
}
}
/***************************************/
// Determine if the current state should terminate.
if (sc.state == SCE_F_OPERATOR) {
sc.SetState(SCE_F_DEFAULT);
} else if (sc.state == SCE_F_NUMBER) {
if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) {
sc.SetState(SCE_F_DEFAULT);
}
} else if (sc.state == SCE_F_IDENTIFIER) {
if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_F_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_F_WORD2);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_F_WORD3);
}
sc.SetState(SCE_F_DEFAULT);
}
} else if (sc.state == SCE_F_COMMENT || sc.state == SCE_F_PREPROCESSOR) {
if (sc.ch == '\r' || sc.ch == '\n') {
sc.SetState(SCE_F_DEFAULT);
}
} else if (sc.state == SCE_F_STRING1) {
prevState = sc.state;
if (sc.ch == '\'') {
if (sc.chNext == '\'') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_F_DEFAULT);
prevState = SCE_F_DEFAULT;
}
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_F_STRINGEOL);
sc.ForwardSetState(SCE_F_DEFAULT);
}
} else if (sc.state == SCE_F_STRING2) {
prevState = sc.state;
if (sc.atLineEnd) {
sc.ChangeState(SCE_F_STRINGEOL);
sc.ForwardSetState(SCE_F_DEFAULT);
} else if (sc.ch == '\"') {
if (sc.chNext == '\"') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_F_DEFAULT);
prevState = SCE_F_DEFAULT;
}
}
} else if (sc.state == SCE_F_OPERATOR2) {
if (sc.ch == '.') {
sc.ForwardSetState(SCE_F_DEFAULT);
}
} else if (sc.state == SCE_F_CONTINUATION) {
sc.SetState(SCE_F_DEFAULT);
} else if (sc.state == SCE_F_LABEL) {
if (!IsADigit(sc.ch)) {
sc.SetState(SCE_F_DEFAULT);
} else {
if (isFixFormat && sc.currentPos-posLineStart > 4)
sc.SetState(SCE_F_DEFAULT);
else if (numNonBlank > 5)
sc.SetState(SCE_F_DEFAULT);
}
}
/***************************************/
// Determine if a new state should be entered.
if (sc.state == SCE_F_DEFAULT) {
if (sc.ch == '!') {
if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR);
} else {
sc.SetState(SCE_F_COMMENT);
}
} else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) {
sc.SetState(SCE_F_LABEL);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_F_NUMBER);
} else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
sc.SetState(SCE_F_NUMBER);
sc.Forward();
} else if (sc.ch == '.' && isalpha(sc.chNext)) {
sc.SetState(SCE_F_OPERATOR2);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_F_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_F_STRING2);
} else if (sc.ch == '\'') {
sc.SetState(SCE_F_STRING1);
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_F_OPERATOR);
}
}
}
sc.Complete();
}
/***************************************/
// To determine the folding level depending on keywords
static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
int lev = 0;
if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
return -1;
if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
|| strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
|| strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
|| strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
|| strcmp(s, "module") == 0 || strcmp(s, "program") == 0
|| strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
|| (strcmp(s, "type") == 0 && chNextNonBlank != '(') ){
if (strcmp(prevWord, "end") == 0)
lev = 0;
else
lev = 1;
} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
|| strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
|| strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
|| strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
|| strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0
|| strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|| strcmp(s, "endwhere") == 0
|| strcmp(s, "procedure") == 0 ) { // Take care of the module procedure statement
lev = -1;
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
lev = 0;
}
return lev;
}
// Folding the code
static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
Accessor &styler, bool isFixFormat) {
//
// bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
// Do not know how to fold the comment at the moment.
//
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
char chNextNonBlank;
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
/***************************************/
int lastStart = 0;
char prevWord[32] = "";
char Label[6] = "";
// Variables for do label folding.
static int doLabels[100];
static int posLabel=-1;
/***************************************/
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
chNextNonBlank = chNext;
unsigned int j=i+1;
while(IsABlank(chNextNonBlank) && j<endPos) {
j ++ ;
chNextNonBlank = styler.SafeGetCharAt(j);
}
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
//
if (stylePrev == SCE_F_DEFAULT && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
// Store last word and label start point.
lastStart = i;
}
/***************************************/
if (style == SCE_F_WORD) {
if(iswordchar(ch) && !iswordchar(chNext)) {
char s[32];
unsigned int k;
for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
s[k] = static_cast<char>(tolower(styler[lastStart+k]));
}
s[k] = '\0';
// Handle the forall and where statement and structure.
if (strcmp(s, "forall") == 0 || strcmp(s, "where") == 0) {
if (strcmp(prevWord, "end") != 0) {
j = i + 1;
char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j);
// Find the position of the first (
while (ch1 != chBrace && j<endPos) {
j++;
ch1 = styler.SafeGetCharAt(j);
}
char styBrace = styler.StyleAt(j);
int depth = 1;
char chAtPos;
char styAtPos;
while (j<endPos) {
j++;
chAtPos = styler.SafeGetCharAt(j);
styAtPos = styler.StyleAt(j);
if (styAtPos == styBrace) {
if (chAtPos == chBrace) depth++;
if (chAtPos == chSeek) depth--;
if (depth == 0) break;
}
}
while (j<endPos) {
j++;
chAtPos = styler.SafeGetCharAt(j);
styAtPos = styler.StyleAt(j);
if (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos)) continue;
if (isFixFormat) {
if (!IsALineEnd(chAtPos)) {
break;
} else {
if (lineCurrent < styler.GetLine(styler.Length()-1)) {
j = styler.LineStart(lineCurrent+1);
if (styler.StyleAt(j+5) == SCE_F_CONTINUATION) {
j += 5;
continue;
} else {
levelCurrent++;
break;
}
}
}
} else {
if (chAtPos == '&' && styler.StyleAt(j) == SCE_F_CONTINUATION) {
j = GetContinuedPos(j+1, styler);
continue;
} else if (IsALineEnd(chAtPos)) {
levelCurrent ++;
break;
} else {
break;
}
}
}
}
} else {
levelCurrent += classifyFoldPointFortran(s, prevWord, chNextNonBlank);
// Store the do Labels into array
if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) {
unsigned int k = 0;
for (i=j; (i<j+5 && i<endPos); i++) {
ch = styler.SafeGetCharAt(i);
if (IsADigit(ch))
Label[k++] = ch;
else
break;
}
Label[k] = '\0';
posLabel ++;
doLabels[posLabel] = atoi(Label);
}
}
strcpy(prevWord, s);
}
} else if (style == SCE_F_LABEL) {
if(IsADigit(ch) && !IsADigit(chNext)) {
for(j = 0; ( j < 5 ) && ( j < i-lastStart+1 ); j++) {
ch = styler.SafeGetCharAt(lastStart + j);
if (IsADigit(ch) && styler.StyleAt(lastStart+j) == SCE_F_LABEL)
Label[j] = ch;
else
break;
}
Label[j] = '\0';
while (doLabels[posLabel] == atoi(Label) && posLabel > -1) {
levelCurrent--;
posLabel--;
}
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
strcpy(prevWord, "");
}
/***************************************/
if (!isspacechar(ch)) visibleChars++;
}
/***************************************/
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
/***************************************/
static const char * const FortranWordLists[] = {
"Primary keywords and identifiers",
"Intrinsic functions",
"Extended and user defined functions",
0,
};
/***************************************/
static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
}
/***************************************/
static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
}
/***************************************/
static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
FoldFortranDoc(startPos, length, initStyle,styler, false);
}
/***************************************/
static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
FoldFortranDoc(startPos, length, initStyle,styler, true);
}
/***************************************/
LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists);
LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists);

View File

@@ -0,0 +1,263 @@
// Scintilla source code edit control
/** @file LexGAP.cxx
** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
** http://www.gap-system.org
**/
// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsGAPOperator(char ch) {
if (isascii(ch) && isalnum(ch)) return false;
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
ch == ')' || ch == ';' || ch == '[' || ch == ']' ||
ch == '{' || ch == '}' || ch == ':' )
return true;
return false;
}
static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) {
unsigned int i = 0;
while ((i < end - start + 1) && (i < len-1)) {
s[i] = static_cast<char>(styler[start + i]);
i++;
}
s[i] = '\0';
}
static void ColouriseGAPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
WordList &keywords1 = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
// Do not leak onto next line
if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
// Prevent SCE_GAP_STRINGEOL from leaking back to previous line
if ( sc.atLineStart ) {
if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);
if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);
}
// Handle line continuation generically
if (sc.ch == '\\' ) {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continue;
}
}
// Determine if the current state should terminate
switch (sc.state) {
case SCE_GAP_OPERATOR :
sc.SetState(SCE_GAP_DEFAULT);
break;
case SCE_GAP_NUMBER :
if (!IsADigit(sc.ch)) {
if (sc.ch == '\\') {
if (!sc.atLineEnd) {
if (!IsADigit(sc.chNext)) {
sc.Forward();
sc.ChangeState(SCE_GAP_IDENTIFIER);
}
}
} else if (isalpha(sc.ch) || sc.ch == '_') {
sc.ChangeState(SCE_GAP_IDENTIFIER);
}
else sc.SetState(SCE_GAP_DEFAULT);
}
break;
case SCE_GAP_IDENTIFIER :
if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {
if (sc.ch == '\\') sc.Forward();
else {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (keywords1.InList(s)) {
sc.ChangeState(SCE_GAP_KEYWORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_GAP_KEYWORD2);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_GAP_KEYWORD3);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_GAP_KEYWORD4);
}
sc.SetState(SCE_GAP_DEFAULT);
}
}
break;
case SCE_GAP_COMMENT :
if (sc.atLineEnd) {
sc.SetState(SCE_GAP_DEFAULT);
}
break;
case SCE_GAP_STRING:
if (sc.atLineEnd) {
sc.ChangeState(SCE_GAP_STRINGEOL);
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_GAP_DEFAULT);
}
break;
case SCE_GAP_CHAR:
if (sc.atLineEnd) {
sc.ChangeState(SCE_GAP_STRINGEOL);
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_GAP_DEFAULT);
}
break;
case SCE_GAP_STRINGEOL:
if (sc.atLineStart) {
sc.SetState(SCE_GAP_DEFAULT);
}
break;
}
// Determine if a new state should be entered
if (sc.state == SCE_GAP_DEFAULT) {
if (IsGAPOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_GAP_OPERATOR);
}
else if (IsADigit(sc.ch)) {
sc.SetState(SCE_GAP_NUMBER);
} else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') {
sc.SetState(SCE_GAP_IDENTIFIER);
if (sc.ch == '\\') sc.Forward();
} else if (sc.ch == '#') {
sc.SetState(SCE_GAP_COMMENT);
} else if (sc.ch == '\"') {
sc.SetState(SCE_GAP_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_GAP_CHAR);
}
}
}
sc.Complete();
}
static int ClassifyFoldPointGAP(const char* s) {
int level = 0;
if (strcmp(s, "function") == 0 ||
strcmp(s, "do") == 0 ||
strcmp(s, "if") == 0 ||
strcmp(s, "repeat") == 0 ) {
level = 1;
} else if (strcmp(s, "end") == 0 ||
strcmp(s, "od") == 0 ||
strcmp(s, "fi") == 0 ||
strcmp(s, "until") == 0 ) {
level = -1;
}
return level;
}
static void FoldGAPDoc( unsigned int startPos, int length, int initStyle, WordList** , Accessor &styler) {
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int lastStart = 0;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) {
// Store last word start point.
lastStart = i;
}
if (stylePrev == SCE_GAP_KEYWORD) {
if(iswordchar(ch) && !iswordchar(chNext)) {
char s[100];
GetRange(lastStart, i, styler, s, sizeof(s));
levelCurrent += ClassifyFoldPointGAP(s);
}
}
if (atEOL) {
int lev = levelPrev;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const GAPWordListDesc[] = {
"Keywords 1",
"Keywords 2",
"Keywords 3 (unused)",
"Keywords 4 (unused)",
0
};
LexerModule lmGAP(
SCLEX_GAP,
ColouriseGAPDoc,
"gap",
FoldGAPDoc,
GAPWordListDesc);

View File

@@ -0,0 +1,119 @@
// Scintilla source code edit control
/** @file LexOthers.cxx
** Lexers for batch files, diff results, properties files, make files and error lists.
** Also lexer for LaTeX documents.
**/
// Copyright 1998-2001 by Eran Ifrah <eran.ifrah@gmail.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <string>
#include <wx/string.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StyleContext.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
typedef int (*GCC_COLOUR_FUNC_PTR)(int, const char*, size_t&, size_t&);
static GCC_COLOUR_FUNC_PTR s_gccColourFunc = NULL;
void SetGccColourFunction(GCC_COLOUR_FUNC_PTR func)
{
s_gccColourFunc = func;
}
static inline bool AtEOL(Accessor &styler, unsigned int i)
{
return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
}
static void ColouriseGccDoc(
unsigned int pos,
int length,
int /*initStyle*/,
WordList * /*keywordlists*/[],
Accessor &styler)
{
std::string line;
line.reserve(2048);
styler.StartAt(pos);
styler.StartSegment(pos);
for (; length > 0; pos++, length--) {
line += styler[pos];
if (AtEOL(styler, pos)) {
// End of line met, colourise it
int style = SCLEX_GCC_OUTPUT;
if (s_gccColourFunc) {
size_t start(0);
size_t len(0);
int startLine = pos-line.size()+1;
style = s_gccColourFunc(startLine, line.c_str(), start, len);
if(len != 0) {
styler.ColourTo(startLine + start - 1, style);
styler.ColourTo(startLine + start + len - 1, SCLEX_GCC_FILE_LINK);
}
}
styler.ColourTo(pos, style);
line.clear();
}
}
}
static void FoldGccDoc(unsigned int pos, int length, int,
WordList*[], Accessor &styler)
{
int curLine = styler.GetLine(pos);
int prevLevel = curLine > 0 ? styler.LevelAt(curLine-1) : SC_FOLDLEVELBASE;
unsigned int end = pos+length;
pos = styler.LineStart(curLine);
do {
int nextLevel;
switch (styler.StyleAt(pos)) {
case SCLEX_GCC_BUILDING:
nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
break;
default:
nextLevel = prevLevel & SC_FOLDLEVELHEADERFLAG ? (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1 : prevLevel;
break;
}
if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && nextLevel == prevLevel) {
styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
}
styler.SetLevel(curLine, nextLevel);
curLine++;
prevLevel = nextLevel;
pos = styler.LineStart(curLine);
} while (pos < end);
}
static const char * const gccWordListDesc[] = {
"Internal Commands",
"External Commands",
0
};
static const char * const emptyWordListDesc[] = {
0
};
LexerModule lmGcc(SCLEX_GCC, ColouriseGccDoc, "gcc", FoldGccDoc, gccWordListDesc);

View File

@@ -0,0 +1,287 @@
# LexGen.py - implemented 2002 by Neil Hodgson neilh@scintilla.org
# Released to the public domain.
# Regenerate the Scintilla and SciTE source files that list
# all the lexers and all the properties files.
# Should be run whenever a new lexer is added or removed.
# Requires Python 2.4 or later
# Most files are regenerated in place with templates stored in comments.
# The VS .NET project file is generated into a different file as the
# VS .NET environment will not retain comments when modifying the file.
# The files are copied to a string apart from sections between a
# ++Autogenerated comment and a --Autogenerated comment which is
# generated by the CopyWithInsertion function. After the whole
# string is instantiated, it is compared with the target file and
# if different the file is rewritten.
# Does not regenerate the Visual C++ 6 project files but does the VS .NET
# project file.
import string
import sys
import os
import glob
# EOL constants
CR = "\r"
LF = "\n"
CRLF = "\r\n"
if sys.platform == "win32":
NATIVE = CRLF
else:
# Yes, LF is the native EOL even on Mac OS X. CR is just for
# Mac OS <=9 (a.k.a. "Mac Classic")
NATIVE = LF
# Automatically generated sections contain start and end comments,
# a definition line and the results.
# The results are replaced by regenerating based on the definition line.
# The definition line is a comment prefix followed by "**".
# If there is a digit after the ** then this indicates which list to use
# and the digit and next character are not part of the definition
# Backslash is used as an escape within the definition line.
# The part between \( and \) is repeated for each item in the list.
# \* is replaced by each list item. \t, and \n are tab and newline.
def CopyWithInsertion(input, commentPrefix, retainDefs, eolType, *lists):
copying = 1
listid = 0
output = []
for line in input.splitlines(0):
isStartGenerated = line.startswith(commentPrefix + "++Autogenerated")
if copying and not isStartGenerated:
output.append(line)
if isStartGenerated:
if retainDefs:
output.append(line)
copying = 0
definition = ""
elif not copying and line.startswith(commentPrefix + "**"):
if retainDefs:
output.append(line)
definition = line[len(commentPrefix + "**"):]
if (commentPrefix == "<!--") and (" -->" in definition):
definition = definition.replace(" -->", "")
listid = 0
if definition[0] in string.digits:
listid = int(definition[:1])
definition = definition[2:]
# Hide double slashes as a control character
definition = definition.replace("\\\\", "\001")
# Do some normal C style transforms
definition = definition.replace("\\n", "\n")
definition = definition.replace("\\t", "\t")
# Get the doubled backslashes back as single backslashes
definition = definition.replace("\001", "\\")
startRepeat = definition.find("\\(")
endRepeat = definition.find("\\)")
intro = definition[:startRepeat]
out = ""
if intro.endswith("\n"):
pos = 0
else:
pos = len(intro)
out += intro
middle = definition[startRepeat+2:endRepeat]
for i in lists[listid]:
item = middle.replace("\\*", i)
if pos and (pos + len(item) >= 80):
out += "\\\n"
pos = 0
out += item
pos += len(item)
if item.endswith("\n"):
pos = 0
outro = definition[endRepeat+2:]
out += outro
out = out.replace("\n", eolType) # correct EOLs in generated content
output.append(out)
elif line.startswith(commentPrefix + "--Autogenerated"):
copying = 1
if retainDefs:
output.append(line)
output = [line.rstrip(" \t") for line in output] # trim trailing whitespace
return eolType.join(output) + eolType
def UpdateFile(filename, updated):
""" If the file is different to updated then copy updated
into the file else leave alone so CVS and make don't treat
it as modified. """
try:
infile = open(filename, "rb")
except IOError: # File is not there yet
out = open(filename, "wb")
out.write(updated.encode('utf-8'))
out.close()
print("New %s" % filename)
return
original = infile.read()
infile.close()
original = original.decode('utf-8')
if updated != original:
os.unlink(filename)
out = open(filename, "wb")
out.write(updated.encode('utf-8'))
out.close()
print("Changed %s " % filename)
#~ else:
#~ print "Unchanged", filename
def Generate(inpath, outpath, commentPrefix, eolType, *lists):
"""Generate 'outpath' from 'inpath'.
"eolType" indicates the type of EOLs to use in the generated
file. It should be one of following constants: LF, CRLF,
CR, or NATIVE.
"""
#print "generate '%s' -> '%s' (comment prefix: %r, eols: %r)"\
# % (inpath, outpath, commentPrefix, eolType)
try:
infile = open(inpath, "rb")
except IOError:
print("Can not open %s" % inpath)
return
original = infile.read()
infile.close()
original = original.decode('utf-8')
updated = CopyWithInsertion(original, commentPrefix,
inpath == outpath, eolType, *lists)
UpdateFile(outpath, updated)
def Regenerate(filename, commentPrefix, eolType, *lists):
"""Regenerate the given file.
"eolType" indicates the type of EOLs to use in the generated
file. It should be one of following constants: LF, CRLF,
CR, or NATIVE.
"""
Generate(filename, filename, commentPrefix, eolType, *lists)
def FindModules(lexFile):
modules = []
f = open(lexFile)
for l in f.readlines():
if l.startswith("LexerModule"):
l = l.replace("(", " ")
modules.append(l.split()[1])
return modules
knownIrregularProperties = [
"fold",
"styling.within.preprocessor",
"tab.timmy.whinge.level",
"asp.default.language",
"html.tags.case.sensitive",
"ps.level",
"ps.tokenize",
"sql.backslash.escapes",
"nsis.uservars",
"nsis.ignorecase"
]
def FindProperties(lexFile):
properties = {}
f = open(lexFile)
for l in f.readlines():
if "GetProperty" in l and '"' in l:
l = l.strip()
if not l.startswith("//"): # Drop comments
propertyName = l.split("\"")[1]
if propertyName.lower() == propertyName:
# Only allow lower case property names
if propertyName in knownIrregularProperties or \
propertyName.startswith("fold.") or \
propertyName.startswith("lexer."):
properties[propertyName] = 1
return properties
def FindPropertyDocumentation(lexFile):
documents = {}
f = open(lexFile)
name = ""
for l in f.readlines():
l = l.strip()
if "// property " in l:
propertyName = l.split()[2]
if propertyName.lower() == propertyName:
# Only allow lower case property names
name = propertyName
documents[name] = ""
elif name:
if l.startswith("//"):
if documents[name]:
documents[name] += " "
documents[name] += l[2:].strip()
else:
name = ""
return documents
def ciCompare(a,b):
return cmp(a.lower(), b.lower())
def ciKey(a):
return a.lower()
def sortListInsensitive(l):
try: # Try key function
l.sort(key=ciKey)
except TypeError: # Earlier version of Python, so use comparison function
l.sort(ciCompare)
def RegenerateAll():
root="../../"
# Find all the lexer source code files
lexFilePaths = glob.glob(root + "scintilla/src/Lex*.cxx")
sortListInsensitive(lexFilePaths)
lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
print(lexFiles)
lexerModules = []
lexerProperties = {}
propertyDocuments = {}
for lexFile in lexFilePaths:
lexerModules.extend(FindModules(lexFile))
for k in FindProperties(lexFile).keys():
lexerProperties[k] = 1
documents = FindPropertyDocumentation(lexFile)
for k in documents.keys():
propertyDocuments[k] = documents[k]
sortListInsensitive(lexerModules)
del lexerProperties["fold.comment.python"]
lexerProperties = list(lexerProperties.keys())
sortListInsensitive(lexerProperties)
# Generate HTML to document each property
# This is done because tags can not be safely put inside comments in HTML
documentProperties = list(propertyDocuments.keys())
sortListInsensitive(documentProperties)
propertiesHTML = []
for k in documentProperties:
propertiesHTML.append("\t<tr>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" %
(k, propertyDocuments[k]))
# Find all the SciTE properties files
otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"]
if os.path.exists(root + "scite"):
propFilePaths = glob.glob(root + "scite/src/*.properties")
sortListInsensitive(propFilePaths)
propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps]
sortListInsensitive(propFiles)
print(propFiles)
Regenerate(root + "scintilla/src/KeyWords.cxx", "//", NATIVE, lexerModules)
Regenerate(root + "scintilla/win32/makefile", "#", NATIVE, lexFiles)
Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
# Use Unix EOLs for gtk Makefiles so they work for Linux users when
# extracted from the Scintilla source ZIP (typically created on
# Windows).
Regenerate(root + "scintilla/gtk/makefile", "#", LF, lexFiles)
Regenerate(root + "scintilla/macosx/makefile", "#", LF, lexFiles)
if os.path.exists(root + "scite"):
Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)
Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties)
Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", NATIVE, propertiesHTML)
Generate(root + "scite/boundscheck/vcproj.gen",
root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
RegenerateAll()

View File

@@ -0,0 +1,313 @@
// Scintilla source code edit control
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
/*
This is the Lexer for Gui4Cli, included in SciLexer.dll
- by d. Keletsekis, 2/10/2003
To add to SciLexer.dll:
1. Add the values below to INCLUDE\Scintilla.iface
2. Run the include/HFacer.py script
3. Run the src/lexGen.py script
val SCE_GC_DEFAULT=0
val SCE_GC_COMMENTLINE=1
val SCE_GC_COMMENTBLOCK=2
val SCE_GC_GLOBAL=3
val SCE_GC_EVENT=4
val SCE_GC_ATTRIBUTE=5
val SCE_GC_CONTROL=6
val SCE_GC_COMMAND=7
val SCE_GC_STRING=8
val SCE_GC_OPERATOR=9
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#define debug Platform::DebugPrintf
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
}
inline bool isGCOperator(int ch)
{ if (isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '%' ||
ch == '[' || ch == ']' || ch == '<' || ch == '>' ||
ch == ',' || ch == ';' || ch == ':')
return true;
return false;
}
#define isSpace(x) ((x)==' ' || (x)=='\t')
#define isNL(x) ((x)=='\n' || (x)=='\r')
#define isSpaceOrNL(x) (isSpace(x) || isNL(x))
#define BUFFSIZE 500
#define isFoldPoint(x) ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)
static void colorFirstWord(WordList *keywordlists[], Accessor &styler,
StyleContext *sc, char *buff, int length, int)
{
int c = 0;
while (sc->More() && isSpaceOrNL(sc->ch))
{ sc->Forward();
}
styler.ColourTo(sc->currentPos - 1, sc->state);
if (!IsAWordChar(sc->ch)) // comment, marker, etc..
return;
while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))
{ buff[c] = static_cast<char>(sc->ch);
++c; sc->Forward();
}
buff[c] = '\0';
char *p = buff;
while (*p) // capitalize..
{ if (islower(*p)) *p = static_cast<char>(toupper(*p));
++p;
}
WordList &kGlobal = *keywordlists[0]; // keyword lists set by the user
WordList &kEvent = *keywordlists[1];
WordList &kAttribute = *keywordlists[2];
WordList &kControl = *keywordlists[3];
WordList &kCommand = *keywordlists[4];
int state = 0;
// int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
// debug ("line = %d, level = %d", line, level);
if (kGlobal.InList(buff)) state = SCE_GC_GLOBAL;
else if (kAttribute.InList(buff)) state = SCE_GC_ATTRIBUTE;
else if (kControl.InList(buff)) state = SCE_GC_CONTROL;
else if (kCommand.InList(buff)) state = SCE_GC_COMMAND;
else if (kEvent.InList(buff)) state = SCE_GC_EVENT;
if (state)
{ sc->ChangeState(state);
styler.ColourTo(sc->currentPos - 1, sc->state);
sc->ChangeState(SCE_GC_DEFAULT);
}
else
{ sc->ChangeState(SCE_GC_DEFAULT);
styler.ColourTo(sc->currentPos - 1, sc->state);
}
}
// Main colorizing function called by Scintilla
static void
ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler)
{
styler.StartAt(startPos);
int quotestart = 0, oldstate, currentline = styler.GetLine(startPos);
styler.StartSegment(startPos);
bool noforward;
char buff[BUFFSIZE+1]; // buffer for command name
StyleContext sc(startPos, length, initStyle, styler);
buff[0] = '\0'; // cbuff = 0;
if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..
colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
while (sc.More())
{ noforward = 0;
switch (sc.ch)
{
case '/':
if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)
break;
if (sc.chNext == '/') // line comment
{ sc.SetState (SCE_GC_COMMENTLINE);
sc.Forward();
styler.ColourTo(sc.currentPos, sc.state);
}
else if (sc.chNext == '*') // block comment
{ sc.SetState(SCE_GC_COMMENTBLOCK);
sc.Forward();
styler.ColourTo(sc.currentPos, sc.state);
}
else
styler.ColourTo(sc.currentPos, sc.state);
break;
case '*': // end of comment block, or operator..
if (sc.state == SCE_GC_STRING)
break;
if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')
{ sc.Forward();
styler.ColourTo(sc.currentPos, sc.state);
sc.ChangeState (SCE_GC_DEFAULT);
}
else
styler.ColourTo(sc.currentPos, sc.state);
break;
case '\'': case '\"': // strings..
if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)
break;
if (sc.state == SCE_GC_STRING)
{ if (sc.ch == quotestart) // match same quote char..
{ styler.ColourTo(sc.currentPos, sc.state);
sc.ChangeState(SCE_GC_DEFAULT);
quotestart = 0;
} }
else
{ styler.ColourTo(sc.currentPos - 1, sc.state);
sc.ChangeState(SCE_GC_STRING);
quotestart = sc.ch;
}
break;
case ';': // end of commandline character
if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
sc.state != SCE_GC_STRING)
{
styler.ColourTo(sc.currentPos - 1, sc.state);
styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
sc.ChangeState(SCE_GC_DEFAULT);
sc.Forward();
colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
noforward = 1; // don't move forward - already positioned at next char..
}
break;
case '+': case '-': case '=': case '!': // operators..
case '<': case '>': case '&': case '|': case '$':
if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
sc.state != SCE_GC_STRING)
{
styler.ColourTo(sc.currentPos - 1, sc.state);
styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
sc.ChangeState(SCE_GC_DEFAULT);
}
break;
case '\\': // escape - same as operator, but also mark in strings..
if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)
{
oldstate = sc.state;
styler.ColourTo(sc.currentPos - 1, sc.state);
sc.Forward(); // mark also the next char..
styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
sc.ChangeState(oldstate);
}
break;
case '\n': case '\r':
++currentline;
if (sc.state == SCE_GC_COMMENTLINE)
{ styler.ColourTo(sc.currentPos, sc.state);
sc.ChangeState (SCE_GC_DEFAULT);
}
else if (sc.state != SCE_GC_COMMENTBLOCK)
{ colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
noforward = 1; // don't move forward - already positioned at next char..
}
break;
// case ' ': case '\t':
// default :
}
if (!noforward) sc.Forward();
}
sc.Complete();
}
// Main folding function called by Scintilla - (based on props (.ini) files function)
static void FoldGui4Cli(unsigned int startPos, int length, int,
WordList *[], Accessor &styler)
{
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
bool headerPoint = false;
for (unsigned int i = startPos; i < endPos; i++)
{
char ch = chNext;
chNext = styler[i+1];
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL)
{ headerPoint = true; // fold at events and globals
}
if (atEOL)
{ int lev = SC_FOLDLEVELBASE+1;
if (headerPoint)
lev = SC_FOLDLEVELBASE;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (headerPoint)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct
{ styler.SetLevel(lineCurrent, lev);
}
lineCurrent++; // re-initialize our flags
visibleChars = 0;
headerPoint = false;
}
if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))
visibleChars++;
}
int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, lev | flagsNext);
}
// I have no idea what these are for.. probably accessible by some message.
static const char * const gui4cliWordListDesc[] = {
"Globals", "Events", "Attributes", "Control", "Commands",
0
};
// Declare language & pass our function pointers to Scintilla
LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc);
#undef debug

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,275 @@
/******************************************************************
* LexHaskell.cxx
*
* A haskell lexer for the scintilla code control.
* Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
* External lexer stuff inspired from the caml external lexer.
*
* Written by Tobias Engvall - tumm at dtek dot chalmers dot se
*
*
* TODO:
* * Implement a folder :)
* * Nice Character-lexing (stuff inside '\''), LexPython has
* this.
*
*
*****************************************************************/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#ifdef BUILD_AS_EXTERNAL_LEXER
#include "ExternalLexer.h"
#include "WindowAccessor.h"
#define BUILD_EXTERNAL_LEXER 0
#endif
// Max level of nested comments
#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
static inline bool IsNewline(const int ch) {
return (ch == '\n' || ch == '\r');
}
static inline bool IsWhitespace(const int ch) {
return ( ch == ' '
|| ch == '\t'
|| IsNewline(ch) );
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
}
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
int kwLast = kwOther;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
// Check for state end
// Operator
if (sc.state == SCE_HA_OPERATOR) {
kwLast = kwOther;
sc.SetState(SCE_HA_DEFAULT);
}
// String
else if (sc.state == SCE_HA_STRING) {
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') {
sc.Forward();
}
}
// Char
else if (sc.state == SCE_HA_CHARACTER) {
if (sc.ch == '\'') {
sc.ForwardSetState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') {
sc.Forward();
}
}
// Number
else if (sc.state == SCE_HA_NUMBER) {
if (!IsADigit(sc.ch)) {
sc.SetState(SCE_HA_DEFAULT);
}
}
// Types, constructors, etc.
else if (sc.state == SCE_HA_CAPITAL) {
if (!IsAWordChar(sc.ch) || sc.ch == '.') {
sc.SetState(SCE_HA_DEFAULT);
}
}
// Identifier
else if (sc.state == SCE_HA_IDENTIFIER) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrent(s, sizeof(s));
int style = SCE_HA_IDENTIFIER;
if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
style = SCE_HA_IMPORT;
} else if (keywords.InList(s)) {
style = SCE_HA_KEYWORD;
} else if (kwLast == kwData) {
style = SCE_HA_DATA;
} else if (kwLast == kwClass) {
style = SCE_HA_CLASS;
} else if (kwLast == kwModule) {
style = SCE_HA_MODULE;
} else if (isupper(s[0])) {
style = SCE_HA_CAPITAL;
}
sc.ChangeState(style);
sc.SetState(SCE_HA_DEFAULT);
if (style == SCE_HA_KEYWORD) {
if (0 == strcmp(s, "class"))
kwLast = kwClass;
else if (0 == strcmp(s, "data"))
kwLast = kwData;
else if (0 == strcmp(s, "instance"))
kwLast = kwInstance;
else if (0 == strcmp(s, "import"))
kwLast = kwImport;
else if (0 == strcmp(s, "module"))
kwLast = kwModule;
else
kwLast = kwOther;
} else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
kwLast = kwOther;
}
}
}
// Comments
// Oneliner
else if (sc.state == SCE_HA_COMMENTLINE) {
if (IsNewline(sc.ch))
sc.SetState(SCE_HA_DEFAULT);
}
// Nested
else if (sc.state >= SCE_HA_COMMENTBLOCK) {
if (sc.Match("{-")) {
if (sc.state < SCE_HA_COMMENTMAX)
sc.SetState(sc.state + 1);
}
else if (sc.Match("-}")) {
sc.Forward();
if (sc.state == SCE_HA_COMMENTBLOCK)
sc.ForwardSetState(SCE_HA_DEFAULT);
else
sc.ForwardSetState(sc.state - 1);
}
}
// New state?
if (sc.state == SCE_HA_DEFAULT) {
// Digit
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_HA_NUMBER);
if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too
sc.Forward(1);
}
}
// Comment line
else if (sc.Match("--")) {
sc.SetState(SCE_HA_COMMENTLINE);
// Comment block
}
else if (sc.Match("{-")) {
sc.SetState(SCE_HA_COMMENTBLOCK);
}
// String
else if (sc.Match('\"')) {
sc.SetState(SCE_HA_STRING);
}
// Character
else if (sc.Match('\'')) {
sc.SetState(SCE_HA_CHARACTER);
}
// Stringstart
else if (sc.Match('\"')) {
sc.SetState(SCE_HA_STRING);
}
// Operator
else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_HA_OPERATOR);
}
// Keyword
else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_HA_IDENTIFIER);
}
}
}
sc.Complete();
}
// External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
// Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
#ifdef BUILD_EXTERNAL_LEXER
static const char* LexerName = "haskell";
void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
char *words[], WindowID window, char *props)
{
PropSetSimple ps;
ps.SetMultiple(props);
WindowAccessor wa(window, ps);
int nWL = 0;
for (; words[nWL]; nWL++) ;
WordList** wl = new WordList* [nWL + 1];
int i = 0;
for (; i<nWL; i++)
{
wl[i] = new WordList();
wl[i]->Set(words[i]);
}
wl[i] = 0;
ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
wa.Flush();
for (i=nWL-1;i>=0;i--)
delete wl[i];
delete [] wl;
}
void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
char *words[], WindowID window, char *props)
{
}
int EXT_LEXER_DECL GetLexerCount()
{
return 1;
}
void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
{
if (buflength > 0) {
buflength--;
int n = strlen(LexerName);
if (n > buflength)
n = buflength;
memcpy(name, LexerName, n), name[n] = '\0';
}
}
#endif
LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");

View File

@@ -0,0 +1,279 @@
// Scintilla source code edit control
/** @file LexInno.cxx
** Lexer for Inno Setup scripts.
**/
// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
int state = SCE_INNO_DEFAULT;
char chPrev;
char ch = 0;
char chNext = styler[startPos];
int lengthDoc = startPos + length;
char *buffer = new char[length];
int bufferCount = 0;
bool isBOL, isEOL, isWS, isBOLWS = 0;
bool isCode = false;
bool isCStyleComment = false;
WordList &sectionKeywords = *keywordLists[0];
WordList &standardKeywords = *keywordLists[1];
WordList &parameterKeywords = *keywordLists[2];
WordList &preprocessorKeywords = *keywordLists[3];
WordList &pascalKeywords = *keywordLists[4];
WordList &userKeywords = *keywordLists[5];
// Go through all provided text segment
// using the hand-written state machine shown below
styler.StartAt(startPos);
styler.StartSegment(startPos);
for (int i = startPos; i < lengthDoc; i++) {
chPrev = ch;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
continue;
}
isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
isEOL = (ch == '\n' || ch == '\r');
isWS = (ch == ' ' || ch == '\t');
switch(state) {
case SCE_INNO_DEFAULT:
if (!isCode && ch == ';' && isBOLWS) {
// Start of a comment
state = SCE_INNO_COMMENT;
} else if (ch == '[' && isBOLWS) {
// Start of a section name
bufferCount = 0;
state = SCE_INNO_SECTION;
} else if (ch == '#' && isBOLWS) {
// Start of a preprocessor directive
state = SCE_INNO_PREPROC;
} else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
// Start of an inline expansion
state = SCE_INNO_INLINE_EXPANSION;
} else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
// Start of a Pascal comment
state = SCE_INNO_COMMENT_PASCAL;
isCStyleComment = false;
} else if (isCode && ch == '/' && chNext == '/') {
// Apparently, C-style comments are legal, too
state = SCE_INNO_COMMENT_PASCAL;
isCStyleComment = true;
} else if (ch == '"') {
// Start of a double-quote string
state = SCE_INNO_STRING_DOUBLE;
} else if (ch == '\'') {
// Start of a single-quote string
state = SCE_INNO_STRING_SINGLE;
} else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {
// Start of an identifier
bufferCount = 0;
buffer[bufferCount++] = static_cast<char>(tolower(ch));
state = SCE_INNO_IDENTIFIER;
} else {
// Style it the default style
styler.ColourTo(i,SCE_INNO_DEFAULT);
}
break;
case SCE_INNO_COMMENT:
if (isEOL) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_COMMENT);
}
break;
case SCE_INNO_IDENTIFIER:
if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
buffer[bufferCount++] = static_cast<char>(tolower(ch));
} else {
state = SCE_INNO_DEFAULT;
buffer[bufferCount] = '\0';
// Check if the buffer contains a keyword
if (!isCode && standardKeywords.InList(buffer)) {
styler.ColourTo(i-1,SCE_INNO_KEYWORD);
} else if (!isCode && parameterKeywords.InList(buffer)) {
styler.ColourTo(i-1,SCE_INNO_PARAMETER);
} else if (isCode && pascalKeywords.InList(buffer)) {
styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
} else if (!isCode && userKeywords.InList(buffer)) {
styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
} else {
styler.ColourTo(i-1,SCE_INNO_DEFAULT);
}
// Push back the faulty character
chNext = styler[i--];
ch = chPrev;
}
break;
case SCE_INNO_SECTION:
if (ch == ']') {
state = SCE_INNO_DEFAULT;
buffer[bufferCount] = '\0';
// Check if the buffer contains a section name
if (sectionKeywords.InList(buffer)) {
styler.ColourTo(i,SCE_INNO_SECTION);
isCode = !CompareCaseInsensitive(buffer, "code");
} else {
styler.ColourTo(i,SCE_INNO_DEFAULT);
}
} else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
buffer[bufferCount++] = static_cast<char>(tolower(ch));
} else {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_DEFAULT);
}
break;
case SCE_INNO_PREPROC:
if (isWS || isEOL) {
if (isascii(chPrev) && isalpha(chPrev)) {
state = SCE_INNO_DEFAULT;
buffer[bufferCount] = '\0';
// Check if the buffer contains a preprocessor directive
if (preprocessorKeywords.InList(buffer)) {
styler.ColourTo(i-1,SCE_INNO_PREPROC);
} else {
styler.ColourTo(i-1,SCE_INNO_DEFAULT);
}
// Push back the faulty character
chNext = styler[i--];
ch = chPrev;
}
} else if (isascii(ch) && isalpha(ch)) {
if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
bufferCount = 0;
buffer[bufferCount++] = static_cast<char>(tolower(ch));
}
break;
case SCE_INNO_STRING_DOUBLE:
if (ch == '"' || isEOL) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
}
break;
case SCE_INNO_STRING_SINGLE:
if (ch == '\'' || isEOL) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
}
break;
case SCE_INNO_INLINE_EXPANSION:
if (ch == '}') {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
} else if (isEOL) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_DEFAULT);
}
break;
case SCE_INNO_COMMENT_PASCAL:
if (isCStyleComment) {
if (isEOL) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
}
} else {
if (ch == '}' || (ch == ')' && chPrev == '*')) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
} else if (isEOL) {
state = SCE_INNO_DEFAULT;
styler.ColourTo(i,SCE_INNO_DEFAULT);
}
}
break;
}
}
delete []buffer;
}
static const char * const innoWordListDesc[] = {
"Sections",
"Keywords",
"Parameters",
"Preprocessor directives",
"Pascal keywords",
"User defined keywords",
0
};
static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
unsigned int endPos = startPos + length;
char chNext = styler[startPos];
int lineCurrent = styler.GetLine(startPos);
bool sectionFlag = false;
int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
int level;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler[i+1];
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
int style = styler.StyleAt(i);
if (style == SCE_INNO_SECTION)
sectionFlag = true;
if (atEOL || i == endPos - 1) {
if (sectionFlag) {
level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
if (level == levelPrev)
styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
} else {
level = levelPrev & SC_FOLDLEVELNUMBERMASK;
if (levelPrev & SC_FOLDLEVELHEADERFLAG)
level++;
}
styler.SetLevel(lineCurrent, level);
levelPrev = level;
lineCurrent++;
sectionFlag = false;
}
}
}
LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);

View File

@@ -0,0 +1,126 @@
// Scintilla source code edit control
/** @file LexKix.cxx
** Lexer for KIX-Scripts.
**/
// Copyright 2004 by Manfred Becker <manfred@becker-trdf.de>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
return ch >= 0x80 || isalnum(ch) || ch == '_';
}
static inline bool IsOperator(const int ch) {
return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '=');
}
static void ColouriseKixDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
// WordList &keywords4 = *keywordlists[3];
styler.StartAt(startPos);
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.state == SCE_KIX_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_STRING1) {
// This is a doubles quotes string
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_STRING2) {
// This is a single quote string
if (sc.ch == '\'') {
sc.ForwardSetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_NUMBER) {
if (!IsADigit(sc.ch)) {
sc.SetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_VAR) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_MACRO) {
if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (!keywords3.InList(&s[1])) {
sc.ChangeState(SCE_KIX_DEFAULT);
}
sc.SetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_OPERATOR) {
if (!IsOperator(sc.ch)) {
sc.SetState(SCE_KIX_DEFAULT);
}
} else if (sc.state == SCE_KIX_IDENTIFIER) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_KIX_KEYWORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_KIX_FUNCTIONS);
}
sc.SetState(SCE_KIX_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_KIX_DEFAULT) {
if (sc.ch == ';') {
sc.SetState(SCE_KIX_COMMENT);
} else if (sc.ch == '\"') {
sc.SetState(SCE_KIX_STRING1);
} else if (sc.ch == '\'') {
sc.SetState(SCE_KIX_STRING2);
} else if (sc.ch == '$') {
sc.SetState(SCE_KIX_VAR);
} else if (sc.ch == '@') {
sc.SetState(SCE_KIX_MACRO);
} else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) {
sc.SetState(SCE_KIX_NUMBER);
} else if (IsOperator(sc.ch)) {
sc.SetState(SCE_KIX_OPERATOR);
} else if (IsAWordChar(sc.ch)) {
sc.SetState(SCE_KIX_IDENTIFIER);
}
}
}
sc.Complete();
}
LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, "kix");

View File

@@ -0,0 +1,282 @@
// Scintilla source code edit control
/** @file LexLisp.cxx
** Lexer for Lisp.
** Written by Alexey Yutkin.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StyleContext.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#define SCE_LISP_CHARACTER 29
#define SCE_LISP_MACRO 30
#define SCE_LISP_MACRO_DISPATCH 31
static inline bool isLispoperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
return true;
return false;
}
static inline bool isLispwordstart(char ch) {
return isascii(ch) && ch != ';' && !isspacechar(ch) && !isLispoperator(ch) &&
ch != '\n' && ch != '\r' && ch != '\"';
}
static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
PLATFORM_ASSERT(end >= start);
char s[100];
unsigned int i;
bool digit_flag = true;
for (i = 0; (i < end - start + 1) && (i < 99); i++) {
s[i] = styler[start + i];
s[i + 1] = '\0';
if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
}
char chAttr = SCE_LISP_IDENTIFIER;
if(digit_flag) chAttr = SCE_LISP_NUMBER;
else {
if (keywords.InList(s)) {
chAttr = SCE_LISP_KEYWORD;
} else if (keywords_kw.InList(s)) {
chAttr = SCE_LISP_KEYWORD_KW;
} else if ((s[0] == '*' && s[i-1] == '*') ||
(s[0] == '+' && s[i-1] == '+')) {
chAttr = SCE_LISP_SPECIAL;
}
}
styler.ColourTo(end, chAttr);
return;
}
static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords_kw = *keywordlists[1];
styler.StartAt(startPos);
int state = initStyle, radix = -1;
char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length;
styler.StartSegment(startPos);
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i += 1;
continue;
}
if (state == SCE_LISP_DEFAULT) {
if (ch == '#') {
styler.ColourTo(i - 1, state);
radix = -1;
state = SCE_LISP_MACRO_DISPATCH;
} else if (ch == ':' && isLispwordstart(chNext)) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_SYMBOL;
} else if (isLispwordstart(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_IDENTIFIER;
}
else if (ch == ';') {
styler.ColourTo(i - 1, state);
state = SCE_LISP_COMMENT;
}
else if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
if (ch=='\'' && isLispwordstart(chNext)) {
state = SCE_LISP_SYMBOL;
}
}
else if (ch == '\"') {
styler.ColourTo(i - 1, state);
state = SCE_LISP_STRING;
}
} else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
if (!isLispwordstart(ch)) {
if (state == SCE_LISP_IDENTIFIER) {
classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
} else {
styler.ColourTo(i - 1, state);
}
state = SCE_LISP_DEFAULT;
} /*else*/
if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
if (ch=='\'' && isLispwordstart(chNext)) {
state = SCE_LISP_SYMBOL;
}
}
} else if (state == SCE_LISP_MACRO_DISPATCH) {
if (!(isascii(ch) && isdigit(ch))) {
if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
state = SCE_LISP_DEFAULT;
} else {
switch (ch) {
case '|': state = SCE_LISP_MULTI_COMMENT; break;
case 'o':
case 'O': radix = 8; state = SCE_LISP_MACRO; break;
case 'x':
case 'X': radix = 16; state = SCE_LISP_MACRO; break;
case 'b':
case 'B': radix = 2; state = SCE_LISP_MACRO; break;
case '\\': state = SCE_LISP_CHARACTER; break;
case ':':
case '-':
case '+': state = SCE_LISP_MACRO; break;
case '\'': if (isLispwordstart(chNext)) {
state = SCE_LISP_SPECIAL;
} else {
styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
styler.ColourTo(i, SCE_LISP_OPERATOR);
state = SCE_LISP_DEFAULT;
}
break;
default: if (isLispoperator(ch)) {
styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
styler.ColourTo(i, SCE_LISP_OPERATOR);
}
state = SCE_LISP_DEFAULT;
break;
}
}
}
} else if (state == SCE_LISP_MACRO) {
if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
state = SCE_LISP_SPECIAL;
} else {
state = SCE_LISP_DEFAULT;
}
} else if (state == SCE_LISP_CHARACTER) {
if (isLispoperator(ch)) {
styler.ColourTo(i, SCE_LISP_SPECIAL);
state = SCE_LISP_DEFAULT;
} else if (isLispwordstart(ch)) {
styler.ColourTo(i, SCE_LISP_SPECIAL);
state = SCE_LISP_SPECIAL;
} else {
state = SCE_LISP_DEFAULT;
}
} else if (state == SCE_LISP_SPECIAL) {
if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_DEFAULT;
}
if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
if (ch=='\'' && isLispwordstart(chNext)) {
state = SCE_LISP_SYMBOL;
}
}
} else {
if (state == SCE_LISP_COMMENT) {
if (atEOL) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_DEFAULT;
}
} else if (state == SCE_LISP_MULTI_COMMENT) {
if (ch == '|' && chNext == '#') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i, state);
state = SCE_LISP_DEFAULT;
}
} else if (state == SCE_LISP_STRING) {
if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
} else if (ch == '\"') {
styler.ColourTo(i, state);
state = SCE_LISP_DEFAULT;
}
}
}
}
styler.ColourTo(lengthDoc - 1, state);
}
static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_LISP_OPERATOR) {
if (ch == '(' || ch == '[' || ch == '{') {
levelCurrent++;
} else if (ch == ')' || ch == ']' || ch == '}') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const lispWordListDesc[] = {
"Functions and special operators",
"Keywords",
0
};
LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);

View File

@@ -0,0 +1,212 @@
// Scintilla source code edit control
/** @file LexLout.cxx
** Lexer for the Basser Lout (>= version 3) typesetting language
**/
// Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
}
static inline bool IsAnOther(const int ch) {
return (ch < 0x80) && (ch == '{' || ch == '}' ||
ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
}
static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
int visibleChars = 0;
int firstWordInLine = 0;
int leadingAtSign = 0;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
// Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
sc.SetState(SCE_LOUT_STRING);
}
// Determine if the current state should terminate.
if (sc.state == SCE_LOUT_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_LOUT_DEFAULT);
visibleChars = 0;
}
} else if (sc.state == SCE_LOUT_NUMBER) {
if (!IsADigit(sc.ch) && sc.ch != '.') {
sc.SetState(SCE_LOUT_DEFAULT);
}
} else if (sc.state == SCE_LOUT_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LOUT_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_LOUT_STRINGEOL);
sc.ForwardSetState(SCE_LOUT_DEFAULT);
visibleChars = 0;
}
} else if (sc.state == SCE_LOUT_IDENTIFIER) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (leadingAtSign) {
if (keywords.InList(s)) {
sc.ChangeState(SCE_LOUT_WORD);
} else {
sc.ChangeState(SCE_LOUT_WORD4);
}
} else if (firstWordInLine && keywords3.InList(s)) {
sc.ChangeState(SCE_LOUT_WORD3);
}
sc.SetState(SCE_LOUT_DEFAULT);
}
} else if (sc.state == SCE_LOUT_OPERATOR) {
if (!IsAnOther(sc.ch)) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords2.InList(s)) {
sc.ChangeState(SCE_LOUT_WORD2);
}
sc.SetState(SCE_LOUT_DEFAULT);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_LOUT_DEFAULT) {
if (sc.ch == '#') {
sc.SetState(SCE_LOUT_COMMENT);
} else if (sc.ch == '\"') {
sc.SetState(SCE_LOUT_STRING);
} else if (IsADigit(sc.ch) ||
(sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_LOUT_NUMBER);
} else if (IsAWordChar(sc.ch)) {
firstWordInLine = (visibleChars == 0);
leadingAtSign = (sc.ch == '@');
sc.SetState(SCE_LOUT_IDENTIFIER);
} else if (IsAnOther(sc.ch)) {
sc.SetState(SCE_LOUT_OPERATOR);
}
}
if (sc.atLineEnd) {
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
visibleChars = 0;
}
if (!IsASpace(sc.ch)) {
visibleChars++;
}
}
sc.Complete();
}
static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
int styleNext = styler.StyleAt(startPos);
char s[10];
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_LOUT_WORD) {
if (ch == '@') {
for (unsigned int j = 0; j < 8; j++) {
if (!IsAWordChar(styler[i + j])) {
break;
}
s[j] = styler[i + j];
s[j + 1] = '\0';
}
if (strcmp(s, "@Begin") == 0) {
levelCurrent++;
} else if (strcmp(s, "@End") == 0) {
levelCurrent--;
}
}
} else if (style == SCE_LOUT_OPERATOR) {
if (ch == '{') {
levelCurrent++;
} else if (ch == '}') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact) {
lev |= SC_FOLDLEVELWHITEFLAG;
}
if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const loutWordLists[] = {
"Predefined identifiers",
"Predefined delimiters",
"Predefined keywords",
0,
};
LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);

View File

@@ -0,0 +1,358 @@
// Scintilla source code edit control
/** @file LexLua.cxx
** Lexer for Lua language.
**
** Written by Paul Winwood.
** Folder by Alexey Yutkin.
** Modified by Marcos E. Wurzius & Philippe Lhoste
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "CharacterSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],
// return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.
// The maximum number of '=' characters allowed is 254.
static int LongDelimCheck(StyleContext &sc) {
int sep = 1;
while (sc.GetRelative(sep) == '=' && sep < 0xFF)
sep++;
if (sc.GetRelative(sep) == sc.ch)
return sep;
return 0;
}
static void ColouriseLuaDoc(
unsigned int startPos,
int length,
int initStyle,
WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
WordList &keywords7 = *keywordlists[6];
WordList &keywords8 = *keywordlists[7];
// Accepts accented characters
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
int currentLine = styler.GetLine(startPos);
// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
// if we are inside such a string. Block comment was introduced in Lua 5.0,
// blocks with separators [=[ ... ]=] in Lua 5.1.
int nestLevel = 0;
int sepCount = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
int lineState = styler.GetLineState(currentLine - 1);
nestLevel = lineState >> 8;
sepCount = lineState & 0xFF;
}
// Do not leak onto next line
if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
initStyle = SCE_LUA_DEFAULT;
}
StyleContext sc(startPos, length, initStyle, styler);
if (startPos == 0 && sc.ch == '#') {
// shbang line: # is a comment only if first char of the script
sc.SetState(SCE_LUA_COMMENTLINE);
}
for (; sc.More(); sc.Forward()) {
if (sc.atLineEnd) {
// Update the line state, so it can be seen by next line
currentLine = styler.GetLine(sc.currentPos);
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
case SCE_LUA_COMMENT:
// Inside a literal string or block comment, we set the line state
styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
break;
default:
// Reset the line state
styler.SetLineState(currentLine, 0);
break;
}
}
if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {
// Prevent SCE_LUA_STRINGEOL from leaking back to previous line
sc.SetState(SCE_LUA_STRING);
}
// Handle string line continuation
if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&
sc.ch == '\\') {
if (sc.chNext == '\n' || sc.chNext == '\r') {
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
continue;
}
}
// Determine if the current state should terminate.
if (sc.state == SCE_LUA_OPERATOR) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.state == SCE_LUA_NUMBER) {
// We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
if (!setNumber.Contains(sc.ch)) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.ch == '-' || sc.ch == '+') {
if (sc.chPrev != 'E' && sc.chPrev != 'e')
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_IDENTIFIER) {
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_LUA_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_LUA_WORD2);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_LUA_WORD3);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_LUA_WORD4);
} else if (keywords5.InList(s)) {
sc.ChangeState(SCE_LUA_WORD5);
} else if (keywords6.InList(s)) {
sc.ChangeState(SCE_LUA_WORD6);
} else if (keywords7.InList(s)) {
sc.ChangeState(SCE_LUA_WORD7);
} else if (keywords8.InList(s)) {
sc.ChangeState(SCE_LUA_WORD8);
}
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_COMMENTLINE || sc.state == SCE_LUA_PREPROCESSOR) {
if (sc.atLineEnd) {
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_CHARACTER) {
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) {
if (sc.ch == '[') {
int sep = LongDelimCheck(sc);
if (sep == 1 && sepCount == 1) { // [[-only allowed to nest
nestLevel++;
sc.Forward();
}
} else if (sc.ch == ']') {
int sep = LongDelimCheck(sc);
if (sep == 1 && sepCount == 1) { // un-nest with ]]-only
nestLevel--;
sc.Forward();
if (nestLevel == 0) {
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sep > 1 && sep == sepCount) { // ]=]-style delim
sc.Forward(sep);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_LUA_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_LUA_NUMBER);
if (sc.ch == '0' && toupper(sc.chNext) == 'X') {
sc.Forward();
}
} else if (setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_LUA_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
} else if (sc.ch == '[') {
sepCount = LongDelimCheck(sc);
if (sepCount == 0) {
sc.SetState(SCE_LUA_OPERATOR);
} else {
nestLevel = 1;
sc.SetState(SCE_LUA_LITERALSTRING);
sc.Forward(sepCount);
}
} else if (sc.Match('-', '-')) {
sc.SetState(SCE_LUA_COMMENTLINE);
if (sc.Match("--[")) {
sc.Forward(2);
sepCount = LongDelimCheck(sc);
if (sepCount > 0) {
nestLevel = 1;
sc.ChangeState(SCE_LUA_COMMENT);
sc.Forward(sepCount);
}
} else {
sc.Forward();
}
} else if (sc.atLineStart && sc.Match('$')) {
sc.SetState(SCE_LUA_PREPROCESSOR); // Obsolete since Lua 4.0, but still in old code
} else if (setLuaOperator.Contains(sc.ch)) {
sc.SetState(SCE_LUA_OPERATOR);
}
}
}
if (setWord.Contains(sc.chPrev)) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_LUA_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_LUA_WORD2);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_LUA_WORD3);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_LUA_WORD4);
} else if (keywords5.InList(s)) {
sc.ChangeState(SCE_LUA_WORD5);
} else if (keywords6.InList(s)) {
sc.ChangeState(SCE_LUA_WORD6);
} else if (keywords7.InList(s)) {
sc.ChangeState(SCE_LUA_WORD7);
} else if (keywords8.InList(s)) {
sc.ChangeState(SCE_LUA_WORD8);
}
}
sc.Complete();
}
static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
int styleNext = styler.StyleAt(startPos);
char s[10];
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_LUA_WORD) {
if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
for (unsigned int j = 0; j < 8; j++) {
if (!iswordchar(styler[i + j])) {
break;
}
s[j] = styler[i + j];
s[j + 1] = '\0';
}
if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) {
levelCurrent++;
}
if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) {
levelCurrent--;
}
}
} else if (style == SCE_LUA_OPERATOR) {
if (ch == '{' || ch == '(') {
levelCurrent++;
} else if (ch == '}' || ch == ')') {
levelCurrent--;
}
} else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
if (ch == '[') {
levelCurrent++;
} else if (ch == ']') {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact) {
lev |= SC_FOLDLEVELWHITEFLAG;
}
if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch)) {
visibleChars++;
}
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const luaWordListDesc[] = {
"Keywords",
"Basic functions",
"String, (table) & math functions",
"(coroutines), I/O & system facilities",
"user1",
"user2",
"user3",
"user4",
0
};
LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);

View File

@@ -0,0 +1,186 @@
// Scintilla source code edit control
/** @file LexMMIXAL.cxx
** Lexer for MMIX Assembler Language.
** Written by Christoph H<>sler <christoph.hoesler@student.uni-tuebingen.de>
** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
}
inline bool isMMIXALOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
ch == '*' || ch == '/' || ch == '/' ||
ch == '%' || ch == '<' || ch == '>' || ch == '&' ||
ch == '~' || ch == '$' ||
ch == ',' || ch == '(' || ch == ')' ||
ch == '[' || ch == ']')
return true;
return false;
}
static void ColouriseMMIXALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &opcodes = *keywordlists[0];
WordList &special_register = *keywordlists[1];
WordList &predef_symbols = *keywordlists[2];
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
// No EOL continuation
if (sc.atLineStart) {
if (sc.ch == '@' && sc.chNext == 'i') {
sc.SetState(SCE_MMIXAL_INCLUDE);
} else {
sc.SetState(SCE_MMIXAL_LEADWS);
}
}
// Check if first non whitespace character in line is alphanumeric
if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) { // LEADWS
if(!IsAWordChar(sc.ch)) {
sc.SetState(SCE_MMIXAL_COMMENT);
} else {
if(sc.atLineStart) {
sc.SetState(SCE_MMIXAL_LABEL);
} else {
sc.SetState(SCE_MMIXAL_OPCODE_PRE);
}
}
}
// Determine if the current state should terminate.
if (sc.state == SCE_MMIXAL_OPERATOR) { // OPERATOR
sc.SetState(SCE_MMIXAL_OPERANDS);
} else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER
if (!isdigit(sc.ch)) {
if (IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrent(s, sizeof(s));
sc.ChangeState(SCE_MMIXAL_REF);
sc.SetState(SCE_MMIXAL_REF);
} else {
sc.SetState(SCE_MMIXAL_OPERANDS);
}
}
} else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
if (!IsAWordChar(sc.ch) ) {
sc.SetState(SCE_MMIXAL_OPCODE_PRE);
}
} else if (sc.state == SCE_MMIXAL_REF) { // REF
if (!IsAWordChar(sc.ch) ) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (*s == ':') { // ignore base prefix for match
for (size_t i = 0; i != sizeof(s); ++i) {
*(s+i) = *(s+i+1);
}
}
if (special_register.InList(s)) {
sc.ChangeState(SCE_MMIXAL_REGISTER);
} else if (predef_symbols.InList(s)) {
sc.ChangeState(SCE_MMIXAL_SYMBOL);
}
sc.SetState(SCE_MMIXAL_OPERANDS);
}
} else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
if (!isspace(sc.ch)) {
sc.SetState(SCE_MMIXAL_OPCODE);
}
} else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
if (!IsAWordChar(sc.ch) ) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (opcodes.InList(s)) {
sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
} else {
sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
}
sc.SetState(SCE_MMIXAL_OPCODE_POST);
}
} else if (sc.state == SCE_MMIXAL_STRING) { // STRING
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
} else if (sc.atLineEnd) {
sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
}
} else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
} else if (sc.atLineEnd) {
sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
}
} else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
if (!isdigit(sc.ch)) {
sc.SetState(SCE_MMIXAL_OPERANDS);
}
} else if (sc.state == SCE_MMIXAL_HEX) { // HEX
if (!isxdigit(sc.ch)) {
sc.SetState(SCE_MMIXAL_OPERANDS);
}
}
// Determine if a new state should be entered.
if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST
sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS
if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
if (!sc.atLineEnd) {
sc.SetState(SCE_MMIXAL_COMMENT);
}
} else if (isdigit(sc.ch)) {
sc.SetState(SCE_MMIXAL_NUMBER);
} else if (IsAWordChar(sc.ch) || sc.Match('@')) {
sc.SetState(SCE_MMIXAL_REF);
} else if (sc.Match('\"')) {
sc.SetState(SCE_MMIXAL_STRING);
} else if (sc.Match('\'')) {
sc.SetState(SCE_MMIXAL_CHAR);
} else if (sc.Match('$')) {
sc.SetState(SCE_MMIXAL_REGISTER);
} else if (sc.Match('#')) {
sc.SetState(SCE_MMIXAL_HEX);
} else if (isMMIXALOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_MMIXAL_OPERATOR);
}
}
}
sc.Complete();
}
static const char * const MMIXALWordListDesc[] = {
"Operation Codes",
"Special Register",
"Predefined Symbols",
0
};
LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);

View File

@@ -0,0 +1,188 @@
// Scintilla source code edit control
/** @file LexMPT.cxx
** Lexer for MPT specific files. Based on LexOthers.cxx
** LOT = the text log file created by the MPT application while running a test program
** Other MPT specific files to be added later.
**/
// Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static int GetLotLineState(std::string &line) {
if (line.length()) {
// Most of the time the first non-blank character in line determines that line's type
// Now finds the first non-blank character
unsigned i; // Declares counter here to make it persistent after the for loop
for (i = 0; i < line.length(); ++i) {
if (!(isascii(line[i]) && isspace(line[i])))
break;
}
// Checks if it was a blank line
if (i == line.length())
return SCE_LOT_DEFAULT;
switch (line[i]) {
case '*': // Fail measurement
return SCE_LOT_FAIL;
case '+': // Header
case '|': // Header
return SCE_LOT_HEADER;
case ':': // Set test limits
return SCE_LOT_SET;
case '-': // Section break
return SCE_LOT_BREAK;
default: // Any other line
// Checks for message at the end of lot file
if (line.find("PASSED") != std::string::npos) {
return SCE_LOT_PASS;
}
else if (line.find("FAILED") != std::string::npos) {
return SCE_LOT_FAIL;
}
else if (line.find("ABORTED") != std::string::npos) {
return SCE_LOT_ABORT;
}
else {
return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
}
}
}
else {
return SCE_LOT_DEFAULT;
}
}
static void ColourizeLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
styler.StartAt(startPos);
styler.StartSegment(startPos);
bool atLineStart = true;// Arms the 'at line start' flag
char chNext = styler.SafeGetCharAt(startPos);
std::string line("");
line.reserve(256); // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
// Styles LOT document
unsigned int i; // Declared here because it's used after the for loop
for (i = startPos; i < startPos + length; ++i) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
line += ch;
atLineStart = false;
// LOT files are only used on the Win32 platform, thus EOL == CR+LF
// Searches for the end of line
if (ch == '\r' && chNext == '\n') {
line += chNext; // Gets the '\n'
++i; // Advances past the '\n'
chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line
styler.ColourTo(i, GetLotLineState(line));
line = "";
atLineStart = true; // Arms flag for next line
}
}
// Last line may not have a line ending
if (!atLineStart) {
styler.ColourTo(i - 1, GetLotLineState(line));
}
}
// Folds an MPT LOT file: the blocks that can be folded are:
// sections (headed by a set line)
// passes (contiguous pass results within a section)
// fails (contiguous fail results within a section)
static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
char chNext = styler.SafeGetCharAt(startPos);
int style = SCE_LOT_DEFAULT;
int styleNext = styler.StyleAt(startPos);
int lev = SC_FOLDLEVELBASE;
// Gets style of previous line if not at the beginning of the document
if (startPos > 1)
style = styler.StyleAt(startPos - 2);
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (ch == '\r' && chNext == '\n') {
// TO DO:
// Should really get the state of the previous line from the styler
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 2);
switch (style) {
/*
case SCE_LOT_SET:
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
break;
*/
case SCE_LOT_FAIL:
/*
if (stylePrev != SCE_LOT_FAIL)
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
else
lev = SC_FOLDLEVELBASE + 1;
*/
lev = SC_FOLDLEVELBASE;
break;
default:
if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
else
lev = SC_FOLDLEVELBASE + 1;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
break;
}
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, lev | flagsNext);
}
static const char * const emptyWordListDesc[] = {
0
};
LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc);

View File

@@ -0,0 +1,363 @@
// Scintilla source code edit control
/** @file LexMSSQL.cxx
** Lexer for MSSQL.
**/
// By Filip Yaghob <fyaghob@gmail.com>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#define KW_MSSQL_STATEMENTS 0
#define KW_MSSQL_DATA_TYPES 1
#define KW_MSSQL_SYSTEM_TABLES 2
#define KW_MSSQL_GLOBAL_VARIABLES 3
#define KW_MSSQL_FUNCTIONS 4
#define KW_MSSQL_STORED_PROCEDURES 5
#define KW_MSSQL_OPERATORS 6
static bool isMSSQLOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
ch == '<' || ch == '>' || ch == '/' ||
ch == '!' || ch == '~' || ch == '(' || ch == ')' ||
ch == ',')
return true;
return false;
}
static char classifyWordSQL(unsigned int start,
unsigned int end,
WordList *keywordlists[],
Accessor &styler,
unsigned int actualState,
unsigned int prevState) {
char s[256];
bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
WordList &kwStoredProcedures = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
WordList &kwOperators = *keywordlists[KW_MSSQL_OPERATORS];
for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0';
}
char chAttr = SCE_MSSQL_IDENTIFIER;
if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {
if (kwGlobalVariables.InList(&s[2]))
chAttr = SCE_MSSQL_GLOBAL_VARIABLE;
} else if (wordIsNumber) {
chAttr = SCE_MSSQL_NUMBER;
} else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
// Look first in datatypes
if (kwDataTypes.InList(s))
chAttr = SCE_MSSQL_DATATYPE;
else if (kwOperators.InList(s))
chAttr = SCE_MSSQL_OPERATOR;
else if (kwStatements.InList(s))
chAttr = SCE_MSSQL_STATEMENT;
else if (kwSystemTables.InList(s))
chAttr = SCE_MSSQL_SYSTABLE;
else if (kwFunctions.InList(s))
chAttr = SCE_MSSQL_FUNCTION;
else if (kwStoredProcedures.InList(s))
chAttr = SCE_MSSQL_STORED_PROCEDURE;
} else {
if (kwOperators.InList(s))
chAttr = SCE_MSSQL_OPERATOR;
else if (kwStatements.InList(s))
chAttr = SCE_MSSQL_STATEMENT;
else if (kwSystemTables.InList(s))
chAttr = SCE_MSSQL_SYSTABLE;
else if (kwFunctions.InList(s))
chAttr = SCE_MSSQL_FUNCTION;
else if (kwStoredProcedures.InList(s))
chAttr = SCE_MSSQL_STORED_PROCEDURE;
else if (kwDataTypes.InList(s))
chAttr = SCE_MSSQL_DATATYPE;
}
styler.ColourTo(end, chAttr);
return chAttr;
}
static void ColouriseMSSQLDoc(unsigned int startPos, int length,
int initStyle, WordList *keywordlists[], Accessor &styler) {
styler.StartAt(startPos);
bool fold = styler.GetPropertyInt("fold") != 0;
int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0;
int state = initStyle;
int prevState = initStyle;
char chPrev = ' ';
char chNext = styler[startPos];
styler.StartSegment(startPos);
unsigned int lengthDoc = startPos + length;
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
int lev = indentCurrent;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
}
if (fold) {
styler.SetLevel(lineCurrent, lev);
}
}
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
chPrev = ' ';
i += 1;
continue;
}
// When the last char isn't part of the state (have to deal with it too)...
if ( (state == SCE_MSSQL_IDENTIFIER) ||
(state == SCE_MSSQL_STORED_PROCEDURE) ||
(state == SCE_MSSQL_DATATYPE) ||
//~ (state == SCE_MSSQL_COLUMN_NAME) ||
(state == SCE_MSSQL_FUNCTION) ||
//~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
(state == SCE_MSSQL_VARIABLE)) {
if (!iswordchar(ch)) {
int stateTmp;
if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
styler.ColourTo(i - 1, state);
stateTmp = state;
} else
stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
prevState = state;
if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
else
state = SCE_MSSQL_DEFAULT;
}
} else if (state == SCE_MSSQL_LINE_COMMENT) {
if (ch == '\r' || ch == '\n') {
styler.ColourTo(i - 1, state);
prevState = state;
state = SCE_MSSQL_DEFAULT;
}
} else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
if ((ch != '@') && !iswordchar(ch)) {
classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
prevState = state;
state = SCE_MSSQL_DEFAULT;
}
}
// If is the default or one of the above succeeded
if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
if (iswordstart(ch)) {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
state = SCE_MSSQL_IDENTIFIER;
} else if (ch == '/' && chNext == '*') {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
state = SCE_MSSQL_COMMENT;
} else if (ch == '-' && chNext == '-') {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
state = SCE_MSSQL_LINE_COMMENT;
} else if (ch == '\'') {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
state = SCE_MSSQL_STRING;
} else if (ch == '"') {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
state = SCE_MSSQL_COLUMN_NAME;
} else if (ch == '[') {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
state = SCE_MSSQL_COLUMN_NAME_2;
} else if (isMSSQLOperator(ch)) {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
styler.ColourTo(i, SCE_MSSQL_OPERATOR);
//~ style = SCE_MSSQL_DEFAULT;
prevState = state;
state = SCE_MSSQL_DEFAULT;
} else if (ch == '@') {
styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
prevState = state;
if (chNext == '@') {
state = SCE_MSSQL_GLOBAL_VARIABLE;
// i += 2;
} else
state = SCE_MSSQL_VARIABLE;
}
// When the last char is part of the state...
} else if (state == SCE_MSSQL_COMMENT) {
if (ch == '/' && chPrev == '*') {
if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
(styler.GetStartSegment() == startPos)))) {
styler.ColourTo(i, state);
//~ state = SCE_MSSQL_COMMENT;
prevState = state;
state = SCE_MSSQL_DEFAULT;
}
}
} else if (state == SCE_MSSQL_STRING) {
if (ch == '\'') {
if ( chNext == '\'' ) {
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
} else {
styler.ColourTo(i, state);
prevState = state;
state = SCE_MSSQL_DEFAULT;
//i++;
}
//ch = chNext;
//chNext = styler.SafeGetCharAt(i + 1);
}
} else if (state == SCE_MSSQL_COLUMN_NAME) {
if (ch == '"') {
if (chNext == '"') {
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
} else {
styler.ColourTo(i, state);
prevState = state;
state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
//i++;
}
}
} else if (state == SCE_MSSQL_COLUMN_NAME_2) {
if (ch == ']') {
styler.ColourTo(i, state);
prevState = state;
state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
//i++;
}
}
chPrev = ch;
}
styler.ColourTo(lengthDoc - 1, state);
}
static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
char s[10];
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styler.StyleAt(i);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
// Comment folding
if (foldComment) {
if (!inComment && (style == SCE_MSSQL_COMMENT))
levelCurrent++;
else if (inComment && (style != SCE_MSSQL_COMMENT))
levelCurrent--;
inComment = (style == SCE_MSSQL_COMMENT);
}
if (style == SCE_MSSQL_STATEMENT) {
// Folding between begin or case and end
if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') {
for (unsigned int j = 0; j < 5; j++) {
if (!iswordchar(styler[i + j])) {
break;
}
s[j] = static_cast<char>(tolower(styler[i + j]));
s[j + 1] = '\0';
}
if ((strcmp(s, "begin") == 0) || (strcmp(s, "case") == 0)) {
levelCurrent++;
}
if (strcmp(s, "end") == 0) {
levelCurrent--;
}
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const sqlWordListDesc[] = {
"Statements",
"Data Types",
"System tables",
"Global variables",
"Functions",
"System Stored Procedures",
"Operators",
0,
};
LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);

View File

@@ -0,0 +1,445 @@
// Scintilla source code edit control
/**
* @file LexMagik.cxx
* Lexer for GE(r) Smallworld(tm) MagikSF
*/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/**
* Is it a core character (C isalpha(), exclamation and question mark)
*
* \param ch The character
* \return True if ch is a character, False otherwise
*/
static inline bool IsAlphaCore(int ch) {
return (isalpha(ch) || ch == '!' || ch == '?');
}
/**
* Is it a character (IsAlphaCore() and underscore)
*
* \param ch The character
* \return True if ch is a character, False otherwise
*/
static inline bool IsAlpha(int ch) {
return (IsAlphaCore(ch) || ch == '_');
}
/**
* Is it a symbolic character (IsAlpha() and colon)
*
* \param ch The character
* \return True if ch is a character, False otherwise
*/
static inline bool IsAlphaSym(int ch) {
return (IsAlpha(ch) || ch == ':');
}
/**
* Is it a numerical character (IsAlpha() and 0 - 9)
*
* \param ch The character
* \return True if ch is a character, False otherwise
*/
static inline bool IsAlNum(int ch) {
return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
}
/**
* Is it a symbolic numerical character (IsAlNum() and colon)
*
* \param ch The character
* \return True if ch is a character, False otherwise
*/
static inline bool IsAlNumSym(int ch) {
return (IsAlNum(ch) || ch == ':');
}
/**
* The lexer function
*
* \param startPos Where to start scanning
* \param length Where to scan to
* \param initStyle The style at the initial point, not used in this folder
* \param keywordslists The keywordslists, currently, number 5 is used
* \param styler The styler
*/
static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
styler.StartAt(startPos);
WordList &keywords = *keywordlists[0];
WordList &pragmatics = *keywordlists[1];
WordList &containers = *keywordlists[2];
WordList &flow = *keywordlists[3];
WordList &characters = *keywordlists[4];
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
repeat:
if(sc.ch == '#') {
if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
else sc.SetState(SCE_MAGIK_COMMENT);
for(; sc.More() && !(sc.atLineEnd); sc.Forward());
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
if(sc.ch == '"') {
sc.SetState(SCE_MAGIK_STRING);
if(sc.More())
{
sc.Forward();
for(; sc.More() && sc.ch != '"'; sc.Forward());
}
sc.ForwardSetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
// The default state
if(sc.state == SCE_MAGIK_DEFAULT) {
// A certain keyword has been detected
if (sc.ch == '_' && (
sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
char keyword[50];
memset(keyword, '\0', 50);
for(
int scanPosition = 0;
scanPosition < 50;
scanPosition++) {
char keywordChar = static_cast<char>(
tolower(styler.SafeGetCharAt(
scanPosition +
static_cast<int>(sc.currentPos+1), ' ')));
if(IsAlpha(keywordChar)) {
keyword[scanPosition] = keywordChar;
} else {
break;
}
}
// It is a pragma
if(pragmatics.InList(keyword)) {
sc.SetState(SCE_MAGIK_PRAGMA);
}
// it is a normal keyword like _local, _self, etc.
else if(keywords.InList(keyword)) {
sc.SetState(SCE_MAGIK_KEYWORD);
}
// It is a container keyword, such as _method, _proc, etc.
else if(containers.InList(keyword)) {
sc.SetState(SCE_MAGIK_CONTAINER);
}
// It is a flow keyword, such as _for, _if, _try, etc.
else if(flow.InList(keyword)) {
sc.SetState(SCE_MAGIK_FLOW);
}
// Interpret as unknown keyword
else {
sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
}
}
// Symbolic expression
else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
sc.SetState(SCE_MAGIK_SYMBOL);
bool firstTrip = true;
for(sc.Forward(); sc.More(); sc.Forward()) {
if(firstTrip && IsAlphaSym(sc.ch));
else if(!firstTrip && IsAlNumSym(sc.ch));
else if(sc.ch == '|') {
for(sc.Forward();
sc.More() && sc.ch != '|';
sc.Forward());
}
else break;
firstTrip = false;
}
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
// Identifier (label) expression
else if(sc.ch == '@') {
sc.SetState(SCE_MAGIK_IDENTIFIER);
bool firstTrip = true;
for(sc.Forward(); sc.More(); sc.Forward()) {
if(firstTrip && IsAlphaCore(sc.ch)) {
firstTrip = false;
}
else if(!firstTrip && IsAlpha(sc.ch));
else break;
}
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
// Start of a character
else if(sc.ch == '%') {
sc.SetState(SCE_MAGIK_CHARACTER);
sc.Forward();
char keyword[50];
memset(keyword, '\0', 50);
for(
int scanPosition = 0;
scanPosition < 50;
scanPosition++) {
char keywordChar = static_cast<char>(
tolower(styler.SafeGetCharAt(
scanPosition +
static_cast<int>(sc.currentPos), ' ')));
if(IsAlpha(keywordChar)) {
keyword[scanPosition] = keywordChar;
} else {
break;
}
}
if(characters.InList(keyword)) {
sc.Forward(strlen(keyword));
} else {
sc.Forward();
}
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
// Operators
else if(
sc.ch == '>' ||
sc.ch == '<' ||
sc.ch == '.' ||
sc.ch == ',' ||
sc.ch == '+' ||
sc.ch == '-' ||
sc.ch == '/' ||
sc.ch == '*' ||
sc.ch == '~' ||
sc.ch == '$' ||
sc.ch == '=') {
sc.SetState(SCE_MAGIK_OPERATOR);
}
// Braces
else if(sc.ch == '(' || sc.ch == ')') {
sc.SetState(SCE_MAGIK_BRACE_BLOCK);
}
// Brackets
else if(sc.ch == '{' || sc.ch == '}') {
sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
}
// Square Brackets
else if(sc.ch == '[' || sc.ch == ']') {
sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
}
}
// It is an operator
else if(
sc.state == SCE_MAGIK_OPERATOR ||
sc.state == SCE_MAGIK_BRACE_BLOCK ||
sc.state == SCE_MAGIK_BRACKET_BLOCK ||
sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
// It is the pragma state
else if(sc.state == SCE_MAGIK_PRAGMA) {
if(!IsAlpha(sc.ch)) {
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
}
// It is the keyword state
else if(
sc.state == SCE_MAGIK_KEYWORD ||
sc.state == SCE_MAGIK_CONTAINER ||
sc.state == SCE_MAGIK_FLOW ||
sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
if(!IsAlpha(sc.ch)) {
sc.SetState(SCE_MAGIK_DEFAULT);
goto repeat;
}
}
}
sc.Complete();
}
/**
* The word list description
*/
static const char * const magikWordListDesc[] = {
"Accessors (local, global, self, super, thisthread)",
"Pragmatic (pragma, private)",
"Containers (method, block, proc)",
"Flow (if, then, elif, else)",
"Characters (space, tab, newline, return)",
"Fold Containers (method, proc, block, if, loop)",
0};
/**
* This function detects keywords which are able to have a body. Note that it
* uses the Fold Containers word description, not the containers description. It
* only works when the style at that particular position is set on Containers
* or Flow (number 3 or 4).
*
* \param keywordslist The list of keywords that are scanned, they should only
* contain the start keywords, not the end keywords
* \param The actual keyword
* \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
* 0 otherwise
*/
static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
if(
strlen(keyword) > 3 &&
keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
if (keywordslist.InList(keyword + 3)) {
return -1;
}
} else {
if(keywordslist.InList(keyword)) {
return 1;
}
}
return 0;
}
/**
* The folding function
*
* \param startPos Where to start scanning
* \param length Where to scan to
* \param keywordslists The keywordslists, currently, number 5 is used
* \param styler The styler
*/
static void FoldMagikDoc(unsigned int startPos, int length, int,
WordList *keywordslists[], Accessor &styler) {
bool compact = styler.GetPropertyInt("fold.compact") != 0;
WordList &foldingElements = *keywordslists[5];
int endPos = startPos + length;
int line = styler.GetLine(startPos);
int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
for(
int currentPos = startPos;
currentPos < endPos;
currentPos++) {
char currentState = styler.StyleAt(currentPos);
char c = styler.SafeGetCharAt(currentPos, ' ');
int prevLine = styler.GetLine(currentPos - 1);
line = styler.GetLine(currentPos);
// Default situation
if(prevLine < line) {
styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
}
if(
(
currentState == SCE_MAGIK_CONTAINER ||
currentState == SCE_MAGIK_FLOW
) &&
c == '_') {
char keyword[50];
memset(keyword, '\0', 50);
for(
int scanPosition = 0;
scanPosition < 50;
scanPosition++) {
char keywordChar = static_cast<char>(
tolower(styler.SafeGetCharAt(
scanPosition +
currentPos + 1, ' ')));
if(IsAlpha(keywordChar)) {
keyword[scanPosition] = keywordChar;
} else {
break;
}
}
if(IsFoldingContainer(foldingElements, keyword) > 0) {
styler.SetLevel(
line,
styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
level++;
} else if(IsFoldingContainer(foldingElements, keyword) < 0) {
styler.SetLevel(line, styler.LevelAt(line));
level--;
}
}
if(
compact && (
currentState == SCE_MAGIK_BRACE_BLOCK ||
currentState == SCE_MAGIK_BRACKET_BLOCK ||
currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
if(c == '{' || c == '[' || c == '(') {
styler.SetLevel(
line,
styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
level++;
} else if(c == '}' || c == ']' || c == ')') {
styler.SetLevel(line, styler.LevelAt(line));
level--;
}
}
}
}
/**
* Injecting the module
*/
LexerModule lmMagikSF(
SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);

View File

@@ -0,0 +1,412 @@
/******************************************************************
* LexMarkdown.cxx
*
* A simple Markdown lexer for scintilla.
*
* Includes highlighting for some extra features from the
* Pandoc implementation; strikeout, using '#.' as a default
* ordered list item marker, and delimited code blocks.
*
* Limitations:
*
* Standard indented code blocks are not highlighted at all,
* as it would conflict with other indentation schemes. Use
* delimited code blocks for blanket highlighting of an
* entire code block. Embedded HTML is not highlighted either.
* Blanket HTML highlighting has issues, because some Markdown
* implementations allow Markdown markup inside of the HTML. Also,
* there is a following blank line issue that can't be ignored,
* explained in the next paragraph. Embedded HTML and code
* blocks would be better supported with language specific
* highlighting.
*
* The highlighting aims to accurately reflect correct syntax,
* but a few restrictions are relaxed. Delimited code blocks are
* highlighted, even if the line following the code block is not blank.
* Requiring a blank line after a block, breaks the highlighting
* in certain cases, because of the way Scintilla ends up calling
* the lexer.
*
* Written by Jon Strait - jstrait@moonloop.net
*
* The License.txt file describes the conditions under which this
* software may be distributed.
*
*****************************************************************/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsNewline(const int ch) {
return (ch == '\n' || ch == '\r');
}
// True if can follow ch down to the end with possibly trailing whitespace
static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
unsigned int i = 0;
while (sc.GetRelative(++i) == ch)
;
// Skip over whitespace
while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
++i;
if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
sc.Forward(i);
sc.ChangeState(state);
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
return true;
}
else return false;
}
// Set the state on text section from current to length characters,
// then set the rest until the newline to default, except for any characters matching token
static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
sc.SetState(state);
sc.Forward(length);
sc.SetState(SCE_MARKDOWN_DEFAULT);
sc.Forward();
bool started = false;
while (sc.More() && !IsNewline(sc.ch)) {
if (sc.ch == token && !started) {
sc.SetState(state);
started = true;
}
else if (sc.ch != token) {
sc.SetState(SCE_MARKDOWN_DEFAULT);
started = false;
}
sc.Forward();
}
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
// Does the previous line have more than spaces and tabs?
static bool HasPrevLineContent(StyleContext &sc) {
int i = 0;
// Go back to the previous newline
while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
;
while (--i + sc.currentPos) {
if (IsNewline(sc.GetRelative(i)))
break;
if (!IsASpaceOrTab(sc.GetRelative(i)))
return true;
}
return false;
}
static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
int c, count = 1;
unsigned int i = 0;
while (++i) {
c = sc.GetRelative(i);
if (c == sc.ch)
++count;
// hit a terminating character
else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
// Are we a valid HRULE
if ((IsNewline(c) || sc.currentPos + i == endPos) &&
count >= 3 && !HasPrevLineContent(sc)) {
sc.SetState(SCE_MARKDOWN_HRULE);
sc.Forward(i);
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
return true;
}
else {
sc.SetState(SCE_MARKDOWN_DEFAULT);
return false;
}
}
}
return false;
}
static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle,
WordList **, Accessor &styler) {
unsigned int endPos = startPos + length;
int precharCount = 0;
// Don't advance on a new loop iteration and retry at the same position.
// Useful in the corner case of having to start at the beginning file position
// in the default state.
bool freezeCursor = false;
StyleContext sc(startPos, length, initStyle, styler);
while (sc.More()) {
// Skip past escaped characters
if (sc.ch == '\\') {
sc.Forward();
continue;
}
// A blockquotes resets the line semantics
if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
// Conditional state-based actions
if (sc.state == SCE_MARKDOWN_CODE2) {
if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
else if (sc.state == SCE_MARKDOWN_CODE) {
if (sc.ch == '`' && sc.chPrev != ' ')
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
}
/* De-activated because it gets in the way of other valid indentation
* schemes, for example multiple paragraphs inside a list item.
// Code block
else if (sc.state == SCE_MARKDOWN_CODEBK) {
bool d = true;
if (IsNewline(sc.ch)) {
if (sc.chNext != '\t') {
for (int c = 1; c < 5; ++c) {
if (sc.GetRelative(c) != ' ')
d = false;
}
}
}
else if (sc.atLineStart) {
if (sc.ch != '\t' ) {
for (int i = 0; i < 4; ++i) {
if (sc.GetRelative(i) != ' ')
d = false;
}
}
}
if (!d)
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
*/
// Strong
else if (sc.state == SCE_MARKDOWN_STRONG1) {
if (sc.Match("**") && sc.chPrev != ' ') {
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
else if (sc.state == SCE_MARKDOWN_STRONG2) {
if (sc.Match("__") && sc.chPrev != ' ') {
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
// Emphasis
else if (sc.state == SCE_MARKDOWN_EM1) {
if (sc.ch == '*' && sc.chPrev != ' ')
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
}
else if (sc.state == SCE_MARKDOWN_EM2) {
if (sc.ch == '_' && sc.chPrev != ' ')
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
}
else if (sc.state == SCE_MARKDOWN_CODEBK) {
if (sc.atLineStart && sc.Match("~~~")) {
int i = 1;
while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
i++;
sc.Forward(i);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
else if (sc.state == SCE_MARKDOWN_STRIKEOUT) {
if (sc.Match("~~") && sc.chPrev != ' ') {
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) {
// Header
if (sc.Match("######"))
SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc);
else if (sc.Match("#####"))
SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc);
else if (sc.Match("####"))
SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc);
else if (sc.Match("###"))
SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc);
else if (sc.Match("##"))
SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc);
else if (sc.Match("#")) {
// Catch the special case of an unordered list
if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
precharCount = 0;
sc.SetState(SCE_MARKDOWN_PRECHAR);
}
else
SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc);
}
// Code block
else if (sc.Match("~~~")) {
if (!HasPrevLineContent(sc))
sc.SetState(SCE_MARKDOWN_CODEBK);
else
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
else if (sc.ch == '=') {
if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc))
;
else
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
else if (sc.ch == '-') {
if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc))
;
else {
precharCount = 0;
sc.SetState(SCE_MARKDOWN_PRECHAR);
}
}
else if (IsNewline(sc.ch))
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
else {
precharCount = 0;
sc.SetState(SCE_MARKDOWN_PRECHAR);
}
}
// The header lasts until the newline
else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) {
if (IsNewline(sc.ch))
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
// New state only within the initial whitespace
if (sc.state == SCE_MARKDOWN_PRECHAR) {
// Blockquote
if (sc.ch == '>' && precharCount < 5)
sc.SetState(SCE_MARKDOWN_BLOCKQUOTE);
/*
// Begin of code block
else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
sc.SetState(SCE_MARKDOWN_CODEBK);
*/
// HRule - Total of three or more hyphens, asterisks, or underscores
// on a line by themselves
else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
;
// Unordered list
else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) {
sc.SetState(SCE_MARKDOWN_ULIST_ITEM);
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
}
// Ordered list
else if (IsADigit(sc.ch)) {
int digitCount = 0;
while (IsADigit(sc.GetRelative(++digitCount)))
;
if (sc.GetRelative(digitCount) == '.' &&
IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
sc.Forward(digitCount + 1);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
// Alternate Ordered list
else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
else if (sc.ch != ' ' || precharCount > 2)
sc.SetState(SCE_MARKDOWN_DEFAULT);
else
++precharCount;
}
// New state anywhere in doc
if (sc.state == SCE_MARKDOWN_DEFAULT) {
if (sc.atLineStart && sc.ch == '#') {
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
freezeCursor = true;
}
// Links and Images
if (sc.Match("![") || sc.ch == '[') {
int i = 0, j = 0, k = 0;
int len = endPos - sc.currentPos;
while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
;
if (sc.GetRelative(i) == ']') {
j = i;
if (sc.GetRelative(++i) == '(') {
while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\'))
;
if (sc.GetRelative(i) == ')')
k = i;
}
else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
;
if (sc.GetRelative(i) == ']')
k = i;
}
}
// At least a link text
if (j) {
sc.SetState(SCE_MARKDOWN_LINK);
sc.Forward(j);
// Also has a URL or reference portion
if (k)
sc.Forward(k - j);
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
}
}
// Code - also a special case for alternate inside spacing
if (sc.Match("``") && sc.GetRelative(3) != ' ') {
sc.SetState(SCE_MARKDOWN_CODE2);
sc.Forward();
}
else if (sc.ch == '`' && sc.chNext != ' ') {
sc.SetState(SCE_MARKDOWN_CODE);
}
// Strong
else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
sc.SetState(SCE_MARKDOWN_STRONG1);
sc.Forward();
}
else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
sc.SetState(SCE_MARKDOWN_STRONG2);
sc.Forward();
}
// Emphasis
else if (sc.ch == '*' && sc.chNext != ' ')
sc.SetState(SCE_MARKDOWN_EM1);
else if (sc.ch == '_' && sc.chNext != ' ')
sc.SetState(SCE_MARKDOWN_EM2);
// Strikeout
else if (sc.Match("~~") && sc.GetRelative(2) != ' ') {
sc.SetState(SCE_MARKDOWN_STRIKEOUT);
sc.Forward();
}
// Beginning of line
else if (IsNewline(sc.ch))
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
// Advance if not holding back the cursor for this iteration.
if (!freezeCursor)
sc.Forward();
freezeCursor = false;
}
sc.Complete();
}
LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown");

View File

@@ -0,0 +1,236 @@
// Scintilla source code edit control
/** @file LexMatlab.cxx
** Lexer for Matlab.
** Written by Jos<6F> Fonseca
**
** Changes by Christoph Dalitz 2003/12/04:
** - added support for Octave
** - Strings can now be included both in single or double quotes
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static bool IsMatlabCommentChar(int c) {
return (c == '%') ;
}
static bool IsOctaveCommentChar(int c) {
return (c == '%' || c == '#') ;
}
static bool IsMatlabComment(Accessor &styler, int pos, int len) {
return len > 0 && IsMatlabCommentChar(styler[pos]) ;
}
static bool IsOctaveComment(Accessor &styler, int pos, int len) {
return len > 0 && IsOctaveCommentChar(styler[pos]) ;
}
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static void ColouriseMatlabOctaveDoc(
unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler,
bool (*IsCommentChar)(int)) {
WordList &keywords = *keywordlists[0];
styler.StartAt(startPos);
bool transpose = false;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
if (sc.state == SCE_MATLAB_OPERATOR) {
if (sc.chPrev == '.') {
if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
transpose = false;
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
transpose = true;
} else {
sc.SetState(SCE_MATLAB_DEFAULT);
}
} else {
sc.SetState(SCE_MATLAB_DEFAULT);
}
} else if (sc.state == SCE_MATLAB_KEYWORD) {
if (!isalnum(sc.ch) && sc.ch != '_') {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords.InList(s)) {
sc.SetState(SCE_MATLAB_DEFAULT);
transpose = false;
} else {
sc.ChangeState(SCE_MATLAB_IDENTIFIER);
sc.SetState(SCE_MATLAB_DEFAULT);
transpose = true;
}
}
} else if (sc.state == SCE_MATLAB_NUMBER) {
if (!isdigit(sc.ch) && sc.ch != '.'
&& !(sc.ch == 'e' || sc.ch == 'E')
&& !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
sc.SetState(SCE_MATLAB_DEFAULT);
transpose = true;
}
} else if (sc.state == SCE_MATLAB_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
} else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
if (sc.atLineEnd) {
sc.SetState(SCE_MATLAB_DEFAULT);
transpose = false;
}
}
if (sc.state == SCE_MATLAB_DEFAULT) {
if (IsCommentChar(sc.ch)) {
sc.SetState(SCE_MATLAB_COMMENT);
} else if (sc.ch == '!' && sc.chNext != '=' ) {
sc.SetState(SCE_MATLAB_COMMAND);
} else if (sc.ch == '\'') {
if (transpose) {
sc.SetState(SCE_MATLAB_OPERATOR);
} else {
sc.SetState(SCE_MATLAB_STRING);
}
} else if (sc.ch == '"') {
sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
} else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
sc.SetState(SCE_MATLAB_NUMBER);
} else if (isalpha(sc.ch)) {
sc.SetState(SCE_MATLAB_KEYWORD);
} else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
if (sc.ch == ')' || sc.ch == ']') {
transpose = true;
} else {
transpose = false;
}
sc.SetState(SCE_MATLAB_OPERATOR);
} else {
transpose = false;
}
}
}
sc.Complete();
}
static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
}
static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
}
static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler,
bool (*IsComment)(Accessor&, int, int)) {
int endPos = startPos + length;
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
}
int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
char chNext = styler[startPos];
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
int lev = indentCurrent;
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
// Line after is blank so check the next - maybe should continue further?
int spaceFlags2 = 0;
int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
}
}
indentCurrent = indentNext;
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
}
}
}
static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
}
static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
}
static const char * const matlabWordListDesc[] = {
"Keywords",
0
};
static const char * const octaveWordListDesc[] = {
"Keywords",
0
};
LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);

View File

@@ -0,0 +1,399 @@
// Scintilla source code edit control
// File: LexMetapost.cxx - general context conformant metapost coloring scheme
// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
// Version: September 28, 2003
// Modified by instanton: July 10, 2007
// Folding based on keywordlists[]
// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// This lexer is derived from the one written for the texwork environment (1999++) which in
// turn is inspired on texedit (1991++) which finds its roots in wdt (1986).
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "StyleContext.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// val SCE_METAPOST_DEFAULT = 0
// val SCE_METAPOST_SPECIAL = 1
// val SCE_METAPOST_GROUP = 2
// val SCE_METAPOST_SYMBOL = 3
// val SCE_METAPOST_COMMAND = 4
// val SCE_METAPOST_TEXT = 5
// Definitions in SciTEGlobal.properties:
//
// Metapost Highlighting
//
// # Default
// style.metapost.0=fore:#7F7F00
// # Special
// style.metapost.1=fore:#007F7F
// # Group
// style.metapost.2=fore:#880000
// # Symbol
// style.metapost.3=fore:#7F7F00
// # Command
// style.metapost.4=fore:#008800
// # Text
// style.metapost.5=fore:#000000
// lexer.tex.comment.process=0
// Auxiliary functions:
static inline bool endOfLine(Accessor &styler, unsigned int i) {
return
(styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
}
static inline bool isMETAPOSTcomment(int ch) {
return
(ch == '%') ;
}
static inline bool isMETAPOSTone(int ch) {
return
(ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') ||
(ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') ||
(ch == '{') || (ch == '}') || (ch == '\'') || (ch == '\"') ;
}
static inline bool isMETAPOSTtwo(int ch) {
return
(ch == ';') || (ch == '$') || (ch == '@') || (ch == '#');
}
static inline bool isMETAPOSTthree(int ch) {
return
(ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') ||
(ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') ||
(ch == '!') || (ch == '?') || (ch == '^') || (ch == '&') ||
(ch == '%') ;
}
static inline bool isMETAPOSTidentifier(int ch) {
return
((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
(ch == '_') ;
}
static inline bool isMETAPOSTnumber(int ch) {
return
(ch >= '0') && (ch <= '9') ;
}
static inline bool isMETAPOSTstring(int ch) {
return
(ch == '\"') ;
}
static inline bool isMETAPOSTcolon(int ch) {
return
(ch == ':') ;
}
static inline bool isMETAPOSTequal(int ch) {
return
(ch == '=') ;
}
static int CheckMETAPOSTInterface(
unsigned int startPos,
int length,
Accessor &styler,
int defaultInterface) {
char lineBuffer[1024] ;
unsigned int linePos = 0 ;
// some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)...
if (styler.SafeGetCharAt(0) == '%') {
for (unsigned int i = 0; i < startPos + length; i++) {
lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
lineBuffer[linePos] = '\0';
if (strstr(lineBuffer, "interface=none")) {
return 0 ;
} else if (strstr(lineBuffer, "interface=metapost") || strstr(lineBuffer, "interface=mp")) {
return 1 ;
} else if (strstr(lineBuffer, "interface=metafun")) {
return 2 ;
} else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) {
// better would be to limit the search to just one line
return 2 ;
} else {
return defaultInterface ;
}
}
}
}
return defaultInterface ;
}
static void ColouriseMETAPOSTDoc(
unsigned int startPos,
int length,
int,
WordList *keywordlists[],
Accessor &styler) {
styler.StartAt(startPos) ;
styler.StartSegment(startPos) ;
bool processComment = styler.GetPropertyInt("lexer.metapost.comment.process", 0) == 1 ;
int defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ;
int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
// 0 no keyword highlighting
// 1 metapost keyword hightlighting
// 2+ metafun keyword hightlighting
int extraInterface = 0 ;
if (currentInterface != 0) {
extraInterface = currentInterface ;
}
WordList &keywords = *keywordlists[0] ;
WordList &keywords2 = *keywordlists[extraInterface-1] ;
StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;
char key[100] ;
bool inTeX = false ;
bool inComment = false ;
bool inString = false ;
bool inClause = false ;
bool going = sc.More() ; // needed because of a fuzzy end of file state
for (; going; sc.Forward()) {
if (! sc.More()) { going = false ; } // we need to go one behind the end of text
if (inClause) {
sc.SetState(SCE_METAPOST_TEXT) ;
inClause = false ;
}
if (inComment) {
if (sc.atLineEnd) {
sc.SetState(SCE_METAPOST_TEXT) ;
inTeX = false ;
inComment = false ;
inClause = false ;
inString = false ; // not correct but we want to stimulate one-lines
}
} else if (inString) {
if (isMETAPOSTstring(sc.ch)) {
sc.SetState(SCE_METAPOST_SPECIAL) ;
sc.ForwardSetState(SCE_METAPOST_TEXT) ;
inString = false ;
} else if (sc.atLineEnd) {
sc.SetState(SCE_METAPOST_TEXT) ;
inTeX = false ;
inComment = false ;
inClause = false ;
inString = false ; // not correct but we want to stimulate one-lines
}
} else {
if ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) {
if (sc.state == SCE_METAPOST_COMMAND) {
sc.GetCurrent(key, sizeof(key)) ;
if ((strcmp(key,"btex") == 0) || (strcmp(key,"verbatimtex") == 0)) {
sc.ChangeState(SCE_METAPOST_GROUP) ;
inTeX = true ;
} else if (inTeX) {
if (strcmp(key,"etex") == 0) {
sc.ChangeState(SCE_METAPOST_GROUP) ;
inTeX = false ;
} else {
sc.ChangeState(SCE_METAPOST_TEXT) ;
}
} else {
if (keywords && keywords.InList(key)) {
sc.ChangeState(SCE_METAPOST_COMMAND) ;
} else if (keywords2 && keywords2.InList(key)) {
sc.ChangeState(SCE_METAPOST_EXTRA) ;
} else {
sc.ChangeState(SCE_METAPOST_TEXT) ;
}
}
}
}
if (isMETAPOSTcomment(sc.ch)) {
if (! inTeX) {
sc.SetState(SCE_METAPOST_SYMBOL) ;
sc.ForwardSetState(SCE_METAPOST_DEFAULT) ;
inComment = ! processComment ;
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
} else if (isMETAPOSTstring(sc.ch)) {
if (! inTeX) {
sc.SetState(SCE_METAPOST_SPECIAL) ;
if (! isMETAPOSTstring(sc.chNext)) {
sc.ForwardSetState(SCE_METAPOST_TEXT) ;
}
inString = true ;
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
} else if (isMETAPOSTcolon(sc.ch)) {
if (! inTeX) {
if (! isMETAPOSTequal(sc.chNext)) {
sc.SetState(SCE_METAPOST_COMMAND) ;
inClause = true ;
} else {
sc.SetState(SCE_METAPOST_SPECIAL) ;
}
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
} else if (isMETAPOSTone(sc.ch)) {
if (! inTeX) {
sc.SetState(SCE_METAPOST_SPECIAL) ;
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
} else if (isMETAPOSTtwo(sc.ch)) {
if (! inTeX) {
sc.SetState(SCE_METAPOST_GROUP) ;
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
} else if (isMETAPOSTthree(sc.ch)) {
if (! inTeX) {
sc.SetState(SCE_METAPOST_SYMBOL) ;
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
} else if (isMETAPOSTidentifier(sc.ch)) {
if (sc.state != SCE_METAPOST_COMMAND) {
sc.SetState(SCE_METAPOST_TEXT) ;
sc.ChangeState(SCE_METAPOST_COMMAND) ;
}
} else if (isMETAPOSTnumber(sc.ch)) {
// rather redundant since for the moment we don't handle numbers
sc.SetState(SCE_METAPOST_TEXT) ;
} else if (sc.atLineEnd) {
sc.SetState(SCE_METAPOST_TEXT) ;
inTeX = false ;
inComment = false ;
inClause = false ;
inString = false ;
} else {
sc.SetState(SCE_METAPOST_TEXT) ;
}
}
}
sc.Complete();
}
// Hooks info the system:
static const char * const metapostWordListDesc[] = {
"MetaPost",
"MetaFun",
0
} ;
static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {
WordList& keywordsStart=*keywordlists[3];
WordList& keywordsStop1=*keywordlists[4];
if (keywordsStart.InList(s)) {return 1;}
else if (keywordsStop1.InList(s)) {return -1;}
return 0;
}
static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
{
int length=0;
char ch=styler.SafeGetCharAt(pos);
*word=0;
while(isMETAPOSTidentifier(ch) && isalpha(ch) && length<100){
word[length]=ch;
length++;
ch=styler.SafeGetCharAt(pos+length);
}
word[length]=0;
return length;
}
static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler)
{
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos+length;
int visibleChars=0;
int lineCurrent=styler.GetLine(startPos);
int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent=levelPrev;
char chNext=styler[startPos];
char buffer[100]="";
for (unsigned int i=startPos; i < endPos; i++) {
char ch=chNext;
chNext=styler.SafeGetCharAt(i+1);
char chPrev=styler.SafeGetCharAt(i-1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if(i==0 || chPrev == '\r' || chPrev=='\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$')
{
ParseMetapostWord(i, styler, buffer);
levelCurrent += classifyFoldPointMetapost(buffer,keywordlists);
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
LexerModule lmMETAPOST(SCLEX_METAPOST, ColouriseMETAPOSTDoc, "metapost", FoldMetapostDoc, metapostWordListDesc);

View File

@@ -0,0 +1,518 @@
/**
* Scintilla source code edit control
* @file LexMySQL.cxx
* Lexer for MySQL
*
* Improved by Mike Lischke <mike.lischke@sun.com>
* Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com>
* Original work by Neil Hodgson <neilh@scintilla.org>
* Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
* The License.txt file describes the conditions under which this software may be distributed.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAWordStart(int ch) {
return (ch < 0x80) && (isalpha(ch) || ch == '_');
}
static inline bool IsADoxygenChar(int ch) {
return (islower(ch) || ch == '$' || ch == '@' ||
ch == '\\' || ch == '&' || ch == '<' ||
ch == '>' || ch == '#' || ch == '{' ||
ch == '}' || ch == '[' || ch == ']');
}
static inline bool IsANumberChar(int ch) {
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
return (ch < 0x80) &&
(isdigit(ch) || toupper(ch) == 'E' ||
ch == '.' || ch == '-' || ch == '+');
}
//--------------------------------------------------------------------------------------------------
/**
* Check if the current content context represent a keyword and set the context state if so.
*/
static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[])
{
int length = sc.LengthCurrent() + 1; // +1 for the next char
char* s = new char[length];
sc.GetCurrentLowered(s, length);
if (keywordlists[0]->InList(s))
sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
else
if (keywordlists[1]->InList(s))
sc.ChangeState(SCE_MYSQL_KEYWORD);
else
if (keywordlists[2]->InList(s))
sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
else
if (keywordlists[3]->InList(s))
sc.ChangeState(SCE_MYSQL_FUNCTION);
else
if (keywordlists[5]->InList(s))
sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
else
if (keywordlists[6]->InList(s))
sc.ChangeState(SCE_MYSQL_USER1);
else
if (keywordlists[7]->InList(s))
sc.ChangeState(SCE_MYSQL_USER2);
else
if (keywordlists[8]->InList(s))
sc.ChangeState(SCE_MYSQL_USER3);
delete [] s;
}
//--------------------------------------------------------------------------------------------------
static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler)
{
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
// Determine if the current state should terminate.
switch (sc.state)
{
case SCE_MYSQL_OPERATOR:
sc.SetState(SCE_MYSQL_DEFAULT);
break;
case SCE_MYSQL_NUMBER:
// We stop the number definition on non-numerical non-dot non-eE non-sign char.
if (!IsANumberChar(sc.ch))
sc.SetState(SCE_MYSQL_DEFAULT);
break;
case SCE_MYSQL_IDENTIFIER:
// Switch from identifier to keyword state and open a new state for the new char.
if (!IsAWordChar(sc.ch))
{
CheckForKeyword(sc, keywordlists);
// Additional check for function keywords needed.
// A function name must be followed by an opening parenthesis.
if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
sc.ChangeState(SCE_MYSQL_DEFAULT);
sc.SetState(SCE_MYSQL_DEFAULT);
}
break;
case SCE_MYSQL_VARIABLE:
if (!IsAWordChar(sc.ch))
sc.SetState(SCE_MYSQL_DEFAULT);
break;
case SCE_MYSQL_SYSTEMVARIABLE:
if (!IsAWordChar(sc.ch))
{
int length = sc.LengthCurrent() + 1;
char* s = new char[length];
sc.GetCurrentLowered(s, length);
// Check for known system variables here.
if (keywordlists[4]->InList(&s[2]))
sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
delete [] s;
sc.SetState(SCE_MYSQL_DEFAULT);
}
break;
case SCE_MYSQL_QUOTEDIDENTIFIER:
if (sc.ch == '`')
{
if (sc.chNext == '`')
sc.Forward(); // Ignore it
else
sc.ForwardSetState(SCE_MYSQL_DEFAULT);
}
break;
case SCE_MYSQL_COMMENT:
case SCE_MYSQL_HIDDENCOMMAND:
if (sc.Match('*', '/'))
{
sc.Forward();
sc.ForwardSetState(SCE_MYSQL_DEFAULT);
}
break;
case SCE_MYSQL_COMMENTLINE:
if (sc.atLineStart)
sc.SetState(SCE_MYSQL_DEFAULT);
break;
case SCE_MYSQL_SQSTRING:
if (sc.ch == '\\')
sc.Forward(); // Escape sequence
else
if (sc.ch == '\'')
{
// End of single quoted string reached?
if (sc.chNext == '\'')
sc.Forward();
else
sc.ForwardSetState(SCE_MYSQL_DEFAULT);
}
break;
case SCE_MYSQL_DQSTRING:
if (sc.ch == '\\')
sc.Forward(); // Escape sequence
else
if (sc.ch == '\"')
{
// End of single quoted string reached?
if (sc.chNext == '\"')
sc.Forward();
else
sc.ForwardSetState(SCE_MYSQL_DEFAULT);
}
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_MYSQL_DEFAULT)
{
switch (sc.ch)
{
case '@':
if (sc.chNext == '@')
{
sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
sc.Forward(2); // Skip past @@.
}
else
if (IsAWordStart(sc.ch))
{
sc.SetState(SCE_MYSQL_VARIABLE);
sc.Forward(); // Skip past @.
}
else
sc.SetState(SCE_MYSQL_OPERATOR);
break;
case '`':
sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
break;
case '#':
sc.SetState(SCE_MYSQL_COMMENTLINE);
break;
case '\'':
sc.SetState(SCE_MYSQL_SQSTRING);
break;
case '\"':
sc.SetState(SCE_MYSQL_DQSTRING);
break;
default:
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
sc.SetState(SCE_MYSQL_NUMBER);
else
if (IsAWordStart(sc.ch))
sc.SetState(SCE_MYSQL_IDENTIFIER);
else
if (sc.Match('/', '*'))
{
sc.SetState(SCE_MYSQL_COMMENT);
// Skip comment introducer and check for hidden command.
sc.Forward(2);
if (sc.ch == '!')
{
sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
sc.Forward();
}
}
else
if (sc.Match("--"))
{
// Special MySQL single line comment.
sc.SetState(SCE_MYSQL_COMMENTLINE);
sc.Forward(2);
// Check the third character too. It must be a space or EOL.
if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
sc.ChangeState(SCE_MYSQL_OPERATOR);
}
else
if (isoperator(static_cast<char>(sc.ch)))
sc.SetState(SCE_MYSQL_OPERATOR);
}
}
}
// Do a final check for keywords if we currently have an identifier, to highlight them
// also at the end of a line.
if (sc.state == SCE_MYSQL_IDENTIFIER)
{
CheckForKeyword(sc, keywordlists);
// Additional check for function keywords needed.
// A function name must be followed by an opening parenthesis.
if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
sc.ChangeState(SCE_MYSQL_DEFAULT);
}
sc.Complete();
}
//--------------------------------------------------------------------------------------------------
/**
* Helper function to determine if we have a foldable comment currently.
*/
static bool IsStreamCommentStyle(int style)
{
return style == SCE_MYSQL_COMMENT;
}
//--------------------------------------------------------------------------------------------------
/**
* Code copied from StyleContext and modified to work here. Should go into Accessor as a
* companion to Match()...
*/
bool MatchIgnoreCase(Accessor &styler, int currentPos, const char *s)
{
for (int n = 0; *s; n++)
{
if (*s != tolower(styler.SafeGetCharAt(currentPos + n)))
return false;
s++;
}
return true;
}
//--------------------------------------------------------------------------------------------------
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment.
static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)
{
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
int levelNext = levelCurrent;
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
bool endFound = false;
bool whenFound = false;
bool elseFound = false;
char nextChar = styler.SafeGetCharAt(startPos);
for (unsigned int i = startPos; length > 0; i++, length--)
{
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
char currentChar = nextChar;
nextChar = styler.SafeGetCharAt(i + 1);
bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
switch (style)
{
case SCE_MYSQL_COMMENT:
if (foldComment)
{
// Multiline comment style /* .. */.
if (IsStreamCommentStyle(style))
{
// Increase level if we just start a foldable comment.
if (!IsStreamCommentStyle(stylePrev))
levelNext++;
else
// If we are in the middle of a foldable comment check if it ends now.
// Don't end at the line end, though.
if (!IsStreamCommentStyle(styleNext) && !atEOL)
levelNext--;
}
}
break;
case SCE_MYSQL_COMMENTLINE:
if (foldComment)
{
// Not really a standard, but we add support for single line comments
// with special curly braces syntax as foldable comments too.
// MySQL needs -- comments to be followed by space or control char
if (styler.Match(i, "--"))
{
char chNext2 = styler.SafeGetCharAt(i + 2);
char chNext3 = styler.SafeGetCharAt(i + 3);
if (chNext2 == '{' || chNext3 == '{')
levelNext++;
else
if (chNext2 == '}' || chNext3 == '}')
levelNext--;
}
}
break;
case SCE_MYSQL_HIDDENCOMMAND:
if (style != stylePrev)
levelNext++;
else
if (style != styleNext)
levelNext--;
break;
case SCE_MYSQL_OPERATOR:
if (currentChar == '(')
levelNext++;
else
if (currentChar == ')')
levelNext--;
break;
case SCE_MYSQL_MAJORKEYWORD:
case SCE_MYSQL_KEYWORD:
case SCE_MYSQL_FUNCTION:
case SCE_MYSQL_PROCEDUREKEYWORD:
// Reserved and other keywords.
if (style != stylePrev)
{
bool beginFound = MatchIgnoreCase(styler, i, "begin");
bool ifFound = MatchIgnoreCase(styler, i, "if");
bool thenFound = MatchIgnoreCase(styler, i, "then");
bool whileFound = MatchIgnoreCase(styler, i, "while");
bool loopFound = MatchIgnoreCase(styler, i, "loop");
bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
{
endFound = false;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
// Note that "else" is special here. It may or may not be followed by an "if .. then",
// but in any case the level stays the same. When followed by an "if .. then" the level
// will be increased later, if not, then at eol.
}
else
if (!foldOnlyBegin && MatchIgnoreCase(styler, i, "else"))
{
levelNext--;
elseFound = true;
}
else
if (!foldOnlyBegin && thenFound)
{
if (whenFound)
whenFound = false;
else
levelNext++;
}
else
if (ifFound)
elseFound = false;
else
if (MatchIgnoreCase(styler, i, "when"))
whenFound = true;
else
{
if (beginFound)
levelNext++;
else
if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
{
if (endFound)
endFound = false;
else
levelNext++;
}
else
if (MatchIgnoreCase(styler, i, "end"))
{
// Multiple "end" in a row are counted multiple times!
if (endFound)
{
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
endFound = true;
whenFound = false;
}
}
}
break;
}
// Handle the case of a trailing end without an if / while etc, as in the case of a begin.
if (endFound)
{
endFound = false;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
if (atEOL)
{
if (elseFound)
{
levelNext++;
elseFound = false;
}
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
levelCurrent = levelNext;
visibleChars = 0;
endFound = false;
whenFound = false;
}
if (!isspacechar(currentChar))
visibleChars++;
}
}
//--------------------------------------------------------------------------------------------------
static const char * const mysqlWordListDesc[] = {
"Major Keywords",
"Keywords",
"Database Objects",
"Functions",
"System Variables",
"Procedure keywords",
"User Keywords 1",
"User Keywords 2",
"User Keywords 3",
0
};
LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc);

View File

@@ -0,0 +1,430 @@
// Scintilla source code edit control
// Nimrod lexer
// (c) 2009 Andreas Rumpf
/** @file LexNimrod.cxx
** Lexer for Nimrod.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(int ch) {
return (ch >= 0x80) || isalnum(ch) || ch == '_';
}
static int tillEndOfTripleQuote(Accessor &styler, int pos, int max) {
/* search for """ */
for (;;) {
if (styler.SafeGetCharAt(pos, '\0') == '\0') return pos;
if (pos >= max) return pos;
if (styler.Match(pos, "\"\"\"")) {
return pos + 2;
}
pos++;
}
}
#define CR 13 /* use both because Scite allows changing the line ending */
#define LF 10
static bool inline isNewLine(int ch) {
return ch == CR || ch == LF;
}
static int scanString(Accessor &styler, int pos, int max, bool rawMode) {
for (;;) {
if (pos >= max) return pos;
char ch = styler.SafeGetCharAt(pos, '\0');
if (ch == CR || ch == LF || ch == '\0') return pos;
if (ch == '"') return pos;
if (ch == '\\' && !rawMode) {
pos += 2;
} else {
pos++;
}
}
}
static int scanChar(Accessor &styler, int pos, int max) {
for (;;) {
if (pos >= max) return pos;
char ch = styler.SafeGetCharAt(pos, '\0');
if (ch == CR || ch == LF || ch == '\0') return pos;
if (ch == '\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\0')) )
return pos;
if (ch == '\\') {
pos += 2;
} else {
pos++;
}
}
}
static int scanIdent(Accessor &styler, int pos, WordList &keywords) {
char buf[100]; /* copy to lowercase and ignore underscores */
int i = 0;
for (;;) {
char ch = styler.SafeGetCharAt(pos, '\0');
if (!IsAWordChar(ch)) break;
if (ch != '_' && i < ((int)sizeof(buf))-1) {
buf[i] = static_cast<char>(tolower(ch));
i++;
}
pos++;
}
buf[i] = '\0';
/* look for keyword */
if (keywords.InList(buf)) {
styler.ColourTo(pos-1, SCE_P_WORD);
} else {
styler.ColourTo(pos-1, SCE_P_IDENTIFIER);
}
return pos;
}
static int scanNumber(Accessor &styler, int pos) {
char ch, ch2;
ch = styler.SafeGetCharAt(pos, '\0');
ch2 = styler.SafeGetCharAt(pos+1, '\0');
if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) {
/* binary number: */
pos += 2;
for (;;) {
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
else break;
}
} else if (ch == '0' &&
(ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
/* octal number: */
pos += 2;
for (;;) {
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos;
else break;
}
} else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) {
/* hexadecimal number: */
pos += 2;
for (;;) {
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '_' || (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'f')
|| (ch >= 'A' && ch <= 'F')) ++pos;
else break;
}
} else {
// skip decimal part:
for (;;) {
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
else break;
}
ch2 = styler.SafeGetCharAt(pos+1, '\0');
if (ch == '.' && ch2 >= '0' && ch2 <= '9') {
++pos; // skip '.'
for (;;) {
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
else break;
}
}
if (ch == 'e' || ch == 'E') {
++pos;
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '-' || ch == '+') ++pos;
for (;;) {
ch = styler.SafeGetCharAt(pos, '\0');
if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
else break;
}
}
}
if (ch == '\'') {
/* a type suffix: */
pos++;
for (;;) {
ch = styler.SafeGetCharAt(pos);
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')
|| (ch >= 'a' && ch <= 'z') || ch == '_') ++pos;
else break;
}
}
styler.ColourTo(pos-1, SCE_P_NUMBER);
return pos;
}
/* rewritten from scratch, because I couldn't get rid of the bugs...
(A character based approach sucks!)
*/
static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
int pos = startPos;
int max = startPos + length;
char ch;
WordList &keywords = *keywordlists[0];
styler.StartAt(startPos);
styler.StartSegment(startPos);
switch (initStyle) {
/* check where we are: */
case SCE_P_TRIPLEDOUBLE:
pos = tillEndOfTripleQuote(styler, pos, max);
styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
pos++;
break;
default: /* nothing to do: */
break;
}
while (pos < max) {
ch = styler.SafeGetCharAt(pos, '\0');
switch (ch) {
case '\0': return;
case '#': {
bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
if (doccomment)
styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
else
styler.ColourTo(pos, SCE_P_COMMENTLINE);
} break;
case 'r': case 'R': {
if (styler.SafeGetCharAt(pos+1) == '"') {
pos = scanString(styler, pos+2, max, true);
styler.ColourTo(pos, SCE_P_STRING);
pos++;
} else {
pos = scanIdent(styler, pos, keywords);
}
} break;
case '"':
if (styler.Match(pos+1, "\"\"")) {
pos = tillEndOfTripleQuote(styler, pos+3, max);
styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
} else {
pos = scanString(styler, pos+1, max, false);
styler.ColourTo(pos, SCE_P_STRING);
}
pos++;
break;
case '\'':
pos = scanChar(styler, pos+1, max);
styler.ColourTo(pos, SCE_P_CHARACTER);
pos++;
break;
default: // identifers, numbers, operators, whitespace
if (ch >= '0' && ch <= '9') {
pos = scanNumber(styler, pos);
} else if (IsAWordChar(ch)) {
pos = scanIdent(styler, pos, keywords);
} else if (ch == '`') {
pos++;
while (pos < max) {
ch = styler.SafeGetCharAt(pos, LF);
if (ch == '`') {
++pos;
break;
}
if (ch == CR || ch == LF) break;
++pos;
}
styler.ColourTo(pos, SCE_P_IDENTIFIER);
} else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", ch)) {
styler.ColourTo(pos, SCE_P_OPERATOR);
pos++;
} else {
styler.ColourTo(pos, SCE_P_DEFAULT);
pos++;
}
break;
}
}
}
static bool IsCommentLine(int line, Accessor &styler) {
int pos = styler.LineStart(line);
int eol_pos = styler.LineStart(line + 1) - 1;
for (int i = pos; i < eol_pos; i++) {
char ch = styler[i];
if (ch == '#')
return true;
else if (ch != ' ' && ch != '\t')
return false;
}
return false;
}
static bool IsQuoteLine(int line, Accessor &styler) {
int style = styler.StyleAt(styler.LineStart(line)) & 31;
return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
}
static void FoldNimrodDoc(unsigned int startPos, int length,
int /*initStyle - unused*/,
WordList *[], Accessor &styler) {
const int maxPos = startPos + length;
const int maxLines = styler.GetLine(maxPos - 1); // Requested last line
const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
const bool foldComment = styler.GetPropertyInt("fold.comment.nimrod") != 0;
const bool foldQuotes = styler.GetPropertyInt("fold.quotes.nimrod") != 0;
// Backtrack to previous non-blank line so we can determine indent level
// for any white space lines (needed esp. within triple quoted strings)
// and so we can fix any preceding fold level (which is why we go back
// at least one line in all cases)
int spaceFlags = 0;
int lineCurrent = styler.GetLine(startPos);
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
while (lineCurrent > 0) {
lineCurrent--;
indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
(!IsCommentLine(lineCurrent, styler)) &&
(!IsQuoteLine(lineCurrent, styler)))
break;
}
int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
// Set up initial loop state
startPos = styler.LineStart(lineCurrent);
int prev_state = SCE_P_DEFAULT & 31;
if (lineCurrent >= 1)
prev_state = styler.StyleAt(startPos - 1) & 31;
int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||
(prev_state == SCE_P_TRIPLEDOUBLE));
int prevComment = 0;
if (lineCurrent >= 1)
prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
// Process all characters to end of requested range or end of any triple quote
// or comment that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote or comment at end).
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||
prevQuote || prevComment)) {
// Gather info
int lev = indentCurrent;
int lineNext = lineCurrent + 1;
int indentNext = indentCurrent;
int quote = false;
if (lineNext <= docLines) {
// Information about next line is only available if not at end of document
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
}
const int quote_start = (quote && !prevQuote);
const int quote_continue = (quote && prevQuote);
const int comment = foldComment && IsCommentLine(lineCurrent, styler);
const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
IsCommentLine(lineNext, styler) &&
(lev > SC_FOLDLEVELBASE));
const int comment_continue = (comment && prevComment);
if ((!quote || !prevQuote) && !comment)
indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
if (quote)
indentNext = indentCurrentLevel;
if (indentNext & SC_FOLDLEVELWHITEFLAG)
indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
if (quote_start) {
// Place fold point at start of triple quoted string
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (quote_continue || prevQuote) {
// Add level to rest of lines in the string
lev = lev + 1;
} else if (comment_start) {
// Place fold point at start of a block of comments
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (comment_continue) {
// Add level to rest of lines in the block
lev = lev + 1;
}
// Skip past any blank lines for next indent level info; we skip also
// comments (all comments, not just those starting in column 0)
// which effectively folds them into surrounding code rather
// than screwing up folding.
while (!quote &&
(lineNext < docLines) &&
((indentNext & SC_FOLDLEVELWHITEFLAG) ||
(lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
lineNext++;
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
}
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
const int levelBeforeComments =
Platform::Maximum(indentCurrentLevel,levelAfterComments);
// Now set all the indent levels on the lines we skipped
// Do this from end to start. Once we encounter one line
// which is indented more than the line after the end of
// the comment-block, use the level of the block before
int skipLine = lineNext;
int skipLevel = levelAfterComments;
while (--skipLine > lineCurrent) {
int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
skipLevel = levelBeforeComments;
int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
styler.SetLevel(skipLine, skipLevel | whiteFlag);
}
// Set fold header on non-quote/non-comment line
if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <
(indentNext & SC_FOLDLEVELNUMBERMASK))
lev |= SC_FOLDLEVELHEADERFLAG;
}
// Keep track of triple quote and block comment state of previous line
prevQuote = quote;
prevComment = comment_start || comment_continue;
// Set fold level for this line and move to next line
styler.SetLevel(lineCurrent, lev);
indentCurrent = indentNext;
lineCurrent = lineNext;
}
// NOTE: Cannot set level of last line here because indentCurrent doesn't have
// header flag set; the loop above is crafted to take care of this case!
//styler.SetLevel(lineCurrent, indentCurrent);
}
static const char * const nimrodWordListDesc[] = {
"Keywords",
0
};
LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, "nimrod", FoldNimrodDoc,
nimrodWordListDesc);

View File

@@ -0,0 +1,655 @@
// Scintilla source code edit control
/** @file LexNsis.cxx
** Lexer for NSIS
**/
// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
// Last Updated: 03/13/2005
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/*
// located in SciLexer.h
#define SCLEX_NSIS 43
#define SCE_NSIS_DEFAULT 0
#define SCE_NSIS_COMMENT 1
#define SCE_NSIS_STRINGDQ 2
#define SCE_NSIS_STRINGLQ 3
#define SCE_NSIS_STRINGRQ 4
#define SCE_NSIS_FUNCTION 5
#define SCE_NSIS_VARIABLE 6
#define SCE_NSIS_LABEL 7
#define SCE_NSIS_USERDEFINED 8
#define SCE_NSIS_SECTIONDEF 9
#define SCE_NSIS_SUBSECTIONDEF 10
#define SCE_NSIS_IFDEFINEDEF 11
#define SCE_NSIS_MACRODEF 12
#define SCE_NSIS_STRINGVAR 13
#define SCE_NSIS_NUMBER 14
// ADDED for Scintilla v1.63
#define SCE_NSIS_SECTIONGROUP 15
#define SCE_NSIS_PAGEEX 16
#define SCE_NSIS_FUNCTIONDEF 17
#define SCE_NSIS_COMMENTBOX 18
*/
static bool isNsisNumber(char ch)
{
return (ch >= '0' && ch <= '9');
}
static bool isNsisChar(char ch)
{
return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static bool isNsisLetter(char ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
{
int nNextLine = -1;
for( unsigned int i = start; i < end; i++ )
{
char cNext = styler.SafeGetCharAt( i );
if( cNext == '\n' )
{
nNextLine = i+1;
break;
}
}
if( nNextLine == -1 ) // We never found the next line...
return false;
for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
{
char cNext = styler.SafeGetCharAt( firstChar );
if( cNext == ' ' )
continue;
if( cNext == '\t' )
continue;
if( cNext == '!' )
{
if( styler.Match(firstChar, "!else") )
return true;
}
break;
}
return false;
}
static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )
{
if( bIgnoreCase )
return CompareCaseInsensitive( s1, s2);
return strcmp( s1, s2 );
}
static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
{
int style = styler.StyleAt(end);
// If the word is too long, it is not what we are looking for
if( end - start > 20 )
return foldlevel;
if( foldUtilityCmd )
{
// Check the style at this point, if it is not valid, then return zero
if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
style != SCE_NSIS_PAGEEX )
return foldlevel;
}
else
{
if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
style != SCE_NSIS_PAGEEX )
return foldlevel;
}
int newFoldlevel = foldlevel;
bool bIgnoreCase = false;
if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
bIgnoreCase = true;
char s[20]; // The key word we are looking for has atmost 13 characters
for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
{
s[i] = static_cast<char>( styler[ start + i ] );
s[i + 1] = '\0';
}
if( s[0] == '!' )
{
if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
newFoldlevel++;
else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
newFoldlevel--;
else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
newFoldlevel++;
}
else
{
if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
newFoldlevel++;
else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
newFoldlevel--;
}
return newFoldlevel;
}
static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
{
bool bIgnoreCase = false;
if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
bIgnoreCase = true;
bool bUserVars = false;
if( styler.GetPropertyInt("nsis.uservars") == 1 )
bUserVars = true;
char s[100];
WordList &Functions = *keywordLists[0];
WordList &Variables = *keywordLists[1];
WordList &Lables = *keywordLists[2];
WordList &UserDefined = *keywordLists[3];
for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)
{
if( bIgnoreCase )
s[i] = static_cast<char>( tolower(styler[ start + i ] ) );
else
s[i] = static_cast<char>( styler[ start + i ] );
s[i + 1] = '\0';
}
// Check for special words...
if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
return SCE_NSIS_MACRODEF;
if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
return SCE_NSIS_IFDEFINEDEF;
if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // Covers !if and else
return SCE_NSIS_IFDEFINEDEF;
if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 ) // Covers !ifmacrodef and !ifnmacrodef
return SCE_NSIS_IFDEFINEDEF;
if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
return SCE_NSIS_SECTIONGROUP;
if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
return SCE_NSIS_SECTIONDEF;
if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
return SCE_NSIS_SUBSECTIONDEF;
if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
return SCE_NSIS_PAGEEX;
if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
return SCE_NSIS_FUNCTIONDEF;
if ( Functions.InList(s) )
return SCE_NSIS_FUNCTION;
if ( Variables.InList(s) )
return SCE_NSIS_VARIABLE;
if ( Lables.InList(s) )
return SCE_NSIS_LABEL;
if( UserDefined.InList(s) )
return SCE_NSIS_USERDEFINED;
if( strlen(s) > 3 )
{
if( s[1] == '{' && s[strlen(s)-1] == '}' )
return SCE_NSIS_VARIABLE;
}
// See if the variable is a user defined variable
if( s[0] == '$' && bUserVars )
{
bool bHasSimpleNsisChars = true;
for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
{
if( !isNsisChar( s[j] ) )
{
bHasSimpleNsisChars = false;
break;
}
}
if( bHasSimpleNsisChars )
return SCE_NSIS_VARIABLE;
}
// To check for numbers
if( isNsisNumber( s[0] ) )
{
bool bHasSimpleNsisNumber = true;
for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
{
if( !isNsisNumber( s[j] ) )
{
bHasSimpleNsisNumber = false;
break;
}
}
if( bHasSimpleNsisNumber )
return SCE_NSIS_NUMBER;
}
return SCE_NSIS_DEFAULT;
}
static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_NSIS_DEFAULT;
if( startPos > 0 )
state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
styler.StartAt( startPos );
styler.GetLine( startPos );
unsigned int nLengthDoc = startPos + length;
styler.StartSegment( startPos );
char cCurrChar;
bool bVarInString = false;
bool bClassicVarInString = false;
unsigned int i;
for( i = startPos; i < nLengthDoc; i++ )
{
cCurrChar = styler.SafeGetCharAt( i );
char cNextChar = styler.SafeGetCharAt(i+1);
switch(state)
{
case SCE_NSIS_DEFAULT:
if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line
{
styler.ColourTo(i-1, state );
state = SCE_NSIS_COMMENT;
break;
}
if( cCurrChar == '"' )
{
styler.ColourTo(i-1, state );
state = SCE_NSIS_STRINGDQ;
bVarInString = false;
bClassicVarInString = false;
break;
}
if( cCurrChar == '\'' )
{
styler.ColourTo(i-1, state );
state = SCE_NSIS_STRINGRQ;
bVarInString = false;
bClassicVarInString = false;
break;
}
if( cCurrChar == '`' )
{
styler.ColourTo(i-1, state );
state = SCE_NSIS_STRINGLQ;
bVarInString = false;
bClassicVarInString = false;
break;
}
// NSIS KeyWord,Function, Variable, UserDefined:
if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )
{
styler.ColourTo(i-1,state);
state = SCE_NSIS_FUNCTION;
// If it is a number, we must check and set style here first...
if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
styler.ColourTo( i, SCE_NSIS_NUMBER);
break;
}
if( cCurrChar == '/' && cNextChar == '*' )
{
styler.ColourTo(i-1,state);
state = SCE_NSIS_COMMENTBOX;
break;
}
break;
case SCE_NSIS_COMMENT:
if( cNextChar == '\n' || cNextChar == '\r' )
{
// Special case:
if( cCurrChar == '\\' )
{
styler.ColourTo(i-2,state);
styler.ColourTo(i,SCE_NSIS_DEFAULT);
}
else
{
styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
}
}
break;
case SCE_NSIS_STRINGDQ:
case SCE_NSIS_STRINGLQ:
case SCE_NSIS_STRINGRQ:
if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
break; // Ignore the next character, even if it is a quote of some sort
if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
{
styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
break;
}
if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
{
styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
break;
}
if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
{
styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
break;
}
if( cNextChar == '\r' || cNextChar == '\n' )
{
int nCurLine = styler.GetLine(i+1);
int nBack = i;
// We need to check if the previous line has a \ in it...
bool bNextLine = false;
while( nBack > 0 )
{
if( styler.GetLine(nBack) != nCurLine )
break;
char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
if( cTemp == '\\' )
{
bNextLine = true;
break;
}
if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
break;
nBack--;
}
if( bNextLine )
{
styler.ColourTo(i+1,state);
}
if( bNextLine == false )
{
styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
}
}
break;
case SCE_NSIS_FUNCTION:
// NSIS KeyWord:
if( cCurrChar == '$' )
state = SCE_NSIS_DEFAULT;
else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
state = SCE_NSIS_DEFAULT;
else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
{
state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
styler.ColourTo( i, state);
state = SCE_NSIS_DEFAULT;
}
else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )
{
if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )
styler.ColourTo( i-1, SCE_NSIS_NUMBER );
state = SCE_NSIS_DEFAULT;
if( cCurrChar == '"' )
{
state = SCE_NSIS_STRINGDQ;
bVarInString = false;
bClassicVarInString = false;
}
else if( cCurrChar == '`' )
{
state = SCE_NSIS_STRINGLQ;
bVarInString = false;
bClassicVarInString = false;
}
else if( cCurrChar == '\'' )
{
state = SCE_NSIS_STRINGRQ;
bVarInString = false;
bClassicVarInString = false;
}
else if( cCurrChar == '#' || cCurrChar == ';' )
{
state = SCE_NSIS_COMMENT;
}
}
break;
case SCE_NSIS_COMMENTBOX:
if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
{
styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
}
break;
}
if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
{
styler.ColourTo(i,state);
}
else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )
{
bool bIngoreNextDollarSign = false;
bool bUserVars = false;
if( styler.GetPropertyInt("nsis.uservars") == 1 )
bUserVars = true;
if( bVarInString && cCurrChar == '$' )
{
bVarInString = false;
bIngoreNextDollarSign = true;
}
else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
{
styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
bVarInString = false;
bIngoreNextDollarSign = false;
}
// Covers "$INSTDIR and user vars like $MYVAR"
else if( bVarInString && !isNsisChar(cNextChar) )
{
int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
if( nWordState == SCE_NSIS_VARIABLE )
styler.ColourTo( i, SCE_NSIS_STRINGVAR);
else if( bUserVars )
styler.ColourTo( i, SCE_NSIS_STRINGVAR);
bVarInString = false;
}
// Covers "${TEST}..."
else if( bClassicVarInString && cNextChar == '}' )
{
styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
bClassicVarInString = false;
}
// Start of var in string
if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )
{
styler.ColourTo( i-1, state);
bClassicVarInString = true;
bVarInString = false;
}
else if( !bIngoreNextDollarSign && cCurrChar == '$' )
{
styler.ColourTo( i-1, state);
bVarInString = true;
bClassicVarInString = false;
}
}
}
// Colourise remaining document
styler.ColourTo(nLengthDoc-1,state);
}
static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
{
// No folding enabled, no reason to continue...
if( styler.GetPropertyInt("fold") == 0 )
return;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
bool blockComment = false;
int lineCurrent = styler.GetLine(startPos);
unsigned int safeStartPos = styler.LineStart( lineCurrent );
bool bArg1 = true;
int nWordStart = -1;
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
int style = styler.StyleAt(safeStartPos);
if( style == SCE_NSIS_COMMENTBOX )
{
if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
levelNext++;
blockComment = true;
}
for (unsigned int i = safeStartPos; i < startPos + length; i++)
{
char chCurr = styler.SafeGetCharAt(i);
style = styler.StyleAt(i);
if( blockComment && style != SCE_NSIS_COMMENTBOX )
{
levelNext--;
blockComment = false;
}
else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
{
levelNext++;
blockComment = true;
}
if( bArg1 && !blockComment)
{
if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
{
nWordStart = i;
}
else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
{
int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
if( newLevel == levelNext )
{
if( foldAtElse && foldUtilityCmd )
{
if( NsisNextLineHasElse(i, startPos + length, styler) )
levelNext--;
}
}
else
levelNext = newLevel;
bArg1 = false;
}
}
if( chCurr == '\n' )
{
if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
{
if( NsisNextLineHasElse(i, startPos + length, styler) )
levelNext--;
}
// If we are on a new line...
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (levelUse < levelNext )
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
levelCurrent = levelNext;
bArg1 = true; // New line, lets look at first argument again
nWordStart = -1;
}
}
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
}
static const char * const nsisWordLists[] = {
"Functions",
"Variables",
"Lables",
"UserDefined",
0, };
LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);

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