[geany/geany] f3852d: Merge branch 'scintilla-update'
Colomban Wendling
git-noreply at xxxxx
Sat Apr 27 16:38:26 UTC 2013
Branch: refs/heads/master
Author: Colomban Wendling <ban at herbesfolles.org>
Committer: Colomban Wendling <ban at herbesfolles.org>
Date: Sat, 27 Apr 2013 16:38:26 UTC
Commit: f3852dc13c01289e50c66989473b271424a7e4cc
https://github.com/geany/geany/commit/f3852dc13c01289e50c66989473b271424a7e4cc
Log Message:
-----------
Merge branch 'scintilla-update'
Modified Paths:
--------------
data/filetypes.haskell
scintilla/Makefile.am
scintilla/gtk/PlatGTK.cxx
scintilla/gtk/ScintillaGTK.cxx
scintilla/include/ILexer.h
scintilla/include/Platform.h
scintilla/include/SciLexer.h
scintilla/include/Scintilla.h
scintilla/include/Scintilla.iface
scintilla/lexers/LexCPP.cxx
scintilla/lexers/LexHTML.cxx
scintilla/lexers/LexHaskell.cxx
scintilla/lexers/LexLaTeX.cxx
scintilla/lexers/LexMatlab.cxx
scintilla/lexers/LexOthers.cxx
scintilla/lexers/LexPO.cxx
scintilla/lexers/LexRuby.cxx
scintilla/lexlib/LexAccessor.h
scintilla/lexlib/LexerBase.cxx
scintilla/lexlib/LexerModule.cxx
scintilla/lexlib/StyleContext.h
scintilla/lexlib/SubStyles.h
scintilla/makefile.win32
scintilla/scintilla_changes.patch
scintilla/src/AutoComplete.cxx
scintilla/src/AutoComplete.h
scintilla/src/CellBuffer.cxx
scintilla/src/CellBuffer.h
scintilla/src/ContractionState.cxx
scintilla/src/Document.cxx
scintilla/src/Document.h
scintilla/src/Editor.cxx
scintilla/src/Editor.h
scintilla/src/LineMarker.cxx
scintilla/src/PositionCache.h
scintilla/src/RunStyles.h
scintilla/src/ScintillaBase.cxx
scintilla/src/ScintillaBase.h
scintilla/src/UniConversion.h
scintilla/src/ViewStyle.cxx
scintilla/src/ViewStyle.h
scintilla/version.txt
src/highlighting.c
src/highlightingmappings.h
Modified: data/filetypes.haskell
2 files changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -18,6 +18,8 @@ instance=type
capital=string_2
module=function
data=number_2
+pragma=preprocessor
+preprocessor=preprocessor
[keywords]
# all items must be in one line
Modified: scintilla/Makefile.am
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -22,6 +22,7 @@ lexers/LexForth.cxx \
lexers/LexFortran.cxx \
lexers/LexHTML.cxx \
lexers/LexHaskell.cxx \
+lexers/LexLaTeX.cxx \
lexers/LexLisp.cxx \
lexers/LexLua.cxx \
lexers/LexMarkdown.cxx \
Modified: scintilla/gtk/PlatGTK.cxx
15 files changed, 13 insertions(+), 2 deletions(-)
===================================================================
@@ -105,9 +105,11 @@ struct LOGFONT {
static GMutex *fontMutex = NULL;
static void InitializeGLIBThreads() {
+#if !GLIB_CHECK_VERSION(2,31,0)
if (!g_thread_supported()) {
g_thread_init(NULL);
}
+#endif
}
#endif
@@ -115,7 +117,12 @@ static void FontMutexAllocate() {
#if USE_LOCK
if (!fontMutex) {
InitializeGLIBThreads();
+#if GLIB_CHECK_VERSION(2,31,0)
+ fontMutex = g_new(GMutex, 1);
+ g_mutex_init(fontMutex);
+#else
fontMutex = g_mutex_new();
+#endif
}
#endif
}
@@ -123,7 +130,12 @@ static void FontMutexAllocate() {
static void FontMutexFree() {
#if USE_LOCK
if (fontMutex) {
+#if GLIB_CHECK_VERSION(2,31,0)
+ g_mutex_clear(fontMutex);
+ g_free(fontMutex);
+#else
g_mutex_free(fontMutex);
+#endif
fontMutex = NULL;
}
#endif
@@ -143,8 +155,7 @@ static void FontMutexUnlock() {
#endif
}
-// On GTK+ 1.x holds a GdkFont* but on GTK+ 2.x can hold a GdkFont* or a
-// PangoFontDescription*.
+// Holds a PangoFontDescription*.
class FontHandle {
XYPOSITION width[128];
encodingType et;
Modified: scintilla/gtk/ScintillaGTK.cxx
21 files changed, 15 insertions(+), 6 deletions(-)
===================================================================
@@ -296,7 +296,7 @@ class ScintillaGTK : public ScintillaBase {
static gboolean TimeOut(ScintillaGTK *sciThis);
static gboolean IdleCallback(ScintillaGTK *sciThis);
static gboolean StyleIdle(ScintillaGTK *sciThis);
- virtual void QueueStyling(int upTo);
+ virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo);
static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
#if GTK_CHECK_VERSION(3,0,0)
@@ -1138,6 +1138,7 @@ void ScintillaGTK::ScrollText(int linesToMove) {
//Platform::DebugPrintf("ScintillaGTK::ScrollText %d %d %0d,%0d %0d,%0d\n", linesToMove, diff,
// rc.left, rc.top, rc.right, rc.bottom);
GtkWidget *wi = PWidget(wText);
+ NotifyUpdateUI();
if (IS_WIDGET_REALIZED(wi)) {
gdk_window_scroll(WindowFromWidget(wi), 0, -diff);
@@ -2740,7 +2741,9 @@ int ScintillaGTK::TimeOut(ScintillaGTK *sciThis) {
gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
// Idler will be automatically stopped, if there is nothing
// to do while idle.
+#ifndef GDK_VERSION_3_6
gdk_threads_enter();
+#endif
bool ret = sciThis->Idle();
if (ret == false) {
// FIXME: This will remove the idler from GTK, we don't want to
@@ -2748,23 +2751,29 @@ gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
// returns false (although, it should be harmless).
sciThis->SetIdle(false);
}
+#ifndef GDK_VERSION_3_6
gdk_threads_leave();
+#endif
return ret;
}
gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) {
+#ifndef GDK_VERSION_3_6
gdk_threads_enter();
- sciThis->IdleStyling();
+#endif
+ sciThis->IdleWork();
+#ifndef GDK_VERSION_3_6
gdk_threads_leave();
+#endif
// Idler will be automatically stopped
return FALSE;
}
-void ScintillaGTK::QueueStyling(int upTo) {
- Editor::QueueStyling(upTo);
- if (!styleNeeded.active) {
+void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, int upTo) {
+ Editor::QueueIdleWork(items, upTo);
+ if (!workNeeded.active) {
// Only allow one style needed to be queued
- styleNeeded.active = true;
+ workNeeded.active = true;
g_idle_add_full(G_PRIORITY_HIGH_IDLE,
reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL);
}
Modified: scintilla/include/ILexer.h
21 files changed, 19 insertions(+), 2 deletions(-)
===================================================================
@@ -18,7 +18,7 @@
#define SCI_METHOD
#endif
-enum { dvOriginal=0 };
+enum { dvOriginal=0, dvLineEnd=1 };
class IDocument {
public:
@@ -45,7 +45,12 @@ class IDocument {
virtual int SCI_METHOD GetLineIndentation(int line) = 0;
};
-enum { lvOriginal=0 };
+class IDocumentWithLineEnd : public IDocument {
+public:
+ virtual int SCI_METHOD LineEnd(int line) const = 0;
+};
+
+enum { lvOriginal=0, lvSubStyles=1 };
class ILexer {
public:
@@ -62,6 +67,18 @@ class ILexer {
virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0;
};
+class ILexerWithSubStyles : public ILexer {
+public:
+ virtual int SCI_METHOD LineEndTypesSupported() = 0;
+ virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0;
+ virtual int SCI_METHOD SubStylesStart(int styleBase) = 0;
+ virtual int SCI_METHOD SubStylesLength(int styleBase) = 0;
+ virtual void SCI_METHOD FreeSubStyles() = 0;
+ virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0;
+ virtual int SCI_METHOD DistanceToSecondaryStyles() = 0;
+ virtual const char * SCI_METHOD GetSubStyleBases() = 0;
+};
+
class ILoader {
public:
virtual int SCI_METHOD Release() = 0;
Modified: scintilla/include/Platform.h
8 files changed, 4 insertions(+), 4 deletions(-)
===================================================================
@@ -22,7 +22,7 @@
#define PLAT_WX 0
#define PLAT_QT 0
#define PLAT_FOX 0
-#define PLAT_NCURSES 0
+#define PLAT_CURSES 0
#if defined(FOX)
#undef PLAT_FOX
@@ -32,9 +32,9 @@
#undef PLAT_WX
#define PLAT_WX 1
-#elif defined(NCURSES)
-#undef PLAT_NCURSES
-#define PLAT_NCURSES 1
+#elif defined(CURSES)
+#undef PLAT_CURSES
+#define PLAT_CURSES 1
#elif defined(SCINTILLA_QT)
#undef PLAT_QT
Modified: scintilla/include/SciLexer.h
4 files changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -477,6 +477,7 @@
#define SCE_ERR_TIDY 19
#define SCE_ERR_JAVA_STACK 20
#define SCE_ERR_VALUE 21
+#define SCE_ERR_GCC_INCLUDED_FROM 22
#define SCE_BAT_DEFAULT 0
#define SCE_BAT_COMMENT 1
#define SCE_BAT_WORD 2
@@ -1019,6 +1020,8 @@
#define SCE_HA_COMMENTBLOCK 14
#define SCE_HA_COMMENTBLOCK2 15
#define SCE_HA_COMMENTBLOCK3 16
+#define SCE_HA_PRAGMA 17
+#define SCE_HA_PREPROCESSOR 18
#define SCE_T3_DEFAULT 0
#define SCE_T3_X_DEFAULT 1
#define SCE_T3_PREPROCESSOR 2
@@ -1345,6 +1348,7 @@
#define SCE_MYSQL_USER2 19
#define SCE_MYSQL_USER3 20
#define SCE_MYSQL_HIDDENCOMMAND 21
+#define SCE_MYSQL_PLACEHOLDER 22
#define SCE_PO_DEFAULT 0
#define SCE_PO_COMMENT 1
#define SCE_PO_MSGID 2
Modified: scintilla/include/Scintilla.h
26 files changed, 26 insertions(+), 0 deletions(-)
===================================================================
@@ -148,6 +148,7 @@
#define SCI_MARKERDEFINEPIXMAP 2049
#define SCI_MARKERADDSET 2466
#define SCI_MARKERSETALPHA 2476
+#define SC_MAX_MARGIN 4
#define SC_MARGIN_SYMBOL 0
#define SC_MARGIN_NUMBER 1
#define SC_MARGIN_BACK 2
@@ -381,6 +382,7 @@
#define SCI_POSITIONFROMLINE 2167
#define SCI_LINESCROLL 2168
#define SCI_SCROLLCARET 2169
+#define SCI_SCROLLRANGE 2569
#define SCI_REPLACESEL 2170
#define SCI_SETREADONLY 2171
#define SCI_NULL 2172
@@ -696,6 +698,11 @@
#define SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE 1
#define SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR 2634
#define SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR 2635
+#define SC_ORDER_PRESORTED 0
+#define SC_ORDER_PERFORMSORT 1
+#define SC_ORDER_CUSTOM 2
+#define SCI_AUTOCSETORDER 2660
+#define SCI_AUTOCGETORDER 2661
#define SCI_ALLOCATE 2446
#define SCI_TARGETASUTF8 2447
#define SCI_SETLENGTHFORENCODE 2448
@@ -775,6 +782,8 @@
#define SCI_ANNOTATIONGETVISIBLE 2549
#define SCI_ANNOTATIONSETSTYLEOFFSET 2550
#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
+#define SCI_RELEASEALLEXTENDEDSTYLES 2552
+#define SCI_ALLOCATEEXTENDEDSTYLES 2553
#define UNDO_MAY_COALESCE 1
#define SCI_ADDUNDOACTION 2560
#define SCI_CHARPOSITIONFROMPOINT 2561
@@ -853,6 +862,8 @@
#define SCI_FINDINDICATORHIDE 2642
#define SCI_VCHOMEDISPLAY 2652
#define SCI_VCHOMEDISPLAYEXTEND 2653
+#define SCI_GETCARETLINEVISIBLEALWAYS 2654
+#define SCI_SETCARETLINEVISIBLEALWAYS 2655
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@@ -957,6 +968,21 @@
#define SCN_AUTOCCANCELLED 2025
#define SCN_AUTOCCHARDELETED 2026
#define SCN_HOTSPOTRELEASECLICK 2027
+#ifndef SCI_DISABLE_PROVISIONAL
+#define SC_LINE_END_TYPE_DEFAULT 0
+#define SC_LINE_END_TYPE_UNICODE 1
+#define SCI_SETLINEENDTYPESALLOWED 2656
+#define SCI_GETLINEENDTYPESALLOWED 2657
+#define SCI_GETLINEENDTYPESACTIVE 2658
+#define SCI_GETLINEENDTYPESSUPPORTED 4018
+#define SCI_ALLOCATESUBSTYLES 4020
+#define SCI_GETSUBSTYLESSTART 4021
+#define SCI_GETSUBSTYLESLENGTH 4022
+#define SCI_FREESUBSTYLES 4023
+#define SCI_SETIDENTIFIERS 4024
+#define SCI_DISTANCETOSECONDARYSTYLES 4025
+#define SCI_GETSUBSTYLEBASES 4026
+#endif
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* These structures are defined to be exactly the same shape as the Win32
Modified: scintilla/include/Scintilla.iface
79 files changed, 79 insertions(+), 0 deletions(-)
===================================================================
@@ -326,6 +326,8 @@ fun void MarkerAddSet=2466(int line, int set)
# Set the alpha used for a marker that is drawn in the text area, not the margin.
set void MarkerSetAlpha=2476(int markerNumber, int alpha)
+val SC_MAX_MARGIN=4
+
enu MarginType=SC_MARGIN_
val SC_MARGIN_SYMBOL=0
val SC_MARGIN_NUMBER=1
@@ -922,6 +924,11 @@ fun void LineScroll=2168(int columns, int lines)
# Ensure the caret is visible.
fun void ScrollCaret=2169(,)
+# Scroll the argument positions and the range between them into view giving
+# priority to the primary position then the secondary position.
+# This may be used to make a search match visible.
+fun void ScrollRange=2569(position secondary, position primary)
+
# Replace the selected text with the argument text.
fun void ReplaceSel=2170(, string text)
@@ -1835,6 +1842,17 @@ set void AutoCSetCaseInsensitiveBehaviour=2634(int behaviour,)
# Get auto-completion case insensitive behaviour.
get int AutoCGetCaseInsensitiveBehaviour=2635(,)
+enu Ordering=SC_ORDER_
+val SC_ORDER_PRESORTED=0
+val SC_ORDER_PERFORMSORT=1
+val SC_ORDER_CUSTOM=2
+
+# Set the way autocompletion lists are ordered.
+set void AutoCSetOrder=2660(int order,)
+
+# Get the way autocompletion lists are ordered.
+get int AutoCGetOrder=2661(,)
+
# Enlarge the document to a particular size of text bytes.
fun void Allocate=2446(int bytes,)
@@ -2062,6 +2080,12 @@ set void AnnotationSetStyleOffset=2550(int style,)
# Get the start of the range of style numbers used for annotations
get int AnnotationGetStyleOffset=2551(,)
+# Release all extended (>255) style numbers
+fun void ReleaseAllExtendedStyles=2552(,)
+
+# Allocate some extended (>255) style numbers and return the start of the range
+fun int AllocateExtendedStyles=2553(int numberStyles,)
+
val UNDO_MAY_COALESCE=1
# Add a container action to the undo stack
@@ -2267,6 +2291,12 @@ fun void VCHomeDisplay=2652(,)
# Like VCHomeDisplay but extending selection to new caret position.
fun void VCHomeDisplayExtend=2653(,)
+# Is the caret line always visible?
+get bool GetCaretLineVisibleAlways=2654(,)
+
+# Sets the caret line to always visible.
+set void SetCaretLineVisibleAlways=2655(bool alwaysVisible,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@@ -2922,6 +2952,7 @@ val SCE_ERR_ABSF=18
val SCE_ERR_TIDY=19
val SCE_ERR_JAVA_STACK=20
val SCE_ERR_VALUE=21
+val SCE_ERR_GCC_INCLUDED_FROM=22
# Lexical states for SCLEX_BATCH
lex Batch=SCLEX_BATCH SCE_BAT_
val SCE_BAT_DEFAULT=0
@@ -3405,6 +3436,7 @@ val SCE_KIX_FUNCTIONS=8
val SCE_KIX_OPERATOR=9
val SCE_KIX_IDENTIFIER=31
# Lexical states for SCLEX_GUI4CLI
+lex Gui4Cli=SCLEX_GUI4CLI SCE_GC_
val SCE_GC_DEFAULT=0
val SCE_GC_COMMENTLINE=1
val SCE_GC_COMMENTBLOCK=2
@@ -3549,6 +3581,8 @@ val SCE_HA_COMMENTLINE=13
val SCE_HA_COMMENTBLOCK=14
val SCE_HA_COMMENTBLOCK2=15
val SCE_HA_COMMENTBLOCK3=16
+val SCE_HA_PRAGMA=17
+val SCE_HA_PREPROCESSOR=18
# Lexical states of SCLEX_TADS3
lex TADS3=SCLEX_TADS3 SCE_T3_
val SCE_T3_DEFAULT=0
@@ -3913,6 +3947,7 @@ val SCE_MYSQL_USER1=18
val SCE_MYSQL_USER2=19
val SCE_MYSQL_USER3=20
val SCE_MYSQL_HIDDENCOMMAND=21
+val SCE_MYSQL_PLACEHOLDER=22
# Lexical state for SCLEX_PO
lex Po=SCLEX_PO SCE_PO_
val SCE_PO_DEFAULT=0
@@ -4242,6 +4277,50 @@ evt void AutoCCancelled=2025(void)
evt void AutoCCharDeleted=2026(void)
evt void HotSpotReleaseClick=2027(int modifiers, int position)
+cat Provisional
+
+# Line end types which may be used in addition to LF, CR, and CRLF
+# SC_LINE_END_TYPE_UNICODE includes U+2028 Line Separator,
+# U+2029 Paragraph Separator, and U+0085 Next Line
+enu LineEndType=SC_LINE_END_TYPE_
+val SC_LINE_END_TYPE_DEFAULT=0
+val SC_LINE_END_TYPE_UNICODE=1
+
+# Set the line end types that the application wants to use. May not be used if incompatible with lexer or encoding.
+set void SetLineEndTypesAllowed=2656(int lineEndBitSet,)
+
+# Get the line end types currently allowed.
+get int GetLineEndTypesAllowed=2657(,)
+
+# Get the line end types currently recognised. May be a subset of the allowed types due to lexer limitation.
+get int GetLineEndTypesActive=2658(,)
+
+# Bit set of LineEndType enumertion for which line ends beyond the standard
+# LF, CR, and CRLF are supported by the lexer.
+get int GetLineEndTypesSupported=4018(,)
+
+# Allocate a set of sub styles for a particular base style, returning start of range
+fun int AllocateSubStyles=4020(int styleBase, int numberStyles)
+
+# The starting style number for the sub styles associated with a base style
+get int GetSubStylesStart=4021(int styleBase,)
+
+# The number of sub styles associated with a base style
+get int GetSubStylesLength=4022(int styleBase,)
+
+# Free allocated sub styles
+fun void FreeSubStyles=4023(,)
+
+# Set the identifiers that are shown in a particular style
+set void SetIdentifiers=4024(int style, string identifiers)
+
+# Where styles are duplicated by a feature such as active/inactive code
+# return the distance between the two types.
+get int DistanceToSecondaryStyles=4025(,)
+
+# Get the set of base styles that can be extended with sub styles
+get int GetSubStyleBases=4026(, stringresult styles)
+
cat Deprecated
# Deprecated in 2.21
Modified: scintilla/lexers/LexCPP.cxx
162 files changed, 121 insertions(+), 41 deletions(-)
===================================================================
@@ -30,6 +30,7 @@
#include "LexerModule.h"
#include "OptionSet.h"
#include "SparseState.h"
+#include "SubStyles.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -65,9 +66,8 @@ static bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) {
int pos = (int) sc.currentPos;
int currentLine = styler.GetLine(pos);
int lineStartPos = styler.LineStart(currentLine);
- char ch;
while (--pos > lineStartPos) {
- ch = styler.SafeGetCharAt(pos);
+ char ch = styler.SafeGetCharAt(pos);
if (ch != ' ' && ch != '\t') {
break;
}
@@ -87,11 +87,15 @@ static std::string GetRestOfLine(LexAccessor &styler, int start, bool allowSpace
std::string restOfLine;
int i =0;
char ch = styler.SafeGetCharAt(start, '\n');
- while ((ch != '\r') && (ch != '\n')) {
+ int endLine = styler.LineEnd(styler.GetLine(start));
+ while (((start+i) < endLine) && (ch != '\r')) {
+ char chNext = styler.SafeGetCharAt(start + i + 1, '\n');
+ if (ch == '/' && (chNext == '/' || chNext == '*'))
+ break;
if (allowSpace || (ch != ' '))
restOfLine += ch;
i++;
- ch = styler.SafeGetCharAt(start + i, '\n');
+ ch = chNext;
}
return restOfLine;
}
@@ -127,8 +131,9 @@ struct PPDefinition {
int line;
std::string key;
std::string value;
- PPDefinition(int line_, const std::string &key_, const std::string &value_) :
- line(line_), key(key_), value(value_) {
+ bool isUndef;
+ PPDefinition(int line_, const std::string &key_, const std::string &value_, bool isUndef_ = false) :
+ line(line_), key(key_), value(value_), isUndef(isUndef_) {
}
};
@@ -307,7 +312,9 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
}
};
-class LexerCPP : public ILexer {
+static const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};
+
+class LexerCPP : public ILexerWithSubStyles {
bool caseSensitive;
CharacterSet setWord;
CharacterSet setNegationOp;
@@ -326,6 +333,8 @@ class LexerCPP : public ILexer {
OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
+ enum { ssIdentifier, ssDocKeyword };
+ SubStyles subStyles;
public:
LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_),
@@ -333,7 +342,8 @@ class LexerCPP : public ILexer {
setNegationOp(CharacterSet::setNone, "!"),
setArithmethicOp(CharacterSet::setNone, "+-/*%"),
setRelOp(CharacterSet::setNone, "=!<>"),
- setLogicalOp(CharacterSet::setNone, "|&") {
+ setLogicalOp(CharacterSet::setNone, "|&"),
+ subStyles(styleSubable, 0x80, 0x40, activeFlag) {
}
virtual ~LexerCPP() {
}
@@ -341,7 +351,7 @@ class LexerCPP : public ILexer {
delete this;
}
int SCI_METHOD Version() const {
- return lvOriginal;
+ return lvSubStyles;
}
const char * SCI_METHOD PropertyNames() {
return osCPP.PropertyNames();
@@ -364,6 +374,32 @@ class LexerCPP : public ILexer {
return 0;
}
+ int SCI_METHOD LineEndTypesSupported() {
+ return SC_LINE_END_TYPE_UNICODE;
+ };
+
+ int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) {
+ return subStyles.Allocate(styleBase, numberStyles);
+ }
+ int SCI_METHOD SubStylesStart(int styleBase) {
+ return subStyles.Start(styleBase);
+ }
+ int SCI_METHOD SubStylesLength(int styleBase) {
+ return subStyles.Length(styleBase);
+ }
+ void SCI_METHOD FreeSubStyles() {
+ subStyles.Free();
+ }
+ void SCI_METHOD SetIdentifiers(int style, const char *identifiers) {
+ subStyles.SetIdentifiers(style, identifiers);
+ }
+ int SCI_METHOD DistanceToSecondaryStyles() {
+ return activeFlag;
+ }
+ const char * SCI_METHOD GetSubStyleBases() {
+ return styleSubable;
+ }
+
static ILexer *LexerFactoryCPP() {
return new LexerCPP(true);
}
@@ -457,6 +493,8 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setInvalidRawFirst(CharacterSet::setNone, " )\\\t\v\f\n");
+
if (options.identifiersAllowDollars) {
setWordStart.Add('$');
}
@@ -468,6 +506,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
bool continuationLine = false;
bool isIncludePreprocessor = false;
bool isStringInPreprocessor = false;
+ bool inRERange = false;
int lineCurrent = styler.GetLine(startPos);
if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) ||
@@ -475,15 +514,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
(MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) {
// Set continuationLine if last character of previous line is '\'
if (lineCurrent > 0) {
- int chBack = styler.SafeGetCharAt(startPos-1, 0);
- int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
- int lineEndChar = '!';
- if (chBack2 == '\r' && chBack == '\n') {
- lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
- } else if (chBack == '\n' || chBack == '\r') {
- lineEndChar = chBack2;
+ int endLinePrevious = styler.LineEnd(lineCurrent - 1);
+ if (endLinePrevious > 0) {
+ continuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\';
}
- continuationLine = lineEndChar == '\\';
}
}
@@ -497,7 +531,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
}
- StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+ StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(0xff));
LinePPState preproc = vlls.ForLine(lineCurrent);
bool definitionsChanged = false;
@@ -515,7 +549,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
std::map<std::string, std::string> preprocessorDefinitions = preprocessorDefinitionsStart;
for (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) {
- preprocessorDefinitions[itDef->key] = itDef->value;
+ if (itDef->isUndef)
+ preprocessorDefinitions.erase(itDef->key);
+ else
+ preprocessorDefinitions[itDef->key] = itDef->value;
}
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
@@ -523,6 +560,11 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
int activitySet = preproc.IsInactive() ? activeFlag : 0;
+ const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER);
+ const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD);
+
+ int lineEndNext = styler.LineEnd(lineCurrent);
+
for (; sc.More();) {
if (sc.atLineStart) {
@@ -541,6 +583,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
visibleChars = 0;
lastWordWasUUID = false;
isIncludePreprocessor = false;
+ inRERange = false;
if (preproc.IsInactive()) {
activitySet = activeFlag;
sc.SetState(sc.state | activitySet);
@@ -549,6 +592,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
if (sc.atLineEnd) {
lineCurrent++;
+ lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
if (rawStringTerminator != "") {
rawSTNew.Set(lineCurrent-1, rawStringTerminator);
@@ -557,11 +601,13 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
// Handle line continuation generically.
if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
+ if (static_cast<int>((sc.currentPos+1)) >= lineEndNext) {
lineCurrent++;
+ lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
+ // Even in UTF-8, \r and \n are separate
sc.Forward();
}
continuationLine = true;
@@ -586,7 +632,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_C_IDENTIFIER:
- if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
+ if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) {
char s[1000];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
@@ -600,11 +646,16 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_C_WORD2|activitySet);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
+ } else {
+ int subStyle = classifierIdentifiers.ValueFor(s);
+ if (subStyle >= 0) {
+ sc.ChangeState(subStyle|activitySet);
+ }
}
const bool literalString = sc.ch == '\"';
if (literalString || sc.ch == '\'') {
size_t lenS = strlen(s);
- const bool raw = literalString && sc.chPrev == 'R';
+ const bool raw = literalString && sc.chPrev == 'R' && !setInvalidRawFirst.Contains(sc.chNext);
if (raw)
s[lenS--] = '\0';
bool valid =
@@ -692,8 +743,15 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
- if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+ if (!IsASpace(sc.ch)) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
+ } else if (!keywords3.InList(s + 1)) {
+ int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1);
+ if (subStyleCDKW >= 0) {
+ sc.ChangeState(subStyleCDKW|activitySet);
+ } else {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
+ }
}
sc.SetState(styleBeforeDCKeyword|activitySet);
}
@@ -745,16 +803,18 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
case SCE_C_REGEX:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT|activitySet);
- } else if (sc.ch == '/') {
+ } else if (! inRERange && sc.ch == '/') {
sc.Forward();
while ((sc.ch < 0x80) && islower(sc.ch))
sc.Forward(); // gobble regex flags
sc.SetState(SCE_C_DEFAULT|activitySet);
- } else if (sc.ch == '\\') {
- // Gobble up the quoted character
- if (sc.chNext == '\\' || sc.chNext == '/') {
- sc.Forward();
- }
+ } else if (sc.ch == '\\' && (static_cast<int>(sc.currentPos+1) < lineEndNext)) {
+ // Gobble up the escaped character
+ sc.Forward();
+ } else if (sc.ch == '[') {
+ inRERange = true;
+ } else if (sc.ch == ']') {
+ inRERange = false;
}
break;
case SCE_C_STRINGEOL:
@@ -780,7 +840,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_C_UUID:
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ if (sc.atLineEnd || sc.ch == ')') {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
}
@@ -788,6 +848,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
if (sc.atLineEnd && !atLineEndBeforeSwitch) {
// State exit processing consumed characters up to end of line.
lineCurrent++;
+ lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
}
@@ -809,7 +870,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else {
sc.SetState(SCE_C_NUMBER|activitySet);
}
- } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
+ } else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch) || (sc.ch == '@'))) {
if (lastWordWasUUID) {
sc.SetState(SCE_C_UUID|activitySet);
lastWordWasUUID = false;
@@ -835,6 +896,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
&& (!setCouldBePostOp.Contains(chPrevNonWhite)
|| !FollowsPostfixOperator(sc, styler))) {
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
+ inRERange = false;
} else if (sc.ch == '\"') {
if (sc.chPrev == 'R') {
styler.Flush();
@@ -934,10 +996,22 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
}
}
+ } else if (sc.Match("undef")) {
+ if (options.updatePreprocessor && !preproc.IsInactive()) {
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, true);
+ std::vector<std::string> tokens = Tokenize(restOfLine);
+ std::string key;
+ if (tokens.size() >= 1) {
+ key = tokens[0];
+ preprocessorDefinitions.erase(key);
+ ppDefineHistory.push_back(PPDefinition(lineCurrent, key, "", true));
+ definitionsChanged = true;
+ }
+ }
}
}
}
- } else if (isoperator(static_cast<char>(sc.ch))) {
+ } else if (isoperator(sc.ch)) {
sc.SetState(SCE_C_OPERATOR|activitySet);
}
}
@@ -968,10 +1042,12 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
unsigned int endPos = startPos + length;
int visibleChars = 0;
+ bool inLineComment = false;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ unsigned int lineStartNext = styler.LineStart(lineCurrent+1);
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
@@ -984,11 +1060,13 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
int stylePrev = style;
style = styleNext;
styleNext = MaskActive(styler.StyleAt(i + 1));
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
+ bool atEOL = i == (lineStartNext-1);
+ if ((style == SCE_C_COMMENTLINE) || (style == SCE_C_COMMENTLINEDOC))
+ inLineComment = true;
+ if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) {
+ if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
- } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelNext--;
}
@@ -1052,6 +1130,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
+ lineStartNext = styler.LineStart(lineCurrent+1);
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
@@ -1059,6 +1138,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
}
visibleChars = 0;
+ inLineComment = false;
}
}
}
@@ -1172,7 +1252,7 @@ bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::s
std::vector<std::string> tokens;
const char *cp = expr.c_str();
for (;;) {
- if (setWord.Contains(*cp)) {
+ if (setWord.Contains(static_cast<unsigned char>(*cp))) {
word += *cp;
} else {
std::map<std::string, std::string>::const_iterator it = preprocessorDefinitions.find(word);
@@ -1187,13 +1267,13 @@ bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::s
}
if ((*cp != ' ') && (*cp != '\t')) {
std::string op(cp, 1);
- if (setRelOp.Contains(*cp)) {
- if (setRelOp.Contains(cp[1])) {
+ if (setRelOp.Contains(static_cast<unsigned char>(*cp))) {
+ if (setRelOp.Contains(static_cast<unsigned char>(cp[1]))) {
op += cp[1];
cp++;
}
- } else if (setLogicalOp.Contains(*cp)) {
- if (setLogicalOp.Contains(cp[1])) {
+ } else if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) {
+ if (setLogicalOp.Contains(static_cast<unsigned char>(cp[1]))) {
op += cp[1];
cp++;
}
Modified: scintilla/lexers/LexHTML.cxx
15 files changed, 4 insertions(+), 11 deletions(-)
===================================================================
@@ -445,11 +445,6 @@ static int StateForScript(script_type scriptLanguage) {
return Result;
}
-static inline bool ishtmlwordchar(int ch) {
- return !isascii(ch) ||
- (isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
-}
-
static inline bool issgmlwordchar(int ch) {
return !isascii(ch) ||
(isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
@@ -484,10 +479,6 @@ static bool isLineEnd(int ch) {
return ch == '\r' || ch == '\n';
}
-static bool isOKBeforeRE(int ch) {
- return (ch == '(') || (ch == '=') || (ch == ',');
-}
-
static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
if (strlen(blockType) == 0) {
return ((ch == '%') && (chNext == '>'));
@@ -691,6 +682,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
+ // TODO: also handle + and - (except if they're part of ++ or --) and return keywords
+ const CharacterSet setOKBeforeJSRE(CharacterSet::setNone, "([{=,:;!%^&*|?~");
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
@@ -905,7 +898,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
!IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP);
- if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
+ if ((scriptLanguage != eScriptPHP) && (isStringState(state) || (state==SCE_H_COMMENT))) continue;
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
i++;
@@ -1592,7 +1585,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (ch == '/' && chNext == '/') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_COMMENTLINE;
- } else if (ch == '/' && isOKBeforeRE(chPrevNonWhite)) {
+ } else if (ch == '/' && setOKBeforeJSRE.Contains(chPrevNonWhite)) {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_REGEX;
} else if (ch == '\"') {
Modified: scintilla/lexers/LexHaskell.cxx
351 files changed, 209 insertions(+), 142 deletions(-)
===================================================================
@@ -9,6 +9,8 @@
*
* Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
*
+ * Improvements by kudah - kudahkukarek at gmail.com
+ *
* TODO:
* * Implement a folder :)
* * Nice Character-lexing (stuff inside '\''), LexPython has
@@ -57,22 +59,24 @@
#define HA_MODE_FFI 5
#define HA_MODE_TYPE 6
-static inline bool IsNewline(const int ch) {
- return (ch == '\n' || ch == '\r');
-}
-
-static inline bool IsWhitespace(const int ch) {
- return ( ch == ' '
- || ch == '\t'
- || IsNewline(ch) );
+static inline bool IsAWordStart(const int ch) {
+ return (IsLowerCase(ch) || IsUpperCase(ch) || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordChar(const int ch, const bool magicHash) {
+ return ( IsAlphaNumeric(ch)
+ || ch == '_'
+ || ch == '\''
+ || (magicHash && ch == '#'));
}
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
+static inline bool IsAnOperatorChar(const int ch) {
+ return
+ ( ch == '!' || ch == '#' || ch == '$' || ch == '%'
+ || ch == '&' || ch == '*' || ch == '+' || ch == '-'
+ || ch == '.' || ch == '/' || ch == ':' || ch == '<'
+ || ch == '=' || ch == '>' || ch == '?' || ch == '@'
+ || ch == '\\' || ch == '^' || ch == '|' || ch == '~');
}
static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
@@ -81,230 +85,293 @@ static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
WordList &keywords = *keywordlists[0];
WordList &ffi = *keywordlists[1];
+ // property lexer.haskell.allow.hash
+ // Set to 1 to allow the # character in identifiers with the haskell lexer.
+ // (GHC -XMagicHash extension)
+ const bool magicHash = styler.GetPropertyInt("lexer.haskell.allow.hash") != 0;
+ const bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
+
StyleContext sc(startPos, length, initStyle, styler);
int lineCurrent = styler.GetLine(startPos);
int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
: HA_MODE_DEFAULT;
int mode = state & 0xF;
- int xmode = state >> 4;
+ int xmode = state >> 4; // obscure parameter. Means different things in different modes.
while (sc.More()) {
// Check for state end
// Operator
if (sc.state == SCE_HA_OPERATOR) {
- if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
- sc.Forward();
- } else {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
+ int style = SCE_HA_OPERATOR;
+
+ if (sc.ch == ':' &&
+ // except "::"
+ !(sc.chNext == ':' && !IsAnOperatorChar(sc.GetRelative(2)))) {
+ style = SCE_HA_CAPITAL;
}
+
+ while(IsAnOperatorChar(sc.ch))
+ sc.Forward();
+
+ styler.ColourTo(sc.currentPos - 1, style);
+ sc.ChangeState(SCE_HA_DEFAULT);
}
// String
else if (sc.state == SCE_HA_STRING) {
if (sc.ch == '\"') {
- sc.Forward();
- styler.ColourTo(sc.currentPos-1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
+ sc.Forward();
+ sc.SetState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') {
sc.Forward(2);
} else if (sc.atLineEnd) {
- styler.ColourTo(sc.currentPos-1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
- } else {
- sc.Forward();
- }
+ sc.SetState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
}
// Char
else if (sc.state == SCE_HA_CHARACTER) {
if (sc.ch == '\'') {
- sc.Forward();
- styler.ColourTo(sc.currentPos-1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
+ sc.Forward();
+ sc.SetState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') {
sc.Forward(2);
} else if (sc.atLineEnd) {
- styler.ColourTo(sc.currentPos-1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
- } else {
- sc.Forward();
- }
+ sc.SetState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
}
// Number
else if (sc.state == SCE_HA_NUMBER) {
- if (IsADigit(sc.ch, xmode)) {
+ if (IsADigit(sc.ch, xmode) ||
+ (sc.ch=='.' && IsADigit(sc.chNext, xmode))) {
sc.Forward();
} else if ((xmode == 10) &&
(sc.ch == 'e' || sc.ch == 'E') &&
(IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
- sc.Forward();
- if (sc.ch == '+' || sc.ch == '-')
- sc.Forward();
+ sc.Forward();
+ if (sc.ch == '+' || sc.ch == '-')
+ sc.Forward();
} else {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
+ sc.SetState(SCE_HA_DEFAULT);
}
}
- // Identifier
+ // Keyword or Identifier
else if (sc.state == SCE_HA_IDENTIFIER) {
- if (IsAWordChar(sc.ch)) {
- sc.Forward();
- } else {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- int style = sc.state;
- int new_mode = 0;
- if (keywords.InList(s)) {
- style = SCE_HA_KEYWORD;
- } else if (isupper(s[0])) {
- if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
- style = SCE_HA_MODULE;
- new_mode = HA_MODE_IMPORT2;
- } else if (mode == HA_MODE_MODULE)
- style = SCE_HA_MODULE;
- else
- style = SCE_HA_CAPITAL;
- } else if (mode == HA_MODE_IMPORT1 &&
- strcmp(s,"qualified") == 0) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_IMPORT1;
- } else if (mode == HA_MODE_IMPORT2) {
- if (strcmp(s,"as") == 0) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_IMPORT3;
- } else if (strcmp(s,"hiding") == 0) {
- style = SCE_HA_KEYWORD;
- }
- } else if (mode == HA_MODE_FFI) {
- if (ffi.InList(s)) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_FFI;
+ while (sc.More()) {
+ if (IsAWordChar(sc.ch, magicHash)) {
+ sc.Forward();
+ } else if (xmode == SCE_HA_CAPITAL && sc.ch=='.') {
+ if (isupper(sc.chNext)) {
+ xmode = SCE_HA_CAPITAL;
+ sc.Forward();
+ } else if (IsAWordStart(sc.chNext)) {
+ xmode = SCE_HA_IDENTIFIER;
+ sc.Forward();
+ } else if (IsAnOperatorChar(sc.chNext)) {
+ xmode = SCE_HA_OPERATOR;
+ sc.Forward();
+ } else {
+ break;
}
+ } else if (xmode == SCE_HA_OPERATOR && IsAnOperatorChar(sc.ch)) {
+ sc.Forward();
+ } else {
+ break;
+ }
+ }
+
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+
+ int style = xmode;
+
+ int new_mode = HA_MODE_DEFAULT;
+
+ if (keywords.InList(s)) {
+ style = SCE_HA_KEYWORD;
+ } else if (isupper(s[0])) {
+ if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
+ style = SCE_HA_MODULE;
+ new_mode = HA_MODE_IMPORT2;
+ } else if (mode == HA_MODE_MODULE) {
+ style = SCE_HA_MODULE;
}
- else if (mode == HA_MODE_TYPE) {
- if (strcmp(s,"family") == 0)
- style = SCE_HA_KEYWORD;
- }
- styler.ColourTo(sc.currentPos - 1, style);
- if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
- new_mode = HA_MODE_IMPORT1;
- else if (strcmp(s,"module") == 0)
- new_mode = HA_MODE_MODULE;
- else if (strcmp(s,"foreign") == 0)
+ } else if (mode == HA_MODE_IMPORT1 &&
+ strcmp(s,"qualified") == 0) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_IMPORT1;
+ } else if (mode == HA_MODE_IMPORT2) {
+ if (strcmp(s,"as") == 0) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_IMPORT3;
+ } else if (strcmp(s,"hiding") == 0) {
+ style = SCE_HA_KEYWORD;
+ }
+ } else if (mode == HA_MODE_TYPE) {
+ if (strcmp(s,"family") == 0)
+ style = SCE_HA_KEYWORD;
+ }
+
+ if (mode == HA_MODE_FFI) {
+ if (ffi.InList(s)) {
+ style = SCE_HA_KEYWORD;
new_mode = HA_MODE_FFI;
- else if (strcmp(s,"type") == 0)
- new_mode = HA_MODE_TYPE;
- sc.ChangeState(SCE_HA_DEFAULT);
- mode = new_mode;
+ }
}
+
+ styler.ColourTo(sc.currentPos - 1, style);
+
+ if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
+ new_mode = HA_MODE_IMPORT1;
+ else if (strcmp(s,"module") == 0)
+ new_mode = HA_MODE_MODULE;
+ else if (strcmp(s,"foreign") == 0)
+ new_mode = HA_MODE_FFI;
+ else if (strcmp(s,"type") == 0
+ || strcmp(s,"data") == 0)
+ new_mode = HA_MODE_TYPE;
+
+ xmode = 0;
+ sc.ChangeState(SCE_HA_DEFAULT);
+ mode = new_mode;
}
// Comments
// Oneliner
else if (sc.state == SCE_HA_COMMENTLINE) {
- if (sc.atLineEnd) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
+ if (xmode == 1 && sc.ch != '-') {
+ xmode = 0;
+ if (IsAnOperatorChar(sc.ch))
+ sc.ChangeState(SCE_HA_OPERATOR);
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_HA_DEFAULT);
} else {
sc.Forward();
}
}
// Nested
else if (sc.state == SCE_HA_COMMENTBLOCK) {
- if (sc.Match("{-")) {
+ if (sc.Match('{','-')) {
sc.Forward(2);
xmode++;
}
- else if (sc.Match("-}")) {
+ else if (sc.Match('-','}')) {
sc.Forward(2);
xmode--;
if (xmode == 0) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.ChangeState(SCE_HA_DEFAULT);
+ sc.SetState(SCE_HA_DEFAULT);
}
} else {
if (sc.atLineEnd) {
- // Remember the line state for future incremental lexing
- styler.SetLineState(lineCurrent, (xmode << 4) | mode);
- lineCurrent++;
- }
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+ lineCurrent++;
+ }
+ sc.Forward();
+ }
+ }
+ // Pragma
+ else if (sc.state == SCE_HA_PRAGMA) {
+ if (sc.Match("#-}")) {
+ sc.Forward(3);
+ sc.SetState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
+ }
+ // Preprocessor
+ else if (sc.state == SCE_HA_PREPROCESSOR) {
+ if (stylingWithinPreprocessor && !IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HA_DEFAULT);
+ } else if (sc.ch == '\\' && !stylingWithinPreprocessor) {
+ sc.Forward(2);
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_HA_DEFAULT);
+ } else {
sc.Forward();
}
}
// New state?
if (sc.state == SCE_HA_DEFAULT) {
// Digit
- if (IsADigit(sc.ch) ||
- (sc.ch == '.' && IsADigit(sc.chNext)) ||
- (sc.ch == '-' && IsADigit(sc.chNext))) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.ChangeState(SCE_HA_NUMBER);
+ if (IsADigit(sc.ch)) {
+ 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(2);
- xmode = 16;
+ // Match anything starting with "0x" or "0X", too
+ sc.Forward(2);
+ xmode = 16;
} else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
- // Match anything starting with "0x" or "0X", too
- sc.Forward(2);
- xmode = 8;
+ // Match anything starting with "0x" or "0X", too
+ sc.Forward(2);
+ xmode = 8;
} else {
- sc.Forward();
- xmode = 10;
- }
+ sc.Forward();
+ xmode = 10;
+ }
mode = HA_MODE_DEFAULT;
}
+ // Pragma
+ else if (sc.Match("{-#")) {
+ sc.SetState(SCE_HA_PRAGMA);
+ sc.Forward(3);
+ }
// Comment line
- else if (sc.Match("--")) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
+ else if (sc.Match('-','-')) {
+ sc.SetState(SCE_HA_COMMENTLINE);
sc.Forward(2);
- sc.ChangeState(SCE_HA_COMMENTLINE);
- // Comment block
+ xmode = 1;
}
- else if (sc.Match("{-")) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
+ // Comment block
+ else if (sc.Match('{','-')) {
+ sc.SetState(SCE_HA_COMMENTBLOCK);
sc.Forward(2);
- sc.ChangeState(SCE_HA_COMMENTBLOCK);
xmode = 1;
}
// String
else if (sc.Match('\"')) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.SetState(SCE_HA_STRING);
sc.Forward();
- sc.ChangeState(SCE_HA_STRING);
}
// Character
else if (sc.Match('\'')) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.SetState(SCE_HA_CHARACTER);
sc.Forward();
- sc.ChangeState(SCE_HA_CHARACTER);
}
- else if (sc.ch == '(' || sc.ch == ')' ||
- sc.ch == '{' || sc.ch == '}' ||
- sc.ch == '[' || sc.ch == ']') {
- styler.ColourTo(sc.currentPos - 1, sc.state);
- sc.Forward();
- styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR);
- mode = HA_MODE_DEFAULT;
- }
- // Operator
- else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
+ // Preprocessor
+ else if (sc.atLineStart && sc.ch == '#') {
+ mode = HA_MODE_DEFAULT;
+ sc.SetState(SCE_HA_PREPROCESSOR);
sc.Forward();
- sc.ChangeState(SCE_HA_OPERATOR);
+ }
+ // Operator
+ else if (IsAnOperatorChar(sc.ch)) {
mode = HA_MODE_DEFAULT;
+ sc.SetState(SCE_HA_OPERATOR);
+ }
+ // Braces and punctuation
+ else if (sc.ch == ',' || sc.ch == ';'
+ || sc.ch == '(' || sc.ch == ')'
+ || sc.ch == '[' || sc.ch == ']'
+ || sc.ch == '{' || sc.ch == '}') {
+ sc.SetState(SCE_HA_OPERATOR);
+ sc.Forward();
+ sc.SetState(SCE_HA_DEFAULT);
}
- // Keyword
+ // Keyword or Identifier
else if (IsAWordStart(sc.ch)) {
- styler.ColourTo(sc.currentPos - 1, sc.state);
+ xmode = isupper(sc.ch) ? SCE_HA_CAPITAL : SCE_HA_IDENTIFIER;
+ sc.SetState(SCE_HA_IDENTIFIER);
sc.Forward();
- sc.ChangeState(SCE_HA_IDENTIFIER);
} else {
if (sc.atLineEnd) {
- // Remember the line state for future incremental lexing
- styler.SetLineState(lineCurrent, (xmode << 4) | mode);
- lineCurrent++;
- }
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+ lineCurrent++;
+ }
sc.Forward();
}
}
Modified: scintilla/lexers/LexLaTeX.cxx
539 files changed, 539 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,539 @@
+// Scintilla source code edit control
+/** @file LexLaTeX.cxx
+ ** Lexer for LaTeX2e.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh at scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// Modified by G. HU in 2013. Added folding, syntax highting inside math environments, and changed some minor behaviors.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <vector>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+using namespace std;
+
+struct latexFoldSave {
+ latexFoldSave() : structLev(0) {
+ for (int i = 0; i < 8; ++i) openBegins[i] = 0;
+ }
+ latexFoldSave(const latexFoldSave &save) : structLev(save.structLev) {
+ for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];
+ }
+ int openBegins[8];
+ int structLev;
+};
+
+class LexerLaTeX : public LexerBase {
+private:
+ vector<int> modes;
+ void setMode(int line, int mode) {
+ if (line >= static_cast<int>(modes.size())) modes.resize(line + 1, 0);
+ modes[line] = mode;
+ }
+ int getMode(int line) {
+ if (line >= 0 && line < static_cast<int>(modes.size())) return modes[line];
+ return 0;
+ }
+ void truncModes(int numLines) {
+ if (static_cast<int>(modes.size()) > numLines * 2 + 256)
+ modes.resize(numLines + 128);
+ }
+
+ vector<latexFoldSave> saves;
+ void setSave(int line, const latexFoldSave &save) {
+ if (line >= static_cast<int>(saves.size())) saves.resize(line + 1);
+ saves[line] = save;
+ }
+ void getSave(int line, latexFoldSave &save) {
+ if (line >= 0 && line < static_cast<int>(saves.size())) save = saves[line];
+ else {
+ save.structLev = 0;
+ for (int i = 0; i < 8; ++i) save.openBegins[i] = 0;
+ }
+ }
+ void truncSaves(int numLines) {
+ if (static_cast<int>(saves.size()) > numLines * 2 + 256)
+ saves.resize(numLines + 128);
+ }
+public:
+ static ILexer *LexerFactoryLaTeX() {
+ return new LexerLaTeX();
+ }
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+};
+
+static bool latexIsSpecial(int ch) {
+ return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
+ (ch == '{') || (ch == '}') || (ch == ' ');
+}
+
+static bool latexIsBlank(int ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+static bool latexIsBlankAndNL(int ch) {
+ return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
+}
+
+static bool latexIsLetter(int ch) {
+ return isascii(ch) && isalpha(ch);
+}
+
+static bool latexIsTagValid(int &i, int l, Accessor &styler) {
+ while (i < l) {
+ if (styler.SafeGetCharAt(i) == '{') {
+ while (i < l) {
+ i++;
+ if (styler.SafeGetCharAt(i) == '}') {
+ return true;
+ } else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
+ styler.SafeGetCharAt(i)!='*') {
+ return false;
+ }
+ }
+ } else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
+ return false;
+ }
+ i++;
+ }
+ return false;
+}
+
+static bool latexNextNotBlankIs(int i, Accessor &styler, char needle) {
+ char ch;
+ while (i < styler.Length()) {
+ ch = styler.SafeGetCharAt(i);
+ if (!latexIsBlankAndNL(ch) && ch != '*') {
+ if (ch == needle)
+ return true;
+ else
+ return false;
+ }
+ i++;
+ }
+ return false;
+}
+
+static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
+ unsigned int i = 0;
+ unsigned int l = static_cast<unsigned int>(strlen(needle));
+ int ini = start-l+1;
+ char s[32];
+
+ while (i < l && i < 31) {
+ s[i] = styler.SafeGetCharAt(ini + i);
+ i++;
+ }
+ s[i] = '\0';
+
+ return (strcmp(s, needle) == 0);
+}
+
+static bool latexLastWordIsMathEnv(int pos, Accessor &styler) {
+ int i, j;
+ char s[32];
+ const char *mathEnvs[] = { "align", "alignat", "flalign", "gather",
+ "multiline", "displaymath", "eqnarray", "equation" };
+ if (styler.SafeGetCharAt(pos) != '}') return false;
+ for (i = pos - 1; i >= 0; --i) {
+ if (styler.SafeGetCharAt(i) == '{') break;
+ if (pos - i >= 20) return false;
+ }
+ if (i < 0 || i == pos - 1) return false;
+ ++i;
+ for (j = 0; i + j < pos; ++j)
+ s[j] = styler.SafeGetCharAt(i + j);
+ s[j] = '\0';
+ if (j == 0) return false;
+ if (s[j - 1] == '*') s[--j] = '\0';
+ for (i = 0; i < static_cast<int>(sizeof(mathEnvs) / sizeof(const char *)); ++i)
+ if (strcmp(s, mathEnvs[i]) == 0) return true;
+ return false;
+}
+
+static inline void latexStateReset(int &mode, int &state) {
+ switch (mode) {
+ case 1: state = SCE_L_MATH; break;
+ case 2: state = SCE_L_MATH2; break;
+ default: state = SCE_L_DEFAULT; break;
+ }
+}
+
+// There are cases not handled correctly, like $abcd\textrm{what is $x+y$}z+w$.
+// But I think it's already good enough.
+void SCI_METHOD LexerLaTeX::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ // startPos is assumed to be the first character of a line
+ Accessor styler(pAccess, &props);
+ styler.StartAt(startPos);
+ int mode = getMode(styler.GetLine(startPos) - 1);
+ int state = initStyle;
+ if (state == SCE_L_ERROR || state == SCE_L_SHORTCMD || state == SCE_L_SPECIAL) // should not happen
+ latexStateReset(mode, state);
+
+ char chNext = styler.SafeGetCharAt(startPos);
+ char chVerbatimDelim = '\0';
+ styler.StartSegment(startPos);
+ int lengthDoc = startPos + length;
+
+ for (int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch)) {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ continue;
+ }
+
+ if (ch == '\r' || ch == '\n')
+ setMode(styler.GetLine(i), mode);
+
+ switch (state) {
+ case SCE_L_DEFAULT :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsLetter(chNext)) {
+ state = SCE_L_COMMAND;
+ } else if (latexIsSpecial(chNext)) {
+ styler.ColourTo(i + 1, SCE_L_SPECIAL);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext == '\r' || chNext == '\n') {
+ styler.ColourTo(i, SCE_L_ERROR);
+ } else {
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ if (chNext == '(') {
+ mode = 1;
+ state = SCE_L_MATH;
+ } else if (chNext == '[') {
+ mode = 2;
+ state = SCE_L_MATH2;
+ }
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ if (chNext == '$') {
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ mode = 2;
+ state = SCE_L_MATH2;
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ styler.ColourTo(i, SCE_L_SHORTCMD);
+ mode = 1;
+ state = SCE_L_MATH;
+ }
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ // These 3 will never be reached.
+ case SCE_L_ERROR:
+ case SCE_L_SPECIAL:
+ case SCE_L_SHORTCMD:
+ break;
+ case SCE_L_COMMAND :
+ if (!latexIsLetter(chNext)) {
+ styler.ColourTo(i, state);
+ if (latexNextNotBlankIs(i + 1, styler, '[' )) {
+ state = SCE_L_CMDOPT;
+ } else if (latexLastWordIs(i, styler, "\\begin")) {
+ state = SCE_L_TAG;
+ } else if (latexLastWordIs(i, styler, "\\end")) {
+ state = SCE_L_TAG2;
+ } else if (latexLastWordIs(i, styler, "\\verb") && chNext != '*' && chNext != ' ') {
+ chVerbatimDelim = chNext;
+ state = SCE_L_VERBATIM;
+ } else {
+ latexStateReset(mode, state);
+ }
+ }
+ break;
+ case SCE_L_CMDOPT :
+ if (ch == ']') {
+ styler.ColourTo(i, state);
+ latexStateReset(mode, state);
+ }
+ break;
+ case SCE_L_TAG :
+ if (latexIsTagValid(i, lengthDoc, styler)) {
+ styler.ColourTo(i, state);
+ latexStateReset(mode, state);
+ if (latexLastWordIs(i, styler, "{verbatim}")) {
+ state = SCE_L_VERBATIM;
+ } else if (latexLastWordIs(i, styler, "{comment}")) {
+ state = SCE_L_COMMENT2;
+ } else if (latexLastWordIs(i, styler, "{math}") && mode == 0) {
+ mode = 1;
+ state = SCE_L_MATH;
+ } else if (latexLastWordIsMathEnv(i, styler) && mode == 0) {
+ mode = 2;
+ state = SCE_L_MATH2;
+ }
+ } else {
+ styler.ColourTo(i, SCE_L_ERROR);
+ latexStateReset(mode, state);
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
+ }
+ chNext = styler.SafeGetCharAt(i+1);
+ break;
+ case SCE_L_TAG2 :
+ if (latexIsTagValid(i, lengthDoc, styler)) {
+ styler.ColourTo(i, state);
+ latexStateReset(mode, state);
+ } else {
+ styler.ColourTo(i, SCE_L_ERROR);
+ latexStateReset(mode, state);
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
+ }
+ chNext = styler.SafeGetCharAt(i+1);
+ break;
+ case SCE_L_MATH :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsLetter(chNext)) {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{math}"))
+ mode = 0;
+ }
+ }
+ state = SCE_L_COMMAND;
+ } else if (latexIsSpecial(chNext)) {
+ styler.ColourTo(i + 1, SCE_L_SPECIAL);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext == '\r' || chNext == '\n') {
+ styler.ColourTo(i, SCE_L_ERROR);
+ } else {
+ if (chNext == ')') {
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ }
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_L_SHORTCMD);
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ case SCE_L_MATH2 :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsLetter(chNext)) {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIsMathEnv(match, styler))
+ mode = 0;
+ }
+ }
+ state = SCE_L_COMMAND;
+ } else if (latexIsSpecial(chNext)) {
+ styler.ColourTo(i + 1, SCE_L_SPECIAL);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext == '\r' || chNext == '\n') {
+ styler.ColourTo(i, SCE_L_ERROR);
+ } else {
+ if (chNext == ']') {
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ }
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ if (chNext == '$') {
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ } else { // This may not be an error, e.g. \begin{equation}\text{$a$}\end{equation}
+ styler.ColourTo(i, SCE_L_SHORTCMD);
+ }
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ case SCE_L_COMMENT :
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, state);
+ latexStateReset(mode, state);
+ }
+ break;
+ case SCE_L_COMMENT2 :
+ if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{comment}")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ }
+ break;
+ case SCE_L_VERBATIM :
+ if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{verbatim}")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ } else if (chNext == chVerbatimDelim) {
+ styler.ColourTo(i + 1, state);
+ latexStateReset(mode, state);
+ chVerbatimDelim = '\0';
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
+ styler.ColourTo(i, SCE_L_ERROR);
+ latexStateReset(mode, state);
+ chVerbatimDelim = '\0';
+ }
+ break;
+ }
+ }
+ if (lengthDoc == styler.Length()) truncModes(styler.GetLine(lengthDoc - 1));
+ styler.ColourTo(lengthDoc - 1, state);
+ styler.Flush();
+}
+
+static int latexFoldSaveToInt(const latexFoldSave &save) {
+ int sum = 0;
+ for (int i = 0; i <= save.structLev; ++i)
+ sum += save.openBegins[i];
+ return ((sum + save.structLev + SC_FOLDLEVELBASE) & SC_FOLDLEVELNUMBERMASK);
+}
+
+// Change folding state while processing a line
+// Return the level before the first relevant command
+void SCI_METHOD LexerLaTeX::Fold(unsigned int startPos, int length, int, IDocument *pAccess) {
+ const char *structWords[7] = {"part", "chapter", "section", "subsection",
+ "subsubsection", "paragraph", "subparagraph"};
+ Accessor styler(pAccess, &props);
+ unsigned int endPos = startPos + length;
+ int curLine = styler.GetLine(startPos);
+ latexFoldSave save;
+ getSave(curLine - 1, save);
+ do {
+ char ch, buf[16];
+ int i, j, lev = -1;
+ bool needFold = false;
+ for (i = static_cast<int>(startPos); i < static_cast<int>(endPos); ++i) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\r' || ch == '\n') break;
+ if (ch != '\\' || styler.StyleAt(i) != SCE_L_COMMAND) continue;
+ for (j = 0; j < 15 && i + 1 < static_cast<int>(endPos); ++j, ++i) {
+ buf[j] = styler.SafeGetCharAt(i + 1);
+ if (!latexIsLetter(buf[j])) break;
+ }
+ buf[j] = '\0';
+ if (strcmp(buf, "begin") == 0) {
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ ++save.openBegins[save.structLev];
+ needFold = true;
+ }
+ else if (strcmp(buf, "end") == 0) {
+ while (save.structLev > 0 && save.openBegins[save.structLev] == 0)
+ --save.structLev;
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ if (save.openBegins[save.structLev] > 0) --save.openBegins[save.structLev];
+ }
+ else {
+ for (j = 0; j < 7; ++j)
+ if (strcmp(buf, structWords[j]) == 0) break;
+ if (j >= 7) continue;
+ save.structLev = j; // level before the command
+ for (j = save.structLev + 1; j < 8; ++j) {
+ save.openBegins[save.structLev] += save.openBegins[j];
+ save.openBegins[j] = 0;
+ }
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ ++save.structLev; // level after the command
+ needFold = true;
+ }
+ }
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ if (needFold) lev |= SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(curLine, lev);
+ setSave(curLine, save);
+ ++curLine;
+ startPos = styler.LineStart(curLine);
+ if (static_cast<int>(startPos) == styler.Length()) {
+ lev = latexFoldSaveToInt(save);
+ styler.SetLevel(curLine, lev);
+ setSave(curLine, save);
+ truncSaves(curLine);
+ }
+ } while (startPos < endPos);
+ styler.Flush();
+}
+
+static const char *const emptyWordListDesc[] = {
+ 0
+};
+
+LexerModule lmLatex(SCLEX_LATEX, LexerLaTeX::LexerFactoryLaTeX, "latex", emptyWordListDesc);
Modified: scintilla/lexers/LexMatlab.cxx
87 files changed, 77 insertions(+), 10 deletions(-)
===================================================================
@@ -6,6 +6,12 @@
** Changes by Christoph Dalitz 2003/12/04:
** - added support for Octave
** - Strings can now be included both in single or double quotes
+ **
+ ** Changes by John Donoghue 2012/04/02
+ ** - added block comment (and nested block comments)
+ ** - added ... displayed as a comment
+ ** - removed unused IsAWord functions
+ ** - added some comments
**/
// Copyright 1998-2001 by Neil Hodgson <neilh at scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -48,14 +54,6 @@ 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,
@@ -65,12 +63,41 @@ static void ColouriseMatlabOctaveDoc(
styler.StartAt(startPos);
+ // boolean for when the ' is allowed to be transpose vs the start/end
+ // of a string
bool transpose = false;
+ // approximate position of first non space character in a line
+ int nonSpaceColumn = -1;
+ // approximate column position of the current character in a line
+ int column = 0;
+
+ // use the line state of each line to store the block comment depth
+ int curLine = styler.GetLine(startPos);
+ int commentDepth = curLine > 0 ? styler.GetLineState(curLine-1) : 0;
+
+
StyleContext sc(startPos, length, initStyle, styler);
- for (; sc.More(); sc.Forward()) {
+ for (; sc.More(); sc.Forward(), column++) {
+
+ if(sc.atLineStart) {
+ // set the line state to the current commentDepth
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, commentDepth);
+ // reset the column to 0, nonSpace to -1 (not set)
+ column = 0;
+ nonSpaceColumn = -1;
+ }
+
+ // save the column position of first non space character in a line
+ if((nonSpaceColumn == -1) && (! IsASpace(sc.ch)))
+ {
+ nonSpaceColumn = column;
+ }
+
+ // check for end of states
if (sc.state == SCE_MATLAB_OPERATOR) {
if (sc.chPrev == '.') {
if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
@@ -79,6 +106,10 @@ static void ColouriseMatlabOctaveDoc(
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
transpose = true;
+ } else if(sc.ch == '.' && sc.chNext == '.') {
+ // we werent an operator, but a '...'
+ sc.ChangeState(SCE_MATLAB_COMMENT);
+ transpose = false;
} else {
sc.SetState(SCE_MATLAB_DEFAULT);
}
@@ -121,15 +152,51 @@ static void ColouriseMatlabOctaveDoc(
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
- } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
+ } else if (sc.state == SCE_MATLAB_COMMAND) {
if (sc.atLineEnd) {
sc.SetState(SCE_MATLAB_DEFAULT);
transpose = false;
}
+ } else if (sc.state == SCE_MATLAB_COMMENT) {
+ // end or start of a nested a block comment?
+ if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) {
+ if(commentDepth > 0) commentDepth --;
+
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, commentDepth);
+ sc.Forward();
+
+ if (commentDepth == 0) {
+ sc.ForwardSetState(SCE_D_DEFAULT);
+ transpose = false;
+ }
+ }
+ else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column)
+ {
+ commentDepth ++;
+
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, commentDepth);
+ sc.Forward();
+ transpose = false;
+
+ } else if(commentDepth == 0) {
+ // single line comment
+ if (sc.atLineEnd || sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_MATLAB_DEFAULT);
+ transpose = false;
+ }
+ }
}
+ // check start of a new state
if (sc.state == SCE_MATLAB_DEFAULT) {
if (IsCommentChar(sc.ch)) {
+ // ncrement depth if we are a block comment
+ if(sc.chNext == '{' && nonSpaceColumn == column)
+ commentDepth ++;
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, commentDepth);
sc.SetState(SCE_MATLAB_COMMENT);
} else if (sc.ch == '!' && sc.chNext != '=' ) {
sc.SetState(SCE_MATLAB_COMMAND);
Modified: scintilla/lexers/LexOthers.cxx
301 files changed, 4 insertions(+), 297 deletions(-)
===================================================================
@@ -1,7 +1,6 @@
// Scintilla source code edit control
/** @file LexOthers.cxx
** Lexers for batch files, diff results, properties files, make files and error lists.
- ** Also lexer for LaTeX documents.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh at scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -943,6 +942,10 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
strstr(lineBuffer, ".java:")) {
// Java stack back trace
return SCE_ERR_JAVA_STACK;
+ } else if (strstart(lineBuffer, "In file included from ") ||
+ strstart(lineBuffer, " from ")) {
+ // GCC showing include path to following error
+ return SCE_ERR_GCC_INCLUDED_FROM;
} else {
// Look for one of the following formats:
// GCC: <filename>:<line>:<message>
@@ -1109,301 +1112,6 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
}
}
-static bool latexIsSpecial(int ch) {
- return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
- (ch == '{') || (ch == '}') || (ch == ' ');
-}
-
-static bool latexIsBlank(int ch) {
- return (ch == ' ') || (ch == '\t');
-}
-
-static bool latexIsBlankAndNL(int ch) {
- return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
-}
-
-static bool latexIsLetter(int ch) {
- return isascii(ch) && isalpha(ch);
-}
-
-static bool latexIsTagValid(int &i, int l, Accessor &styler) {
- while (i < l) {
- if (styler.SafeGetCharAt(i) == '{') {
- while (i < l) {
- i++;
- if (styler.SafeGetCharAt(i) == '}') {
- return true;
- } else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
- styler.SafeGetCharAt(i)!='*') {
- return false;
- }
- }
- } else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
- return false;
- }
- i++;
- }
- return false;
-}
-
-static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) {
- char ch;
- while (i < l) {
- ch = styler.SafeGetCharAt(i);
- if (!latexIsBlankAndNL(ch) && ch != '*') {
- if (ch == needle)
- return true;
- else
- return false;
- }
- i++;
- }
- return false;
-}
-
-static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
- unsigned int i = 0;
- unsigned int l = static_cast<unsigned int>(strlen(needle));
- int ini = start-l+1;
- char s[32];
-
- while (i < l && i < 32) {
- s[i] = styler.SafeGetCharAt(ini + i);
- i++;
- }
- s[i] = '\0';
-
- return (strcmp(s, needle) == 0);
-}
-
-static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
-
- styler.StartAt(startPos);
-
- int state = initStyle;
- char chNext = styler.SafeGetCharAt(startPos);
- styler.StartSegment(startPos);
- int lengthDoc = startPos + length;
- char chVerbatimDelim = '\0';
-
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (styler.IsLeadByte(ch)) {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- continue;
- }
-
- switch (state) {
- case SCE_L_DEFAULT :
- switch (ch) {
- case '\\' :
- styler.ColourTo(i - 1, state);
- if (latexIsSpecial(chNext)) {
- state = SCE_L_SPECIAL;
- } else {
- if (latexIsLetter(chNext)) {
- state = SCE_L_COMMAND;
- } else {
- if (chNext == '(' || chNext == '[') {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i+1, SCE_L_SHORTCMD);
- state = SCE_L_MATH;
- if (chNext == '[')
- state = SCE_L_MATH2;
- i++;
- chNext = styler.SafeGetCharAt(i+1);
- } else {
- state = SCE_L_SHORTCMD;
- }
- }
- }
- break;
- case '$' :
- styler.ColourTo(i - 1, state);
- state = SCE_L_MATH;
- if (chNext == '$') {
- state = SCE_L_MATH2;
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- break;
- case '%' :
- styler.ColourTo(i - 1, state);
- state = SCE_L_COMMENT;
- break;
- }
- break;
- case SCE_L_ERROR:
- styler.ColourTo(i-1, state);
- state = SCE_L_DEFAULT;
- break;
- case SCE_L_SPECIAL:
- case SCE_L_SHORTCMD:
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- break;
- case SCE_L_COMMAND :
- if (!latexIsLetter(chNext)) {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) {
- state = SCE_L_CMDOPT;
- } else if (latexLastWordIs(i, styler, "\\begin")) {
- state = SCE_L_TAG;
- } else if (latexLastWordIs(i, styler, "\\end")) {
- state = SCE_L_TAG2;
- } else if (latexLastWordIs(i, styler, "\\verb") &&
- chNext != '*' && chNext != ' ') {
- chVerbatimDelim = chNext;
- state = SCE_L_VERBATIM;
- }
- }
- break;
- case SCE_L_CMDOPT :
- if (ch == ']') {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- }
- break;
- case SCE_L_TAG :
- if (latexIsTagValid(i, lengthDoc, styler)) {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- if (latexLastWordIs(i, styler, "{verbatim}")) {
- state = SCE_L_VERBATIM;
- } else if (latexLastWordIs(i, styler, "{comment}")) {
- state = SCE_L_COMMENT2;
- } else if (latexLastWordIs(i, styler, "{math}")) {
- state = SCE_L_MATH;
- } else if (latexLastWordIs(i, styler, "{displaymath}")) {
- state = SCE_L_MATH2;
- } else if (latexLastWordIs(i, styler, "{equation}")) {
- state = SCE_L_MATH2;
- }
- } else {
- state = SCE_L_ERROR;
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- }
- chNext = styler.SafeGetCharAt(i+1);
- break;
- case SCE_L_TAG2 :
- if (latexIsTagValid(i, lengthDoc, styler)) {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- } else {
- state = SCE_L_ERROR;
- }
- chNext = styler.SafeGetCharAt(i+1);
- break;
- case SCE_L_MATH :
- if (ch == '$') {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- } else if (ch == '\\' && chNext == ')') {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i+1, SCE_L_SHORTCMD);
- i++;
- chNext = styler.SafeGetCharAt(i+1);
- state = SCE_L_DEFAULT;
- } else if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{math}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- }
-
- break;
- case SCE_L_MATH2 :
- if (ch == '$') {
- if (chNext == '$') {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- } else {
- styler.ColourTo(i, SCE_L_ERROR);
- state = SCE_L_DEFAULT;
- }
- } else if (ch == '\\' && chNext == ']') {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i+1, SCE_L_SHORTCMD);
- i++;
- chNext = styler.SafeGetCharAt(i+1);
- state = SCE_L_DEFAULT;
- } else if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{displaymath}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- } else if (latexLastWordIs(match, styler, "{equation}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- }
- break;
- case SCE_L_COMMENT :
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_L_DEFAULT;
- }
- break;
- case SCE_L_COMMENT2 :
- if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{comment}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- }
- break;
- case SCE_L_VERBATIM :
- if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{verbatim}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- } else if (chNext == chVerbatimDelim) {
- styler.ColourTo(i+1, state);
- state = SCE_L_DEFAULT;
- chVerbatimDelim = '\0';
- } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
- styler.ColourTo(i, SCE_L_ERROR);
- state = SCE_L_DEFAULT;
- chVerbatimDelim = '\0';
- }
- break;
- }
- }
- styler.ColourTo(lengthDoc-1, state);
-}
-
static const char *const batchWordListDesc[] = {
"Internal Commands",
"External Commands",
@@ -1429,5 +1137,4 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[
LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
-LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
Modified: scintilla/lexers/LexPO.cxx
66 files changed, 65 insertions(+), 1 deletions(-)
===================================================================
@@ -98,6 +98,12 @@ static void ColourisePODoc(unsigned int startPos, int length, int initStyle, Wor
// forward to the first non-white character on the line
bool atLineStart = sc.atLineStart;
if (atLineStart) {
+ // reset line state if it is set to comment state so empty lines don't get
+ // comment line state, and the folding code folds comments separately,
+ // and anyway the styling don't use line state for comments
+ if (curLineState == SCE_PO_COMMENT)
+ curLineState = SCE_PO_DEFAULT;
+
while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch))
sc.Forward();
}
@@ -142,8 +148,66 @@ static void ColourisePODoc(unsigned int startPos, int length, int initStyle, Wor
sc.Complete();
}
+static int FindNextNonEmptyLineState(unsigned int startPos, Accessor &styler) {
+ unsigned int length = styler.Length();
+ for (unsigned int i = startPos; i < length; i++) {
+ if (! isspacechar(styler[i])) {
+ return styler.GetLineState(styler.GetLine(i));
+ }
+ }
+ return 0;
+}
+
+static void FoldPODoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ if (! styler.GetPropertyInt("fold"))
+ return;
+ bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+ unsigned int endPos = startPos + length;
+ int curLine = styler.GetLine(startPos);
+ int lineState = styler.GetLineState(curLine);
+ int nextLineState;
+ int level = styler.LevelAt(curLine) & SC_FOLDLEVELNUMBERMASK;
+ int nextLevel;
+ int visible = 0;
+ int chNext = styler[startPos];
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ int ch = chNext;
+ chNext = styler.SafeGetCharAt(i+1);
+
+ if (! isspacechar(ch)) {
+ visible++;
+ } else if ((ch == '\r' && chNext != '\n') || ch == '\n' || i+1 >= endPos) {
+ int lvl = level;
+ int nextLine = curLine + 1;
+
+ nextLineState = styler.GetLineState(nextLine);
+ if ((lineState != SCE_PO_COMMENT || foldComment) &&
+ nextLineState == lineState &&
+ FindNextNonEmptyLineState(i, styler) == lineState)
+ nextLevel = SC_FOLDLEVELBASE + 1;
+ else
+ nextLevel = SC_FOLDLEVELBASE;
+
+ if (nextLevel > level)
+ lvl |= SC_FOLDLEVELHEADERFLAG;
+ if (visible == 0 && foldCompact)
+ lvl |= SC_FOLDLEVELWHITEFLAG;
+
+ styler.SetLevel(curLine, lvl);
+
+ lineState = nextLineState;
+ curLine = nextLine;
+ level = nextLevel;
+ visible = 0;
+ }
+ }
+}
+
static const char *const poWordListDesc[] = {
0
};
-LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", 0, poWordListDesc);
+LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", FoldPODoc, poWordListDesc);
Modified: scintilla/lexers/LexRuby.cxx
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -119,7 +119,7 @@ static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywor
chAttr = SCE_RB_MODULE_NAME;
else if (0 == strcmp(prevWord, "def"))
chAttr = SCE_RB_DEFNAME;
- else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
+ else if (keywords.InList(s) && ((start == 0) || !followsDot(start - 1, styler))) {
if (keywordIsAmbiguous(s)
&& keywordIsModifier(s, start, styler)) {
Modified: scintilla/lexlib/LexAccessor.h
39 files changed, 36 insertions(+), 3 deletions(-)
===================================================================
@@ -12,6 +12,8 @@
namespace Scintilla {
#endif
+enum EncodingType { enc8bit, encUnicode, encDBCS };
+
class LexAccessor {
private:
IDocument *pAccess;
@@ -25,6 +27,7 @@ class LexAccessor {
int startPos;
int endPos;
int codePage;
+ enum EncodingType encodingType;
int lenDoc;
int mask;
char styleBuf[bufferSize];
@@ -33,6 +36,7 @@ class LexAccessor {
char chWhile;
unsigned int startSeg;
int startPosStyling;
+ int documentVersion;
void Fill(int position) {
startPos = position - slopSize;
@@ -51,9 +55,23 @@ class LexAccessor {
public:
LexAccessor(IDocument *pAccess_) :
pAccess(pAccess_), startPos(extremePosition), endPos(0),
- codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
+ codePage(pAccess->CodePage()),
+ encodingType(enc8bit),
+ lenDoc(pAccess->Length()),
mask(127), validLen(0), chFlags(0), chWhile(0),
- startSeg(0), startPosStyling(0) {
+ startSeg(0), startPosStyling(0),
+ documentVersion(pAccess->Version()) {
+ switch (codePage) {
+ case 65001:
+ encodingType = encUnicode;
+ break;
+ case 932:
+ case 936:
+ case 949:
+ case 950:
+ case 1361:
+ encodingType = encDBCS;
+ }
}
char operator[](int position) {
if (position < startPos || position >= endPos) {
@@ -75,7 +93,9 @@ class LexAccessor {
bool IsLeadByte(char ch) {
return pAccess->IsDBCSLeadByte(ch);
}
-
+ EncodingType Encoding() const {
+ return encodingType;
+ }
bool Match(int pos, const char *s) {
for (int i=0; *s; i++) {
if (*s != SafeGetCharAt(pos+i))
@@ -93,6 +113,19 @@ class LexAccessor {
int LineStart(int line) {
return pAccess->LineStart(line);
}
+ int LineEnd(int line) {
+ if (documentVersion >= dvLineEnd) {
+ return (static_cast<IDocumentWithLineEnd *>(pAccess))->LineEnd(line);
+ } else {
+ // Old interface means only '\r', '\n' and '\r\n' line ends.
+ int startNext = pAccess->LineStart(line+1);
+ char chLineEnd = SafeGetCharAt(startNext-1);
+ if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r'))
+ return startNext - 2;
+ else
+ return startNext - 1;
+ }
+ }
int LevelAt(int line) {
return pAccess->GetLevel(line);
}
Modified: scintilla/lexlib/LexerBase.cxx
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -1,5 +1,5 @@
// Scintilla source code edit control
-/** @file LexerSimple.cxx
+/** @file LexerBase.cxx
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh at scintilla.org>
Modified: scintilla/lexlib/LexerModule.cxx
4 files changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -74,11 +74,9 @@ int LexerModule::GetNumWordLists() const {
}
const char *LexerModule::GetWordListDescription(int index) const {
- static const char *emptyStr = "";
-
assert(index < GetNumWordLists());
if (index >= GetNumWordLists()) {
- return emptyStr;
+ return "";
} else {
return wordListDescriptions[index];
}
Modified: scintilla/lexlib/StyleContext.h
117 files changed, 95 insertions(+), 22 deletions(-)
===================================================================
@@ -19,6 +19,30 @@ static inline int MakeLowerCase(int ch) {
return ch - 'A' + 'a';
}
+inline int UnicodeCodePoint(const unsigned char *us) {
+ if (us[0] < 0xC2) {
+ return us[0];
+ } else if (us[0] < 0xE0) {
+ return ((us[0] & 0x1F) << 6) + (us[1] & 0x3F);
+ } else if (us[0] < 0xF0) {
+ return ((us[0] & 0xF) << 12) + ((us[1] & 0x3F) << 6) + (us[2] & 0x3F);
+ } else if (us[0] < 0xF5) {
+ return ((us[0] & 0x7) << 18) + ((us[1] & 0x3F) << 12) + ((us[2] & 0x3F) << 6) + (us[3] & 0x3F);
+ }
+ return us[0];
+}
+
+inline int BytesInUnicodeCodePoint(int codePoint) {
+ if (codePoint < 0x80)
+ return 1;
+ else if (codePoint < 0x800)
+ return 2;
+ else if (codePoint < 0x10000)
+ return 3;
+ else
+ return 4;
+}
+
// All languages handled so far can treat all characters >= 0x80 as one class
// which just continues the current token or starts an identifier if in default.
// DBCS treated specially as the second character can be < 0x80 and hence
@@ -26,23 +50,42 @@ static inline int MakeLowerCase(int ch) {
class StyleContext {
LexAccessor &styler;
unsigned int endPos;
+ unsigned int lengthDocument;
StyleContext &operator=(const StyleContext &);
+
void GetNextChar(unsigned int pos) {
- chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+ chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1, 0));
+ if (styler.Encoding() == encUnicode) {
+ if (chNext >= 0x80) {
+ unsigned char bytes[4] = { static_cast<unsigned char>(chNext), 0, 0, 0 };
+ for (int trail=1; trail<3; trail++) {
+ bytes[trail] = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1+trail, 0));
+ if (!((bytes[trail] >= 0x80) && (bytes[trail] < 0xc0))) {
+ bytes[trail] = 0;
+ break;
+ }
+ }
+ chNext = UnicodeCodePoint(bytes);
+ }
+ } else if (styler.Encoding() == encDBCS) {
+ if (styler.IsLeadByte(static_cast<char>(chNext))) {
+ chNext = chNext << 8;
+ chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2, 0));
+ }
}
// End of line?
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
// or on LF alone (Unix). Avoid triggering two times on Dos/Win.
- atLineEnd = (ch == '\r' && chNext != '\n') ||
- (ch == '\n') ||
- (currentPos >= endPos);
+ if (lineStartNext < styler.Length())
+ atLineEnd = static_cast<int>(pos) >= (lineStartNext-1);
+ else // Last line
+ atLineEnd = static_cast<int>(pos) >= lineStartNext;
}
public:
unsigned int currentPos;
+ int currentLine;
+ int lineStartNext;
bool atLineStart;
bool atLineEnd;
int state;
@@ -55,6 +98,8 @@ class StyleContext {
styler(styler_),
endPos(startPos + length),
currentPos(startPos),
+ currentLine(-1),
+ lineStartNext(-1),
atLineEnd(false),
state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
@@ -62,18 +107,30 @@ class StyleContext {
chNext(0) {
styler.StartAt(startPos, chMask);
styler.StartSegment(startPos);
- atLineStart = static_cast<unsigned int>(styler.LineStart(styler.GetLine(startPos))) == startPos;
+ currentLine = styler.GetLine(startPos);
+ lineStartNext = styler.LineStart(currentLine+1);
+ lengthDocument = static_cast<unsigned int>(styler.Length());
+ if (endPos == lengthDocument)
+ endPos++;
+ atLineStart = static_cast<unsigned int>(styler.LineStart(currentLine)) == startPos;
unsigned int pos = currentPos;
- ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
- if (styler.IsLeadByte(static_cast<char>(ch))) {
- pos++;
- ch = ch << 8;
- ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos, 0));
+ if (styler.Encoding() == encUnicode) {
+ // Get the current char
+ GetNextChar(pos-1);
+ ch = chNext;
+ pos += BytesInUnicodeCodePoint(ch) - 1;
+ } else if (styler.Encoding() == encDBCS) {
+ if (styler.IsLeadByte(static_cast<char>(ch))) {
+ pos++;
+ ch = ch << 8;
+ ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos, 0));
+ }
}
GetNextChar(pos);
}
void Complete() {
- styler.ColourTo(currentPos - 1, state);
+ styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
styler.Flush();
}
bool More() const {
@@ -82,12 +139,28 @@ class StyleContext {
void Forward() {
if (currentPos < endPos) {
atLineStart = atLineEnd;
+ if (atLineStart) {
+ currentLine++;
+ lineStartNext = styler.LineStart(currentLine+1);
+ }
chPrev = ch;
- currentPos++;
- if (ch >= 0x100)
+ if (styler.Encoding() == encUnicode) {
+ currentPos += BytesInUnicodeCodePoint(ch);
+ } else if (styler.Encoding() == encDBCS) {
+ currentPos++;
+ if (ch >= 0x100)
+ currentPos++;
+ } else {
currentPos++;
+ }
ch = chNext;
- GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
+ if (styler.Encoding() == encUnicode) {
+ GetNextChar(currentPos + BytesInUnicodeCodePoint(ch)-1);
+ } else if (styler.Encoding() == encDBCS) {
+ GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
+ } else {
+ GetNextChar(currentPos);
+ }
} else {
atLineStart = false;
chPrev = ' ';
@@ -105,19 +178,19 @@ class StyleContext {
state = state_;
}
void SetState(int state_) {
- styler.ColourTo(currentPos - 1, state);
+ styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
state = state_;
}
void ForwardSetState(int state_) {
Forward();
- styler.ColourTo(currentPos - 1, state);
+ styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
state = state_;
}
int LengthCurrent() {
return currentPos - styler.GetStartSegment();
}
int GetRelative(int n) {
- return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
+ return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, 0));
}
bool Match(char ch0) const {
return ch == static_cast<unsigned char>(ch0);
@@ -135,7 +208,7 @@ class StyleContext {
return false;
s++;
for (int n=2; *s; n++) {
- if (*s != styler.SafeGetCharAt(currentPos+n))
+ if (*s != styler.SafeGetCharAt(currentPos+n, 0))
return false;
s++;
}
@@ -150,7 +223,7 @@ class StyleContext {
s++;
for (int n=2; *s; n++) {
if (static_cast<unsigned char>(*s) !=
- MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
+ MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, 0))))
return false;
s++;
}
Modified: scintilla/lexlib/SubStyles.h
162 files changed, 162 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,162 @@
+// Scintilla source code edit control
+/** @file SubStyles.h
+ ** Manage substyles for a lexer.
+ **/
+// Copyright 2012 by Neil Hodgson <neilh at scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SUBSTYLES_H
+#define SUBSTYLES_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class WordClassifier {
+ int firstStyle;
+ int lenStyles;
+ std::map<std::string, int> wordToStyle;
+
+public:
+
+ WordClassifier() : firstStyle(0), lenStyles(0) {
+ }
+
+ void Allocate(int firstStyle_, int lenStyles_) {
+ firstStyle = firstStyle_;
+ lenStyles = lenStyles_;
+ wordToStyle.clear();
+ }
+
+ int Start() const {
+ return firstStyle;
+ }
+
+ int Length() const {
+ return lenStyles;
+ }
+
+ void Clear() {
+ firstStyle = 0;
+ lenStyles = 0;
+ wordToStyle.clear();
+ }
+
+ int ValueFor(const std::string &s) const {
+ std::map<std::string, int>::const_iterator it = wordToStyle.find(s);
+ if (it != wordToStyle.end())
+ return it->second;
+ else
+ return -1;
+ }
+
+ bool IncludesStyle(int style) const {
+ return (style >= firstStyle) && (style < (firstStyle + lenStyles));
+ }
+
+ void SetIdentifiers(int style, const char *identifiers) {
+ while (*identifiers) {
+ const char *cpSpace = identifiers;
+ while (*cpSpace && *cpSpace != ' ')
+ cpSpace++;
+ std::string word(identifiers, cpSpace - identifiers);
+ wordToStyle[word] = style;
+ identifiers = cpSpace;
+ if (*identifiers)
+ identifiers++;
+ }
+ }
+};
+
+class SubStyles {
+ int classifications;
+ const char *baseStyles;
+ int styleFirst;
+ int stylesAvailable;
+ int secondaryDistance;
+ int allocated;
+ std::vector<WordClassifier> classifiers;
+
+ int BlockFromBaseStyle(int baseStyle) const {
+ for (int b=0; b < classifications; b++) {
+ if (baseStyle == baseStyles[b])
+ return b;
+ }
+ return -1;
+ }
+
+ int BlockFromStyle(int style) const {
+ int b = 0;
+ for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) {
+ if (it->IncludesStyle(style))
+ return b;
+ b++;
+ }
+ return -1;
+ }
+
+public:
+
+ SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
+ classifications(0),
+ baseStyles(baseStyles_),
+ styleFirst(styleFirst_),
+ stylesAvailable(stylesAvailable_),
+ secondaryDistance(secondaryDistance_),
+ allocated(0) {
+ while (baseStyles[classifications]) {
+ classifications++;
+ classifiers.push_back(WordClassifier());
+ }
+ }
+
+ int Allocate(int styleBase, int numberStyles) {
+ int block = BlockFromBaseStyle(styleBase);
+ if (block >= 0) {
+ if ((allocated + numberStyles) > stylesAvailable)
+ return -1;
+ int startBlock = styleFirst + allocated;
+ allocated += numberStyles;
+ classifiers[block].Allocate(startBlock, numberStyles);
+ return startBlock;
+ } else {
+ return -1;
+ }
+ }
+
+ int Start(int styleBase) {
+ int block = BlockFromBaseStyle(styleBase);
+ return (block >= 0) ? classifiers[block].Start() : -1;
+ }
+
+ int Length(int styleBase) {
+ int block = BlockFromBaseStyle(styleBase);
+ return (block >= 0) ? classifiers[block].Length() : 0;
+ }
+
+ int DistanceToSecondaryStyles() const {
+ return secondaryDistance;
+ }
+
+ void SetIdentifiers(int style, const char *identifiers) {
+ int block = BlockFromStyle(style);
+ if (block >= 0)
+ classifiers[block].SetIdentifiers(style, identifiers);
+ }
+
+ void Free() {
+ allocated = 0;
+ for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it)
+ it->Clear();
+ }
+
+ const WordClassifier &Classifier(int baseStyle) const {
+ return classifiers[BlockFromBaseStyle(baseStyle)];
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
Modified: scintilla/makefile.win32
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -89,6 +89,7 @@ LexVerilog.o \
LexMarkdown.o \
LexMatlab.o \
LexD.o \
+LexLaTeX.o \
LexLisp.o \
LexLua.o \
LexHaskell.o \
Modified: scintilla/scintilla_changes.patch
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -31,7 +31,7 @@ diff --git b/scintilla/src/Catalogue.cxx a/scintilla/src/Catalogue.cxx
index 2f75247..a34f834 100644
+++ scintilla/src/Catalogue.cxx
--- scintilla/src/Catalogue.cxx
-@@ -81,108 +81,44 @@ int Scintilla_LinkLexers() {
+@@ -81,108 +81,45 @@ int Scintilla_LinkLexers() {
//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
Modified: scintilla/src/AutoComplete.cxx
119 files changed, 110 insertions(+), 9 deletions(-)
===================================================================
@@ -10,7 +10,9 @@
#include <stdio.h>
#include <assert.h>
+#include <algorithm>
#include <string>
+#include <vector>
#include "Platform.h"
@@ -36,7 +38,8 @@
dropRestOfWord(false),
ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE),
widthLBDefault(100),
- heightLBDefault(100) {
+ heightLBDefault(100),
+ autoSort(SC_ORDER_PRESORTED) {
lb = ListBox::Allocate();
stopChars[0] = '\0';
fillUpChars[0] = '\0';
@@ -101,8 +104,91 @@ char AutoComplete::GetTypesep() const {
return typesep;
}
+struct Sorter {
+ AutoComplete *ac;
+ const char *list;
+ std::vector<int> indices;
+
+ Sorter(AutoComplete *ac_, const char *list_) : ac(ac_), list(list_) {
+ int i = 0;
+ while (list[i]) {
+ indices.push_back(i); // word start
+ while (list[i] != ac->GetTypesep() && list[i] != ac->GetSeparator() && list[i])
+ ++i;
+ indices.push_back(i); // word end
+@@ Diff output truncated at 100000 characters. @@
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list