From 64a3ee5fd2926c3e5341af2e4d62925fddb90c43 Mon Sep 17 00:00:00 2001 From: "Eric W. Sink" Date: Thu, 30 Mar 2000 18:43:38 +0000 Subject: [PATCH] This commit includes the following changes: 1. I have grabbed a new copy of the original Scintilla code from its CVS repository on SourceForge. I believe this code corresponds to Scintilla 1.24. 2. That code included several new files (stc/scintilla/src/Lex*.cxx) 3. I added mentions of those files to Makefile.in and the .dsp file. 4. I added a new required method to PlatWX.cpp, but it doesn't do anything, and I don't think it needs to. 5. I added code to stc.cpp which gratuitously references all of the lexers, to prevent them from being optimized away by the linker. 6. I modified (stc/scintilla/src/Lex*.cxx) to make the LexerModule objects externally visible. Gripes to me. (eric@sourcegear.com) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6998 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/src/stc/Makefile.in | 7 + contrib/src/stc/PlatWX.cpp | 16 +- contrib/src/stc/ScintillaWX.cpp | 2 + contrib/src/stc/StcVC.dsp | 42 +- contrib/src/stc/scintilla/include/Accessor.h | 16 +- contrib/src/stc/scintilla/include/KeyWords.h | 37 +- contrib/src/stc/scintilla/include/Platform.h | 3 + contrib/src/stc/scintilla/include/SciLexer.h | 120 +- contrib/src/stc/scintilla/include/Scintilla.h | 10 +- contrib/src/stc/scintilla/src/Accessor.cxx | 86 +- contrib/src/stc/scintilla/src/CellBuffer.cxx | 313 ++- contrib/src/stc/scintilla/src/CellBuffer.h | 49 +- .../stc/scintilla/src/ContractionState.cxx | 8 +- contrib/src/stc/scintilla/src/Document.cxx | 83 +- contrib/src/stc/scintilla/src/Document.h | 15 +- contrib/src/stc/scintilla/src/Editor.cxx | 175 +- contrib/src/stc/scintilla/src/Editor.h | 6 + contrib/src/stc/scintilla/src/KeyMap.cxx | 45 +- contrib/src/stc/scintilla/src/KeyMap.h | 1 + contrib/src/stc/scintilla/src/KeyWords.cxx | 2220 +---------------- contrib/src/stc/scintilla/src/LexCPP.cxx | 255 ++ contrib/src/stc/scintilla/src/LexHTML.cxx | 1139 +++++++++ contrib/src/stc/scintilla/src/LexOthers.cxx | 200 ++ contrib/src/stc/scintilla/src/LexPerl.cxx | 488 ++++ contrib/src/stc/scintilla/src/LexPython.cxx | 254 ++ contrib/src/stc/scintilla/src/LexSQL.cxx | 158 ++ contrib/src/stc/scintilla/src/LexVB.cxx | 118 + contrib/src/stc/scintilla/src/PropSet.cxx | 5 + contrib/src/stc/scintilla/src/SVector.h | 12 +- .../src/stc/scintilla/src/ScintillaBase.cxx | 7 +- contrib/src/stc/scintilla/src/Style.cxx | 58 +- contrib/src/stc/scintilla/src/Style.h | 14 +- contrib/src/stc/scintilla/src/ViewStyle.cxx | 66 +- contrib/src/stc/scintilla/src/ViewStyle.h | 13 + contrib/src/stc/stc.cpp | 44 +- src/stc/Makefile.in | 7 + src/stc/PlatWX.cpp | 16 +- src/stc/ScintillaWX.cpp | 2 + src/stc/StcVC.dsp | 42 +- src/stc/scintilla/include/Accessor.h | 16 +- src/stc/scintilla/include/KeyWords.h | 37 +- src/stc/scintilla/include/Platform.h | 3 + src/stc/scintilla/include/SciLexer.h | 120 +- src/stc/scintilla/include/Scintilla.h | 10 +- src/stc/scintilla/src/Accessor.cxx | 86 +- src/stc/scintilla/src/CellBuffer.cxx | 313 ++- src/stc/scintilla/src/CellBuffer.h | 49 +- src/stc/scintilla/src/ContractionState.cxx | 8 +- src/stc/scintilla/src/Document.cxx | 83 +- src/stc/scintilla/src/Document.h | 15 +- src/stc/scintilla/src/Editor.cxx | 175 +- src/stc/scintilla/src/Editor.h | 6 + src/stc/scintilla/src/KeyMap.cxx | 45 +- src/stc/scintilla/src/KeyMap.h | 1 + src/stc/scintilla/src/KeyWords.cxx | 2220 +---------------- src/stc/scintilla/src/LexCPP.cxx | 255 ++ src/stc/scintilla/src/LexHTML.cxx | 1139 +++++++++ src/stc/scintilla/src/LexOthers.cxx | 200 ++ src/stc/scintilla/src/LexPerl.cxx | 488 ++++ src/stc/scintilla/src/LexPython.cxx | 254 ++ src/stc/scintilla/src/LexSQL.cxx | 158 ++ src/stc/scintilla/src/LexVB.cxx | 118 + src/stc/scintilla/src/PropSet.cxx | 5 + src/stc/scintilla/src/SVector.h | 12 +- src/stc/scintilla/src/ScintillaBase.cxx | 7 +- src/stc/scintilla/src/Style.cxx | 58 +- src/stc/scintilla/src/Style.h | 14 +- src/stc/scintilla/src/ViewStyle.cxx | 66 +- src/stc/scintilla/src/ViewStyle.h | 13 + src/stc/stc.cpp | 44 +- 70 files changed, 7180 insertions(+), 4990 deletions(-) create mode 100644 contrib/src/stc/scintilla/src/LexCPP.cxx create mode 100644 contrib/src/stc/scintilla/src/LexHTML.cxx create mode 100644 contrib/src/stc/scintilla/src/LexOthers.cxx create mode 100644 contrib/src/stc/scintilla/src/LexPerl.cxx create mode 100644 contrib/src/stc/scintilla/src/LexPython.cxx create mode 100644 contrib/src/stc/scintilla/src/LexSQL.cxx create mode 100644 contrib/src/stc/scintilla/src/LexVB.cxx create mode 100644 src/stc/scintilla/src/LexCPP.cxx create mode 100644 src/stc/scintilla/src/LexHTML.cxx create mode 100644 src/stc/scintilla/src/LexOthers.cxx create mode 100644 src/stc/scintilla/src/LexPerl.cxx create mode 100644 src/stc/scintilla/src/LexPython.cxx create mode 100644 src/stc/scintilla/src/LexSQL.cxx create mode 100644 src/stc/scintilla/src/LexVB.cxx diff --git a/contrib/src/stc/Makefile.in b/contrib/src/stc/Makefile.in index 425ea48714..3666daed78 100644 --- a/contrib/src/stc/Makefile.in +++ b/contrib/src/stc/Makefile.in @@ -29,6 +29,13 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ Indicator.o \ KeyMap.o \ KeyWords.o \ + LexCPP.o \ + LexHTML.o \ + LexOthers.o \ + LexPerl.o \ + LexPython.o \ + LexSQL.o \ + LexVB.o \ LineMarker.o \ PropSet.o \ ScintillaBase.o \ diff --git a/contrib/src/stc/PlatWX.cpp b/contrib/src/stc/PlatWX.cpp index 0dbd3d5ea7..0fc480d806 100644 --- a/contrib/src/stc/PlatWX.cpp +++ b/contrib/src/stc/PlatWX.cpp @@ -4,6 +4,7 @@ // Robin Dunn // The License.txt file describes the conditions under which this software may be distributed. +#include #include "Platform.h" #include "wx/stc/stc.h" @@ -181,7 +182,14 @@ void Surface::BrushColor(Colour back) { } void Surface::SetFont(Font &font_) { - hdc->SetFont(*font_.GetID()); + + // I think the following check is valid. + // It eliminates a crash for me. -- eric@sourcegear.com + + if (font_.GetID()) + { + hdc->SetFont(*font_.GetID()); + } } int Surface::LogPixelsY() { @@ -344,7 +352,11 @@ void Surface::SetClip(PRectangle rc) { hdc->SetClippingRegion(wxRectFromPRectangle(rc)); } - +void Surface::FlushCachedState() { + // TODO Is there anything we need to do here? eric@sourcegear.com + // TODO I had to add this method when I merged new Scintilla code + // TODO from Neil. +} Window::~Window() { } diff --git a/contrib/src/stc/ScintillaWX.cpp b/contrib/src/stc/ScintillaWX.cpp index cd0064be5c..cc6fbe7fcf 100644 --- a/contrib/src/stc/ScintillaWX.cpp +++ b/contrib/src/stc/ScintillaWX.cpp @@ -14,6 +14,8 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +#include + #include "ScintillaWX.h" #include "wx/stc/stc.h" diff --git a/contrib/src/stc/StcVC.dsp b/contrib/src/stc/StcVC.dsp index 3b8fc6d9e7..5e77ef19e2 100644 --- a/contrib/src/stc/StcVC.dsp +++ b/contrib/src/stc/StcVC.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="StcVC" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 5.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 @@ -22,11 +22,9 @@ CFG=StcVC - Win32 Debug !MESSAGE # Begin Project -# PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe -RSC=rc.exe !IF "$(CFG)" == "StcVC - Win32 Release" @@ -40,11 +38,12 @@ RSC=rc.exe # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" +RSC=rc.exe +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../include" /I "../../include" /I "scintilla/include" /I "scintilla/src" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D "__WX__" /D "SCI_LEXER" /FD /c # SUBTRACT CPP /YX -# ADD BASE RSC /l 0x809 -# ADD RSC /l 0x809 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -64,11 +63,12 @@ LIB32=link.exe -lib # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" +RSC=rc.exe +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "../../../include" /I "../../include" /I "scintilla/include" /I "scintilla/src" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D "__WX__" /D "SCI_LEXER" /FD /c # SUBTRACT CPP /YX -# ADD BASE RSC /l 0x809 -# ADD RSC /l 0x809 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -179,6 +179,34 @@ SOURCE=.\scintilla\src\KeyWords.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexCPP.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexHTML.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexOthers.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexPerl.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexPython.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexSQL.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexVB.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LineMarker.cxx # End Source File # Begin Source File diff --git a/contrib/src/stc/scintilla/include/Accessor.h b/contrib/src/stc/scintilla/include/Accessor.h index 1bba4af55e..031ad7a914 100644 --- a/contrib/src/stc/scintilla/include/Accessor.h +++ b/contrib/src/stc/scintilla/include/Accessor.h @@ -3,6 +3,8 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; + class Accessor { protected: // bufferSize is a trade off between time taken to copy the characters and SendMessage overhead @@ -15,12 +17,15 @@ protected: int endPos; int lenDoc; int offset; // Optional but including an offset makes GCC generate better code + int codePage; + bool InternalIsLeadByte(char ch); void Fill(int position); public: Accessor(WindowID id_, PropSet &props_, int offset_=0) : id(id_), props(props_), startPos(0x7FFFFFFF), endPos(0), - lenDoc(-1), offset(offset_) { + lenDoc(-1), offset(offset_), codePage(0) { } + void SetCodePage(int codePage_) { codePage = codePage_; } char operator[](int position) { position += offset; if (position < startPos || position >= endPos) { @@ -40,6 +45,9 @@ public: } return buf[position - startPos]; } + bool IsLeadByte(char ch) { + return codePage && InternalIsLeadByte(ch); + } char StyleAt(int position); int GetLine(int position); int LineStart(int line); @@ -54,6 +62,10 @@ public: PropSet &GetPropSet() { return props; } }; +class StylingContext; + +typedef bool (*PFNIsCommentLeader)(StylingContext &styler, int pos, int len); + class StylingContext : public Accessor { char styleBuf[bufferSize]; int validLen; @@ -65,12 +77,12 @@ public: Accessor(id_,props_,offset_), validLen(0), chFlags(0) {} void StartAt(unsigned int start, char chMask=31); void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; - void ColourSegment(unsigned int start, unsigned int end, int chAttr); unsigned int GetStartSegment() { return startSeg; } void StartSegment(unsigned int pos); void ColourTo(unsigned int pos, int chAttr); int GetLine(int position); void SetLevel(int line, int level); void Flush(); + int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); }; diff --git a/contrib/src/stc/scintilla/include/KeyWords.h b/contrib/src/stc/scintilla/include/KeyWords.h index 2cc03b788f..1b42ecdd93 100644 --- a/contrib/src/stc/scintilla/include/KeyWords.h +++ b/contrib/src/stc/scintilla/include/KeyWords.h @@ -3,6 +3,39 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. -void ColouriseDoc(int codePage, int startPos, int lengthDoc, int initStyle, - int language, WordList *keywordlists[], StylingContext &styler); +typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], StylingContext &styler); + +class LexerModule { + static LexerModule *base; + LexerModule *next; + int language; + LexerFunction fn; +public: + LexerModule(int language_, LexerFunction fn_); + static void Colourise(unsigned int startPos, int lengthDoc, int initStyle, + int language, WordList *keywordlists[], StylingContext &styler); +}; + +inline bool iswordchar(char ch) { + return isalnum(ch) || ch == '.' || ch == '_'; +} + +inline bool iswordstart(char ch) { + return isalnum(ch) || ch == '_'; +} + +inline bool isoperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || + ch == '(' || ch == ')' || ch == '-' || ch == '+' || + ch == '=' || ch == '|' || ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ':' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || ch == '/' || + ch == '?' || ch == '!' || ch == '.' || ch == '~') + return true; + return false; +} diff --git a/contrib/src/stc/scintilla/include/Platform.h b/contrib/src/stc/scintilla/include/Platform.h index 3a5e9816dc..021bcf686f 100644 --- a/contrib/src/stc/scintilla/include/Platform.h +++ b/contrib/src/stc/scintilla/include/Platform.h @@ -213,6 +213,8 @@ public: void Release(); FontID GetID() { return id; } + // Alias another font - caller guarantees not to Release + void SetID(FontID id_) { id = id_; } friend class Surface; }; @@ -290,6 +292,7 @@ public: int SetPalette(Palette *pal, bool inBackGround); void SetClip(PRectangle rc); + void FlushCachedState(); }; // Class to hide the details of window manipulation diff --git a/contrib/src/stc/scintilla/include/SciLexer.h b/contrib/src/stc/scintilla/include/SciLexer.h index d6667e4e25..3e0ad31b42 100644 --- a/contrib/src/stc/scintilla/include/SciLexer.h +++ b/contrib/src/stc/scintilla/include/SciLexer.h @@ -35,6 +35,8 @@ #define SCE_P_DEFNAME 9 #define SCE_P_OPERATOR 10 #define SCE_P_IDENTIFIER 11 +#define SCE_P_COMMENTBLOCK 12 +#define SCE_P_STRINGEOL 13 // Lexical states for SCLEX_CPP, SCLEX_VB #define SCE_C_DEFAULT 0 @@ -45,7 +47,7 @@ #define SCE_C_WORD 5 #define SCE_C_STRING 6 #define SCE_C_CHARACTER 7 -#define SCE_C_PUNTUATION 8 +#define SCE_C_UUID 8 #define SCE_C_PREPROCESSOR 9 #define SCE_C_OPERATOR 10 #define SCE_C_IDENTIFIER 11 @@ -63,49 +65,85 @@ #define SCE_H_OTHER 8 #define SCE_H_COMMENT 9 #define SCE_H_ENTITY 10 -// Embedded Javascript -#define SCE_HJ_START 11 -#define SCE_HJ_DEFAULT 12 -#define SCE_HJ_COMMENT 13 -#define SCE_HJ_COMMENTLINE 14 -#define SCE_HJ_COMMENTDOC 15 -#define SCE_HJ_NUMBER 16 -#define SCE_HJ_WORD 17 -#define SCE_HJ_KEYWORD 18 -#define SCE_HJ_DOUBLESTRING 19 -#define SCE_HJ_SINGLESTRING 20 -#define SCE_HJ_SYMBOLS 21 -#define SCE_HJ_STRINGEOL 28 // XML and ASP -#define SCE_H_TAGEND 22 -#define SCE_H_XMLSTART 23 -#define SCE_H_XMLEND 24 -#define SCE_H_SCRIPT 25 -#define SCE_H_ASP 26 -#define SCE_H_ASPAT 27 +#define SCE_H_TAGEND 11 +#define SCE_H_XMLSTART 12 +#define SCE_H_XMLEND 13 +#define SCE_H_SCRIPT 14 +#define SCE_H_ASP 15 +#define SCE_H_ASPAT 16 +// Embedded Javascript +#define SCE_HJ_START 40 +#define SCE_HJ_DEFAULT 41 +#define SCE_HJ_COMMENT 42 +#define SCE_HJ_COMMENTLINE 43 +#define SCE_HJ_COMMENTDOC 44 +#define SCE_HJ_NUMBER 45 +#define SCE_HJ_WORD 46 +#define SCE_HJ_KEYWORD 47 +#define SCE_HJ_DOUBLESTRING 48 +#define SCE_HJ_SINGLESTRING 49 +#define SCE_HJ_SYMBOLS 50 +#define SCE_HJ_STRINGEOL 51 +// ASP Javascript +#define SCE_HJA_START 55 +#define SCE_HJA_DEFAULT 56 +#define SCE_HJA_COMMENT 57 +#define SCE_HJA_COMMENTLINE 58 +#define SCE_HJA_COMMENTDOC 59 +#define SCE_HJA_NUMBER 60 +#define SCE_HJA_WORD 61 +#define SCE_HJA_KEYWORD 62 +#define SCE_HJA_DOUBLESTRING 63 +#define SCE_HJA_SINGLESTRING 64 +#define SCE_HJA_SYMBOLS 65 +#define SCE_HJA_STRINGEOL 66 // Embedded VBScript -#define SCE_HB_START 40 -#define SCE_HB_DEFAULT 41 -#define SCE_HB_COMMENTLINE 42 -#define SCE_HB_NUMBER 43 -#define SCE_HB_WORD 44 -#define SCE_HB_STRING 45 -#define SCE_HB_IDENTIFIER 46 -#define SCE_HB_STRINGEOL 47 +#define SCE_HB_START 70 +#define SCE_HB_DEFAULT 71 +#define SCE_HB_COMMENTLINE 72 +#define SCE_HB_NUMBER 73 +#define SCE_HB_WORD 74 +#define SCE_HB_STRING 75 +#define SCE_HB_IDENTIFIER 76 +#define SCE_HB_STRINGEOL 77 +// ASP VBScript +#define SCE_HBA_START 80 +#define SCE_HBA_DEFAULT 81 +#define SCE_HBA_COMMENTLINE 82 +#define SCE_HBA_NUMBER 83 +#define SCE_HBA_WORD 84 +#define SCE_HBA_STRING 85 +#define SCE_HBA_IDENTIFIER 86 +#define SCE_HBA_STRINGEOL 87 // Embedded Python -#define SCE_HP_START 50 -#define SCE_HP_DEFAULT 51 -#define SCE_HP_COMMENTLINE 52 -#define SCE_HP_NUMBER 53 -#define SCE_HP_STRING 54 -#define SCE_HP_CHARACTER 55 -#define SCE_HP_WORD 56 -#define SCE_HP_TRIPLE 57 -#define SCE_HP_TRIPLEDOUBLE 58 -#define SCE_HP_CLASSNAME 59 -#define SCE_HP_DEFNAME 60 -#define SCE_HP_OPERATOR 61 -#define SCE_HP_IDENTIFIER 62 +#define SCE_HP_START 90 +#define SCE_HP_DEFAULT 91 +#define SCE_HP_COMMENTLINE 92 +#define SCE_HP_NUMBER 93 +#define SCE_HP_STRING 94 +#define SCE_HP_CHARACTER 95 +#define SCE_HP_WORD 96 +#define SCE_HP_TRIPLE 97 +#define SCE_HP_TRIPLEDOUBLE 98 +#define SCE_HP_CLASSNAME 99 +#define SCE_HP_DEFNAME 100 +#define SCE_HP_OPERATOR 101 +#define SCE_HP_IDENTIFIER 102 +// ASP Python +#define SCE_HPA_START 105 +#define SCE_HPA_DEFAULT 106 +#define SCE_HPA_COMMENTLINE 107 +#define SCE_HPA_NUMBER 108 +#define SCE_HPA_STRING 109 +#define SCE_HPA_CHARACTER 110 +#define SCE_HPA_WORD 111 +#define SCE_HPA_TRIPLE 112 +#define SCE_HPA_TRIPLEDOUBLE 113 +#define SCE_HPA_CLASSNAME 114 +#define SCE_HPA_DEFNAME 115 +#define SCE_HPA_OPERATOR 116 +#define SCE_HPA_IDENTIFIER 117 // Lexical states for SCLEX_PERL #define SCE_PL_DEFAULT 0 diff --git a/contrib/src/stc/scintilla/include/Scintilla.h b/contrib/src/stc/scintilla/include/Scintilla.h index 07572168dc..822b2ea9d7 100644 --- a/contrib/src/stc/scintilla/include/Scintilla.h +++ b/contrib/src/stc/scintilla/include/Scintilla.h @@ -156,7 +156,7 @@ extern "C" { #define STYLE_BRACELIGHT 34 #define STYLE_BRACEBAD 35 #define STYLE_CONTROLCHAR 36 -#define STYLE_MAX 63 +#define STYLE_MAX 127 #define SCI_STYLECLEARALL SCI_START + 50 #define SCI_STYLESETFORE SCI_START + 51 @@ -279,6 +279,11 @@ extern "C" { #define SCI_ZOOMOUT SCI_START + 334 #define SCI_DELWORDLEFT SCI_START + 335 #define SCI_DELWORDRIGHT SCI_START + 336 +#define SCI_LINECUT SCI_START + 337 +#define SCI_LINEDELETE SCI_START + 338 +#define SCI_LINETRANSPOSE SCI_START + 339 +#define SCI_LOWERCASE SCI_START + 340 +#define SCI_UPPERCASE SCI_START + 341 #define SCI_LINELENGTH SCI_START + 350 #define SCI_BRACEHIGHLIGHT SCI_START + 351 @@ -311,6 +316,8 @@ extern "C" { // OR this with CARET_SLOP to reposition whenever outside slop border #define SCI_SETCARETPOLICY SCI_START + 369 +#define SCI_LINESONSCREEN SCI_START + 370 +#define SCI_USEPOPUP SCI_START + 371 // GTK+ Specific #define SCI_GRABFOCUS SCI_START + 400 @@ -342,6 +349,7 @@ typedef void (tMacroRecorder)(UINT iMessage, WPARAM wParam, LPARAM lParam, #define SC_PERFORMED_UNDO 0x20 #define SC_PERFORMED_REDO 0x40 #define SC_LASTSTEPINUNDOREDO 0x100 +#define SC_MOD_CHANGEMARKER 0x200 #define SC_MODEVENTMASKALL 0x377 diff --git a/contrib/src/stc/scintilla/src/Accessor.cxx b/contrib/src/stc/scintilla/src/Accessor.cxx index 57b7e4dc4e..f080742bd6 100644 --- a/contrib/src/stc/scintilla/src/Accessor.cxx +++ b/contrib/src/stc/scintilla/src/Accessor.cxx @@ -4,6 +4,7 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include #include "Platform.h" @@ -12,6 +13,17 @@ #include "Accessor.h" #include "Scintilla.h" +bool Accessor::InternalIsLeadByte(char ch) { +#if PLAT_GTK + // TODO: support DBCS under GTK+ + return false; +#elif PLAT_WIN + return IsDBCSLeadByteEx(codePage, ch); +#elif PLAT_WX + return false; +#endif +} + void Accessor::Fill(int position) { if (lenDoc == -1) lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); @@ -63,35 +75,31 @@ void StylingContext::StartAt(unsigned int start, char chMask) { Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask); } -void StylingContext::ColourSegment(unsigned int start, unsigned int end, int chAttr) { +void StylingContext::StartSegment(unsigned int pos) { + startSeg = pos; +} + +void StylingContext::ColourTo(unsigned int pos, int chAttr) { // Only perform styling if non empty range - if (end != start - 1) { - if (end < start) { - Platform::DebugPrintf("Bad colour positions %d - %d\n", start, end); + if (pos != startSeg - 1) { + if (pos < startSeg) { + Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos); } - if (validLen + (end - start + 1) >= bufferSize) + if (validLen + (pos - startSeg + 1) >= bufferSize) Flush(); - if (validLen + (end - start + 1) >= bufferSize) { + if (validLen + (pos - startSeg + 1) >= bufferSize) { // Too big for buffer so send directly - Platform::SendScintilla(id, SCI_SETSTYLING, end - start + 1, chAttr); + Platform::SendScintilla(id, SCI_SETSTYLING, pos - startSeg + 1, chAttr); } else { if (chAttr != chWhile) chFlags = 0; chAttr |= chFlags; - for (unsigned int i = start; i <= end; i++) { + for (unsigned int i = startSeg; i <= pos; i++) { styleBuf[validLen++] = chAttr; } } } -} - -void StylingContext::StartSegment(unsigned int pos) { - startSeg = pos; -} - -void StylingContext::ColourTo(unsigned int pos, int chAttr) { - ColourSegment(startSeg, pos, chAttr); startSeg = pos+1; } @@ -110,3 +118,49 @@ void StylingContext::Flush() { validLen = 0; } } + +int StylingContext::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { + int end = Length(); + int spaceFlags = 0; + + // Determines the indentation level of the current line and also checks for consistent + // indentation compared to the previous line. + // Indentation is judged consistent when the indentation whitespace of each line lines + // the same or the indentation of one line is a prefix of the other. + + int pos = LineStart(line); + char ch = (*this)[pos]; + int indent = 0; + bool inPrevPrefix = line > 0; + int posPrev = inPrevPrefix ? LineStart(line-1) : 0; + while ((ch == ' ' || ch == '\t') && (pos < end)) { + if (inPrevPrefix) { + char chPrev = (*this)[posPrev++]; + if (chPrev == ' ' || chPrev == '\t') { + if (chPrev != ch) + spaceFlags |= wsInconsistent; + } else { + inPrevPrefix = false; + } + } + if (ch == ' ') { + spaceFlags |= wsSpace; + indent++; + } else { // Tab + spaceFlags |= wsTab; + if (spaceFlags & wsSpace) + spaceFlags |= wsSpaceTab; + indent = (indent / 8 + 1) * 8; + } + ch = (*this)[++pos]; + } + + *flags = spaceFlags; + indent += SC_FOLDLEVELBASE; + // if completely empty line or the start of a comment... + if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) ) + return indent | SC_FOLDLEVELWHITEFLAG; + else + return indent; +} + diff --git a/contrib/src/stc/scintilla/src/CellBuffer.cxx b/contrib/src/stc/scintilla/src/CellBuffer.cxx index 777688511a..56a4be78c8 100644 --- a/contrib/src/stc/scintilla/src/CellBuffer.cxx +++ b/contrib/src/stc/scintilla/src/CellBuffer.cxx @@ -344,31 +344,200 @@ void Action::Grab(Action *source) { source->lenData = 0; } -CellBuffer::CellBuffer(int initialLength) { - body = new char[initialLength]; - size = initialLength; - length = 0; - part1len = 0; - gaplen = initialLength; - part2body = body + gaplen; - readOnly = false; +// The undo history stores a sequence of user operations that represent the user's view of the +// commands executed on the text. +// Each user operation contains a sequence of text insertion and text deletion actions. +// All the user operations are stored in a list of individual actions with 'start' actions used +// as delimiters between user operations. +// Initially there is one start action in the history. +// As each action is performed, it is recorded in the history. The action may either become +// part of the current user operation or may start a new user operation. If it is to be part of the +// current operation, then it overwrites the current last action. If it is to be part of a new +// operation, it is appended after the current last action. +// After writing the new action, a new start action is appended at the end of the history. +// The decision of whether to start a new user operation is based upon two factors. If a +// compound operation has been explicitly started by calling BeginUndoAction and no matching +// EndUndoAction (these calls nest) has been called, then the action is coalesced into the current +// operation. If there is no outstanding BeginUndoAction call then a new operation is started +// unless it looks as if the new action is caused by the user typing or deleting a stream of text. +// Sequences that look like typing or deletion are coalesced into a single user operation. + +UndoHistory::UndoHistory() { lenActions = 100; actions = new Action[lenActions]; maxAction = 0; currentAction = 0; - collectingUndo = undoCollectAutoStart; undoSequenceDepth = 0; savePoint = 0; actions[currentAction].Create(startAction); } +UndoHistory::~UndoHistory() { + delete []actions; + actions = 0; +} + +void UndoHistory::EnsureUndoRoom() { + //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction); + if (currentAction >= 2) { + // Have to test that there is room for 2 more actions in the array + // as two actions may be created by this function + if (currentAction >= (lenActions - 2)) { + // Run out of undo nodes so extend the array + int lenActionsNew = lenActions * 2; + Action *actionsNew = new Action[lenActionsNew]; + if (!actionsNew) + return; + for (int act = 0; act <= currentAction; act++) + actionsNew[act].Grab(&actions[act]); + delete []actions; + lenActions = lenActionsNew; + actions = actionsNew; + } + } +} + +void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData) { + EnsureUndoRoom(); + //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); + //Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at, + // actions[currentAction - 1].position, actions[currentAction - 1].lenData); + if (currentAction >= 1) { + if (0 == undoSequenceDepth) { + // Top level actions may not always be coalesced + Action &actPrevious = actions[currentAction - 1]; + // See if current action can be coalesced into previous action + // Will work if both are inserts or deletes and position is same + if (at != actPrevious.at) { + currentAction++; + } else if (currentAction == savePoint) { + currentAction++; + } else if ((at == removeAction) && + ((position + lengthData * 2) != actPrevious.position)) { + // Removals must be at same position to coalesce + currentAction++; + } else if ((at == insertAction) && + (position != (actPrevious.position + actPrevious.lenData*2))) { + // Insertions must be immediately after to coalesce + currentAction++; + } else { + //Platform::DebugPrintf("action coalesced\n"); + } + } else { + currentAction++; + } + } else { + currentAction++; + } + actions[currentAction].Create(at, position, data, lengthData); + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; +} + +void UndoHistory::BeginUndoAction() { + EnsureUndoRoom(); + if (undoSequenceDepth == 0) { + if (actions[currentAction].at != startAction) { + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; + } + } + undoSequenceDepth++; +} + +void UndoHistory::EndUndoAction() { + EnsureUndoRoom(); + undoSequenceDepth--; + if (0 == undoSequenceDepth) { + if (actions[currentAction].at != startAction) { + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; + } + } +} + +void UndoHistory::DropUndoSequence() { + undoSequenceDepth = 0; +} + +void UndoHistory::DeleteUndoHistory() { + for (int i = 1; i < maxAction; i++) + actions[i].Destroy(); + maxAction = 0; + currentAction = 0; + actions[currentAction].Create(startAction); + savePoint = 0; +} + +void UndoHistory::SetSavePoint() { + savePoint = currentAction; +} + +bool UndoHistory::IsSavePoint() const { + return savePoint == currentAction; +} + +bool UndoHistory::CanUndo() const { + return (currentAction > 0) && (maxAction > 0); +} + +int UndoHistory::StartUndo() { + // Drop any trailing startAction + if (actions[currentAction].at == startAction && currentAction > 0) + currentAction--; + + // Count the steps in this action + int act = currentAction; + while (actions[act].at != startAction && act > 0) { + act--; + } + return currentAction - act; +} + +const Action &UndoHistory::UndoStep() { + return actions[currentAction--]; +} + +bool UndoHistory::CanRedo() const { + return maxAction > currentAction; +} + +int UndoHistory::StartRedo() { + // Drop any leading startAction + if (actions[currentAction].at == startAction && currentAction < maxAction) + currentAction++; + + // Count the steps in this action + int act = currentAction; + while (actions[act].at != startAction && act < maxAction) { + act++; + } + return act - currentAction; +} + +const Action &UndoHistory::RedoStep() { + return actions[currentAction++]; +} + +CellBuffer::CellBuffer(int initialLength) { + body = new char[initialLength]; + size = initialLength; + length = 0; + part1len = 0; + gaplen = initialLength; + part2body = body + gaplen; + readOnly = false; + collectingUndo = undoCollectAutoStart; +} + CellBuffer::~CellBuffer() { delete []body; body = 0; - delete []actions; - actions = 0; } void CellBuffer::GapTo(int position) { @@ -486,7 +655,7 @@ const char *CellBuffer::InsertString(int position, char *s, int insertLength) { for (int i = 0; i < insertLength / 2; i++) { data[i] = s[i * 2]; } - AppendAction(insertAction, position, data, insertLength / 2); + uh.AppendAction(insertAction, position, data, insertLength / 2); } BasicInsertString(position, s, insertLength); @@ -525,48 +694,6 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas return changed; } -void CellBuffer::EnsureUndoRoom() { - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction); - if (currentAction >= 2) { - // Have to test that there is room for 2 more actions in the array - // as two actions may be created by this function - if (currentAction >= (lenActions - 2)) { - // Run out of undo nodes so extend the array - int lenActionsNew = lenActions * 2; - Action *actionsNew = new Action[lenActionsNew]; - if (!actionsNew) - return; - for (int act = 0; act <= currentAction; act++) - actionsNew[act].Grab(&actions[act]); - delete []actions; - lenActions = lenActionsNew; - actions = actionsNew; - } - } -} - -void CellBuffer::AppendAction(actionType at, int position, char *data, int lengthData) { - EnsureUndoRoom(); - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); - if (currentAction >= 2) { - // See if current action can be coalesced into previous action - // Will work if both are inserts or deletes and position is same or two different - if ((at != actions[currentAction - 1].at) || (abs(position - actions[currentAction - 1].position) > 2)) { - currentAction++; - } else if (currentAction == savePoint) { - currentAction++; - } - } else { - currentAction++; - } - actions[currentAction].Create(at, position, data, lengthData); - if ((collectingUndo == undoCollectAutoStart) && (0 == undoSequenceDepth)) { - currentAction++; - actions[currentAction].Create(startAction); - } - maxAction = currentAction; -} - const char *CellBuffer::DeleteChars(int position, int deleteLength) { // InsertString and DeleteChars are the bottleneck though which all changes occur char *data = 0; @@ -577,7 +704,7 @@ const char *CellBuffer::DeleteChars(int position, int deleteLength) { for (int i = 0; i < deleteLength / 2; i++) { data[i] = ByteAt(position + i * 2); } - AppendAction(removeAction, position, data, deleteLength / 2); + uh.AppendAction(removeAction, position, data, deleteLength / 2); } BasicDeleteChars(position, deleteLength); @@ -616,11 +743,11 @@ void CellBuffer::SetReadOnly(bool set) { } void CellBuffer::SetSavePoint() { - savePoint = currentAction; + uh.SetSavePoint(); } bool CellBuffer::IsSavePoint() { - return savePoint == currentAction; + return uh.IsSavePoint(); } int CellBuffer::AddMark(int line, int markerNum) { @@ -792,7 +919,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { undoCollectionType CellBuffer::SetUndoCollection(undoCollectionType collectUndo) { collectingUndo = collectUndo; - undoSequenceDepth = 0; + uh.DropUndoSequence(); return collectingUndo; } @@ -800,69 +927,28 @@ bool CellBuffer::IsCollectingUndo() { return collectingUndo; } -void CellBuffer::AppendUndoStartAction() { - EnsureUndoRoom(); - // Finish any currently active undo sequence - undoSequenceDepth = 0; - if (actions[currentAction].at != startAction) { - undoSequenceDepth++; - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } -} - void CellBuffer::BeginUndoAction() { - EnsureUndoRoom(); - if (undoSequenceDepth == 0) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - } - undoSequenceDepth++; + uh.BeginUndoAction(); } void CellBuffer::EndUndoAction() { - EnsureUndoRoom(); - undoSequenceDepth--; - if (0 == undoSequenceDepth) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - } + uh.EndUndoAction(); } void CellBuffer::DeleteUndoHistory() { - for (int i = 1; i < maxAction; i++) - actions[i].Destroy(); - maxAction = 0; - currentAction = 0; - savePoint = 0; + uh.DeleteUndoHistory(); } bool CellBuffer::CanUndo() { - return (!readOnly) && ((currentAction > 0) && (maxAction > 0)); + return (!readOnly) && (uh.CanUndo()); } int CellBuffer::StartUndo() { - // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) - currentAction--; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act > 0) { - act--; - } - return currentAction - act; + return uh.StartUndo(); } const Action &CellBuffer::UndoStep() { - const Action &actionStep = actions[currentAction]; + const Action &actionStep = uh.UndoStep(); if (actionStep.at == insertAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } else if (actionStep.at == removeAction) { @@ -874,29 +960,19 @@ const Action &CellBuffer::UndoStep() { BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } - currentAction--; return actionStep; } bool CellBuffer::CanRedo() { - return (!readOnly) && (maxAction > currentAction); + return (!readOnly) && (uh.CanRedo()); } int CellBuffer::StartRedo() { - // Drop any leading startAction - if (actions[currentAction].at == startAction && currentAction < maxAction) - currentAction++; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act < maxAction) { - act++; - } - return act - currentAction; + return uh.StartRedo(); } const Action &CellBuffer::RedoStep() { - const Action &actionStep = actions[currentAction]; + const Action &actionStep = uh.RedoStep(); if (actionStep.at == insertAction) { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { @@ -908,7 +984,6 @@ const Action &CellBuffer::RedoStep() { } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } - currentAction++; return actionStep; } diff --git a/contrib/src/stc/scintilla/src/CellBuffer.h b/contrib/src/stc/scintilla/src/CellBuffer.h index 5fbe2ea8a0..6e052077e9 100644 --- a/contrib/src/stc/scintilla/src/CellBuffer.h +++ b/contrib/src/stc/scintilla/src/CellBuffer.h @@ -89,6 +89,42 @@ public: enum undoCollectionType { undoCollectNone, undoCollectAutoStart, undoCollectManualStart }; +class UndoHistory { + Action *actions; + int lenActions; + int maxAction; + int currentAction; + int undoSequenceDepth; + int savePoint; + + void EnsureUndoRoom(); + +public: + UndoHistory(); + ~UndoHistory(); + + void AppendAction(actionType at, int position, char *data, int length); + + void BeginUndoAction(); + void EndUndoAction(); + void DropUndoSequence(); + void DeleteUndoHistory(); + + // The save point is a marker in the undo stack where the container has stated that + // the buffer was saved. Undo and redo can move over the save point. + void SetSavePoint(); + bool IsSavePoint() const; + + // To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is + // called that many times. Similarly for redo. + bool CanUndo() const; + int StartUndo(); + const Action &UndoStep(); + bool CanRedo() const; + int StartRedo(); + const Action &RedoStep(); +}; + // Holder for an expandable array of characters that supports undo and line markers // Based on article "Data Structures in a Bit-Mapped Text Editor" // by Wilfred J. Hansen, Byte January 1987, page 183 @@ -102,13 +138,8 @@ private: char *part2body; bool readOnly; - Action *actions; - int lenActions; - int maxAction; - int currentAction; undoCollectionType collectingUndo; - int undoSequenceDepth; - int savePoint; + UndoHistory uh; LineVector lv; @@ -117,9 +148,6 @@ private: void GapTo(int position); void RoomFor(int insertionLength); - void EnsureUndoRoom(); - void AppendAction(actionType at, int position, char *data, int length); - inline char ByteAt(int position); void SetByteAt(int position, char ch); @@ -170,12 +198,11 @@ public: undoCollectionType SetUndoCollection(undoCollectionType collectUndo); bool IsCollectingUndo(); - void AppendUndoStartAction(); void BeginUndoAction(); void EndUndoAction(); void DeleteUndoHistory(); - // To perform an undo, StartUndo is called to retreive the number of steps, then UndoStep is + // To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is // called that many times. Similarly for redo. bool CanUndo(); int StartUndo(); diff --git a/contrib/src/stc/scintilla/src/ContractionState.cxx b/contrib/src/stc/scintilla/src/ContractionState.cxx index 6f41461eb1..816d06aae7 100644 --- a/contrib/src/stc/scintilla/src/ContractionState.cxx +++ b/contrib/src/stc/scintilla/src/ContractionState.cxx @@ -108,8 +108,8 @@ void ContractionState::InsertLines(int lineDoc, int lineCount) { return; } //Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc); - if ((linesInDoc + 2) >= size) { - Grow(size + growSize); + if ((linesInDoc + lineCount + 2) >= size) { + Grow(linesInDoc + lineCount + growSize); } linesInDoc += lineCount; linesInDisplay += lineCount; @@ -155,7 +155,7 @@ bool ContractionState::GetVisible(int lineDoc) const { bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { if (size == 0) { - Grow(lineDocEnd + growSize); + Grow(linesInDoc + growSize); } // TODO: modify docLine members to mirror displayLine int delta = 0; @@ -191,7 +191,7 @@ bool ContractionState::GetExpanded(int lineDoc) const { bool ContractionState::SetExpanded(int lineDoc, bool expanded) { if (size == 0) { - Grow(lineDoc + growSize); + Grow(linesInDoc + growSize); } if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { if (lines[lineDoc].expanded != expanded) { diff --git a/contrib/src/stc/scintilla/src/Document.cxx b/contrib/src/stc/scintilla/src/Document.cxx index 7d832241fc..95107eb087 100644 --- a/contrib/src/stc/scintilla/src/Document.cxx +++ b/contrib/src/stc/scintilla/src/Document.cxx @@ -65,26 +65,54 @@ void Document::SetSavePoint() { NotifySavePoint(true); } -int Document::LineStart(int line) { - return cb.LineStart(line); +int Document::AddMark(int line, int markerNum) { + int prev = cb.AddMark(line, markerNum); + DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0); + NotifyModified(mh); + return prev; } -int Document::LineFromPosition(int pos) { - return cb.LineFromPosition(pos); +void Document::DeleteMark(int line, int markerNum) { + cb.DeleteMark(line, markerNum); + DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0); + NotifyModified(mh); } -int Document::LineEndPosition(int position) { - int line = LineFromPosition(position); +void Document::DeleteMarkFromHandle(int markerHandle) { + cb.DeleteMarkFromHandle(markerHandle); + DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); + NotifyModified(mh); +} + +void Document::DeleteAllMarks(int markerNum) { + cb.DeleteAllMarks(markerNum); + DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); + NotifyModified(mh); +} + +int Document::LineStart(int line) { + return cb.LineStart(line); +} + +int Document::LineEnd(int line) { if (line == LinesTotal() - 1) { - position = LineStart(line + 1); + return LineStart(line + 1); } else { - position = LineStart(line + 1) - 1; + int position = LineStart(line + 1) - 1; // When line terminator is CR+LF, may need to go back one more if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) { position--; } + return position; } - return position; +} + +int Document::LineFromPosition(int pos) { + return cb.LineFromPosition(pos); +} + +int Document::LineEndPosition(int position) { + return LineEnd(LineFromPosition(position)); } int Document::VCHomePosition(int position) { @@ -124,7 +152,10 @@ int Document::GetLastChild(int lineParent, int level) { level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK; int maxLine = LinesTotal(); int lineMaxSubord = lineParent; - while ((lineMaxSubord < maxLine-1) && IsSubordinate(level, GetLevel(lineMaxSubord+1))) { + while (lineMaxSubord < maxLine-1) { + EnsureStyledTo(LineStart(lineMaxSubord+2)); + if (!IsSubordinate(level, GetLevel(lineMaxSubord+1))) + break; lineMaxSubord++; } if (lineMaxSubord > lineParent) { @@ -307,6 +338,7 @@ int Document::Undo() { enteredCount++; bool startSavePoint = cb.IsSavePoint(); int steps = cb.StartUndo(); + //Platform::DebugPrintf("Steps=%d\n", steps); for (int step=0; step GetEndStyled() && i < lenWatchers; i++) + watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos); + return pos <= GetEndStyled(); +} + bool Document::AddWatcher(DocWatcher *watcher, void *userData) { for (int i = 0; i < lenWatchers; i++) { if ((watchers[i].watcher == watcher) && diff --git a/contrib/src/stc/scintilla/src/Document.h b/contrib/src/stc/scintilla/src/Document.h index fba611c7f7..4c212b7bd1 100644 --- a/contrib/src/stc/scintilla/src/Document.h +++ b/contrib/src/stc/scintilla/src/Document.h @@ -111,7 +111,6 @@ public: undoCollectionType SetUndoCollection(undoCollectionType collectUndo) { return cb.SetUndoCollection(collectUndo); } - void AppendUndoStartAction() { cb.AppendUndoStartAction(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void SetSavePoint(); @@ -123,6 +122,7 @@ public: void InsertChar(int pos, char ch); void InsertString(int position, const char *s); void InsertString(int position, const char *s, int insertLength); + void ChangeChar(int pos, char ch); void DelChar(int pos); int DelCharBack(int pos); @@ -132,12 +132,13 @@ public: } char StyleAt(int position) { return cb.StyleAt(position); } int GetMark(int line) { return cb.GetMark(line); } - int AddMark(int line, int markerNum) { return cb.AddMark(line, markerNum); } - void DeleteMark(int line, int markerNum) { cb.DeleteMark(line, markerNum); } - void DeleteMarkFromHandle(int markerHandle) { cb.DeleteMarkFromHandle(markerHandle); } - void DeleteAllMarks(int markerNum) { cb.DeleteAllMarks(markerNum); } + int AddMark(int line, int markerNum); + void DeleteMark(int line, int markerNum); + void DeleteMarkFromHandle(int markerHandle); + void DeleteAllMarks(int markerNum); int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); } int LineStart(int line); + int LineEnd(int line); int LineEndPosition(int position); int VCHomePosition(int position); @@ -154,12 +155,15 @@ public: long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam); int LinesTotal(); + void ChangeCase(Range r, bool makeUpperCase); + void SetWordChars(unsigned char *chars); void SetStylingBits(int bits); void StartStyling(int position, char mask); void SetStyleFor(int length, char style); void SetStyles(int length, char *styles); int GetEndStyled() { return endStyled; } + bool EnsureStyledTo(int pos); int SetLineState(int line, int state) { return cb.SetLineState(line, state); } int GetLineState(int line) { return cb.GetLineState(line); } @@ -217,6 +221,7 @@ public: virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; virtual void NotifyDeleted(Document *doc, void *userData) = 0; + virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; }; #endif diff --git a/contrib/src/stc/scintilla/src/Editor.cxx b/contrib/src/stc/scintilla/src/Editor.cxx index 6508c95b1f..226184db27 100644 --- a/contrib/src/stc/scintilla/src/Editor.cxx +++ b/contrib/src/stc/scintilla/src/Editor.cxx @@ -88,6 +88,8 @@ Editor::Editor() { modEventMask = SC_MODEVENTMASKALL; + displayPopupMenu = true; + pdoc = new Document(); pdoc ->AddRef(); pdoc->AddWatcher(this, 0); @@ -631,7 +633,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { int line = cs.DocFromDisplay(visibleLine); int yposScreen = 0; - while (line < pdoc->LinesTotal() && yposScreen < rcMargin.bottom) { + while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) { int marks = pdoc->GetMark(line); if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { if (cs.GetExpanded(line)) { @@ -648,7 +650,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { char number[100]; number[0] = '\0'; sprintf(number, "%d", line + 1); - if (foldFlags & 8) + if (foldFlags & 64) sprintf(number, "%X", pdoc->GetLevel(line)); int xpos = 0; PRectangle rcNumber=rcMarker; @@ -853,7 +855,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, } else { rcSegment.left = ll.positions[startseg] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; - // Only try do draw if really visible - enhances performance by not calling environment to + // Only try to draw if really visible - enhances performance by not calling environment to // draw strings that are completely past the right side of the window. if (rcSegment.left <= rcLine.right) { surface->DrawText(rcSegment, textFont, @@ -991,10 +993,9 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { ypos += screenLinePaintFirst * vs.lineHeight; int yposScreen = screenLinePaintFirst * vs.lineHeight; - if (endPosPaint > pdoc->GetEndStyled()) { - // Notify container to do some more styling - NotifyStyleNeeded(endPosPaint); - } + // Ensure we are styled as far as we are painting. + pdoc->EnsureStyledTo(endPosPaint); + if (needUpdateUI) { NotifyUpdateUI(); needUpdateUI = false; @@ -1009,7 +1010,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { } if (paintState == paintAbandoned) { - // Either NotifyStyleNeeded or NotifyUpdateUI noticed that painting is needed + // Either styling or NotifyUpdateUI noticed that painting is needed // outside the current painting rectangle //Platform::DebugPrintf("Abandoning paint\n"); return; @@ -1067,13 +1068,21 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (cs.GetVisible(line)) DrawLine(surface, vs, line, xStart, rcLine, ll); - if (foldFlags & 2) { + bool expanded = cs.GetExpanded(line); + if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) { if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { PRectangle rcFoldLine = rcLine; rcFoldLine.bottom = rcFoldLine.top + 1; surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); } } + if ( (expanded && (foldFlags & 8)) || (!expanded && (foldFlags & 16)) ) { + if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { + PRectangle rcFoldLine = rcLine; + rcFoldLine.top = rcFoldLine.bottom - 1; + surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); + } + } // Draw the Caret if (line == lineCaret) { @@ -1204,10 +1213,9 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { if (linePrintLast < pdoc->LinesTotal()) endPosPrint = pdoc->LineStart(linePrintLast + 1); - if (endPosPrint > pdoc->GetEndStyled()) { - // Notify container to do some more styling - NotifyStyleNeeded(endPosPrint); - } + // Ensure we are styled to where we are formatting. + pdoc->EnsureStyledTo(endPosPrint); + int xStart = vsPrint.fixedColumnWidth + pfr->rc.left + lineNumberWidth; int ypos = pfr->rc.top; int line = linePrintStart; @@ -1228,20 +1236,27 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { PRectangle rcNumber = rcLine; rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify - rcNumber.left += lineNumberWidth - + rcNumber.left -= surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number)); surface->DrawText(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, ypos + vsPrint.maxAscent, number, strlen(number), vsPrint.styles[STYLE_LINENUMBER].fore.allocated, vsPrint.styles[STYLE_LINENUMBER].back.allocated); } + + // When printing, the hdc and hdcTarget may be the same, so + // changing the state of surfaceMeasure may change the underlying + // state of surface. Therefore, any cached state is discarded before + // using each surface. // Copy this line and its styles from the document into local arrays // and determine the x position at which each character starts. + surfaceMeasure->FlushCachedState(); LineLayout ll; LayoutLine(line, surfaceMeasure, vsPrint, ll); // Draw the line + surface->FlushCachedState(); DrawLine(surface, vsPrint, line, xStart, rcLine, ll); ypos += vsPrint.lineHeight; @@ -1421,6 +1436,10 @@ void Editor::NotifyStyleNeeded(int endStyleNeeded) { NotifyParent(scn); } +void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) { + NotifyStyleNeeded(endStyleNeeded); +} + void Editor::NotifyChar(char ch) { SCNotification scn; scn.nmhdr.code = SCN_CHARADDED; @@ -1599,6 +1618,10 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { SetScrollBars(); } + if (mh.modificationType & SC_MOD_CHANGEMARKER) { + RedrawSelMargin(); + } + // If client wants to see this modification if (mh.modificationType & modEventMask) { if ((mh.modificationType & SC_MOD_CHANGESTYLE) == 0) { @@ -1677,6 +1700,11 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_VCHOMEEXTEND: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: break; // Filter out all others (display changes, etc) @@ -1712,6 +1740,60 @@ void Editor::PageMove(int direction, bool extend) { } } +void Editor::ChangeCaseOfSelection(bool makeUpperCase) { + pdoc->BeginUndoAction(); + int startCurrent = currentPos; + int startAnchor = anchor; + if (selType == selRectangle) { + int lineStart = pdoc->LineFromPosition(SelectionStart()); + int lineEnd = pdoc->LineFromPosition(SelectionEnd()); + for (int line=lineStart; line <= lineEnd; line++) { + pdoc->ChangeCase( + Range(SelectionStart(line), SelectionEnd(line)), + makeUpperCase); + } + // Would be nicer to keep the rectangular selection but this is complex + selType = selStream; + SetSelection(startCurrent, startCurrent); + } else { + pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()), + makeUpperCase); + SetSelection(startCurrent, startAnchor); + } + pdoc->EndUndoAction(); +} + + +void Editor::LineTranspose() { + int line = pdoc->LineFromPosition(currentPos); + if (line > 0) { + int startPrev = pdoc->LineStart(line-1); + int endPrev = pdoc->LineEnd(line-1); + int start = pdoc->LineStart(line); + int end = pdoc->LineEnd(line); + int startNext = pdoc->LineStart(line+1); + if (end < pdoc->Length()) { + end = startNext; + char *thisLine = CopyRange(start, end); + pdoc->DeleteChars(start, end-start); + pdoc->InsertString(startPrev, thisLine, end-start); + MovePositionTo(startPrev+end-start); + delete []thisLine; + } else { + // Last line so line has no line end + char *thisLine = CopyRange(start, end); + char *prevEnd = CopyRange(endPrev, start); + pdoc->DeleteChars(endPrev, end-endPrev); + pdoc->InsertString(startPrev, thisLine, end-start); + pdoc->InsertString(startPrev + end-start, prevEnd, start-endPrev); + MovePositionTo(startPrev + end-endPrev); + delete []thisLine; + delete []prevEnd; + } + + } +} + int Editor::KeyCommand(UINT iMessage) { Point pt = LocationFromPosition(currentPos); @@ -1884,8 +1966,40 @@ int Editor::KeyCommand(UINT iMessage) { case SCI_DELWORDRIGHT: { int endWord = pdoc->NextWordStart(currentPos, 1); pdoc->DeleteChars(currentPos, endWord - currentPos); + MovePositionTo(currentPos); } break; + case SCI_LINECUT: { + int lineStart = pdoc->LineFromPosition(currentPos); + int lineEnd = pdoc->LineFromPosition(anchor); + if (lineStart > lineEnd) { + int t = lineEnd; + lineEnd = lineStart; + lineStart = t; + } + int start = pdoc->LineStart(lineStart); + int end = pdoc->LineStart(lineEnd+1); + SetSelection(start,end); + Cut(); + } + break; + case SCI_LINEDELETE: { + int line = pdoc->LineFromPosition(currentPos); + int start = pdoc->LineStart(line); + int end = pdoc->LineStart(line+1); + pdoc->DeleteChars(start, end-start); + MovePositionTo(start); + } + break; + case SCI_LINETRANSPOSE: + LineTranspose(); + break; + case SCI_LOWERCASE: + ChangeCaseOfSelection(false); + break; + case SCI_UPPERCASE: + ChangeCaseOfSelection(true); + break; } return 0; } @@ -2111,7 +2225,11 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul int positionWasInSelection = PositionInSelection(position); - if ((!inDragDrop) || !(0 == positionWasInSelection)) { + bool positionOnEdgeOfSelection = + (position == SelectionStart()) || (position == SelectionEnd()); + + if ((!inDragDrop) || !(0 == positionWasInSelection) || + (positionOnEdgeOfSelection && !moving)) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); @@ -2566,6 +2684,10 @@ void Editor::SetDocPointer(Document *document) { pdoc = document; } pdoc->AddRef(); + // Reset the contraction state to fully shown. + cs.Clear(); + cs.InsertLines(0, pdoc->LinesTotal()-1); + pdoc->AddWatcher(this, 0); Redraw(); SetScrollBars(); @@ -2680,6 +2802,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case WM_PASTE: Paste(); SetLastXChosen(); + EnsureCaretVisible(); break; case WM_CLEAR: @@ -3061,7 +3184,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_APPENDUNDOSTARTACTION: - pdoc->AppendUndoStartAction(); + // Not just deprecated - now dead + //pdoc->AppendUndoStartAction(); return 0; #endif @@ -3260,18 +3384,15 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case SCI_MARKERADD: { int markerID = pdoc->AddMark(wParam, lParam); - RedrawSelMargin(); return markerID; } case SCI_MARKERDELETE: pdoc->DeleteMark(wParam, lParam); - RedrawSelMargin(); break; case SCI_MARKERDELETEALL: pdoc->DeleteAllMarks(static_cast(wParam)); - RedrawSelMargin(); break; case SCI_MARKERGET: @@ -3391,7 +3512,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { if (lParam == 0) return 0; if (wParam <= STYLE_MAX) { - strcpy(vs.styles[wParam].fontName, reinterpret_cast(lParam)); + vs.SetStyleFontName(wParam, reinterpret_cast(lParam)); InvalidateStyleRedraw(); } break; @@ -3492,7 +3613,14 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { caretSlop = lParam; break; -#ifdef INCLUDE_DEPRECATED_FEATURES + case SCI_LINESONSCREEN: + return LinesOnScreen(); + + case SCI_USEPOPUP: + displayPopupMenu = wParam; + break; + + #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_SETFORE: vs.styles[STYLE_DEFAULT].fore.desired = Colour(wParam); InvalidateStyleRedraw(); @@ -3612,6 +3740,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_ZOOMOUT: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: return KeyCommand(iMessage); case SCI_BRACEHIGHLIGHT: diff --git a/contrib/src/stc/scintilla/src/Editor.h b/contrib/src/stc/scintilla/src/Editor.h index 4ff334767a..d1281be5a8 100644 --- a/contrib/src/stc/scintilla/src/Editor.h +++ b/contrib/src/stc/scintilla/src/Editor.h @@ -116,6 +116,8 @@ protected: // ScintillaBase subclass needs access to much of Editor int searchAnchor; + int displayPopupMenu; + #ifdef MACRO_SUPPORT int recordingMacro; #endif @@ -218,12 +220,16 @@ protected: // ScintillaBase subclass needs access to much of Editor void NotifySavePoint(Document *document, void *userData, bool atSavePoint); void NotifyModified(Document *document, DocModification mh, void *userData); void NotifyDeleted(Document *document, void *userData); + void NotifyStyleNeeded(Document *doc, void *userData, int endPos); + #ifdef MACRO_SUPPORT void NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam); #endif void PageMove(int direction, bool extend=false); + void ChangeCaseOfSelection(bool makeUpperCase); + void LineTranspose(); virtual int KeyCommand(UINT iMessage); virtual int KeyDefault(int /* key */, int /*modifiers*/); int KeyDown(int key, bool shift, bool ctrl, bool alt); diff --git a/contrib/src/stc/scintilla/src/KeyMap.cxx b/contrib/src/stc/scintilla/src/KeyMap.cxx index f339cd2750..9ab9694df1 100644 --- a/contrib/src/stc/scintilla/src/KeyMap.cxx +++ b/contrib/src/stc/scintilla/src/KeyMap.cxx @@ -61,36 +61,36 @@ UINT KeyMap::Find(int key, int modifiers) { } KeyToCommand KeyMap::MapDefault[] = { - VK_DOWN, SCI_NORM, SCI_LINEDOWN, - VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, - VK_UP, SCI_NORM, SCI_LINEUP, - VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, + VK_DOWN, SCI_NORM, SCI_LINEDOWN, + VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, + VK_UP, SCI_NORM, SCI_LINEUP, + VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, VK_LEFT, SCI_NORM, SCI_CHARLEFT, VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND, VK_LEFT, SCI_CTRL, SCI_WORDLEFT, VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND, - VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, - VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, - VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, - VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, - VK_HOME, SCI_NORM, SCI_VCHOME, - VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, - VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, - VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, + VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, + VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, + VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, + VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, + VK_HOME, SCI_NORM, SCI_VCHOME, + VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, + VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, + VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, VK_END, SCI_NORM, SCI_LINEEND, VK_END, SCI_SHIFT, SCI_LINEENDEXTEND, VK_END, SCI_CTRL, SCI_DOCUMENTEND, VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND, - VK_PRIOR, SCI_NORM, SCI_PAGEUP, - VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, - VK_NEXT, SCI_NORM, SCI_PAGEDOWN, - VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, + VK_PRIOR, SCI_NORM, SCI_PAGEUP, + VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, + VK_NEXT, SCI_NORM, SCI_PAGEDOWN, + VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, VK_DELETE, SCI_NORM, WM_CLEAR, VK_DELETE, SCI_SHIFT, WM_CUT, VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT, - VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, - VK_INSERT, SCI_SHIFT, WM_PASTE, - VK_INSERT, SCI_CTRL, WM_COPY, + VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, + VK_INSERT, SCI_SHIFT, WM_PASTE, + VK_INSERT, SCI_CTRL, WM_COPY, VK_ESCAPE, SCI_NORM, SCI_CANCEL, VK_BACK, SCI_NORM, SCI_DELETEBACK, VK_BACK, SCI_CTRL, SCI_DELWORDLEFT, @@ -103,9 +103,14 @@ KeyToCommand KeyMap::MapDefault[] = { VK_TAB, SCI_NORM, SCI_TAB, VK_TAB, SCI_SHIFT, SCI_BACKTAB, VK_RETURN, SCI_NORM, SCI_NEWLINE, - 'L', SCI_CTRL, SCI_FORMFEED, VK_ADD, SCI_CTRL, SCI_ZOOMIN, VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT, + //'L', SCI_CTRL, SCI_FORMFEED, + 'L', SCI_CTRL, SCI_LINECUT, + 'L', SCI_CSHIFT, SCI_LINEDELETE, + 'T', SCI_CTRL, SCI_LINETRANSPOSE, + 'U', SCI_CTRL, SCI_LOWERCASE, + 'U', SCI_CSHIFT, SCI_UPPERCASE, 0,0,0, }; diff --git a/contrib/src/stc/scintilla/src/KeyMap.h b/contrib/src/stc/scintilla/src/KeyMap.h index 814f3aa3b7..bc435e1970 100644 --- a/contrib/src/stc/scintilla/src/KeyMap.h +++ b/contrib/src/stc/scintilla/src/KeyMap.h @@ -11,6 +11,7 @@ #define SCI_CTRL LEFT_CTRL_PRESSED #define SCI_ALT LEFT_ALT_PRESSED #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) +#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) class KeyToCommand { public: diff --git a/contrib/src/stc/scintilla/src/KeyWords.cxx b/contrib/src/stc/scintilla/src/KeyWords.cxx index 20f6762470..5d6d9c6cfc 100644 --- a/contrib/src/stc/scintilla/src/KeyWords.cxx +++ b/contrib/src/stc/scintilla/src/KeyWords.cxx @@ -17,2201 +17,29 @@ #include "Scintilla.h" #include "SciLexer.h" -inline bool IsLeadByte(int codePage, char ch) { -#if PLAT_GTK - // TODO: support DBCS under GTK+ - return false; -#elif PLAT_WIN - return codePage && IsDBCSLeadByteEx(codePage, ch); -#elif PLAT_WX - return false; -#endif -} - -inline bool iswordchar(char ch) { - return isalnum(ch) || ch == '.' || ch == '_'; -} - -inline bool iswordstart(char ch) { - return isalnum(ch) || ch == '_'; -} - -enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; - -static int IndentAmount(StylingContext &styler, int line, int *flags) { - int end = styler.Length(); - int spaceFlags = 0; - - // Determines the indentation level of the current line and also checks for consistent - // indentation compared to the previous line. - // Indentation is judged consistent when the indentation whitespace of each line lines - // the same or the indentation of one line is a prefix of the other. - - int pos = styler.LineStart(line); - char ch = styler[pos]; - int indent = 0; - bool inPrevPrefix = line > 0; - int posPrev = inPrevPrefix ? styler.LineStart(line-1) : 0; - while ((ch == ' ' || ch == '\t') && (pos < end)) { - if (inPrevPrefix) { - char chPrev = styler[posPrev++]; - if (chPrev == ' ' || chPrev == '\t') { - if (chPrev != ch) - spaceFlags |= wsInconsistent; - } else { - inPrevPrefix = false; - } - } - if (ch == ' ') { - spaceFlags |= wsSpace; - indent++; - } else { // Tab - spaceFlags |= wsTab; - if (spaceFlags & wsSpace) - spaceFlags |= wsSpaceTab; - indent = (indent / 8 + 1) * 8; - } - ch = styler[++pos]; - } - - *flags = spaceFlags; - indent += SC_FOLDLEVELBASE; - if (isspace(ch)) // Completely empty line - return indent | SC_FOLDLEVELWHITEFLAG; - else - return indent; -} - -inline bool isoperator(char ch) { - if (isalnum(ch)) - return false; - // '.' left out as it is used to make up numbers - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; -} - -static void classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_C_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_C_WORD; - } - styler.ColourSegment(start, end, chAttr); -} - -static void ColouriseCppDoc(int codePage, int startPos, int length, - int initStyle, WordList &keywords, StylingContext &styler) { - - bool fold = styler.GetPropSet().GetInt("fold"); - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; - - int state = initStyle; - char chPrev = ' '; - char chNext = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - int visChars = 0; - for (unsigned int i = startPos; i <= lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) { - int lev = levelPrev; - if (visChars == 0) - lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; - styler.SetLevel(lineCurrent, lev); - lineCurrent++; - visChars = 0; - levelPrev = levelCurrent; - } - if (!isspace(ch)) - visChars++; - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - i += 1; - continue; - } - - if (state == SCE_C_STRINGEOL) { - if (ch != '\r' && ch != '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } - if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_WORD; - startSeg = i; - } else if (ch == '/' && chNext == '*') { - styler.ColourSegment(startSeg, i - 1, state); - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_C_COMMENTDOC; - else - state = SCE_C_COMMENT; - startSeg = i; - } else if (ch == '/' && chNext == '/') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRING; - startSeg = i; - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_CHARACTER; - startSeg = i; - } else if (ch == '#') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_PREPROCESSOR; - startSeg = i; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_C_OPERATOR); - startSeg = i + 1; - if ((ch == '{') || (ch == '}')) { - levelCurrent += (ch == '{') ? 1 : -1; - } - } - } else if (state == SCE_C_WORD) { - if (!iswordchar(ch)) { - classifyWordCpp(startSeg, i - 1, keywords, styler); - state = SCE_C_DEFAULT; - startSeg = i; - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_C_COMMENTDOC; - else - state = SCE_C_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } else if (ch == '\'') { - state = SCE_C_CHARACTER; - } else if (ch == '#') { - state = SCE_C_PREPROCESSOR; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - if ((ch == '{') || (ch == '}')) { - levelCurrent += (ch == '{') ? 1 : -1; - } - } - } - } else { - if (state == SCE_C_PREPROCESSOR) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_COMMENT) { - if (ch == '/' && chPrev == '*' && ( - (i > startSeg + 2) || ((initStyle == SCE_C_COMMENT) && (startSeg == startPos)))) { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_C_COMMENTDOC) { - if (ch == '/' && chPrev == '*' && ( - (i > startSeg + 3) || ((initStyle == SCE_C_COMMENTDOC) && (startSeg == startPos)))) { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_C_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_STRING) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRINGEOL; - startSeg = i; - } else if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_C_CHARACTER) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRINGEOL; - startSeg = i; - } else if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } - if (state == SCE_C_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_C_COMMENTDOC; - else - state = SCE_C_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } else if (ch == '\'') { - state = SCE_C_CHARACTER; - } else if (ch == '#') { - state = SCE_C_PREPROCESSOR; - } else if (iswordstart(ch)) { - state = SCE_C_WORD; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - if ((ch == '{') || (ch == '}')) { - levelCurrent += (ch == '{') ? 1 : -1; - } - } - } - } - chPrev = ch; - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc - 1, state); - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - if (fold) { - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); - styler.SetLevel(lineCurrent, levelPrev | flagsNext); - - } -} - -inline bool isPerlOperator(char ch) { - if (isalnum(ch)) - return false; - // '.' left out as it is used to make up numbers - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '\\' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; -} - -static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_PL_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_PL_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_PL_WORD; - } - styler.ColourSegment(start, end, chAttr); - return chAttr; -} - -static bool isEndVar(char ch) { - return !isalnum(ch) && ch != '#' && ch != '$' && - ch != '_' && ch != '\''; -} - -static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) { - if ((pos + static_cast(strlen(val))) >= lengthDoc) { - return false; - } - while (*val) { - if (*val != styler[pos++]) { - return false; - } - val++; - } - return true; -} - -static bool isOKQuote(char ch) { - if (isalnum(ch)) - return false; - if (isspace(ch)) - return false; - if (iscntrl(ch)) - return false; - return true; -} - -static char opposite(char ch) { - if (ch == '(') - return ')'; - if (ch == '[') - return ']'; - if (ch == '{') - return '}'; - if (ch == '<') - return '>'; - return ch; -} - -static void ColourisePerlDoc(int codePage, int startPos, int length, int initStyle, - WordList &keywords, StylingContext &styler) { - char sooked[100]; - int quotes = 0; - char quoteDown = 'd'; - char quoteUp = 'd'; - int quoteRep = 1; - int sookedpos = 0; - bool preferRE = true; - sooked[sookedpos] = '\0'; - int state = initStyle; - int lengthDoc = startPos + length; - // If in a long distance lexical state, seek to the beginning to find quote characters - if (state == SCE_PL_HERE || state == SCE_PL_REGEX || - state == SCE_PL_REGSUBST || state == SCE_PL_LONGQUOTE) { - while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) { - startPos--; - } - state = SCE_PL_DEFAULT; - } - styler.StartAt(startPos); - char chPrev = ' '; - char chNext = styler[startPos]; - int startSeg = startPos; - for (int i = startPos; i <= lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - char chNext2 = styler.SafeGetCharAt(i + 2); - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - i += 1; - continue; - } - - if (state == SCE_PL_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - if (ch == 's' && !isalnum(chNext)) { - state = SCE_PL_REGSUBST; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 2; - startSeg = i; - } else if (ch == 'm' && !isalnum(chNext)) { - state = SCE_PL_REGEX; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 1; - startSeg = i; - } else if (ch == 't' && chNext == 'r' && !isalnum(chNext2)) { - state = SCE_PL_REGSUBST; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 2; - startSeg = i; - i++; - chNext = chNext2; - } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isalnum(chNext2)) { - state = SCE_PL_LONGQUOTE; - startSeg = i; - i++; - chNext = chNext2; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 1; - } else { - state = SCE_PL_WORD; - startSeg = i; - preferRE = false; - } - } else if (ch == '#') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_STRING; - startSeg = i; - } else if (ch == '\'') { - if (chPrev == '&') { - // Archaic call - styler.ColourSegment(i, i, state); - startSeg = i + 1; - } else { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_CHARACTER; - startSeg = i; - } - } else if (ch == '`') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_BACKTICKS; - startSeg = i; - } else if (ch == '$') { - preferRE = false; - styler.ColourSegment(startSeg, i - 1, state); - if (isalnum(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { - state = SCE_PL_SCALAR; - startSeg = i; - } else if (chNext != '{' && chNext != '[') { - styler.ColourSegment(i - 1, i, SCE_PL_SCALAR); - i++; - startSeg = i + 1; - ch = ' '; - chNext = ' '; - } else { - styler.ColourSegment(i, i, SCE_PL_SCALAR); - startSeg = i + 1; - } - } else if (ch == '@') { - preferRE = false; - styler.ColourSegment(startSeg, i - 1, state); - if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { - state = SCE_PL_ARRAY; - startSeg = i; - } else if (chNext != '{' && chNext != '[') { - styler.ColourSegment(i - 1, i, SCE_PL_ARRAY); - i++; - startSeg = i + 1; - ch = ' '; - } else { - styler.ColourSegment(i, i, SCE_PL_ARRAY); - startSeg = i + 1; - } - } else if (ch == '%') { - preferRE = false; - styler.ColourSegment(startSeg, i - 1, state); - if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { - state = SCE_PL_HASH; - startSeg = i; - } else if (chNext != '{' && chNext != '[') { - styler.ColourSegment(i - 1, i, SCE_PL_HASH); - i++; - startSeg = i + 1; - ch = ' '; - } else { - styler.ColourSegment(i, i, SCE_PL_HASH); - startSeg = i + 1; - } - } else if (ch == '*') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_SYMBOLTABLE; - startSeg = i; - } else if (ch == '/' && preferRE) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_REGEX; - quoteUp = '/'; - quoteDown = '/'; - quotes = 1; - quoteRep = 1; - startSeg = i; - } else if (ch == '<' && chNext == '<') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_HERE; - startSeg = i; - i++; - ch = chNext; - chNext = chNext2; - quotes = 0; - sookedpos = 0; - sooked[sookedpos] = '\0'; - } else if (ch == '=' && isalpha(chNext)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_POD; - startSeg = i; - quotes = 0; - sookedpos = 0; - sooked[sookedpos] = '\0'; - } else if (isPerlOperator(ch)) { - if (ch == ')' || ch == ']') - preferRE = false; - else - preferRE = true; - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_PL_OPERATOR); - startSeg = i + 1; - } - } else if (state == SCE_PL_WORD) { - if (!iswordchar(ch) && ch != '\'') { // Archaic Perl has quotes inside names - if (isMatch(styler, lengthDoc, startSeg, "__DATA__")) { - styler.ColourSegment(startSeg, i, SCE_PL_DATASECTION); - state = SCE_PL_DATASECTION; - } else if (isMatch(styler, lengthDoc, startSeg, "__END__")) { - styler.ColourSegment(startSeg, i, SCE_PL_DATASECTION); - state = SCE_PL_DATASECTION; - } else { - if (classifyWordPerl(startSeg, i - 1, keywords, styler) == SCE_PL_WORD) - preferRE = true; - state = SCE_PL_DEFAULT; - startSeg = i; - if (ch == '#') { - state = SCE_PL_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_PL_STRING; - } else if (ch == '\'') { - state = SCE_PL_CHARACTER; - } else if (ch == '<' && chNext == '<') { - state = SCE_PL_HERE; - quotes = 0; - startSeg = i; - sookedpos = 0; - sooked[sookedpos] = '\0'; - } else if (isPerlOperator(ch)) { - if (ch == ')' || ch == ']') - preferRE = false; - else - preferRE = true; - styler.ColourSegment(startSeg, i, SCE_PL_OPERATOR); - state = SCE_PL_DEFAULT; - startSeg = i + 1; - } - } - } - } else { - if (state == SCE_PL_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_DEFAULT; - startSeg = i; - } - } else if (state == SCE_PL_HERE) { - if (isalnum(ch) && quotes < 2) { - sooked[sookedpos++] = ch; - sooked[sookedpos] = '\0'; - if (quotes == 0) - quotes = 1; - } else { - quotes++; - } - - if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked)) { - styler.ColourSegment(startSeg, i + sookedpos - 1, SCE_PL_HERE); - state = SCE_PL_DEFAULT; - i += sookedpos; - startSeg = i; - chNext = ' '; - } - } else if (state == SCE_PL_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_PL_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_PL_CHARACTER) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_PL_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_PL_BACKTICKS) { - if (ch == '`') { - styler.ColourSegment(startSeg, i, state); - state = SCE_PL_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_PL_POD) { - if (ch == '=') { - if (isMatch(styler, lengthDoc, i, "=cut")) { - styler.ColourSegment(startSeg, i - 1 + 4, state); - i += 4; - startSeg = i; - state = SCE_PL_DEFAULT; - chNext = ' '; - ch = ' '; - } - } - } else if (state == SCE_PL_SCALAR) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_ARRAY) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_HASH) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_SYMBOLTABLE) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_REF) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_REGEX) { - if (!quoteUp && !isspace(ch)) { - quoteUp = ch; - quoteDown = opposite(ch); - quotes++; - } else { - if (ch == quoteDown && chPrev != '\\') { - quotes--; - if (quotes == 0) { - quoteRep--; - if (quoteUp == quoteDown) { - quotes++; - } - } - if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - } else if (ch == quoteUp && chPrev != '\\') { - quotes++; - } else if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - } - } else if (state == SCE_PL_REGSUBST) { - if (!quoteUp && !isspace(ch)) { - quoteUp = ch; - quoteDown = opposite(ch); - quotes++; - } else { - if (ch == quoteDown && chPrev != '\\') { - quotes--; - if (quotes == 0) { - quoteRep--; - } - if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - if (quoteUp == quoteDown) { - quotes++; - } - } else if (ch == quoteUp && chPrev != '\\') { - quotes++; - } else if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - } - } else if (state == SCE_PL_LONGQUOTE) { - if (!quoteDown && !isspace(ch)) { - quoteUp = ch; - quoteDown = opposite(quoteUp); - quotes++; - } else if (ch == quoteDown) { - quotes--; - if (quotes == 0) { - quoteRep--; - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - if (quoteUp == quoteDown) { - quotes++; - } - } - } else if (ch == quoteUp) { - quotes++; - } - } - - if (state == SCE_PL_DEFAULT) { // One of the above succeeded - if (ch == '#') { - state = SCE_PL_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_PL_STRING; - } else if (ch == '\'') { - state = SCE_PL_CHARACTER; - } else if (iswordstart(ch)) { - state = SCE_PL_WORD; - preferRE = false; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_PL_OPERATOR); - startSeg = i + 1; - } - } - } - chPrev = ch; - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc, state); -} - - -static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } - char chAttr = SCE_C_DEFAULT; - if (wordIsNumber) - chAttr = SCE_C_NUMBER; - else { - if (keywords.InList(s)) { - chAttr = SCE_C_WORD; - if (strcmp(s, "rem") == 0) - chAttr = SCE_C_COMMENTLINE; - } - } - styler.ColourSegment(start, end, chAttr); - if (chAttr == SCE_C_COMMENTLINE) - return SCE_C_COMMENTLINE; - else - return SCE_C_DEFAULT; -} - -static void ColouriseVBDoc(int codePage, int startPos, int length, int initStyle, - WordList &keywords, StylingContext &styler) { - int state = initStyle; - char chNext = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - for (int i = startPos; i < lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; - } - - if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_WORD; - startSeg = i; - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRING; - startSeg = i; - } - } else if (state == SCE_C_WORD) { - if (!iswordchar(ch)) { - state = classifyWordVB(startSeg, i - 1, keywords, styler); - if (state == SCE_C_DEFAULT) { - startSeg = i; - if (ch == '\'') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } - } - } - } else { - if (state == SCE_C_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_STRING) { - // VB doubles quotes to preserve them - if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } - if (state == SCE_C_DEFAULT) { // One of the above succeeded - if (ch == '\'') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } else if (iswordstart(ch)) { - state = SCE_C_WORD; - } - } - } - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc, state); -} - -static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_P_IDENTIFIER; - if (0 == strcmp(prevWord, "class")) - chAttr = SCE_P_CLASSNAME; - else if (0 == strcmp(prevWord, "def")) - chAttr = SCE_P_DEFNAME; - else if (wordIsNumber) - chAttr = SCE_P_NUMBER; - else if (keywords.InList(s)) - chAttr = SCE_P_WORD; - styler.ColourSegment(start, end, chAttr); - strcpy(prevWord, s); -} - -static void ColourisePyDoc(int codePage, int startPos, int length, int initStyle, WordList &keywords, StylingContext &styler) { - //Platform::DebugPrintf("Python coloured\n"); - bool fold = styler.GetPropSet().GetInt("fold"); - int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level"); - char prevWord[200]; - prevWord[0] = '\0'; - if (length == 0) - return ; - int lineCurrent = styler.GetLine(startPos); - int spaceFlags = 0; - // TODO: Need to check previous line for indentation for both folding and bad indentation - int indentCurrent = IndentAmount(styler, lineCurrent, &spaceFlags); - - int state = initStyle & 31; - char chPrev = ' '; - char chPrev2 = ' '; - char chNext = styler[startPos]; - char chNext2 = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - bool atStartLine = true; - for (int i = startPos; i <= lengthDoc; i++) { - - if (atStartLine) { - if (whingeLevel == 1) { - styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state); - } else if (whingeLevel == 2) { - styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state); - } else if (whingeLevel == 3) { - styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state); - } else if (whingeLevel == 4) { - styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state); - } - atStartLine = false; - } - - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - chNext2 = styler.SafeGetCharAt(i + 2); - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) { - // Perform colourisation of white space and triple quoted strings at end of each line to allow - // tab marking to work inside white space and triple quoted strings - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - } - - int lev = indentCurrent; - int indentNext = IndentAmount(styler, lineCurrent + 1, &spaceFlags); - if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { - // Only non whitespace lines can be headers - if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { - lev |= SC_FOLDLEVELHEADERFLAG; - } - } - indentCurrent = indentNext; - if (fold) { - styler.SetLevel(lineCurrent, lev); - } - lineCurrent++; - atStartLine = true; - } - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - chPrev2 = ' '; - i += 1; - continue; - } - - if (state == SCE_P_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_P_WORD; - startSeg = i; - } else if (ch == '#') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_P_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_P_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_STRING; - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_P_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_P_OPERATOR); - startSeg = i + 1; - } - } else if (state == SCE_P_WORD) { - if (!iswordchar(ch)) { - classifyWordPy(startSeg, i - 1, keywords, styler, prevWord); - state = SCE_P_DEFAULT; - startSeg = i; - if (ch == '#') { - state = SCE_P_COMMENTLINE; - } else if (ch == '\"') { - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_P_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_STRING; - } - } else if (ch == '\'') { - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_P_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_P_OPERATOR); - startSeg = i + 1; - } - } - } else { - if (state == SCE_P_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_P_DEFAULT; - startSeg = i; - } - } else if (state == SCE_P_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_P_CHARACTER) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_P_TRIPLE) { - if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_P_TRIPLEDOUBLE) { - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } - } - chPrev2 = chPrev; - chPrev = ch; - } - if (startSeg <= lengthDoc) { - if (state == SCE_P_DEFAULT) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_WORD) { - classifyWordPy(startSeg, lengthDoc, keywords, styler, prevWord); - } else if (state == SCE_P_COMMENTLINE) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_STRING) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_CHARACTER) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_TRIPLE) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_TRIPLEDOUBLE) { - styler.ColourSegment(startSeg, lengthDoc, state); - } - } -} - -static void ColouriseBatchLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - if (0 == strncmp(lineBuffer, "REM", 3)) { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (0 == strncmp(lineBuffer, "rem", 3)) { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (0 == strncmp(lineBuffer, "SET", 3)) { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if (0 == strncmp(lineBuffer, "set", 3)) { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if (lineBuffer[0] == ':') { - styler.ColourSegment(0, lengthLine - 1, 3); - } else { - styler.ColourSegment(0, lengthLine - 1, 0); - } -} - -static void ColouriseBatchDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i < startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - ColouriseBatchLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColouriseBatchLine(lineBuffer, linePos, styler); -} - -enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; -static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) { - char s[100]; - s[0] = '\0'; - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } -Platform::DebugPrintf("Scripting indicator [%s]\n", s); - if (strstr(s, "vbs")) - return eScriptVBS; - if (strstr(s, "pyth")) - return eScriptPython; - if (strstr(s, "javas")) - return eScriptJS; - if (strstr(s, "jscr")) - return eScriptJS; - - return prevValue; -} - -static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || - (styler[start] == '-') || (styler[start] == '#'); - char chAttr = SCE_H_ATTRIBUTEUNKNOWN; - if (wordIsNumber) { - chAttr = SCE_H_NUMBER; - } else { - char s[100]; - s[0] = '\0'; - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } - if (keywords.InList(s)) - chAttr = SCE_H_ATTRIBUTE; - } - styler.ColourTo(end, chAttr); -} - -static int classifyTagHTML(unsigned int start, unsigned int end, - WordList &keywords, StylingContext &styler) { - char s[100]; - // Copy after the '<' - unsigned int i = 0; - for (int cPos=start; cPos <= end && i < 30; cPos++) { - char ch = styler[cPos]; - if (ch != '<') - s[i++] = tolower(ch); - } - s[i] = '\0'; - char chAttr = SCE_H_TAGUNKNOWN; - if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment - chAttr = SCE_H_COMMENT; - } else if (s[0] == '/') { // Closing tag - if (keywords.InList(s + 1)) - chAttr = SCE_H_TAG; - } else { - if (keywords.InList(s)) { - chAttr = SCE_H_TAG; - if (0 == strcmp(s, "script")) - chAttr = SCE_H_SCRIPT; - } - } - styler.ColourTo(end, chAttr); - return chAttr; -} - -static void classifyWordHTJS(unsigned int start, unsigned int end, - WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_HJ_WORD; - if (wordIsNumber) - chAttr = SCE_HJ_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_HJ_KEYWORD; - } - styler.ColourTo(end, chAttr); -} - -static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } - char chAttr = SCE_HB_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_HB_NUMBER; - else { - if (keywords.InList(s)) { - chAttr = SCE_HB_WORD; - if (strcmp(s, "rem") == 0) - chAttr = SCE_HB_COMMENTLINE; - } - } - styler.ColourTo(end, chAttr); - if (chAttr == SCE_HB_COMMENTLINE) - return SCE_HB_COMMENTLINE; - else - return SCE_HB_DEFAULT; -} - -static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_HP_IDENTIFIER; - if (0 == strcmp(prevWord, "class")) - chAttr = SCE_HP_CLASSNAME; - else if (0 == strcmp(prevWord, "def")) - chAttr = SCE_HP_DEFNAME; - else if (wordIsNumber) - chAttr = SCE_HP_NUMBER; - else if (keywords.InList(s)) - chAttr = SCE_HP_WORD; - styler.ColourTo(end, chAttr); - strcpy(prevWord, s); -} - -inline bool ishtmlwordchar(char ch) { - return isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#'; -} - -static bool InTagState(int state) { - return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || - state == SCE_H_SCRIPT || - state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || - state == SCE_H_NUMBER || state == SCE_H_OTHER || - state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING; -} - -static bool isLineEnd(char ch) { - return ch == '\r' || ch == '\n'; -} - -static void ColouriseHyperTextDoc(int codePage, int startPos, int length, - int initStyle, WordList &keywords, WordList &keywords2, WordList &keywords3, WordList &keywords4, - StylingContext &styler) { - - styler.StartAt(startPos, 63); - bool lastTagWasScript = false; - char prevWord[200]; - prevWord[0] = '\0'; - int scriptLanguage = eScriptJS; - int state = initStyle; - // If inside a tag, it may be a script tage, so reread from the start to ensure any language tas are seen - if (InTagState(state)) { - while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) { - startPos--; - } - state = SCE_H_DEFAULT; - } - styler.StartAt(startPos, 63); - - int lineState = eScriptVBS; - int lineCurrent = styler.GetLine(startPos); - if (lineCurrent > 0) - lineState = styler.GetLineState(lineCurrent); - int defaultScript = lineState &0xff; - int beforeASP = (lineState >> 8) &0xff; - int inASP = (lineState >> 16) &0xff; - - char chPrev = ' '; - char chPrev2 = ' '; - styler.StartSegment(startPos); - int lengthDoc = startPos + length; - for (int i = startPos; i <= lengthDoc; i++) { - char ch = styler[i]; - char chNext = styler.SafeGetCharAt(i + 1); - char chNext2 = styler.SafeGetCharAt(i + 2); - - if (IsLeadByte(codePage, ch)) { // dbcs - chPrev2 = ' '; - chPrev = ' '; - i += 1; - continue; - } - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - // New line -> record any line state onto /next/ line - lineCurrent++; - styler.SetLineState(lineCurrent, - defaultScript | (beforeASP << 8) | (inASP << 16)); - } - - // Handle ASP even within other constructs as it is a preprocessor - if ((ch == '<') && (chNext == '%')) { - beforeASP = state; - styler.ColourTo(i - 1, state); - if (chNext2 == '@') { - styler.ColourTo(i + 2, SCE_H_ASP); - state = SCE_H_ASPAT; - i+=2; - } else { - if (defaultScript == eScriptVBS) - state = SCE_HB_START; - else if (defaultScript == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - if (chNext2 == '=') { - styler.ColourTo(i + 2, SCE_H_ASP); - i+=2; - } else { - styler.ColourTo(i + 1, SCE_H_ASP); - i++; - } - } - inASP = 1; - continue; - } - if (inASP && (ch == '%') && (chNext == '>')) { - if (state == SCE_H_ASPAT) - defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript); - // Bounce out of any ASP mode - styler.ColourTo(i - 1, state); - //if (state == SCE_H_ASPAT) - // styler.ColourTo(i+1, SCE_H_ASPAT); - //else - styler.ColourTo(i+1, SCE_H_ASP); - i++; - state = beforeASP; - beforeASP = SCE_H_DEFAULT; - inASP = 0; - continue; - } - - if (state == SCE_H_DEFAULT) { - if (ch == '<') { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - if (chNext == '?') { - styler.ColourTo(i + 1, SCE_H_XMLSTART); - i++; - ch = chNext; - } - } else if (ch == '&') { - styler.ColourTo(i - 1, SCE_H_DEFAULT); - state = SCE_H_ENTITY; - } - } else if (state == SCE_H_COMMENT) { - if ((ch == '>') && (chPrev == '-')) { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_ENTITY) { - if (ch == ';') { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_TAGUNKNOWN) { - if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { - int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); - lastTagWasScript = eClass == SCE_H_SCRIPT; - if (lastTagWasScript) { - scriptLanguage = eScriptJS; - eClass = SCE_H_TAG; - } - if (ch == '>') { - styler.ColourTo(i, SCE_H_TAG); - if (lastTagWasScript) { - if (scriptLanguage == eScriptVBS) - state = SCE_HB_START; - else if (scriptLanguage == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - } else { - state = SCE_H_DEFAULT; - } - } else { - if (eClass == SCE_H_COMMENT) { - state = SCE_H_COMMENT; - } else { - state = SCE_H_OTHER; - } - } - } - } else if (state == SCE_H_ATTRIBUTE) { - if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage); - classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler); - if (ch == '>') { - styler.ColourTo(i, SCE_H_TAG); - if (lastTagWasScript) { - if (scriptLanguage == eScriptVBS) - state = SCE_HB_START; - else if (scriptLanguage == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - } else { - state = SCE_H_DEFAULT; - } - } else { - state = SCE_H_OTHER; - } - } - } else if (state == SCE_H_ASP) { - if ((ch == '>') && (chPrev == '%')) { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_ASPAT) { - if ((ch == '>') && (chPrev == '%')) { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_OTHER) { - if (ch == '>') { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_H_TAG); - if (lastTagWasScript) { - if (scriptLanguage == eScriptVBS) - state = SCE_HB_START; - else if (scriptLanguage == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - } else { - state = SCE_H_DEFAULT; - } - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - state = SCE_H_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - state = SCE_H_SINGLESTRING; - } else if (ch == '/' && chNext == '>') { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } else if (ch == '?' && chNext == '>') { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_XMLEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } else if (ishtmlwordchar(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_H_ATTRIBUTE; - } - } else if (state == SCE_H_DOUBLESTRING) { - if (ch == '\"') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); - styler.ColourTo(i, SCE_H_DOUBLESTRING); - state = SCE_H_OTHER; - } - } else if (state == SCE_H_SINGLESTRING) { - if (ch == '\'') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); - styler.ColourTo(i, SCE_H_SINGLESTRING); - state = SCE_H_OTHER; - } - } else if (state == SCE_HJ_DEFAULT || state == SCE_HJ_START) { - if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HJ_WORD; - } else if (ch == '/' && chNext == '*') { - styler.ColourTo(i - 1, state); - if (chNext2 == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_SINGLESTRING; - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_COMMENTLINE; - } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HJ_SYMBOLS); - state = SCE_HJ_DEFAULT; - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HJ_START) { - styler.ColourTo(i - 1, state); - state = SCE_HJ_DEFAULT; - } - } - } else if (state == SCE_HJ_WORD) { - if (!iswordchar(ch)) { - classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler); - //styler.ColourTo(i - 1, eHTJSKeyword); - state = SCE_HJ_DEFAULT; - if (ch == '/' && chNext == '*') { - if (chNext2 == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - state = SCE_HJ_SINGLESTRING; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HJ_SYMBOLS); - state = SCE_HJ_DEFAULT; - } - } - } else if (state == SCE_HJ_COMMENT) { - if (ch == '/' && chPrev == '*') { - state = SCE_HJ_DEFAULT; - styler.ColourTo(i, SCE_HJ_COMMENT); - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } - } else if (state == SCE_HJ_COMMENTDOC) { - if (ch == '/' && chPrev == '*') { - state = SCE_HJ_DEFAULT; - styler.ColourTo(i, SCE_HJ_COMMENTDOC); - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } - } else if (state == SCE_HJ_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); - state = SCE_HJ_DEFAULT; - } else if ((ch == '<') && (chNext == '/')) { - // Common to hide end script tag in comment - styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); - state = SCE_H_TAGUNKNOWN; - } - } else if (state == SCE_HJ_DOUBLESTRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - } - } else if (ch == '\"') { - styler.ColourTo(i, SCE_HJ_DOUBLESTRING); - state = SCE_HJ_DEFAULT; - i++; - ch = chNext; - } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); - state = SCE_HJ_STRINGEOL; - } - } else if (state == SCE_HJ_SINGLESTRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - } - } else if (ch == '\'') { - styler.ColourTo(i, SCE_HJ_SINGLESTRING); - state = SCE_HJ_DEFAULT; - i++; - ch = chNext; - } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); - state = SCE_HJ_STRINGEOL; - } - } else if (state == SCE_HJ_STRINGEOL) { - if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HJ_DEFAULT; - } - } else if (state == SCE_HB_DEFAULT || state == SCE_HB_START) { - if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HB_WORD; - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - state = SCE_HB_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - state = SCE_HB_STRING; - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, state); - state = SCE_HB_COMMENTLINE; - } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HB_DEFAULT); - state = SCE_HB_DEFAULT; - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HB_START) { - styler.ColourTo(i - 1, state); - state = SCE_HB_DEFAULT; - } - } - } else if (state == SCE_HB_WORD) { - if (!iswordchar(ch)) { - state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler); - if (state == SCE_HB_DEFAULT) { - if (ch == '\"') { - state = SCE_HB_STRING; - } else if (ch == '\'') { - state = SCE_HB_COMMENTLINE; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HB_DEFAULT); - state = SCE_HB_DEFAULT; - } - } - } - } else if (state == SCE_HB_STRING) { - if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_HB_DEFAULT; - i++; - ch = chNext; - } else if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_HB_STRINGEOL; - } - } else if (state == SCE_HB_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); - state = SCE_HB_DEFAULT; - } else if ((ch == '<') && (chNext == '/')) { - // Common to hide end script tag in comment - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } - } else if (state == SCE_HB_STRINGEOL) { - if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HB_DEFAULT; - } - } else if (state == SCE_HP_DEFAULT || state == SCE_HP_START) { - if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HP_WORD; - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, state); - state = SCE_HP_COMMENTLINE; - } else if (ch == '#') { - styler.ColourTo(i - 1, state); - state = SCE_HP_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_HP_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_STRING; - } - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_HP_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HP_OPERATOR); - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HP_START) { - styler.ColourTo(i - 1, state); - state = SCE_HP_DEFAULT; - } - } - } else if (state == SCE_HP_WORD) { - if (!iswordchar(ch)) { - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); - state = SCE_HP_DEFAULT; - if (ch == '#') { - state = SCE_HP_COMMENTLINE; - } else if (ch == '\"') { - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_HP_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_STRING; - } - } else if (ch == '\'') { - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_HP_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HP_OPERATOR); - } - } - } else { - if (state == SCE_HP_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_CHARACTER) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_TRIPLE) { - if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_TRIPLEDOUBLE) { - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } - } - if (state == SCE_HB_DEFAULT) { // One of the above succeeded - if (ch == '\"') { - state = SCE_HB_STRING; - } else if (ch == '\'') { - state = SCE_HB_COMMENTLINE; - } else if (iswordstart(ch)) { - state = SCE_HB_WORD; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HB_DEFAULT); - } - } - if (state == SCE_HJ_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - state = SCE_HJ_SINGLESTRING; - } else if (iswordstart(ch)) { - state = SCE_HJ_WORD; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HJ_SYMBOLS); - } - } - chPrev2 = chPrev; - chPrev = ch; - } - styler.ColourTo(lengthDoc - 1, state); -} - -static void ColourisePropsLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - int i = 0; - while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces - i++; - if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (lineBuffer[i] == '[') { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if (lineBuffer[i] == '@') { - styler.ColourSegment(0, i, 4); - if (lineBuffer[++i] == '=') - styler.ColourSegment(i, i, 3); - if (++i < lengthLine) - styler.ColourSegment(i, lengthLine - 1, 0); - } else { - while (lineBuffer[i] != '=' && (i < lengthLine)) // Search the '=' character - i++; - if (lineBuffer[i] == '=') { - styler.ColourSegment(0, i - 1, 0); - styler.ColourSegment(i, i, 3); - if (++i < lengthLine) - styler.ColourSegment(i, lengthLine - 1, 0); - } else - styler.ColourSegment(0, lengthLine - 1, 0); - } -} - -static void ColourisePropsDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i <= startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - lineBuffer[linePos] = '\0'; - ColourisePropsLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColourisePropsLine(lineBuffer, linePos, styler); -} - -static void ColouriseMakeLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - int i = 0; - while (isspace(lineBuffer[i]) && (i < lengthLine)) - i++; - if (lineBuffer[i] == '#' || lineBuffer[i] == '!') { - styler.ColourSegment(0, lengthLine - 1, 1); - } else { - styler.ColourSegment(0, lengthLine - 1, 0); - } -} - -static void ColouriseMakeDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i <= startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - ColouriseMakeLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColouriseMakeLine(lineBuffer, linePos, styler); -} - -static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - if (lineBuffer[0] == '>') { - // Command or return status - styler.ColourSegment(0, lengthLine - 1, 4); - } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { - // Borland error message - styler.ColourSegment(0, lengthLine - 1, 5); - } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { - // Borland warning message - styler.ColourSegment(0, lengthLine - 1, 5); - } else { - // Look for ::message - // Look for (line)message - // Look for (line,pos)message - int state = 0; - for (int i = 0; i < lengthLine; i++) { - if (state == 0 && lineBuffer[i] == ':' && isdigit(lineBuffer[i + 1])) { - state = 1; - } else if (state == 0 && lineBuffer[i] == '(') { - state = 10; - } else if (state == 1 && isdigit(lineBuffer[i])) { - state = 2; - } else if (state == 2 && lineBuffer[i] == ':') { - state = 3; - break; - } else if (state == 2 && !isdigit(lineBuffer[i])) { - state = 99; - } else if (state == 10 && isdigit(lineBuffer[i])) { - state = 11; - } else if (state == 11 && lineBuffer[i] == ',') { - state = 14; - } else if (state == 11 && lineBuffer[i] == ')') { - state = 12; - break; - } else if (state == 12 && lineBuffer[i] == ':') { - state = 13; - } else if (state == 14 && lineBuffer[i] == ')') { - state = 15; - break; - } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { - state = 99; - } - } - if (state == 3) { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if ((state == 14) || (state == 15)) { - styler.ColourSegment(0, lengthLine - 1, 3); - } else { - styler.ColourSegment(0, lengthLine - 1, 0); - } - } -} - -static void ColouriseErrorListDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i <= startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - ColouriseErrorListLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColouriseErrorListLine(lineBuffer, linePos, styler); -} - -static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = toupper(styler[start + i]); - s[i + 1] = '\0'; - } - char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_C_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_C_WORD; - } - styler.ColourSegment(start, end, chAttr); -} - -static void ColouriseSQLDoc(int codePage, int startPos, int length, - int initStyle, WordList &keywords, StylingContext &styler) { - - bool fold = styler.GetPropSet().GetInt("fold"); - int lineCurrent = styler.GetLine(startPos); - int spaceFlags = 0; - int indentCurrent = 0; - - int state = initStyle; - char chPrev = ' '; - char chNext = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - bool prevCr = false; - for (int i = startPos; i <= lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - indentCurrent = IndentAmount(styler, lineCurrent, &spaceFlags); - int lev = indentCurrent; - if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { - // Only non whitespace lines can be headers - int indentNext = IndentAmount(styler, lineCurrent + 1, &spaceFlags); - if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) { - lev |= SC_FOLDLEVELHEADERFLAG; - } - } - if (fold) { - styler.SetLevel(lineCurrent, lev); - } - } - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - i += 1; - continue; - } - - if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_WORD; - startSeg = i; - } else if (ch == '/' && chNext == '*') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENT; - startSeg = i; - } else if (ch == '-' && chNext == '-') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENTLINE; - startSeg = i; - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRING; - startSeg = i; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_C_OPERATOR); - startSeg = i + 1; - } - } else if (state == SCE_C_WORD) { - if (!iswordchar(ch)) { - classifyWordSQL(startSeg, i - 1, keywords, styler); - state = SCE_C_DEFAULT; - startSeg = i; - if (ch == '/' && chNext == '*') { - state = SCE_C_COMMENT; - } else if (ch == '-' && chNext == '-') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\'') { - state = SCE_C_STRING; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - } - } - } else { - if (state == SCE_C_COMMENT) { - if (ch == '/' && chPrev == '*' && ( - (i > startSeg + 2) || ((initStyle == SCE_C_COMMENT) && (startSeg == startPos)))) { - state = SCE_C_DEFAULT; - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - } - } else if (state == SCE_C_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_STRING) { - if (ch == '\'') { - if ( chNext == '\'' ) { - i++; - } else { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - startSeg = i; - } - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } - if (state == SCE_C_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - state = SCE_C_COMMENT; - } else if (ch == '-' && chNext == '-') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\'') { - state = SCE_C_STRING; - } else if (iswordstart(ch)) { - state = SCE_C_WORD; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - } - } - } - chPrev = ch; - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc - 1, state); -} - -void ColouriseDoc(int codePage, int startPos, int lengthDoc, int initStyle, - int language, WordList *keywordlists[], StylingContext &styler) { - //Platform::DebugPrintf("ColouriseDoc <%s>\n", language); - if (language == SCLEX_PYTHON) { - // Python uses a different mask because bad indentation is marked by oring with 32 - styler.StartAt(startPos, 127); - ColourisePyDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_PERL) { - // Lexer for perl often has to backtrack to start of current style to determine - // which characters are being used as quotes, how deeply nested is the - // start position and what the termination string is for here documents - ColourisePerlDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if ((language == SCLEX_HTML) || (language == SCLEX_XML)) { - // Lexer for HTML requires more lexical states (6 bits worth) than most lexers - ColouriseHyperTextDoc(codePage, startPos, lengthDoc, initStyle, - *keywordlists[0], *keywordlists[1], *keywordlists[2], *keywordlists[3], styler); - } else { - styler.StartAt(startPos); - if (language == SCLEX_CPP) { - ColouriseCppDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_SQL) { - ColouriseSQLDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_VB) { - ColouriseVBDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_PROPERTIES) { - ColourisePropsDoc(startPos, lengthDoc, initStyle, styler); - } else if (language == SCLEX_ERRORLIST) { - ColouriseErrorListDoc(startPos, lengthDoc, initStyle, styler); - } else if (language == SCLEX_MAKEFILE) { - ColouriseMakeDoc(startPos, lengthDoc, initStyle, styler); - } else if (language == SCLEX_BATCH) { - ColouriseBatchDoc(startPos, lengthDoc, initStyle, styler); - } else { - // Null language means all style bytes are 0 so just mark the end - no need to fill in. - styler.StartAt(startPos + lengthDoc - 1); - styler.ColourSegment(0, 0, 0); - } +LexerModule *LexerModule::base = 0; + +LexerModule::LexerModule(int language_, LexerFunction fn_) : + language(language_), fn(fn_) { + next = base; + base = this; +} + +void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle, + int language, WordList *keywordlists[], StylingContext &styler) { + LexerModule *lm = base; + while (lm) { + if (lm->language == language) { + lm->fn(startPos, lengthDoc, initStyle, keywordlists, styler); + return; + } + lm = lm->next; + } + // Unknown language + // Null language means all style bytes are 0 so just mark the end - no need to fill in. + if (lengthDoc > 0) { + styler.StartAt(startPos + lengthDoc - 1); + styler.StartSegment(startPos + lengthDoc - 1); + styler.ColourTo(startPos + lengthDoc - 1, 0); } } diff --git a/contrib/src/stc/scintilla/src/LexCPP.cxx b/contrib/src/stc/scintilla/src/LexCPP.cxx new file mode 100644 index 0000000000..3199322ba3 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexCPP.cxx @@ -0,0 +1,255 @@ +// SciTE - Scintilla based Text Editor +// LexCPP.cxx - lexer for C++, C, Java, and Javascript +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + bool wordIsUUID = false; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_C_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_C_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_C_WORD; + wordIsUUID = strcmp(s, "uuid") == 0; + } + } + styler.ColourTo(end, chAttr); + return wordIsUUID; +} + +static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + StylingContext &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + bool fold = styler.GetPropSet().GetInt("fold"); + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + + int state = initStyle; + char chPrev = ' '; + char chNext = styler[startPos]; + unsigned int lengthDoc = startPos + length; + int visChars = 0; + styler.StartSegment(startPos); + bool lastWordWasUUID = false; + for (unsigned int i = startPos; i <= lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) { + int lev = levelPrev; + if (visChars == 0) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + styler.SetLevel(lineCurrent, lev); + lineCurrent++; + visChars = 0; + levelPrev = levelCurrent; + } + if (!isspace(ch)) + visChars++; + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_C_STRINGEOL) { + if (ch != '\r' && ch != '\n') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i-1, state); + if (lastWordWasUUID) { + state = SCE_C_UUID; + lastWordWasUUID = false; + } else { + state = SCE_C_WORD; + } + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i-1, state); + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_C_COMMENTDOC; + else + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i-1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i-1, state); + state = SCE_C_STRING; + } else if (ch == '\'') { + styler.ColourTo(i-1, state); + state = SCE_C_CHARACTER; + } else if (ch == '#') { + styler.ColourTo(i-1, state); + state = SCE_C_PREPROCESSOR; + } else if (isoperator(ch)) { + styler.ColourTo(i-1, state); + styler.ColourTo(i, SCE_C_OPERATOR); + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + } else if (state == SCE_C_WORD) { + if (!iswordchar(ch)) { + lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_C_DEFAULT; + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_C_COMMENTDOC; + else + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (ch == '\'') { + state = SCE_C_CHARACTER; + } else if (ch == '#') { + state = SCE_C_PREPROCESSOR; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + } + } else { + if (state == SCE_C_PREPROCESSOR) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_COMMENT) { + if (ch == '/' && chPrev == '*') { + if (((i > styler.GetStartSegment() + 2) || ( + (initStyle == SCE_C_COMMENT) && + (styler.GetStartSegment() == static_cast(startPos))))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTDOC) { + if (ch == '/' && chPrev == '*') { + if (((i > styler.GetStartSegment() + 3) || ( + (initStyle == SCE_C_COMMENTDOC) && + (styler.GetStartSegment() == static_cast(startPos))))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, state); + state = SCE_C_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_C_CHARACTER) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, state); + state = SCE_C_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_C_UUID) { + if (ch == '\r' || ch == '\n' || ch == ')') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } + if (state == SCE_C_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_C_COMMENTDOC; + else + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (ch == '\'') { + state = SCE_C_CHARACTER; + } else if (ch == '#') { + state = SCE_C_PREPROCESSOR; + } else if (iswordstart(ch)) { + state = SCE_C_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + } + } + chPrev = ch; + } + styler.ColourTo(lengthDoc - 1, state); + + // Fill in the real level of the next line, keeping the current flags as they will be filled in later + if (fold) { + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); + styler.SetLevel(lineCurrent, levelPrev | flagsNext); + + } +} + +LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc); diff --git a/contrib/src/stc/scintilla/src/LexHTML.cxx b/contrib/src/stc/scintilla/src/LexHTML.cxx new file mode 100644 index 0000000000..be30bc4626 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexHTML.cxx @@ -0,0 +1,1139 @@ +// SciTE - Scintilla based Text Editor +// LexHTML.cxx - lexer for HTML +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; +static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) { + char s[100]; + s[0] = '\0'; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } +//Platform::DebugPrintf("Scripting indicator [%s]\n", s); + if (strstr(s, "vbs")) + return eScriptVBS; + if (strstr(s, "pyth")) + return eScriptPython; + if (strstr(s, "javas")) + return eScriptJS; + if (strstr(s, "jscr")) + return eScriptJS; + + return prevValue; +} + +static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || + (styler[start] == '-') || (styler[start] == '#'); + char chAttr = SCE_H_ATTRIBUTEUNKNOWN; + if (wordIsNumber) { + chAttr = SCE_H_NUMBER; + } else { + char s[100]; + s[0] = '\0'; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + if (keywords.InList(s)) + chAttr = SCE_H_ATTRIBUTE; + } + styler.ColourTo(end, chAttr); +} + +static int classifyTagHTML(unsigned int start, unsigned int end, + WordList &keywords, StylingContext &styler) { + char s[100]; + // Copy after the '<' + unsigned int i = 0; + for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) { + char ch = styler[cPos]; + if (ch != '<') + s[i++] = tolower(ch); + } + s[i] = '\0'; + char chAttr = SCE_H_TAGUNKNOWN; + if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment + chAttr = SCE_H_COMMENT; + } else if (s[0] == '/') { // Closing tag + if (keywords.InList(s + 1)) + chAttr = SCE_H_TAG; + } else { + if (keywords.InList(s)) { + chAttr = SCE_H_TAG; + if (0 == strcmp(s, "script")) + chAttr = SCE_H_SCRIPT; + } + } + styler.ColourTo(end, chAttr); + return chAttr; +} + +static void classifyWordHTJS(unsigned int start, unsigned int end, + WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HJ_WORD; + if (wordIsNumber) + chAttr = SCE_HJ_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_HJ_KEYWORD; + } + styler.ColourTo(end, chAttr); +} + +static void classifyWordHTJSA(unsigned int start, unsigned int end, + WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HJA_WORD; + if (wordIsNumber) + chAttr = SCE_HJA_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_HJA_KEYWORD; + } + styler.ColourTo(end, chAttr); +} + +static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_HB_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_HB_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_HB_WORD; + if (strcmp(s, "rem") == 0) + chAttr = SCE_HB_COMMENTLINE; + } + } + styler.ColourTo(end, chAttr); + if (chAttr == SCE_HB_COMMENTLINE) + return SCE_HB_COMMENTLINE; + else + return SCE_HB_DEFAULT; +} + +static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_HBA_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_HBA_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_HBA_WORD; + if (strcmp(s, "rem") == 0) + chAttr = SCE_HBA_COMMENTLINE; + } + } + styler.ColourTo(end, chAttr); + if (chAttr == SCE_HBA_COMMENTLINE) + return SCE_HBA_COMMENTLINE; + else + return SCE_HBA_DEFAULT; +} + +static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HP_IDENTIFIER; + if (0 == strcmp(prevWord, "class")) + chAttr = SCE_HP_CLASSNAME; + else if (0 == strcmp(prevWord, "def")) + chAttr = SCE_HP_DEFNAME; + else if (wordIsNumber) + chAttr = SCE_HP_NUMBER; + else if (keywords.InList(s)) + chAttr = SCE_HP_WORD; + styler.ColourTo(end, chAttr); + strcpy(prevWord, s); +} + +static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HPA_IDENTIFIER; + if (0 == strcmp(prevWord, "class")) + chAttr = SCE_HPA_CLASSNAME; + else if (0 == strcmp(prevWord, "def")) + chAttr = SCE_HPA_DEFNAME; + else if (wordIsNumber) + chAttr = SCE_HPA_NUMBER; + else if (keywords.InList(s)) + chAttr = SCE_HPA_WORD; + styler.ColourTo(end, chAttr); + strcpy(prevWord, s); +} + +inline bool ishtmlwordchar(char ch) { + return isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#'; +} + +static bool InTagState(int state) { + return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || + state == SCE_H_SCRIPT || + state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || + state == SCE_H_NUMBER || state == SCE_H_OTHER || + state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING; +} + +static bool isLineEnd(char ch) { + return ch == '\r' || ch == '\n'; +} + +static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + StylingContext &styler) { + + WordList &keywords=*keywordlists[0]; + WordList &keywords2=*keywordlists[1]; + WordList &keywords3=*keywordlists[2]; + WordList &keywords4=*keywordlists[3]; + + // Lexer for HTML requires more lexical states (7 bits worth) than most lexers + styler.StartAt(startPos, 127); + bool lastTagWasScript = false; + char prevWord[200]; + prevWord[0] = '\0'; + int scriptLanguage = eScriptJS; + int state = initStyle; + // If inside a tag, it may be a script tage, so reread from the start to ensure any language tas are seen + if (InTagState(state)) { + while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) { + startPos--; + } + state = SCE_H_DEFAULT; + } + styler.StartAt(startPos, 127); + + int lineState = eScriptVBS; + int lineCurrent = styler.GetLine(startPos); + if (lineCurrent > 0) + lineState = styler.GetLineState(lineCurrent); + int defaultScript = lineState &0xff; + int beforeASP = (lineState >> 8) &0xff; + int inASP = (lineState >> 16) &0xff; + + char chPrev = ' '; + char chPrev2 = ' '; + styler.StartSegment(startPos); + int lengthDoc = startPos + length; + for (int i = startPos; i <= lengthDoc; i++) { + char ch = styler[i]; + char chNext = styler.SafeGetCharAt(i + 1); + char chNext2 = styler.SafeGetCharAt(i + 2); + + if (styler.IsLeadByte(ch)) { + chPrev2 = ' '; + chPrev = ' '; + i += 1; + continue; + } + + if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + // New line -> record any line state onto /next/ line + lineCurrent++; + styler.SetLineState(lineCurrent, + defaultScript | (beforeASP << 8) | (inASP << 16)); + } + + // Handle ASP even within other constructs as it is a preprocessor + if ((ch == '<') && (chNext == '%')) { + beforeASP = state; + styler.ColourTo(i - 1, state); + if (chNext2 == '@') { + styler.ColourTo(i + 2, SCE_H_ASP); + state = SCE_H_ASPAT; + i+=2; + } else { + if (defaultScript == eScriptVBS) + state = SCE_HBA_START; + else if (defaultScript == eScriptPython) + state = SCE_HPA_START; + else + state = SCE_HJA_START; + if (chNext2 == '=') { + styler.ColourTo(i + 2, SCE_H_ASP); + i+=2; + } else { + styler.ColourTo(i + 1, SCE_H_ASP); + i++; + } + } + inASP = 1; + continue; + } + if (inASP && (ch == '%') && (chNext == '>')) { + if (state == SCE_H_ASPAT) + defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript); + // Bounce out of any ASP mode + if (state == SCE_HJA_WORD) { + classifyWordHTJSA(styler.GetStartSegment(), i - 1, keywords2, styler); + } else if (state == SCE_HBA_WORD) { + classifyWordHTVBA(styler.GetStartSegment(), i - 1, keywords3, styler); + } else if (state == SCE_HPA_WORD) { + classifyWordHTPyA(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + } else { + styler.ColourTo(i - 1, state); + } + //if (state == SCE_H_ASPAT) + // styler.ColourTo(i+1, SCE_H_ASPAT); + //else + styler.ColourTo(i+1, SCE_H_ASP); + i++; + state = beforeASP; + beforeASP = SCE_H_DEFAULT; + inASP = 0; + continue; + } + + if (state == SCE_H_DEFAULT) { + if (ch == '<') { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + if (chNext == '?') { + styler.ColourTo(i + 1, SCE_H_XMLSTART); + i++; + ch = chNext; + } + } else if (ch == '&') { + styler.ColourTo(i - 1, SCE_H_DEFAULT); + state = SCE_H_ENTITY; + } + } else if (state == SCE_H_COMMENT) { + if ((ch == '>') && (chPrev == '-')) { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_ENTITY) { + if (ch == ';') { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_TAGUNKNOWN) { + if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { + int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); + lastTagWasScript = eClass == SCE_H_SCRIPT; + if (lastTagWasScript) { + scriptLanguage = eScriptJS; + eClass = SCE_H_TAG; + } + if (ch == '>') { + styler.ColourTo(i, SCE_H_TAG); + if (lastTagWasScript) { + if (scriptLanguage == eScriptVBS) + state = SCE_HB_START; + else if (scriptLanguage == eScriptPython) + state = SCE_HP_START; + else + state = SCE_HJ_START; + } else { + state = SCE_H_DEFAULT; + } + } else { + if (eClass == SCE_H_COMMENT) { + state = SCE_H_COMMENT; + } else { + state = SCE_H_OTHER; + } + } + } + } else if (state == SCE_H_ATTRIBUTE) { + if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { + if (lastTagWasScript) + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage); + classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler); + if (ch == '>') { + styler.ColourTo(i, SCE_H_TAG); + if (lastTagWasScript) { + if (scriptLanguage == eScriptVBS) + state = SCE_HB_START; + else if (scriptLanguage == eScriptPython) + state = SCE_HP_START; + else + state = SCE_HJ_START; + } else { + state = SCE_H_DEFAULT; + } + } else { + state = SCE_H_OTHER; + } + } + } else if (state == SCE_H_ASP) { + if ((ch == '>') && (chPrev == '%')) { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_ASPAT) { + if ((ch == '>') && (chPrev == '%')) { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_OTHER) { + if (ch == '>') { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_H_TAG); + if (lastTagWasScript) { + if (scriptLanguage == eScriptVBS) + state = SCE_HB_START; + else if (scriptLanguage == eScriptPython) + state = SCE_HP_START; + else + state = SCE_HJ_START; + } else { + state = SCE_H_DEFAULT; + } + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_H_DOUBLESTRING; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_H_SINGLESTRING; + } else if (ch == '/' && chNext == '>') { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } else if (ch == '?' && chNext == '>') { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_XMLEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } else if (ishtmlwordchar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_H_ATTRIBUTE; + } + } else if (state == SCE_H_DOUBLESTRING) { + if (ch == '\"') { + if (lastTagWasScript) + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); + styler.ColourTo(i, SCE_H_DOUBLESTRING); + state = SCE_H_OTHER; + } + } else if (state == SCE_H_SINGLESTRING) { + if (ch == '\'') { + if (lastTagWasScript) + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); + styler.ColourTo(i, SCE_H_SINGLESTRING); + state = SCE_H_OTHER; + } + } else if (state == SCE_HJ_DEFAULT || state == SCE_HJ_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJ_WORD; + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + if (chNext2 == '*') + state = SCE_HJ_COMMENTDOC; + else + state = SCE_HJ_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_DOUBLESTRING; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_SINGLESTRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HJ_SYMBOLS); + state = SCE_HJ_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HJ_START) { + styler.ColourTo(i - 1, state); + state = SCE_HJ_DEFAULT; + } + } + } else if (state == SCE_HJ_WORD) { + if (!iswordchar(ch)) { + classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler); + //styler.ColourTo(i - 1, eHTJSKeyword); + state = SCE_HJ_DEFAULT; + if (ch == '/' && chNext == '*') { + if (chNext2 == '*') + state = SCE_HJ_COMMENTDOC; + else + state = SCE_HJ_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJ_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJ_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJ_SINGLESTRING; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJ_SYMBOLS); + state = SCE_HJ_DEFAULT; + } + } + } else if (state == SCE_HJ_COMMENT) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJ_DEFAULT; + styler.ColourTo(i, SCE_HJ_COMMENT); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJ_COMMENTDOC) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJ_DEFAULT; + styler.ColourTo(i, SCE_HJ_COMMENTDOC); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJ_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); + state = SCE_HJ_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HJ_DOUBLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\"') { + styler.ColourTo(i, SCE_HJ_DOUBLESTRING); + state = SCE_HJ_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJ_STRINGEOL; + } + } else if (state == SCE_HJ_SINGLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\'') { + styler.ColourTo(i, SCE_HJ_SINGLESTRING); + state = SCE_HJ_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJ_STRINGEOL; + } + } else if (state == SCE_HJ_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJ_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HJ_DEFAULT; + } + } else if (state == SCE_HJA_DEFAULT || state == SCE_HJA_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJA_WORD; + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + if (chNext2 == '*') + state = SCE_HJA_COMMENTDOC; + else + state = SCE_HJA_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_DOUBLESTRING; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_SINGLESTRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HJA_SYMBOLS); + state = SCE_HJA_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HJA_START) { + styler.ColourTo(i - 1, state); + state = SCE_HJA_DEFAULT; + } + } + } else if (state == SCE_HJA_WORD) { + if (!iswordchar(ch)) { + classifyWordHTJSA(styler.GetStartSegment(), i - 1, keywords2, styler); + //styler.ColourTo(i - 1, eHTJSKeyword); + state = SCE_HJA_DEFAULT; + if (ch == '/' && chNext == '*') { + if (chNext2 == '*') + state = SCE_HJA_COMMENTDOC; + else + state = SCE_HJA_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJA_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJA_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJA_SINGLESTRING; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJA_SYMBOLS); + state = SCE_HJA_DEFAULT; + } + } + } else if (state == SCE_HJA_COMMENT) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJA_DEFAULT; + styler.ColourTo(i, SCE_HJA_COMMENT); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJA_COMMENTDOC) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJA_DEFAULT; + styler.ColourTo(i, SCE_HJA_COMMENTDOC); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJA_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, SCE_HJA_COMMENTLINE); + state = SCE_HJA_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, SCE_HJA_COMMENTLINE); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HJA_DOUBLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\"') { + styler.ColourTo(i, SCE_HJA_DOUBLESTRING); + state = SCE_HJA_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJA_STRINGEOL; + } + } else if (state == SCE_HJA_SINGLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\'') { + styler.ColourTo(i, SCE_HJA_SINGLESTRING); + state = SCE_HJA_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJA_STRINGEOL; + } + } else if (state == SCE_HJA_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJA_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HJA_DEFAULT; + } + } else if (state == SCE_HB_DEFAULT || state == SCE_HB_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HB_WORD; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HB_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HB_STRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HB_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HB_DEFAULT); + state = SCE_HB_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HB_START) { + styler.ColourTo(i - 1, state); + state = SCE_HB_DEFAULT; + } + } + } else if (state == SCE_HB_WORD) { + if (!iswordchar(ch)) { + state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler); + if (state == SCE_HB_DEFAULT) { + if (ch == '\"') { + state = SCE_HB_STRING; + } else if (ch == '\'') { + state = SCE_HB_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HB_DEFAULT); + state = SCE_HB_DEFAULT; + } + } + } + } else if (state == SCE_HB_STRING) { + if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HB_DEFAULT; + i++; + ch = chNext; + } else if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_HB_STRINGEOL; + } + } else if (state == SCE_HB_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HB_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HB_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HB_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HB_DEFAULT; + } + } else if (state == SCE_HBA_DEFAULT || state == SCE_HBA_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HBA_WORD; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_STRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HBA_DEFAULT); + state = SCE_HBA_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HBA_START) { + styler.ColourTo(i - 1, state); + state = SCE_HBA_DEFAULT; + } + } + } else if (state == SCE_HBA_WORD) { + if (!iswordchar(ch)) { + state = classifyWordHTVBA(styler.GetStartSegment(), i - 1, keywords3, styler); + if (state == SCE_HBA_DEFAULT) { + if (ch == '\"') { + state = SCE_HBA_STRING; + } else if (ch == '\'') { + state = SCE_HBA_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HBA_DEFAULT); + state = SCE_HBA_DEFAULT; + } + } + } + } else if (state == SCE_HBA_STRING) { + if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HBA_DEFAULT; + i++; + ch = chNext; + } else if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_HBA_STRINGEOL; + } + } else if (state == SCE_HBA_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HBA_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HBA_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HBA_DEFAULT; + } + } else if (state == SCE_HP_DEFAULT || state == SCE_HP_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HP_WORD; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HP_COMMENTLINE; + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = SCE_HP_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HP_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_STRING; + } + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HP_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HP_OPERATOR); + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HP_START) { + styler.ColourTo(i - 1, state); + state = SCE_HP_DEFAULT; + } + } + } else if (state == SCE_HP_WORD) { + if (!iswordchar(ch)) { + classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + state = SCE_HP_DEFAULT; + if (ch == '#') { + state = SCE_HP_COMMENTLINE; + } else if (ch == '\"') { + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HP_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_STRING; + } + } else if (ch == '\'') { + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HP_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HP_OPERATOR); + } + } + } else if (state == SCE_HP_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_CHARACTER) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_TRIPLE) { + if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_TRIPLEDOUBLE) { + if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HPA_DEFAULT || state == SCE_HPA_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HPA_WORD; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HPA_COMMENTLINE; + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = SCE_HPA_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HPA_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_STRING; + } + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HPA_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HPA_OPERATOR); + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HPA_START) { + styler.ColourTo(i - 1, state); + state = SCE_HPA_DEFAULT; + } + } + } else if (state == SCE_HPA_WORD) { + if (!iswordchar(ch)) { + classifyWordHTPyA(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + state = SCE_HPA_DEFAULT; + if (ch == '#') { + state = SCE_HPA_COMMENTLINE; + } else if (ch == '\"') { + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HPA_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_STRING; + } + } else if (ch == '\'') { + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HPA_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HPA_OPERATOR); + } + } + } else if (state == SCE_HPA_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_CHARACTER) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_TRIPLE) { + if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_TRIPLEDOUBLE) { + if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } + if (state == SCE_HB_DEFAULT) { // One of the above succeeded + if (ch == '\"') { + state = SCE_HB_STRING; + } else if (ch == '\'') { + state = SCE_HB_COMMENTLINE; + } else if (iswordstart(ch)) { + state = SCE_HB_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HB_DEFAULT); + } + } + if (state == SCE_HBA_DEFAULT) { // One of the above succeeded + if (ch == '\"') { + state = SCE_HBA_STRING; + } else if (ch == '\'') { + state = SCE_HBA_COMMENTLINE; + } else if (iswordstart(ch)) { + state = SCE_HBA_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HBA_DEFAULT); + } + } + if (state == SCE_HJ_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_HJ_COMMENTDOC; + else + state = SCE_HJ_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJ_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJ_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJ_SINGLESTRING; + } else if (iswordstart(ch)) { + state = SCE_HJ_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJ_SYMBOLS); + } + } + if (state == SCE_HJA_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_HJA_COMMENTDOC; + else + state = SCE_HJA_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJA_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJA_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJA_SINGLESTRING; + } else if (iswordstart(ch)) { + state = SCE_HJA_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJA_SYMBOLS); + } + } + chPrev2 = chPrev; + chPrev = ch; + } + styler.ColourTo(lengthDoc - 1, state); +} + +LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc); +LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc); diff --git a/contrib/src/stc/scintilla/src/LexOthers.cxx b/contrib/src/stc/scintilla/src/LexOthers.cxx new file mode 100644 index 0000000000..6e576c2c8a --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexOthers.cxx @@ -0,0 +1,200 @@ +// SciTE - Scintilla based Text Editor +// LexOthers.cxx - lexers for properties files, batch files, make files and error lists +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void ColouriseBatchLine(char *lineBuffer, int endLine, StylingContext &styler) { + if (0 == strncmp(lineBuffer, "REM", 3)) { + styler.ColourTo(endLine, 1); + } else if (0 == strncmp(lineBuffer, "rem", 3)) { + styler.ColourTo(endLine, 1); + } else if (0 == strncmp(lineBuffer, "SET", 3)) { + styler.ColourTo(endLine, 2); + } else if (0 == strncmp(lineBuffer, "set", 3)) { + styler.ColourTo(endLine, 2); + } else if (lineBuffer[0] == ':') { + styler.ColourTo(endLine, 3); + } else { + styler.ColourTo(endLine, 0); + } +} + +static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + for (unsigned int i = startPos; i < startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { + ColouriseBatchLine(lineBuffer, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseBatchLine(lineBuffer, startPos + length, styler); +} + +static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, StylingContext &styler) { + int i = 0; + while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces + i++; + if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { + styler.ColourTo(endPos, 1); + } else if (lineBuffer[i] == '[') { + styler.ColourTo(endPos, 2); + } else if (lineBuffer[i] == '@') { + styler.ColourTo(startLine+i, 4); + if (lineBuffer[++i] == '=') + styler.ColourTo(startLine+i, 3); + styler.ColourTo(endPos, 0); + } else { + while (lineBuffer[i] != '=' && (i < lengthLine)) // Search the '=' character + i++; + if (lineBuffer[i] == '=') { + styler.ColourTo(startLine+i-1, 0); + styler.ColourTo(startLine+i, 3); + styler.ColourTo(endPos, 0); + } else { + styler.ColourTo(endPos, 0); + } + } +} + +static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + int startLine = startPos; + for (unsigned int i = startPos; i <= startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if ((styler[i] == '\r' && styler.SafeGetCharAt(i+1) != '\n') || + styler[i] == '\n' || + (linePos >= sizeof(lineBuffer) - 1)) { + lineBuffer[linePos] = '\0'; + ColourisePropsLine(lineBuffer, linePos, startLine, i, styler); + linePos = 0; + startLine = i+1; + } + } + if (linePos > 0) + ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler); +} + +static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { + int i = 0; + while (isspace(lineBuffer[i]) && (i < lengthLine)) + i++; + if (lineBuffer[i] == '#' || lineBuffer[i] == '!') { + styler.ColourTo(endPos, 1); + } else { + styler.ColourTo(endPos, 0); + } +} + +static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + for (unsigned int i = startPos; i <= startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { + ColouriseMakeLine(lineBuffer, linePos, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseMakeLine(lineBuffer, linePos, startPos + length, styler); +} + +static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { + if (lineBuffer[0] == '>') { + // Command or return status + styler.ColourTo(endPos, 4); + } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { + styler.ColourTo(endPos, 1); + } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { + // Borland error message + styler.ColourTo(endPos, 5); + } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { + // Borland warning message + styler.ColourTo(endPos, 5); + } else { + // Look for ::message + // Look for (line)message + // Look for (line,pos)message + int state = 0; + for (int i = 0; i < lengthLine; i++) { + if (state == 0 && lineBuffer[i] == ':' && isdigit(lineBuffer[i + 1])) { + state = 1; + } else if (state == 0 && lineBuffer[i] == '(') { + state = 10; + } else if (state == 1 && isdigit(lineBuffer[i])) { + state = 2; + } else if (state == 2 && lineBuffer[i] == ':') { + state = 3; + break; + } else if (state == 2 && !isdigit(lineBuffer[i])) { + state = 99; + } else if (state == 10 && isdigit(lineBuffer[i])) { + state = 11; + } else if (state == 11 && lineBuffer[i] == ',') { + state = 14; + } else if (state == 11 && lineBuffer[i] == ')') { + state = 12; + break; + } else if (state == 12 && lineBuffer[i] == ':') { + state = 13; + } else if (state == 14 && lineBuffer[i] == ')') { + state = 15; + break; + } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { + state = 99; + } + } + if (state == 3) { + styler.ColourTo(endPos, 2); + } else if ((state == 14) || (state == 15)) { + styler.ColourTo(endPos, 3); + } else { + styler.ColourTo(endPos, 0); + } + } +} + +static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + for (unsigned int i = startPos; i <= startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { + ColouriseErrorListLine(lineBuffer, linePos, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseErrorListLine(lineBuffer, linePos, startPos + length, styler); +} + +LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc); +LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc); +LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc); +LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc); diff --git a/contrib/src/stc/scintilla/src/LexPerl.cxx b/contrib/src/stc/scintilla/src/LexPerl.cxx new file mode 100644 index 0000000000..9ccb207d0f --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexPerl.cxx @@ -0,0 +1,488 @@ +// SciTE - Scintilla based Text Editor +// LexPerl.cxx - lexer for subset of Perl +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +inline bool isPerlOperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '\\' || + ch == '(' || ch == ')' || ch == '-' || ch == '+' || + ch == '=' || ch == '|' || ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ':' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || ch == '/' || + ch == '?' || ch == '!' || ch == '.' || ch == '~') + return true; + return false; +} + +static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_PL_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_PL_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_PL_WORD; + } + styler.ColourTo(end, chAttr); + return chAttr; +} + +static bool isEndVar(char ch) { + return !isalnum(ch) && ch != '#' && ch != '$' && + ch != '_' && ch != '\''; +} + +static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) { + if ((pos + static_cast(strlen(val))) >= lengthDoc) { + return false; + } + while (*val) { + if (*val != styler[pos++]) { + return false; + } + val++; + } + return true; +} + +static bool isOKQuote(char ch) { + if (isalnum(ch)) + return false; + if (isspace(ch)) + return false; + if (iscntrl(ch)) + return false; + return true; +} + +static char opposite(char ch) { + if (ch == '(') + return ')'; + if (ch == '[') + return ']'; + if (ch == '{') + return '}'; + if (ch == '<') + return '>'; + return ch; +} + +static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], StylingContext &styler) { + + // Lexer for perl often has to backtrack to start of current style to determine + // which characters are being used as quotes, how deeply nested is the + // start position and what the termination string is for here documents + + WordList &keywords = *keywordlists[0]; + + char sooked[100]; + int quotes = 0; + char quoteDown = 'd'; + char quoteUp = 'd'; + int quoteRep = 1; + int sookedpos = 0; + bool preferRE = true; + sooked[sookedpos] = '\0'; + int state = initStyle; + int lengthDoc = startPos + length; + // If in a long distance lexical state, seek to the beginning to find quote characters + if (state == SCE_PL_HERE || state == SCE_PL_REGEX || + state == SCE_PL_REGSUBST || state == SCE_PL_LONGQUOTE) { + while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) { + startPos--; + } + state = SCE_PL_DEFAULT; + } + styler.StartAt(startPos); + char chPrev = ' '; + char chNext = styler[startPos]; + styler.StartSegment(startPos); + for (int i = startPos; i <= lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + char chNext2 = styler.SafeGetCharAt(i + 2); + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_PL_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + if (ch == 's' && !isalnum(chNext)) { + state = SCE_PL_REGSUBST; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 2; + } else if (ch == 'm' && !isalnum(chNext)) { + state = SCE_PL_REGEX; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 1; + } else if (ch == 't' && chNext == 'r' && !isalnum(chNext2)) { + state = SCE_PL_REGSUBST; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 2; + i++; + chNext = chNext2; + } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isalnum(chNext2)) { + state = SCE_PL_LONGQUOTE; + i++; + chNext = chNext2; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 1; + } else { + state = SCE_PL_WORD; + preferRE = false; + } + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = SCE_PL_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_PL_STRING; + } else if (ch == '\'') { + if (chPrev == '&') { + // Archaic call + styler.ColourTo(i, state); + } else { + styler.ColourTo(i - 1, state); + state = SCE_PL_CHARACTER; + } + } else if (ch == '`') { + styler.ColourTo(i - 1, state); + state = SCE_PL_BACKTICKS; + } else if (ch == '$') { + preferRE = false; + styler.ColourTo(i - 1, state); + if (isalnum(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { + state = SCE_PL_SCALAR; + } else if (chNext != '{' && chNext != '[') { + styler.ColourTo(i, SCE_PL_SCALAR); + i++; + ch = ' '; + chNext = ' '; + } else { + styler.ColourTo(i, SCE_PL_SCALAR); + } + } else if (ch == '@') { + preferRE = false; + styler.ColourTo(i - 1, state); + if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { + state = SCE_PL_ARRAY; + } else if (chNext != '{' && chNext != '[') { + styler.ColourTo(i, SCE_PL_ARRAY); + i++; + ch = ' '; + } else { + styler.ColourTo(i, SCE_PL_ARRAY); + } + } else if (ch == '%') { + preferRE = false; + styler.ColourTo(i - 1, state); + if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { + state = SCE_PL_HASH; + } else if (chNext != '{' && chNext != '[') { + styler.ColourTo(i, SCE_PL_HASH); + i++; + ch = ' '; + } else { + styler.ColourTo(i, SCE_PL_HASH); + } + } else if (ch == '*') { + styler.ColourTo(i - 1, state); + state = SCE_PL_SYMBOLTABLE; + } else if (ch == '/' && preferRE) { + styler.ColourTo(i - 1, state); + state = SCE_PL_REGEX; + quoteUp = '/'; + quoteDown = '/'; + quotes = 1; + quoteRep = 1; + } else if (ch == '<' && chNext == '<') { + styler.ColourTo(i - 1, state); + state = SCE_PL_HERE; + i++; + ch = chNext; + chNext = chNext2; + quotes = 0; + sookedpos = 0; + sooked[sookedpos] = '\0'; + } else if (ch == '=' && isalpha(chNext)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_POD; + quotes = 0; + sookedpos = 0; + sooked[sookedpos] = '\0'; + } else if (isPerlOperator(ch)) { + if (ch == ')' || ch == ']') + preferRE = false; + else + preferRE = true; + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_PL_OPERATOR); + } + } else if (state == SCE_PL_WORD) { + if (!iswordchar(ch) && ch != '\'') { // Archaic Perl has quotes inside names + if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")) { + styler.ColourTo(i, SCE_PL_DATASECTION); + state = SCE_PL_DATASECTION; + } else if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__")) { + styler.ColourTo(i, SCE_PL_DATASECTION); + state = SCE_PL_DATASECTION; + } else { + if (classifyWordPerl(styler.GetStartSegment(), i - 1, keywords, styler) == SCE_PL_WORD) + preferRE = true; + state = SCE_PL_DEFAULT; + if (ch == '#') { + state = SCE_PL_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_PL_STRING; + } else if (ch == '\'') { + state = SCE_PL_CHARACTER; + } else if (ch == '<' && chNext == '<') { + state = SCE_PL_HERE; + quotes = 0; + sookedpos = 0; + sooked[sookedpos] = '\0'; + } else if (isPerlOperator(ch)) { + if (ch == ')' || ch == ']') + preferRE = false; + else + preferRE = true; + styler.ColourTo(i, SCE_PL_OPERATOR); + state = SCE_PL_DEFAULT; + } + } + } + } else { + if (state == SCE_PL_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_HERE) { + if (isalnum(ch) && quotes < 2) { + sooked[sookedpos++] = ch; + sooked[sookedpos] = '\0'; + if (quotes == 0) + quotes = 1; + } else { + quotes++; + } + + if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked)) { + styler.ColourTo(i + sookedpos - 1, SCE_PL_HERE); + state = SCE_PL_DEFAULT; + i += sookedpos; + chNext = ' '; + } + } else if (state == SCE_PL_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_PL_CHARACTER) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_PL_BACKTICKS) { + if (ch == '`') { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_PL_POD) { + if (ch == '=') { + if (isMatch(styler, lengthDoc, i, "=cut")) { + styler.ColourTo(i - 1 + 4, state); + i += 4; + state = SCE_PL_DEFAULT; + chNext = ' '; + ch = ' '; + } + } + } else if (state == SCE_PL_SCALAR) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_ARRAY) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_HASH) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_SYMBOLTABLE) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_REF) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_REGEX) { + if (!quoteUp && !isspace(ch)) { + quoteUp = ch; + quoteDown = opposite(ch); + quotes++; + } else { + if (ch == quoteDown && chPrev != '\\') { + quotes--; + if (quotes == 0) { + quoteRep--; + if (quoteUp == quoteDown) { + quotes++; + } + } + if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + } else if (ch == quoteUp && chPrev != '\\') { + quotes++; + } else if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + } + } else if (state == SCE_PL_REGSUBST) { + if (!quoteUp && !isspace(ch)) { + quoteUp = ch; + quoteDown = opposite(ch); + quotes++; + } else { + if (ch == quoteDown && chPrev != '\\') { + quotes--; + if (quotes == 0) { + quoteRep--; + } + if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + if (quoteUp == quoteDown) { + quotes++; + } + } else if (ch == quoteUp && chPrev != '\\') { + quotes++; + } else if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + } + } else if (state == SCE_PL_LONGQUOTE) { + if (!quoteDown && !isspace(ch)) { + quoteUp = ch; + quoteDown = opposite(quoteUp); + quotes++; + } else if (ch == quoteDown) { + quotes--; + if (quotes == 0) { + quoteRep--; + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + if (quoteUp == quoteDown) { + quotes++; + } + } + } else if (ch == quoteUp) { + quotes++; + } + } + + if (state == SCE_PL_DEFAULT) { // One of the above succeeded + if (ch == '#') { + state = SCE_PL_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_PL_STRING; + } else if (ch == '\'') { + state = SCE_PL_CHARACTER; + } else if (iswordstart(ch)) { + state = SCE_PL_WORD; + preferRE = false; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_PL_OPERATOR); + } + } + } + chPrev = ch; + } + styler.ColourTo(lengthDoc, state); +} + +LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc); diff --git a/contrib/src/stc/scintilla/src/LexPython.cxx b/contrib/src/stc/scintilla/src/LexPython.cxx new file mode 100644 index 0000000000..c6c5e6d342 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexPython.cxx @@ -0,0 +1,254 @@ +// SciTE - Scintilla based Text Editor +// LexPython.cxx - lexer for Python +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_P_IDENTIFIER; + if (0 == strcmp(prevWord, "class")) + chAttr = SCE_P_CLASSNAME; + else if (0 == strcmp(prevWord, "def")) + chAttr = SCE_P_DEFNAME; + else if (wordIsNumber) + chAttr = SCE_P_NUMBER; + else if (keywords.InList(s)) + chAttr = SCE_P_WORD; + styler.ColourTo(end, chAttr); + strcpy(prevWord, s); +} + +static bool IsPyComment(StylingContext &styler, int pos, int len) { + return len>0 && styler[pos]=='#'; +} + +static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], StylingContext &styler) { + + // Python uses a different mask because bad indentation is marked by oring with 32 + styler.StartAt(startPos, 127); + + WordList &keywords = *keywordlists[0]; + + //Platform::DebugPrintf("Python coloured\n"); + bool fold = styler.GetPropSet().GetInt("fold"); + int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level"); + char prevWord[200]; + prevWord[0] = '\0'; + if (length == 0) + return ; + int lineCurrent = styler.GetLine(startPos); + int spaceFlags = 0; + // TODO: Need to check previous line for indentation for both folding and bad indentation + int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); + + int state = initStyle & 31; + char chPrev = ' '; + char chPrev2 = ' '; + char chNext = styler[startPos]; + char chNext2 = styler[startPos]; + styler.StartSegment(startPos); + int lengthDoc = startPos + length; + bool atStartLine = true; + for (int i = startPos; i <= lengthDoc; i++) { + + if (atStartLine) { + if (whingeLevel == 1) { + styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state); + } else if (whingeLevel == 2) { + styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state); + } else if (whingeLevel == 3) { + styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state); + } else if (whingeLevel == 4) { + styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state); + } + atStartLine = false; + } + + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + chNext2 = styler.SafeGetCharAt(i + 2); + + if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { + if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) { + // Perform colourisation of white space and triple quoted strings at end of each line to allow + // tab marking to work inside white space and triple quoted strings + styler.ColourTo(i, state); + } + + int lev = indentCurrent; + int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsPyComment); + if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { + // Only non whitespace lines can be headers + if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { + // Line after is blank so check the next - maybe should continue further? + int spaceFlags2 = 0; + int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsPyComment); + if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + } + } + indentCurrent = indentNext; + if (fold) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + atStartLine = true; + } + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + chPrev2 = ' '; + i += 1; + continue; + } + + if (state == SCE_P_STRINGEOL) { + if (ch != '\r' && ch != '\n') { + styler.ColourTo(i - 1, state); + state = SCE_P_DEFAULT; + } + } + if (state == SCE_P_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_P_WORD; + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_P_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_STRING; + } + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_P_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_P_OPERATOR); + } + } else if (state == SCE_P_WORD) { + if (!iswordchar(ch)) { + classifyWordPy(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); + state = SCE_P_DEFAULT; + if (ch == '#') { + state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; + } else if (ch == '\"') { + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_P_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_STRING; + } + } else if (ch == '\'') { + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_P_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_P_OPERATOR); + } + } + } else { + if (state == SCE_P_COMMENTLINE || state == SCE_P_COMMENTBLOCK) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_STRING) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i - 1, state); + state = SCE_P_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_CHARACTER) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i - 1, state); + state = SCE_P_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_TRIPLE) { + if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_TRIPLEDOUBLE) { + if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } + } + chPrev2 = chPrev; + chPrev = ch; + } + if (state == SCE_P_WORD) { + classifyWordPy(styler.GetStartSegment(), lengthDoc, keywords, styler, prevWord); + } else { + styler.ColourTo(lengthDoc, state); + } +} + +LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc); diff --git a/contrib/src/stc/scintilla/src/LexSQL.cxx b/contrib/src/stc/scintilla/src/LexSQL.cxx new file mode 100644 index 0000000000..0f29c83074 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexSQL.cxx @@ -0,0 +1,158 @@ +// SciTE - Scintilla based Text Editor +// LexSQL.cxx - lexer for SQL +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = toupper(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_C_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_C_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_C_WORD; + } + styler.ColourTo(end, chAttr); +} + +static void ColouriseSQLDoc(unsigned int startPos, int length, + int initStyle, WordList *keywordlists[], StylingContext &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + bool fold = styler.GetPropSet().GetInt("fold"); + int lineCurrent = styler.GetLine(startPos); + int spaceFlags = 0; + int indentCurrent = 0; + + int state = initStyle; + char chPrev = ' '; + char chNext = styler[startPos]; + styler.StartSegment(startPos); + unsigned int lengthDoc = startPos + length; + bool prevCr = false; + for (unsigned int i = startPos; i <= lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); + int lev = indentCurrent; + if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { + // Only non whitespace lines can be headers + int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags); + if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + } + if (fold) { + styler.SetLevel(lineCurrent, lev); + } + } + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_C_WORD; + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + state = SCE_C_COMMENT; + } else if (ch == '-' && chNext == '-') { + styler.ColourTo(i - 1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_C_STRING; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_C_OPERATOR); + } + } else if (state == SCE_C_WORD) { + if (!iswordchar(ch)) { + classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_C_DEFAULT; + if (ch == '/' && chNext == '*') { + state = SCE_C_COMMENT; + } else if (ch == '-' && chNext == '-') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\'') { + state = SCE_C_STRING; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + } + } + } else { + if (state == SCE_C_COMMENT) { + if (ch == '/' && chPrev == '*') { + if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) && + (styler.GetStartSegment() == startPos)))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + if (ch == '\'') { + if ( chNext == '\'' ) { + i++; + } else { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + } + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + if (state == SCE_C_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + state = SCE_C_COMMENT; + } else if (ch == '-' && chNext == '-') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\'') { + state = SCE_C_STRING; + } else if (iswordstart(ch)) { + state = SCE_C_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + } + } + } + chPrev = ch; + } + styler.ColourTo(lengthDoc - 1, state); +} + +LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc); diff --git a/contrib/src/stc/scintilla/src/LexVB.cxx b/contrib/src/stc/scintilla/src/LexVB.cxx new file mode 100644 index 0000000000..24f65d0fd9 --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexVB.cxx @@ -0,0 +1,118 @@ +// SciTE - Scintilla based Text Editor +// LexVB.cxx - lexer for Visual Basic and VBScript +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_C_DEFAULT; + if (wordIsNumber) + chAttr = SCE_C_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_C_WORD; + if (strcmp(s, "rem") == 0) + chAttr = SCE_C_COMMENTLINE; + } + } + styler.ColourTo(end, chAttr); + if (chAttr == SCE_C_COMMENTLINE) + return SCE_C_COMMENTLINE; + else + return SCE_C_DEFAULT; +} + +static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], StylingContext &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + int state = initStyle; + char chNext = styler[startPos]; + styler.StartSegment(startPos); + int lengthDoc = startPos + length; + for (int i = startPos; i < lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + i += 1; + continue; + } + + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_C_WORD; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_C_STRING; + } + } else if (state == SCE_C_WORD) { + if (!iswordchar(ch)) { + state = classifyWordVB(styler.GetStartSegment(), i - 1, keywords, styler); + if (state == SCE_C_DEFAULT) { + if (ch == '\'') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } + } + } + } else { + if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + // VB doubles quotes to preserve them + if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + if (state == SCE_C_DEFAULT) { // One of the above succeeded + if (ch == '\'') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (iswordstart(ch)) { + state = SCE_C_WORD; + } + } + } + } + styler.ColourTo(lengthDoc, state); +} + +LexerModule lmVB(SCLEX_VB, ColouriseVBDoc); diff --git a/contrib/src/stc/scintilla/src/PropSet.cxx b/contrib/src/stc/scintilla/src/PropSet.cxx index 7e2a906a47..8582105eac 100644 --- a/contrib/src/stc/scintilla/src/PropSet.cxx +++ b/contrib/src/stc/scintilla/src/PropSet.cxx @@ -27,6 +27,7 @@ bool EqualCaseInsensitive(const char *a, const char *b) { // Get a line of input. If end of line escaped with '\\' then continue reading. static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { bool continuation = true; + s[0] = '\0'; while ((len > 1) && lenData > 0) { char ch = *fpc; fpc++; @@ -46,6 +47,7 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { } else { continuation = false; *s++ = ch; + *s = '\0'; len--; } } @@ -253,6 +255,9 @@ void PropSet::ReadFromMemory(const char *data, int len) { if (isalpha(linebuf[0])) Set(linebuf); } + // If there is a final line: + if (isalpha(linebuf[0])) + Set(linebuf); } } diff --git a/contrib/src/stc/scintilla/src/SVector.h b/contrib/src/stc/scintilla/src/SVector.h index 49fc376dda..550dd87ebd 100644 --- a/contrib/src/stc/scintilla/src/SVector.h +++ b/contrib/src/stc/scintilla/src/SVector.h @@ -30,7 +30,7 @@ class SVector { return; } size = newSize; - for (int i=0; i len) { - if (newLen >= size) { - SizeTo(newLen); + void SetLength(unsigned int newLength) { + if (newLength > len) { + if (newLength >= size) { + SizeTo(newLength); } } - len = newLen; + len = newLength; } int Length() const { return len; diff --git a/contrib/src/stc/scintilla/src/ScintillaBase.cxx b/contrib/src/stc/scintilla/src/ScintillaBase.cxx index eb68904b79..21f9840444 100644 --- a/contrib/src/stc/scintilla/src/ScintillaBase.cxx +++ b/contrib/src/stc/scintilla/src/ScintillaBase.cxx @@ -276,15 +276,14 @@ void ScintillaBase::Colourise(int start, int end) { end = lengthDoc; int len = end - start; - PropSet props; - StylingContext styler(wMain.GetID(), props); int styleStart = 0; if (start > 0) styleStart = styler.StyleAt(start - 1); - - ColouriseDoc(pdoc->dbcsCodePage, start, len, styleStart, lexLanguage, keyWordLists, styler); + styler.SetCodePage(pdoc->dbcsCodePage); + + LexerModule::Colourise(start, len, styleStart, lexLanguage, keyWordLists, styler); styler.Flush(); } #endif diff --git a/contrib/src/stc/scintilla/src/Style.cxx b/contrib/src/stc/scintilla/src/Style.cxx index 56312314ff..4830233216 100644 --- a/contrib/src/stc/scintilla/src/Style.cxx +++ b/contrib/src/stc/scintilla/src/Style.cxx @@ -10,23 +10,31 @@ #include "Style.h" Style::Style() { - Clear(); + aliasOfDefaultFont = true; + Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), + Platform::DefaultFontSize(), 0, + false, false, false); } - + Style::~Style() { - font.Release(); + if (aliasOfDefaultFont) + font.SetID(0); + else + font.Release(); + aliasOfDefaultFont = false; } Style &Style::operator=(const Style &source) { if (this == &source) return *this; - Clear(); + Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), + 0, 0, + false, false, false); fore.desired = source.fore.desired; back.desired = source.back.desired; bold = source.bold; italic = source.italic; size = source.size; - strcpy(fontName, source.fontName); eolFilled = source.eolFilled; return *this; } @@ -38,18 +46,48 @@ void Style::Clear(Colour fore_, Colour back_, int size_, const char *fontName_, bold = bold_; italic = italic_; size = size_; - strcpy(fontName, fontName_); + fontName = fontName_; eolFilled = eolFilled_; - font.Release(); + if (aliasOfDefaultFont) + font.SetID(0); + else + font.Release(); + aliasOfDefaultFont = false; +} + +bool Style::EquivalentFontTo(const Style *other) const { + if (bold != other->bold || + italic != other->italic || + size != other->size) + return false; + if (fontName == other->fontName) + return true; + if (!fontName) + return false; + if (!other->fontName) + return false; + return strcmp(fontName, other->fontName) == 0; } -void Style::Realise(Surface &surface, int zoomLevel) { +void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle) { int sizeZoomed = size + zoomLevel; if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1 sizeZoomed = 2; - + + if (aliasOfDefaultFont) + font.SetID(0); + else + font.Release(); int deviceHeight = (sizeZoomed * surface.LogPixelsY()) / 72; - font.Create(fontName, deviceHeight, bold, italic); + aliasOfDefaultFont = defaultStyle && + (EquivalentFontTo(defaultStyle) || !fontName); + if (aliasOfDefaultFont) { + font.SetID(defaultStyle->font.GetID()); + } else if (fontName) { + font.Create(fontName, deviceHeight, bold, italic); + } else { + font.SetID(0); + } ascent = surface.Ascent(font); descent = surface.Descent(font); diff --git a/contrib/src/stc/scintilla/src/Style.h b/contrib/src/stc/scintilla/src/Style.h index 916b646315..a610ff8ba6 100644 --- a/contrib/src/stc/scintilla/src/Style.h +++ b/contrib/src/stc/scintilla/src/Style.h @@ -10,10 +10,11 @@ class Style { public: ColourPair fore; ColourPair back; + bool aliasOfDefaultFont; bool bold; bool italic; int size; - char fontName[100]; + const char *fontName; bool eolFilled; Font font; @@ -27,11 +28,12 @@ public: Style(); ~Style(); Style &operator=(const Style &source); - void Clear(Colour fore_=Colour(0,0,0), Colour back_=Colour(0xff,0xff,0xff), - int size_=Platform::DefaultFontSize(), - const char *fontName_=Platform::DefaultFont(), - bool bold_=false, bool italic_=false, bool eolFilled_=false); - void Realise(Surface &surface, int zoomLevel); + void Clear(Colour fore_, Colour back_, + int size_, + const char *fontName_, + bool bold_, bool italic_, bool eolFilled_); + bool EquivalentFontTo(const Style *other) const; + void Realise(Surface &surface, int zoomLevel, Style *defaultStyle=0); }; #endif diff --git a/contrib/src/stc/scintilla/src/ViewStyle.cxx b/contrib/src/stc/scintilla/src/ViewStyle.cxx index 001ecdb319..2188fd03f7 100644 --- a/contrib/src/stc/scintilla/src/ViewStyle.cxx +++ b/contrib/src/stc/scintilla/src/ViewStyle.cxx @@ -17,14 +17,46 @@ MarginStyle::MarginStyle() : symbol(false), width(16), mask(0xffffffff), sensitive(false) { } +// A list of the fontnames - avoids wasting space in each style +FontNames::FontNames() { + max = 0; +} + +FontNames::~FontNames() { + Clear(); +} + +void FontNames::Clear() { + for (int i=0;i + #include "wx/stc/stc.h" #include "ScintillaWX.h" #include +// The following code forces a reference to all of the Scintilla lexers. +// If we don't do something like this, then the linker tends to "optimize" +// them away. (eric@sourcegear.com) + +int wxForceScintillaLexers(void) +{ + extern LexerModule lmCPP; + extern LexerModule lmHTML; + extern LexerModule lmXML; + extern LexerModule lmProps; + extern LexerModule lmErrorList; + extern LexerModule lmMake; + extern LexerModule lmBatch; + extern LexerModule lmPerl; + extern LexerModule lmPython; + extern LexerModule lmSQL; + extern LexerModule lmVB; + + if ( + &lmCPP + && &lmHTML + && &lmXML + && &lmProps + && &lmErrorList + && &lmMake + && &lmBatch + && &lmPerl + && &lmPython + && &lmSQL + && &lmVB + ) + { + return 1; + } + else + { + return 0; + } +} + //---------------------------------------------------------------------- const wxChar* wxSTCNameStr = "stcwindow"; diff --git a/src/stc/Makefile.in b/src/stc/Makefile.in index 425ea48714..3666daed78 100644 --- a/src/stc/Makefile.in +++ b/src/stc/Makefile.in @@ -29,6 +29,13 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ Indicator.o \ KeyMap.o \ KeyWords.o \ + LexCPP.o \ + LexHTML.o \ + LexOthers.o \ + LexPerl.o \ + LexPython.o \ + LexSQL.o \ + LexVB.o \ LineMarker.o \ PropSet.o \ ScintillaBase.o \ diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 0dbd3d5ea7..0fc480d806 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -4,6 +4,7 @@ // Robin Dunn // The License.txt file describes the conditions under which this software may be distributed. +#include #include "Platform.h" #include "wx/stc/stc.h" @@ -181,7 +182,14 @@ void Surface::BrushColor(Colour back) { } void Surface::SetFont(Font &font_) { - hdc->SetFont(*font_.GetID()); + + // I think the following check is valid. + // It eliminates a crash for me. -- eric@sourcegear.com + + if (font_.GetID()) + { + hdc->SetFont(*font_.GetID()); + } } int Surface::LogPixelsY() { @@ -344,7 +352,11 @@ void Surface::SetClip(PRectangle rc) { hdc->SetClippingRegion(wxRectFromPRectangle(rc)); } - +void Surface::FlushCachedState() { + // TODO Is there anything we need to do here? eric@sourcegear.com + // TODO I had to add this method when I merged new Scintilla code + // TODO from Neil. +} Window::~Window() { } diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index cd0064be5c..cc6fbe7fcf 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -14,6 +14,8 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +#include + #include "ScintillaWX.h" #include "wx/stc/stc.h" diff --git a/src/stc/StcVC.dsp b/src/stc/StcVC.dsp index 3b8fc6d9e7..5e77ef19e2 100644 --- a/src/stc/StcVC.dsp +++ b/src/stc/StcVC.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="StcVC" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 5.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 @@ -22,11 +22,9 @@ CFG=StcVC - Win32 Debug !MESSAGE # Begin Project -# PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe -RSC=rc.exe !IF "$(CFG)" == "StcVC - Win32 Release" @@ -40,11 +38,12 @@ RSC=rc.exe # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" +RSC=rc.exe +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../include" /I "../../include" /I "scintilla/include" /I "scintilla/src" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D "__WX__" /D "SCI_LEXER" /FD /c # SUBTRACT CPP /YX -# ADD BASE RSC /l 0x809 -# ADD RSC /l 0x809 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -64,11 +63,12 @@ LIB32=link.exe -lib # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" +RSC=rc.exe +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 # ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c # ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "../../../include" /I "../../include" /I "scintilla/include" /I "scintilla/src" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D "__WX__" /D "SCI_LEXER" /FD /c # SUBTRACT CPP /YX -# ADD BASE RSC /l 0x809 -# ADD RSC /l 0x809 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo @@ -179,6 +179,34 @@ SOURCE=.\scintilla\src\KeyWords.cxx # End Source File # Begin Source File +SOURCE=.\scintilla\src\LexCPP.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexHTML.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexOthers.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexPerl.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexPython.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexSQL.cxx +# End Source File +# Begin Source File + +SOURCE=.\scintilla\src\LexVB.cxx +# End Source File +# Begin Source File + SOURCE=.\scintilla\src\LineMarker.cxx # End Source File # Begin Source File diff --git a/src/stc/scintilla/include/Accessor.h b/src/stc/scintilla/include/Accessor.h index 1bba4af55e..031ad7a914 100644 --- a/src/stc/scintilla/include/Accessor.h +++ b/src/stc/scintilla/include/Accessor.h @@ -3,6 +3,8 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; + class Accessor { protected: // bufferSize is a trade off between time taken to copy the characters and SendMessage overhead @@ -15,12 +17,15 @@ protected: int endPos; int lenDoc; int offset; // Optional but including an offset makes GCC generate better code + int codePage; + bool InternalIsLeadByte(char ch); void Fill(int position); public: Accessor(WindowID id_, PropSet &props_, int offset_=0) : id(id_), props(props_), startPos(0x7FFFFFFF), endPos(0), - lenDoc(-1), offset(offset_) { + lenDoc(-1), offset(offset_), codePage(0) { } + void SetCodePage(int codePage_) { codePage = codePage_; } char operator[](int position) { position += offset; if (position < startPos || position >= endPos) { @@ -40,6 +45,9 @@ public: } return buf[position - startPos]; } + bool IsLeadByte(char ch) { + return codePage && InternalIsLeadByte(ch); + } char StyleAt(int position); int GetLine(int position); int LineStart(int line); @@ -54,6 +62,10 @@ public: PropSet &GetPropSet() { return props; } }; +class StylingContext; + +typedef bool (*PFNIsCommentLeader)(StylingContext &styler, int pos, int len); + class StylingContext : public Accessor { char styleBuf[bufferSize]; int validLen; @@ -65,12 +77,12 @@ public: Accessor(id_,props_,offset_), validLen(0), chFlags(0) {} void StartAt(unsigned int start, char chMask=31); void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; - void ColourSegment(unsigned int start, unsigned int end, int chAttr); unsigned int GetStartSegment() { return startSeg; } void StartSegment(unsigned int pos); void ColourTo(unsigned int pos, int chAttr); int GetLine(int position); void SetLevel(int line, int level); void Flush(); + int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); }; diff --git a/src/stc/scintilla/include/KeyWords.h b/src/stc/scintilla/include/KeyWords.h index 2cc03b788f..1b42ecdd93 100644 --- a/src/stc/scintilla/include/KeyWords.h +++ b/src/stc/scintilla/include/KeyWords.h @@ -3,6 +3,39 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. -void ColouriseDoc(int codePage, int startPos, int lengthDoc, int initStyle, - int language, WordList *keywordlists[], StylingContext &styler); +typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], StylingContext &styler); + +class LexerModule { + static LexerModule *base; + LexerModule *next; + int language; + LexerFunction fn; +public: + LexerModule(int language_, LexerFunction fn_); + static void Colourise(unsigned int startPos, int lengthDoc, int initStyle, + int language, WordList *keywordlists[], StylingContext &styler); +}; + +inline bool iswordchar(char ch) { + return isalnum(ch) || ch == '.' || ch == '_'; +} + +inline bool iswordstart(char ch) { + return isalnum(ch) || ch == '_'; +} + +inline bool isoperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || + ch == '(' || ch == ')' || ch == '-' || ch == '+' || + ch == '=' || ch == '|' || ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ':' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || ch == '/' || + ch == '?' || ch == '!' || ch == '.' || ch == '~') + return true; + return false; +} diff --git a/src/stc/scintilla/include/Platform.h b/src/stc/scintilla/include/Platform.h index 3a5e9816dc..021bcf686f 100644 --- a/src/stc/scintilla/include/Platform.h +++ b/src/stc/scintilla/include/Platform.h @@ -213,6 +213,8 @@ public: void Release(); FontID GetID() { return id; } + // Alias another font - caller guarantees not to Release + void SetID(FontID id_) { id = id_; } friend class Surface; }; @@ -290,6 +292,7 @@ public: int SetPalette(Palette *pal, bool inBackGround); void SetClip(PRectangle rc); + void FlushCachedState(); }; // Class to hide the details of window manipulation diff --git a/src/stc/scintilla/include/SciLexer.h b/src/stc/scintilla/include/SciLexer.h index d6667e4e25..3e0ad31b42 100644 --- a/src/stc/scintilla/include/SciLexer.h +++ b/src/stc/scintilla/include/SciLexer.h @@ -35,6 +35,8 @@ #define SCE_P_DEFNAME 9 #define SCE_P_OPERATOR 10 #define SCE_P_IDENTIFIER 11 +#define SCE_P_COMMENTBLOCK 12 +#define SCE_P_STRINGEOL 13 // Lexical states for SCLEX_CPP, SCLEX_VB #define SCE_C_DEFAULT 0 @@ -45,7 +47,7 @@ #define SCE_C_WORD 5 #define SCE_C_STRING 6 #define SCE_C_CHARACTER 7 -#define SCE_C_PUNTUATION 8 +#define SCE_C_UUID 8 #define SCE_C_PREPROCESSOR 9 #define SCE_C_OPERATOR 10 #define SCE_C_IDENTIFIER 11 @@ -63,49 +65,85 @@ #define SCE_H_OTHER 8 #define SCE_H_COMMENT 9 #define SCE_H_ENTITY 10 -// Embedded Javascript -#define SCE_HJ_START 11 -#define SCE_HJ_DEFAULT 12 -#define SCE_HJ_COMMENT 13 -#define SCE_HJ_COMMENTLINE 14 -#define SCE_HJ_COMMENTDOC 15 -#define SCE_HJ_NUMBER 16 -#define SCE_HJ_WORD 17 -#define SCE_HJ_KEYWORD 18 -#define SCE_HJ_DOUBLESTRING 19 -#define SCE_HJ_SINGLESTRING 20 -#define SCE_HJ_SYMBOLS 21 -#define SCE_HJ_STRINGEOL 28 // XML and ASP -#define SCE_H_TAGEND 22 -#define SCE_H_XMLSTART 23 -#define SCE_H_XMLEND 24 -#define SCE_H_SCRIPT 25 -#define SCE_H_ASP 26 -#define SCE_H_ASPAT 27 +#define SCE_H_TAGEND 11 +#define SCE_H_XMLSTART 12 +#define SCE_H_XMLEND 13 +#define SCE_H_SCRIPT 14 +#define SCE_H_ASP 15 +#define SCE_H_ASPAT 16 +// Embedded Javascript +#define SCE_HJ_START 40 +#define SCE_HJ_DEFAULT 41 +#define SCE_HJ_COMMENT 42 +#define SCE_HJ_COMMENTLINE 43 +#define SCE_HJ_COMMENTDOC 44 +#define SCE_HJ_NUMBER 45 +#define SCE_HJ_WORD 46 +#define SCE_HJ_KEYWORD 47 +#define SCE_HJ_DOUBLESTRING 48 +#define SCE_HJ_SINGLESTRING 49 +#define SCE_HJ_SYMBOLS 50 +#define SCE_HJ_STRINGEOL 51 +// ASP Javascript +#define SCE_HJA_START 55 +#define SCE_HJA_DEFAULT 56 +#define SCE_HJA_COMMENT 57 +#define SCE_HJA_COMMENTLINE 58 +#define SCE_HJA_COMMENTDOC 59 +#define SCE_HJA_NUMBER 60 +#define SCE_HJA_WORD 61 +#define SCE_HJA_KEYWORD 62 +#define SCE_HJA_DOUBLESTRING 63 +#define SCE_HJA_SINGLESTRING 64 +#define SCE_HJA_SYMBOLS 65 +#define SCE_HJA_STRINGEOL 66 // Embedded VBScript -#define SCE_HB_START 40 -#define SCE_HB_DEFAULT 41 -#define SCE_HB_COMMENTLINE 42 -#define SCE_HB_NUMBER 43 -#define SCE_HB_WORD 44 -#define SCE_HB_STRING 45 -#define SCE_HB_IDENTIFIER 46 -#define SCE_HB_STRINGEOL 47 +#define SCE_HB_START 70 +#define SCE_HB_DEFAULT 71 +#define SCE_HB_COMMENTLINE 72 +#define SCE_HB_NUMBER 73 +#define SCE_HB_WORD 74 +#define SCE_HB_STRING 75 +#define SCE_HB_IDENTIFIER 76 +#define SCE_HB_STRINGEOL 77 +// ASP VBScript +#define SCE_HBA_START 80 +#define SCE_HBA_DEFAULT 81 +#define SCE_HBA_COMMENTLINE 82 +#define SCE_HBA_NUMBER 83 +#define SCE_HBA_WORD 84 +#define SCE_HBA_STRING 85 +#define SCE_HBA_IDENTIFIER 86 +#define SCE_HBA_STRINGEOL 87 // Embedded Python -#define SCE_HP_START 50 -#define SCE_HP_DEFAULT 51 -#define SCE_HP_COMMENTLINE 52 -#define SCE_HP_NUMBER 53 -#define SCE_HP_STRING 54 -#define SCE_HP_CHARACTER 55 -#define SCE_HP_WORD 56 -#define SCE_HP_TRIPLE 57 -#define SCE_HP_TRIPLEDOUBLE 58 -#define SCE_HP_CLASSNAME 59 -#define SCE_HP_DEFNAME 60 -#define SCE_HP_OPERATOR 61 -#define SCE_HP_IDENTIFIER 62 +#define SCE_HP_START 90 +#define SCE_HP_DEFAULT 91 +#define SCE_HP_COMMENTLINE 92 +#define SCE_HP_NUMBER 93 +#define SCE_HP_STRING 94 +#define SCE_HP_CHARACTER 95 +#define SCE_HP_WORD 96 +#define SCE_HP_TRIPLE 97 +#define SCE_HP_TRIPLEDOUBLE 98 +#define SCE_HP_CLASSNAME 99 +#define SCE_HP_DEFNAME 100 +#define SCE_HP_OPERATOR 101 +#define SCE_HP_IDENTIFIER 102 +// ASP Python +#define SCE_HPA_START 105 +#define SCE_HPA_DEFAULT 106 +#define SCE_HPA_COMMENTLINE 107 +#define SCE_HPA_NUMBER 108 +#define SCE_HPA_STRING 109 +#define SCE_HPA_CHARACTER 110 +#define SCE_HPA_WORD 111 +#define SCE_HPA_TRIPLE 112 +#define SCE_HPA_TRIPLEDOUBLE 113 +#define SCE_HPA_CLASSNAME 114 +#define SCE_HPA_DEFNAME 115 +#define SCE_HPA_OPERATOR 116 +#define SCE_HPA_IDENTIFIER 117 // Lexical states for SCLEX_PERL #define SCE_PL_DEFAULT 0 diff --git a/src/stc/scintilla/include/Scintilla.h b/src/stc/scintilla/include/Scintilla.h index 07572168dc..822b2ea9d7 100644 --- a/src/stc/scintilla/include/Scintilla.h +++ b/src/stc/scintilla/include/Scintilla.h @@ -156,7 +156,7 @@ extern "C" { #define STYLE_BRACELIGHT 34 #define STYLE_BRACEBAD 35 #define STYLE_CONTROLCHAR 36 -#define STYLE_MAX 63 +#define STYLE_MAX 127 #define SCI_STYLECLEARALL SCI_START + 50 #define SCI_STYLESETFORE SCI_START + 51 @@ -279,6 +279,11 @@ extern "C" { #define SCI_ZOOMOUT SCI_START + 334 #define SCI_DELWORDLEFT SCI_START + 335 #define SCI_DELWORDRIGHT SCI_START + 336 +#define SCI_LINECUT SCI_START + 337 +#define SCI_LINEDELETE SCI_START + 338 +#define SCI_LINETRANSPOSE SCI_START + 339 +#define SCI_LOWERCASE SCI_START + 340 +#define SCI_UPPERCASE SCI_START + 341 #define SCI_LINELENGTH SCI_START + 350 #define SCI_BRACEHIGHLIGHT SCI_START + 351 @@ -311,6 +316,8 @@ extern "C" { // OR this with CARET_SLOP to reposition whenever outside slop border #define SCI_SETCARETPOLICY SCI_START + 369 +#define SCI_LINESONSCREEN SCI_START + 370 +#define SCI_USEPOPUP SCI_START + 371 // GTK+ Specific #define SCI_GRABFOCUS SCI_START + 400 @@ -342,6 +349,7 @@ typedef void (tMacroRecorder)(UINT iMessage, WPARAM wParam, LPARAM lParam, #define SC_PERFORMED_UNDO 0x20 #define SC_PERFORMED_REDO 0x40 #define SC_LASTSTEPINUNDOREDO 0x100 +#define SC_MOD_CHANGEMARKER 0x200 #define SC_MODEVENTMASKALL 0x377 diff --git a/src/stc/scintilla/src/Accessor.cxx b/src/stc/scintilla/src/Accessor.cxx index 57b7e4dc4e..f080742bd6 100644 --- a/src/stc/scintilla/src/Accessor.cxx +++ b/src/stc/scintilla/src/Accessor.cxx @@ -4,6 +4,7 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include #include "Platform.h" @@ -12,6 +13,17 @@ #include "Accessor.h" #include "Scintilla.h" +bool Accessor::InternalIsLeadByte(char ch) { +#if PLAT_GTK + // TODO: support DBCS under GTK+ + return false; +#elif PLAT_WIN + return IsDBCSLeadByteEx(codePage, ch); +#elif PLAT_WX + return false; +#endif +} + void Accessor::Fill(int position) { if (lenDoc == -1) lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); @@ -63,35 +75,31 @@ void StylingContext::StartAt(unsigned int start, char chMask) { Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask); } -void StylingContext::ColourSegment(unsigned int start, unsigned int end, int chAttr) { +void StylingContext::StartSegment(unsigned int pos) { + startSeg = pos; +} + +void StylingContext::ColourTo(unsigned int pos, int chAttr) { // Only perform styling if non empty range - if (end != start - 1) { - if (end < start) { - Platform::DebugPrintf("Bad colour positions %d - %d\n", start, end); + if (pos != startSeg - 1) { + if (pos < startSeg) { + Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos); } - if (validLen + (end - start + 1) >= bufferSize) + if (validLen + (pos - startSeg + 1) >= bufferSize) Flush(); - if (validLen + (end - start + 1) >= bufferSize) { + if (validLen + (pos - startSeg + 1) >= bufferSize) { // Too big for buffer so send directly - Platform::SendScintilla(id, SCI_SETSTYLING, end - start + 1, chAttr); + Platform::SendScintilla(id, SCI_SETSTYLING, pos - startSeg + 1, chAttr); } else { if (chAttr != chWhile) chFlags = 0; chAttr |= chFlags; - for (unsigned int i = start; i <= end; i++) { + for (unsigned int i = startSeg; i <= pos; i++) { styleBuf[validLen++] = chAttr; } } } -} - -void StylingContext::StartSegment(unsigned int pos) { - startSeg = pos; -} - -void StylingContext::ColourTo(unsigned int pos, int chAttr) { - ColourSegment(startSeg, pos, chAttr); startSeg = pos+1; } @@ -110,3 +118,49 @@ void StylingContext::Flush() { validLen = 0; } } + +int StylingContext::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { + int end = Length(); + int spaceFlags = 0; + + // Determines the indentation level of the current line and also checks for consistent + // indentation compared to the previous line. + // Indentation is judged consistent when the indentation whitespace of each line lines + // the same or the indentation of one line is a prefix of the other. + + int pos = LineStart(line); + char ch = (*this)[pos]; + int indent = 0; + bool inPrevPrefix = line > 0; + int posPrev = inPrevPrefix ? LineStart(line-1) : 0; + while ((ch == ' ' || ch == '\t') && (pos < end)) { + if (inPrevPrefix) { + char chPrev = (*this)[posPrev++]; + if (chPrev == ' ' || chPrev == '\t') { + if (chPrev != ch) + spaceFlags |= wsInconsistent; + } else { + inPrevPrefix = false; + } + } + if (ch == ' ') { + spaceFlags |= wsSpace; + indent++; + } else { // Tab + spaceFlags |= wsTab; + if (spaceFlags & wsSpace) + spaceFlags |= wsSpaceTab; + indent = (indent / 8 + 1) * 8; + } + ch = (*this)[++pos]; + } + + *flags = spaceFlags; + indent += SC_FOLDLEVELBASE; + // if completely empty line or the start of a comment... + if (isspace(ch) || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) ) + return indent | SC_FOLDLEVELWHITEFLAG; + else + return indent; +} + diff --git a/src/stc/scintilla/src/CellBuffer.cxx b/src/stc/scintilla/src/CellBuffer.cxx index 777688511a..56a4be78c8 100644 --- a/src/stc/scintilla/src/CellBuffer.cxx +++ b/src/stc/scintilla/src/CellBuffer.cxx @@ -344,31 +344,200 @@ void Action::Grab(Action *source) { source->lenData = 0; } -CellBuffer::CellBuffer(int initialLength) { - body = new char[initialLength]; - size = initialLength; - length = 0; - part1len = 0; - gaplen = initialLength; - part2body = body + gaplen; - readOnly = false; +// The undo history stores a sequence of user operations that represent the user's view of the +// commands executed on the text. +// Each user operation contains a sequence of text insertion and text deletion actions. +// All the user operations are stored in a list of individual actions with 'start' actions used +// as delimiters between user operations. +// Initially there is one start action in the history. +// As each action is performed, it is recorded in the history. The action may either become +// part of the current user operation or may start a new user operation. If it is to be part of the +// current operation, then it overwrites the current last action. If it is to be part of a new +// operation, it is appended after the current last action. +// After writing the new action, a new start action is appended at the end of the history. +// The decision of whether to start a new user operation is based upon two factors. If a +// compound operation has been explicitly started by calling BeginUndoAction and no matching +// EndUndoAction (these calls nest) has been called, then the action is coalesced into the current +// operation. If there is no outstanding BeginUndoAction call then a new operation is started +// unless it looks as if the new action is caused by the user typing or deleting a stream of text. +// Sequences that look like typing or deletion are coalesced into a single user operation. + +UndoHistory::UndoHistory() { lenActions = 100; actions = new Action[lenActions]; maxAction = 0; currentAction = 0; - collectingUndo = undoCollectAutoStart; undoSequenceDepth = 0; savePoint = 0; actions[currentAction].Create(startAction); } +UndoHistory::~UndoHistory() { + delete []actions; + actions = 0; +} + +void UndoHistory::EnsureUndoRoom() { + //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction); + if (currentAction >= 2) { + // Have to test that there is room for 2 more actions in the array + // as two actions may be created by this function + if (currentAction >= (lenActions - 2)) { + // Run out of undo nodes so extend the array + int lenActionsNew = lenActions * 2; + Action *actionsNew = new Action[lenActionsNew]; + if (!actionsNew) + return; + for (int act = 0; act <= currentAction; act++) + actionsNew[act].Grab(&actions[act]); + delete []actions; + lenActions = lenActionsNew; + actions = actionsNew; + } + } +} + +void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData) { + EnsureUndoRoom(); + //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); + //Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at, + // actions[currentAction - 1].position, actions[currentAction - 1].lenData); + if (currentAction >= 1) { + if (0 == undoSequenceDepth) { + // Top level actions may not always be coalesced + Action &actPrevious = actions[currentAction - 1]; + // See if current action can be coalesced into previous action + // Will work if both are inserts or deletes and position is same + if (at != actPrevious.at) { + currentAction++; + } else if (currentAction == savePoint) { + currentAction++; + } else if ((at == removeAction) && + ((position + lengthData * 2) != actPrevious.position)) { + // Removals must be at same position to coalesce + currentAction++; + } else if ((at == insertAction) && + (position != (actPrevious.position + actPrevious.lenData*2))) { + // Insertions must be immediately after to coalesce + currentAction++; + } else { + //Platform::DebugPrintf("action coalesced\n"); + } + } else { + currentAction++; + } + } else { + currentAction++; + } + actions[currentAction].Create(at, position, data, lengthData); + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; +} + +void UndoHistory::BeginUndoAction() { + EnsureUndoRoom(); + if (undoSequenceDepth == 0) { + if (actions[currentAction].at != startAction) { + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; + } + } + undoSequenceDepth++; +} + +void UndoHistory::EndUndoAction() { + EnsureUndoRoom(); + undoSequenceDepth--; + if (0 == undoSequenceDepth) { + if (actions[currentAction].at != startAction) { + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; + } + } +} + +void UndoHistory::DropUndoSequence() { + undoSequenceDepth = 0; +} + +void UndoHistory::DeleteUndoHistory() { + for (int i = 1; i < maxAction; i++) + actions[i].Destroy(); + maxAction = 0; + currentAction = 0; + actions[currentAction].Create(startAction); + savePoint = 0; +} + +void UndoHistory::SetSavePoint() { + savePoint = currentAction; +} + +bool UndoHistory::IsSavePoint() const { + return savePoint == currentAction; +} + +bool UndoHistory::CanUndo() const { + return (currentAction > 0) && (maxAction > 0); +} + +int UndoHistory::StartUndo() { + // Drop any trailing startAction + if (actions[currentAction].at == startAction && currentAction > 0) + currentAction--; + + // Count the steps in this action + int act = currentAction; + while (actions[act].at != startAction && act > 0) { + act--; + } + return currentAction - act; +} + +const Action &UndoHistory::UndoStep() { + return actions[currentAction--]; +} + +bool UndoHistory::CanRedo() const { + return maxAction > currentAction; +} + +int UndoHistory::StartRedo() { + // Drop any leading startAction + if (actions[currentAction].at == startAction && currentAction < maxAction) + currentAction++; + + // Count the steps in this action + int act = currentAction; + while (actions[act].at != startAction && act < maxAction) { + act++; + } + return act - currentAction; +} + +const Action &UndoHistory::RedoStep() { + return actions[currentAction++]; +} + +CellBuffer::CellBuffer(int initialLength) { + body = new char[initialLength]; + size = initialLength; + length = 0; + part1len = 0; + gaplen = initialLength; + part2body = body + gaplen; + readOnly = false; + collectingUndo = undoCollectAutoStart; +} + CellBuffer::~CellBuffer() { delete []body; body = 0; - delete []actions; - actions = 0; } void CellBuffer::GapTo(int position) { @@ -486,7 +655,7 @@ const char *CellBuffer::InsertString(int position, char *s, int insertLength) { for (int i = 0; i < insertLength / 2; i++) { data[i] = s[i * 2]; } - AppendAction(insertAction, position, data, insertLength / 2); + uh.AppendAction(insertAction, position, data, insertLength / 2); } BasicInsertString(position, s, insertLength); @@ -525,48 +694,6 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas return changed; } -void CellBuffer::EnsureUndoRoom() { - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction); - if (currentAction >= 2) { - // Have to test that there is room for 2 more actions in the array - // as two actions may be created by this function - if (currentAction >= (lenActions - 2)) { - // Run out of undo nodes so extend the array - int lenActionsNew = lenActions * 2; - Action *actionsNew = new Action[lenActionsNew]; - if (!actionsNew) - return; - for (int act = 0; act <= currentAction; act++) - actionsNew[act].Grab(&actions[act]); - delete []actions; - lenActions = lenActionsNew; - actions = actionsNew; - } - } -} - -void CellBuffer::AppendAction(actionType at, int position, char *data, int lengthData) { - EnsureUndoRoom(); - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); - if (currentAction >= 2) { - // See if current action can be coalesced into previous action - // Will work if both are inserts or deletes and position is same or two different - if ((at != actions[currentAction - 1].at) || (abs(position - actions[currentAction - 1].position) > 2)) { - currentAction++; - } else if (currentAction == savePoint) { - currentAction++; - } - } else { - currentAction++; - } - actions[currentAction].Create(at, position, data, lengthData); - if ((collectingUndo == undoCollectAutoStart) && (0 == undoSequenceDepth)) { - currentAction++; - actions[currentAction].Create(startAction); - } - maxAction = currentAction; -} - const char *CellBuffer::DeleteChars(int position, int deleteLength) { // InsertString and DeleteChars are the bottleneck though which all changes occur char *data = 0; @@ -577,7 +704,7 @@ const char *CellBuffer::DeleteChars(int position, int deleteLength) { for (int i = 0; i < deleteLength / 2; i++) { data[i] = ByteAt(position + i * 2); } - AppendAction(removeAction, position, data, deleteLength / 2); + uh.AppendAction(removeAction, position, data, deleteLength / 2); } BasicDeleteChars(position, deleteLength); @@ -616,11 +743,11 @@ void CellBuffer::SetReadOnly(bool set) { } void CellBuffer::SetSavePoint() { - savePoint = currentAction; + uh.SetSavePoint(); } bool CellBuffer::IsSavePoint() { - return savePoint == currentAction; + return uh.IsSavePoint(); } int CellBuffer::AddMark(int line, int markerNum) { @@ -792,7 +919,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { undoCollectionType CellBuffer::SetUndoCollection(undoCollectionType collectUndo) { collectingUndo = collectUndo; - undoSequenceDepth = 0; + uh.DropUndoSequence(); return collectingUndo; } @@ -800,69 +927,28 @@ bool CellBuffer::IsCollectingUndo() { return collectingUndo; } -void CellBuffer::AppendUndoStartAction() { - EnsureUndoRoom(); - // Finish any currently active undo sequence - undoSequenceDepth = 0; - if (actions[currentAction].at != startAction) { - undoSequenceDepth++; - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } -} - void CellBuffer::BeginUndoAction() { - EnsureUndoRoom(); - if (undoSequenceDepth == 0) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - } - undoSequenceDepth++; + uh.BeginUndoAction(); } void CellBuffer::EndUndoAction() { - EnsureUndoRoom(); - undoSequenceDepth--; - if (0 == undoSequenceDepth) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - } + uh.EndUndoAction(); } void CellBuffer::DeleteUndoHistory() { - for (int i = 1; i < maxAction; i++) - actions[i].Destroy(); - maxAction = 0; - currentAction = 0; - savePoint = 0; + uh.DeleteUndoHistory(); } bool CellBuffer::CanUndo() { - return (!readOnly) && ((currentAction > 0) && (maxAction > 0)); + return (!readOnly) && (uh.CanUndo()); } int CellBuffer::StartUndo() { - // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) - currentAction--; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act > 0) { - act--; - } - return currentAction - act; + return uh.StartUndo(); } const Action &CellBuffer::UndoStep() { - const Action &actionStep = actions[currentAction]; + const Action &actionStep = uh.UndoStep(); if (actionStep.at == insertAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } else if (actionStep.at == removeAction) { @@ -874,29 +960,19 @@ const Action &CellBuffer::UndoStep() { BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } - currentAction--; return actionStep; } bool CellBuffer::CanRedo() { - return (!readOnly) && (maxAction > currentAction); + return (!readOnly) && (uh.CanRedo()); } int CellBuffer::StartRedo() { - // Drop any leading startAction - if (actions[currentAction].at == startAction && currentAction < maxAction) - currentAction++; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act < maxAction) { - act++; - } - return act - currentAction; + return uh.StartRedo(); } const Action &CellBuffer::RedoStep() { - const Action &actionStep = actions[currentAction]; + const Action &actionStep = uh.RedoStep(); if (actionStep.at == insertAction) { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { @@ -908,7 +984,6 @@ const Action &CellBuffer::RedoStep() { } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } - currentAction++; return actionStep; } diff --git a/src/stc/scintilla/src/CellBuffer.h b/src/stc/scintilla/src/CellBuffer.h index 5fbe2ea8a0..6e052077e9 100644 --- a/src/stc/scintilla/src/CellBuffer.h +++ b/src/stc/scintilla/src/CellBuffer.h @@ -89,6 +89,42 @@ public: enum undoCollectionType { undoCollectNone, undoCollectAutoStart, undoCollectManualStart }; +class UndoHistory { + Action *actions; + int lenActions; + int maxAction; + int currentAction; + int undoSequenceDepth; + int savePoint; + + void EnsureUndoRoom(); + +public: + UndoHistory(); + ~UndoHistory(); + + void AppendAction(actionType at, int position, char *data, int length); + + void BeginUndoAction(); + void EndUndoAction(); + void DropUndoSequence(); + void DeleteUndoHistory(); + + // The save point is a marker in the undo stack where the container has stated that + // the buffer was saved. Undo and redo can move over the save point. + void SetSavePoint(); + bool IsSavePoint() const; + + // To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is + // called that many times. Similarly for redo. + bool CanUndo() const; + int StartUndo(); + const Action &UndoStep(); + bool CanRedo() const; + int StartRedo(); + const Action &RedoStep(); +}; + // Holder for an expandable array of characters that supports undo and line markers // Based on article "Data Structures in a Bit-Mapped Text Editor" // by Wilfred J. Hansen, Byte January 1987, page 183 @@ -102,13 +138,8 @@ private: char *part2body; bool readOnly; - Action *actions; - int lenActions; - int maxAction; - int currentAction; undoCollectionType collectingUndo; - int undoSequenceDepth; - int savePoint; + UndoHistory uh; LineVector lv; @@ -117,9 +148,6 @@ private: void GapTo(int position); void RoomFor(int insertionLength); - void EnsureUndoRoom(); - void AppendAction(actionType at, int position, char *data, int length); - inline char ByteAt(int position); void SetByteAt(int position, char ch); @@ -170,12 +198,11 @@ public: undoCollectionType SetUndoCollection(undoCollectionType collectUndo); bool IsCollectingUndo(); - void AppendUndoStartAction(); void BeginUndoAction(); void EndUndoAction(); void DeleteUndoHistory(); - // To perform an undo, StartUndo is called to retreive the number of steps, then UndoStep is + // To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is // called that many times. Similarly for redo. bool CanUndo(); int StartUndo(); diff --git a/src/stc/scintilla/src/ContractionState.cxx b/src/stc/scintilla/src/ContractionState.cxx index 6f41461eb1..816d06aae7 100644 --- a/src/stc/scintilla/src/ContractionState.cxx +++ b/src/stc/scintilla/src/ContractionState.cxx @@ -108,8 +108,8 @@ void ContractionState::InsertLines(int lineDoc, int lineCount) { return; } //Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc); - if ((linesInDoc + 2) >= size) { - Grow(size + growSize); + if ((linesInDoc + lineCount + 2) >= size) { + Grow(linesInDoc + lineCount + growSize); } linesInDoc += lineCount; linesInDisplay += lineCount; @@ -155,7 +155,7 @@ bool ContractionState::GetVisible(int lineDoc) const { bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { if (size == 0) { - Grow(lineDocEnd + growSize); + Grow(linesInDoc + growSize); } // TODO: modify docLine members to mirror displayLine int delta = 0; @@ -191,7 +191,7 @@ bool ContractionState::GetExpanded(int lineDoc) const { bool ContractionState::SetExpanded(int lineDoc, bool expanded) { if (size == 0) { - Grow(lineDoc + growSize); + Grow(linesInDoc + growSize); } if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { if (lines[lineDoc].expanded != expanded) { diff --git a/src/stc/scintilla/src/Document.cxx b/src/stc/scintilla/src/Document.cxx index 7d832241fc..95107eb087 100644 --- a/src/stc/scintilla/src/Document.cxx +++ b/src/stc/scintilla/src/Document.cxx @@ -65,26 +65,54 @@ void Document::SetSavePoint() { NotifySavePoint(true); } -int Document::LineStart(int line) { - return cb.LineStart(line); +int Document::AddMark(int line, int markerNum) { + int prev = cb.AddMark(line, markerNum); + DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0); + NotifyModified(mh); + return prev; } -int Document::LineFromPosition(int pos) { - return cb.LineFromPosition(pos); +void Document::DeleteMark(int line, int markerNum) { + cb.DeleteMark(line, markerNum); + DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0); + NotifyModified(mh); } -int Document::LineEndPosition(int position) { - int line = LineFromPosition(position); +void Document::DeleteMarkFromHandle(int markerHandle) { + cb.DeleteMarkFromHandle(markerHandle); + DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); + NotifyModified(mh); +} + +void Document::DeleteAllMarks(int markerNum) { + cb.DeleteAllMarks(markerNum); + DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); + NotifyModified(mh); +} + +int Document::LineStart(int line) { + return cb.LineStart(line); +} + +int Document::LineEnd(int line) { if (line == LinesTotal() - 1) { - position = LineStart(line + 1); + return LineStart(line + 1); } else { - position = LineStart(line + 1) - 1; + int position = LineStart(line + 1) - 1; // When line terminator is CR+LF, may need to go back one more if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) { position--; } + return position; } - return position; +} + +int Document::LineFromPosition(int pos) { + return cb.LineFromPosition(pos); +} + +int Document::LineEndPosition(int position) { + return LineEnd(LineFromPosition(position)); } int Document::VCHomePosition(int position) { @@ -124,7 +152,10 @@ int Document::GetLastChild(int lineParent, int level) { level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK; int maxLine = LinesTotal(); int lineMaxSubord = lineParent; - while ((lineMaxSubord < maxLine-1) && IsSubordinate(level, GetLevel(lineMaxSubord+1))) { + while (lineMaxSubord < maxLine-1) { + EnsureStyledTo(LineStart(lineMaxSubord+2)); + if (!IsSubordinate(level, GetLevel(lineMaxSubord+1))) + break; lineMaxSubord++; } if (lineMaxSubord > lineParent) { @@ -307,6 +338,7 @@ int Document::Undo() { enteredCount++; bool startSavePoint = cb.IsSavePoint(); int steps = cb.StartUndo(); + //Platform::DebugPrintf("Steps=%d\n", steps); for (int step=0; step GetEndStyled() && i < lenWatchers; i++) + watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos); + return pos <= GetEndStyled(); +} + bool Document::AddWatcher(DocWatcher *watcher, void *userData) { for (int i = 0; i < lenWatchers; i++) { if ((watchers[i].watcher == watcher) && diff --git a/src/stc/scintilla/src/Document.h b/src/stc/scintilla/src/Document.h index fba611c7f7..4c212b7bd1 100644 --- a/src/stc/scintilla/src/Document.h +++ b/src/stc/scintilla/src/Document.h @@ -111,7 +111,6 @@ public: undoCollectionType SetUndoCollection(undoCollectionType collectUndo) { return cb.SetUndoCollection(collectUndo); } - void AppendUndoStartAction() { cb.AppendUndoStartAction(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void SetSavePoint(); @@ -123,6 +122,7 @@ public: void InsertChar(int pos, char ch); void InsertString(int position, const char *s); void InsertString(int position, const char *s, int insertLength); + void ChangeChar(int pos, char ch); void DelChar(int pos); int DelCharBack(int pos); @@ -132,12 +132,13 @@ public: } char StyleAt(int position) { return cb.StyleAt(position); } int GetMark(int line) { return cb.GetMark(line); } - int AddMark(int line, int markerNum) { return cb.AddMark(line, markerNum); } - void DeleteMark(int line, int markerNum) { cb.DeleteMark(line, markerNum); } - void DeleteMarkFromHandle(int markerHandle) { cb.DeleteMarkFromHandle(markerHandle); } - void DeleteAllMarks(int markerNum) { cb.DeleteAllMarks(markerNum); } + int AddMark(int line, int markerNum); + void DeleteMark(int line, int markerNum); + void DeleteMarkFromHandle(int markerHandle); + void DeleteAllMarks(int markerNum); int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); } int LineStart(int line); + int LineEnd(int line); int LineEndPosition(int position); int VCHomePosition(int position); @@ -154,12 +155,15 @@ public: long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam); int LinesTotal(); + void ChangeCase(Range r, bool makeUpperCase); + void SetWordChars(unsigned char *chars); void SetStylingBits(int bits); void StartStyling(int position, char mask); void SetStyleFor(int length, char style); void SetStyles(int length, char *styles); int GetEndStyled() { return endStyled; } + bool EnsureStyledTo(int pos); int SetLineState(int line, int state) { return cb.SetLineState(line, state); } int GetLineState(int line) { return cb.GetLineState(line); } @@ -217,6 +221,7 @@ public: virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; virtual void NotifyDeleted(Document *doc, void *userData) = 0; + virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; }; #endif diff --git a/src/stc/scintilla/src/Editor.cxx b/src/stc/scintilla/src/Editor.cxx index 6508c95b1f..226184db27 100644 --- a/src/stc/scintilla/src/Editor.cxx +++ b/src/stc/scintilla/src/Editor.cxx @@ -88,6 +88,8 @@ Editor::Editor() { modEventMask = SC_MODEVENTMASKALL; + displayPopupMenu = true; + pdoc = new Document(); pdoc ->AddRef(); pdoc->AddWatcher(this, 0); @@ -631,7 +633,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { int line = cs.DocFromDisplay(visibleLine); int yposScreen = 0; - while (line < pdoc->LinesTotal() && yposScreen < rcMargin.bottom) { + while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) { int marks = pdoc->GetMark(line); if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { if (cs.GetExpanded(line)) { @@ -648,7 +650,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { char number[100]; number[0] = '\0'; sprintf(number, "%d", line + 1); - if (foldFlags & 8) + if (foldFlags & 64) sprintf(number, "%X", pdoc->GetLevel(line)); int xpos = 0; PRectangle rcNumber=rcMarker; @@ -853,7 +855,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, } else { rcSegment.left = ll.positions[startseg] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; - // Only try do draw if really visible - enhances performance by not calling environment to + // Only try to draw if really visible - enhances performance by not calling environment to // draw strings that are completely past the right side of the window. if (rcSegment.left <= rcLine.right) { surface->DrawText(rcSegment, textFont, @@ -991,10 +993,9 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { ypos += screenLinePaintFirst * vs.lineHeight; int yposScreen = screenLinePaintFirst * vs.lineHeight; - if (endPosPaint > pdoc->GetEndStyled()) { - // Notify container to do some more styling - NotifyStyleNeeded(endPosPaint); - } + // Ensure we are styled as far as we are painting. + pdoc->EnsureStyledTo(endPosPaint); + if (needUpdateUI) { NotifyUpdateUI(); needUpdateUI = false; @@ -1009,7 +1010,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { } if (paintState == paintAbandoned) { - // Either NotifyStyleNeeded or NotifyUpdateUI noticed that painting is needed + // Either styling or NotifyUpdateUI noticed that painting is needed // outside the current painting rectangle //Platform::DebugPrintf("Abandoning paint\n"); return; @@ -1067,13 +1068,21 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if (cs.GetVisible(line)) DrawLine(surface, vs, line, xStart, rcLine, ll); - if (foldFlags & 2) { + bool expanded = cs.GetExpanded(line); + if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) { if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { PRectangle rcFoldLine = rcLine; rcFoldLine.bottom = rcFoldLine.top + 1; surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); } } + if ( (expanded && (foldFlags & 8)) || (!expanded && (foldFlags & 16)) ) { + if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { + PRectangle rcFoldLine = rcLine; + rcFoldLine.top = rcFoldLine.bottom - 1; + surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); + } + } // Draw the Caret if (line == lineCaret) { @@ -1204,10 +1213,9 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { if (linePrintLast < pdoc->LinesTotal()) endPosPrint = pdoc->LineStart(linePrintLast + 1); - if (endPosPrint > pdoc->GetEndStyled()) { - // Notify container to do some more styling - NotifyStyleNeeded(endPosPrint); - } + // Ensure we are styled to where we are formatting. + pdoc->EnsureStyledTo(endPosPrint); + int xStart = vsPrint.fixedColumnWidth + pfr->rc.left + lineNumberWidth; int ypos = pfr->rc.top; int line = linePrintStart; @@ -1228,20 +1236,27 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { PRectangle rcNumber = rcLine; rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify - rcNumber.left += lineNumberWidth - + rcNumber.left -= surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number)); surface->DrawText(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, ypos + vsPrint.maxAscent, number, strlen(number), vsPrint.styles[STYLE_LINENUMBER].fore.allocated, vsPrint.styles[STYLE_LINENUMBER].back.allocated); } + + // When printing, the hdc and hdcTarget may be the same, so + // changing the state of surfaceMeasure may change the underlying + // state of surface. Therefore, any cached state is discarded before + // using each surface. // Copy this line and its styles from the document into local arrays // and determine the x position at which each character starts. + surfaceMeasure->FlushCachedState(); LineLayout ll; LayoutLine(line, surfaceMeasure, vsPrint, ll); // Draw the line + surface->FlushCachedState(); DrawLine(surface, vsPrint, line, xStart, rcLine, ll); ypos += vsPrint.lineHeight; @@ -1421,6 +1436,10 @@ void Editor::NotifyStyleNeeded(int endStyleNeeded) { NotifyParent(scn); } +void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) { + NotifyStyleNeeded(endStyleNeeded); +} + void Editor::NotifyChar(char ch) { SCNotification scn; scn.nmhdr.code = SCN_CHARADDED; @@ -1599,6 +1618,10 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { SetScrollBars(); } + if (mh.modificationType & SC_MOD_CHANGEMARKER) { + RedrawSelMargin(); + } + // If client wants to see this modification if (mh.modificationType & modEventMask) { if ((mh.modificationType & SC_MOD_CHANGESTYLE) == 0) { @@ -1677,6 +1700,11 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_VCHOMEEXTEND: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: break; // Filter out all others (display changes, etc) @@ -1712,6 +1740,60 @@ void Editor::PageMove(int direction, bool extend) { } } +void Editor::ChangeCaseOfSelection(bool makeUpperCase) { + pdoc->BeginUndoAction(); + int startCurrent = currentPos; + int startAnchor = anchor; + if (selType == selRectangle) { + int lineStart = pdoc->LineFromPosition(SelectionStart()); + int lineEnd = pdoc->LineFromPosition(SelectionEnd()); + for (int line=lineStart; line <= lineEnd; line++) { + pdoc->ChangeCase( + Range(SelectionStart(line), SelectionEnd(line)), + makeUpperCase); + } + // Would be nicer to keep the rectangular selection but this is complex + selType = selStream; + SetSelection(startCurrent, startCurrent); + } else { + pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()), + makeUpperCase); + SetSelection(startCurrent, startAnchor); + } + pdoc->EndUndoAction(); +} + + +void Editor::LineTranspose() { + int line = pdoc->LineFromPosition(currentPos); + if (line > 0) { + int startPrev = pdoc->LineStart(line-1); + int endPrev = pdoc->LineEnd(line-1); + int start = pdoc->LineStart(line); + int end = pdoc->LineEnd(line); + int startNext = pdoc->LineStart(line+1); + if (end < pdoc->Length()) { + end = startNext; + char *thisLine = CopyRange(start, end); + pdoc->DeleteChars(start, end-start); + pdoc->InsertString(startPrev, thisLine, end-start); + MovePositionTo(startPrev+end-start); + delete []thisLine; + } else { + // Last line so line has no line end + char *thisLine = CopyRange(start, end); + char *prevEnd = CopyRange(endPrev, start); + pdoc->DeleteChars(endPrev, end-endPrev); + pdoc->InsertString(startPrev, thisLine, end-start); + pdoc->InsertString(startPrev + end-start, prevEnd, start-endPrev); + MovePositionTo(startPrev + end-endPrev); + delete []thisLine; + delete []prevEnd; + } + + } +} + int Editor::KeyCommand(UINT iMessage) { Point pt = LocationFromPosition(currentPos); @@ -1884,8 +1966,40 @@ int Editor::KeyCommand(UINT iMessage) { case SCI_DELWORDRIGHT: { int endWord = pdoc->NextWordStart(currentPos, 1); pdoc->DeleteChars(currentPos, endWord - currentPos); + MovePositionTo(currentPos); } break; + case SCI_LINECUT: { + int lineStart = pdoc->LineFromPosition(currentPos); + int lineEnd = pdoc->LineFromPosition(anchor); + if (lineStart > lineEnd) { + int t = lineEnd; + lineEnd = lineStart; + lineStart = t; + } + int start = pdoc->LineStart(lineStart); + int end = pdoc->LineStart(lineEnd+1); + SetSelection(start,end); + Cut(); + } + break; + case SCI_LINEDELETE: { + int line = pdoc->LineFromPosition(currentPos); + int start = pdoc->LineStart(line); + int end = pdoc->LineStart(line+1); + pdoc->DeleteChars(start, end-start); + MovePositionTo(start); + } + break; + case SCI_LINETRANSPOSE: + LineTranspose(); + break; + case SCI_LOWERCASE: + ChangeCaseOfSelection(false); + break; + case SCI_UPPERCASE: + ChangeCaseOfSelection(true); + break; } return 0; } @@ -2111,7 +2225,11 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul int positionWasInSelection = PositionInSelection(position); - if ((!inDragDrop) || !(0 == positionWasInSelection)) { + bool positionOnEdgeOfSelection = + (position == SelectionStart()) || (position == SelectionEnd()); + + if ((!inDragDrop) || !(0 == positionWasInSelection) || + (positionOnEdgeOfSelection && !moving)) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); @@ -2566,6 +2684,10 @@ void Editor::SetDocPointer(Document *document) { pdoc = document; } pdoc->AddRef(); + // Reset the contraction state to fully shown. + cs.Clear(); + cs.InsertLines(0, pdoc->LinesTotal()-1); + pdoc->AddWatcher(this, 0); Redraw(); SetScrollBars(); @@ -2680,6 +2802,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case WM_PASTE: Paste(); SetLastXChosen(); + EnsureCaretVisible(); break; case WM_CLEAR: @@ -3061,7 +3184,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_APPENDUNDOSTARTACTION: - pdoc->AppendUndoStartAction(); + // Not just deprecated - now dead + //pdoc->AppendUndoStartAction(); return 0; #endif @@ -3260,18 +3384,15 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case SCI_MARKERADD: { int markerID = pdoc->AddMark(wParam, lParam); - RedrawSelMargin(); return markerID; } case SCI_MARKERDELETE: pdoc->DeleteMark(wParam, lParam); - RedrawSelMargin(); break; case SCI_MARKERDELETEALL: pdoc->DeleteAllMarks(static_cast(wParam)); - RedrawSelMargin(); break; case SCI_MARKERGET: @@ -3391,7 +3512,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { if (lParam == 0) return 0; if (wParam <= STYLE_MAX) { - strcpy(vs.styles[wParam].fontName, reinterpret_cast(lParam)); + vs.SetStyleFontName(wParam, reinterpret_cast(lParam)); InvalidateStyleRedraw(); } break; @@ -3492,7 +3613,14 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { caretSlop = lParam; break; -#ifdef INCLUDE_DEPRECATED_FEATURES + case SCI_LINESONSCREEN: + return LinesOnScreen(); + + case SCI_USEPOPUP: + displayPopupMenu = wParam; + break; + + #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_SETFORE: vs.styles[STYLE_DEFAULT].fore.desired = Colour(wParam); InvalidateStyleRedraw(); @@ -3612,6 +3740,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_ZOOMOUT: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: return KeyCommand(iMessage); case SCI_BRACEHIGHLIGHT: diff --git a/src/stc/scintilla/src/Editor.h b/src/stc/scintilla/src/Editor.h index 4ff334767a..d1281be5a8 100644 --- a/src/stc/scintilla/src/Editor.h +++ b/src/stc/scintilla/src/Editor.h @@ -116,6 +116,8 @@ protected: // ScintillaBase subclass needs access to much of Editor int searchAnchor; + int displayPopupMenu; + #ifdef MACRO_SUPPORT int recordingMacro; #endif @@ -218,12 +220,16 @@ protected: // ScintillaBase subclass needs access to much of Editor void NotifySavePoint(Document *document, void *userData, bool atSavePoint); void NotifyModified(Document *document, DocModification mh, void *userData); void NotifyDeleted(Document *document, void *userData); + void NotifyStyleNeeded(Document *doc, void *userData, int endPos); + #ifdef MACRO_SUPPORT void NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam); #endif void PageMove(int direction, bool extend=false); + void ChangeCaseOfSelection(bool makeUpperCase); + void LineTranspose(); virtual int KeyCommand(UINT iMessage); virtual int KeyDefault(int /* key */, int /*modifiers*/); int KeyDown(int key, bool shift, bool ctrl, bool alt); diff --git a/src/stc/scintilla/src/KeyMap.cxx b/src/stc/scintilla/src/KeyMap.cxx index f339cd2750..9ab9694df1 100644 --- a/src/stc/scintilla/src/KeyMap.cxx +++ b/src/stc/scintilla/src/KeyMap.cxx @@ -61,36 +61,36 @@ UINT KeyMap::Find(int key, int modifiers) { } KeyToCommand KeyMap::MapDefault[] = { - VK_DOWN, SCI_NORM, SCI_LINEDOWN, - VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, - VK_UP, SCI_NORM, SCI_LINEUP, - VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, + VK_DOWN, SCI_NORM, SCI_LINEDOWN, + VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, + VK_UP, SCI_NORM, SCI_LINEUP, + VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, VK_LEFT, SCI_NORM, SCI_CHARLEFT, VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND, VK_LEFT, SCI_CTRL, SCI_WORDLEFT, VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND, - VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, - VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, - VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, - VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, - VK_HOME, SCI_NORM, SCI_VCHOME, - VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, - VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, - VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, + VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, + VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, + VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, + VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, + VK_HOME, SCI_NORM, SCI_VCHOME, + VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, + VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, + VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, VK_END, SCI_NORM, SCI_LINEEND, VK_END, SCI_SHIFT, SCI_LINEENDEXTEND, VK_END, SCI_CTRL, SCI_DOCUMENTEND, VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND, - VK_PRIOR, SCI_NORM, SCI_PAGEUP, - VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, - VK_NEXT, SCI_NORM, SCI_PAGEDOWN, - VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, + VK_PRIOR, SCI_NORM, SCI_PAGEUP, + VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, + VK_NEXT, SCI_NORM, SCI_PAGEDOWN, + VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, VK_DELETE, SCI_NORM, WM_CLEAR, VK_DELETE, SCI_SHIFT, WM_CUT, VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT, - VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, - VK_INSERT, SCI_SHIFT, WM_PASTE, - VK_INSERT, SCI_CTRL, WM_COPY, + VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, + VK_INSERT, SCI_SHIFT, WM_PASTE, + VK_INSERT, SCI_CTRL, WM_COPY, VK_ESCAPE, SCI_NORM, SCI_CANCEL, VK_BACK, SCI_NORM, SCI_DELETEBACK, VK_BACK, SCI_CTRL, SCI_DELWORDLEFT, @@ -103,9 +103,14 @@ KeyToCommand KeyMap::MapDefault[] = { VK_TAB, SCI_NORM, SCI_TAB, VK_TAB, SCI_SHIFT, SCI_BACKTAB, VK_RETURN, SCI_NORM, SCI_NEWLINE, - 'L', SCI_CTRL, SCI_FORMFEED, VK_ADD, SCI_CTRL, SCI_ZOOMIN, VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT, + //'L', SCI_CTRL, SCI_FORMFEED, + 'L', SCI_CTRL, SCI_LINECUT, + 'L', SCI_CSHIFT, SCI_LINEDELETE, + 'T', SCI_CTRL, SCI_LINETRANSPOSE, + 'U', SCI_CTRL, SCI_LOWERCASE, + 'U', SCI_CSHIFT, SCI_UPPERCASE, 0,0,0, }; diff --git a/src/stc/scintilla/src/KeyMap.h b/src/stc/scintilla/src/KeyMap.h index 814f3aa3b7..bc435e1970 100644 --- a/src/stc/scintilla/src/KeyMap.h +++ b/src/stc/scintilla/src/KeyMap.h @@ -11,6 +11,7 @@ #define SCI_CTRL LEFT_CTRL_PRESSED #define SCI_ALT LEFT_ALT_PRESSED #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) +#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) class KeyToCommand { public: diff --git a/src/stc/scintilla/src/KeyWords.cxx b/src/stc/scintilla/src/KeyWords.cxx index 20f6762470..5d6d9c6cfc 100644 --- a/src/stc/scintilla/src/KeyWords.cxx +++ b/src/stc/scintilla/src/KeyWords.cxx @@ -17,2201 +17,29 @@ #include "Scintilla.h" #include "SciLexer.h" -inline bool IsLeadByte(int codePage, char ch) { -#if PLAT_GTK - // TODO: support DBCS under GTK+ - return false; -#elif PLAT_WIN - return codePage && IsDBCSLeadByteEx(codePage, ch); -#elif PLAT_WX - return false; -#endif -} - -inline bool iswordchar(char ch) { - return isalnum(ch) || ch == '.' || ch == '_'; -} - -inline bool iswordstart(char ch) { - return isalnum(ch) || ch == '_'; -} - -enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; - -static int IndentAmount(StylingContext &styler, int line, int *flags) { - int end = styler.Length(); - int spaceFlags = 0; - - // Determines the indentation level of the current line and also checks for consistent - // indentation compared to the previous line. - // Indentation is judged consistent when the indentation whitespace of each line lines - // the same or the indentation of one line is a prefix of the other. - - int pos = styler.LineStart(line); - char ch = styler[pos]; - int indent = 0; - bool inPrevPrefix = line > 0; - int posPrev = inPrevPrefix ? styler.LineStart(line-1) : 0; - while ((ch == ' ' || ch == '\t') && (pos < end)) { - if (inPrevPrefix) { - char chPrev = styler[posPrev++]; - if (chPrev == ' ' || chPrev == '\t') { - if (chPrev != ch) - spaceFlags |= wsInconsistent; - } else { - inPrevPrefix = false; - } - } - if (ch == ' ') { - spaceFlags |= wsSpace; - indent++; - } else { // Tab - spaceFlags |= wsTab; - if (spaceFlags & wsSpace) - spaceFlags |= wsSpaceTab; - indent = (indent / 8 + 1) * 8; - } - ch = styler[++pos]; - } - - *flags = spaceFlags; - indent += SC_FOLDLEVELBASE; - if (isspace(ch)) // Completely empty line - return indent | SC_FOLDLEVELWHITEFLAG; - else - return indent; -} - -inline bool isoperator(char ch) { - if (isalnum(ch)) - return false; - // '.' left out as it is used to make up numbers - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; -} - -static void classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_C_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_C_WORD; - } - styler.ColourSegment(start, end, chAttr); -} - -static void ColouriseCppDoc(int codePage, int startPos, int length, - int initStyle, WordList &keywords, StylingContext &styler) { - - bool fold = styler.GetPropSet().GetInt("fold"); - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; - - int state = initStyle; - char chPrev = ' '; - char chNext = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - int visChars = 0; - for (unsigned int i = startPos; i <= lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) { - int lev = levelPrev; - if (visChars == 0) - lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; - styler.SetLevel(lineCurrent, lev); - lineCurrent++; - visChars = 0; - levelPrev = levelCurrent; - } - if (!isspace(ch)) - visChars++; - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - i += 1; - continue; - } - - if (state == SCE_C_STRINGEOL) { - if (ch != '\r' && ch != '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } - if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_WORD; - startSeg = i; - } else if (ch == '/' && chNext == '*') { - styler.ColourSegment(startSeg, i - 1, state); - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_C_COMMENTDOC; - else - state = SCE_C_COMMENT; - startSeg = i; - } else if (ch == '/' && chNext == '/') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRING; - startSeg = i; - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_CHARACTER; - startSeg = i; - } else if (ch == '#') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_PREPROCESSOR; - startSeg = i; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_C_OPERATOR); - startSeg = i + 1; - if ((ch == '{') || (ch == '}')) { - levelCurrent += (ch == '{') ? 1 : -1; - } - } - } else if (state == SCE_C_WORD) { - if (!iswordchar(ch)) { - classifyWordCpp(startSeg, i - 1, keywords, styler); - state = SCE_C_DEFAULT; - startSeg = i; - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_C_COMMENTDOC; - else - state = SCE_C_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } else if (ch == '\'') { - state = SCE_C_CHARACTER; - } else if (ch == '#') { - state = SCE_C_PREPROCESSOR; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - if ((ch == '{') || (ch == '}')) { - levelCurrent += (ch == '{') ? 1 : -1; - } - } - } - } else { - if (state == SCE_C_PREPROCESSOR) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_COMMENT) { - if (ch == '/' && chPrev == '*' && ( - (i > startSeg + 2) || ((initStyle == SCE_C_COMMENT) && (startSeg == startPos)))) { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_C_COMMENTDOC) { - if (ch == '/' && chPrev == '*' && ( - (i > startSeg + 3) || ((initStyle == SCE_C_COMMENTDOC) && (startSeg == startPos)))) { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_C_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_STRING) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRINGEOL; - startSeg = i; - } else if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_C_CHARACTER) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRINGEOL; - startSeg = i; - } else if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } - if (state == SCE_C_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_C_COMMENTDOC; - else - state = SCE_C_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } else if (ch == '\'') { - state = SCE_C_CHARACTER; - } else if (ch == '#') { - state = SCE_C_PREPROCESSOR; - } else if (iswordstart(ch)) { - state = SCE_C_WORD; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - if ((ch == '{') || (ch == '}')) { - levelCurrent += (ch == '{') ? 1 : -1; - } - } - } - } - chPrev = ch; - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc - 1, state); - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - if (fold) { - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); - styler.SetLevel(lineCurrent, levelPrev | flagsNext); - - } -} - -inline bool isPerlOperator(char ch) { - if (isalnum(ch)) - return false; - // '.' left out as it is used to make up numbers - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '\\' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; -} - -static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_PL_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_PL_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_PL_WORD; - } - styler.ColourSegment(start, end, chAttr); - return chAttr; -} - -static bool isEndVar(char ch) { - return !isalnum(ch) && ch != '#' && ch != '$' && - ch != '_' && ch != '\''; -} - -static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) { - if ((pos + static_cast(strlen(val))) >= lengthDoc) { - return false; - } - while (*val) { - if (*val != styler[pos++]) { - return false; - } - val++; - } - return true; -} - -static bool isOKQuote(char ch) { - if (isalnum(ch)) - return false; - if (isspace(ch)) - return false; - if (iscntrl(ch)) - return false; - return true; -} - -static char opposite(char ch) { - if (ch == '(') - return ')'; - if (ch == '[') - return ']'; - if (ch == '{') - return '}'; - if (ch == '<') - return '>'; - return ch; -} - -static void ColourisePerlDoc(int codePage, int startPos, int length, int initStyle, - WordList &keywords, StylingContext &styler) { - char sooked[100]; - int quotes = 0; - char quoteDown = 'd'; - char quoteUp = 'd'; - int quoteRep = 1; - int sookedpos = 0; - bool preferRE = true; - sooked[sookedpos] = '\0'; - int state = initStyle; - int lengthDoc = startPos + length; - // If in a long distance lexical state, seek to the beginning to find quote characters - if (state == SCE_PL_HERE || state == SCE_PL_REGEX || - state == SCE_PL_REGSUBST || state == SCE_PL_LONGQUOTE) { - while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) { - startPos--; - } - state = SCE_PL_DEFAULT; - } - styler.StartAt(startPos); - char chPrev = ' '; - char chNext = styler[startPos]; - int startSeg = startPos; - for (int i = startPos; i <= lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - char chNext2 = styler.SafeGetCharAt(i + 2); - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - i += 1; - continue; - } - - if (state == SCE_PL_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - if (ch == 's' && !isalnum(chNext)) { - state = SCE_PL_REGSUBST; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 2; - startSeg = i; - } else if (ch == 'm' && !isalnum(chNext)) { - state = SCE_PL_REGEX; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 1; - startSeg = i; - } else if (ch == 't' && chNext == 'r' && !isalnum(chNext2)) { - state = SCE_PL_REGSUBST; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 2; - startSeg = i; - i++; - chNext = chNext2; - } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isalnum(chNext2)) { - state = SCE_PL_LONGQUOTE; - startSeg = i; - i++; - chNext = chNext2; - quotes = 0; - quoteUp = '\0'; - quoteDown = '\0'; - quoteRep = 1; - } else { - state = SCE_PL_WORD; - startSeg = i; - preferRE = false; - } - } else if (ch == '#') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_STRING; - startSeg = i; - } else if (ch == '\'') { - if (chPrev == '&') { - // Archaic call - styler.ColourSegment(i, i, state); - startSeg = i + 1; - } else { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_CHARACTER; - startSeg = i; - } - } else if (ch == '`') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_BACKTICKS; - startSeg = i; - } else if (ch == '$') { - preferRE = false; - styler.ColourSegment(startSeg, i - 1, state); - if (isalnum(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { - state = SCE_PL_SCALAR; - startSeg = i; - } else if (chNext != '{' && chNext != '[') { - styler.ColourSegment(i - 1, i, SCE_PL_SCALAR); - i++; - startSeg = i + 1; - ch = ' '; - chNext = ' '; - } else { - styler.ColourSegment(i, i, SCE_PL_SCALAR); - startSeg = i + 1; - } - } else if (ch == '@') { - preferRE = false; - styler.ColourSegment(startSeg, i - 1, state); - if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { - state = SCE_PL_ARRAY; - startSeg = i; - } else if (chNext != '{' && chNext != '[') { - styler.ColourSegment(i - 1, i, SCE_PL_ARRAY); - i++; - startSeg = i + 1; - ch = ' '; - } else { - styler.ColourSegment(i, i, SCE_PL_ARRAY); - startSeg = i + 1; - } - } else if (ch == '%') { - preferRE = false; - styler.ColourSegment(startSeg, i - 1, state); - if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { - state = SCE_PL_HASH; - startSeg = i; - } else if (chNext != '{' && chNext != '[') { - styler.ColourSegment(i - 1, i, SCE_PL_HASH); - i++; - startSeg = i + 1; - ch = ' '; - } else { - styler.ColourSegment(i, i, SCE_PL_HASH); - startSeg = i + 1; - } - } else if (ch == '*') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_SYMBOLTABLE; - startSeg = i; - } else if (ch == '/' && preferRE) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_REGEX; - quoteUp = '/'; - quoteDown = '/'; - quotes = 1; - quoteRep = 1; - startSeg = i; - } else if (ch == '<' && chNext == '<') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_HERE; - startSeg = i; - i++; - ch = chNext; - chNext = chNext2; - quotes = 0; - sookedpos = 0; - sooked[sookedpos] = '\0'; - } else if (ch == '=' && isalpha(chNext)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_POD; - startSeg = i; - quotes = 0; - sookedpos = 0; - sooked[sookedpos] = '\0'; - } else if (isPerlOperator(ch)) { - if (ch == ')' || ch == ']') - preferRE = false; - else - preferRE = true; - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_PL_OPERATOR); - startSeg = i + 1; - } - } else if (state == SCE_PL_WORD) { - if (!iswordchar(ch) && ch != '\'') { // Archaic Perl has quotes inside names - if (isMatch(styler, lengthDoc, startSeg, "__DATA__")) { - styler.ColourSegment(startSeg, i, SCE_PL_DATASECTION); - state = SCE_PL_DATASECTION; - } else if (isMatch(styler, lengthDoc, startSeg, "__END__")) { - styler.ColourSegment(startSeg, i, SCE_PL_DATASECTION); - state = SCE_PL_DATASECTION; - } else { - if (classifyWordPerl(startSeg, i - 1, keywords, styler) == SCE_PL_WORD) - preferRE = true; - state = SCE_PL_DEFAULT; - startSeg = i; - if (ch == '#') { - state = SCE_PL_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_PL_STRING; - } else if (ch == '\'') { - state = SCE_PL_CHARACTER; - } else if (ch == '<' && chNext == '<') { - state = SCE_PL_HERE; - quotes = 0; - startSeg = i; - sookedpos = 0; - sooked[sookedpos] = '\0'; - } else if (isPerlOperator(ch)) { - if (ch == ')' || ch == ']') - preferRE = false; - else - preferRE = true; - styler.ColourSegment(startSeg, i, SCE_PL_OPERATOR); - state = SCE_PL_DEFAULT; - startSeg = i + 1; - } - } - } - } else { - if (state == SCE_PL_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_PL_DEFAULT; - startSeg = i; - } - } else if (state == SCE_PL_HERE) { - if (isalnum(ch) && quotes < 2) { - sooked[sookedpos++] = ch; - sooked[sookedpos] = '\0'; - if (quotes == 0) - quotes = 1; - } else { - quotes++; - } - - if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked)) { - styler.ColourSegment(startSeg, i + sookedpos - 1, SCE_PL_HERE); - state = SCE_PL_DEFAULT; - i += sookedpos; - startSeg = i; - chNext = ' '; - } - } else if (state == SCE_PL_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_PL_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_PL_CHARACTER) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_PL_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_PL_BACKTICKS) { - if (ch == '`') { - styler.ColourSegment(startSeg, i, state); - state = SCE_PL_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } else if (state == SCE_PL_POD) { - if (ch == '=') { - if (isMatch(styler, lengthDoc, i, "=cut")) { - styler.ColourSegment(startSeg, i - 1 + 4, state); - i += 4; - startSeg = i; - state = SCE_PL_DEFAULT; - chNext = ' '; - ch = ' '; - } - } - } else if (state == SCE_PL_SCALAR) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_ARRAY) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_HASH) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_SYMBOLTABLE) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_REF) { - if (isEndVar(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - state = SCE_PL_DEFAULT; - } - } else if (state == SCE_PL_REGEX) { - if (!quoteUp && !isspace(ch)) { - quoteUp = ch; - quoteDown = opposite(ch); - quotes++; - } else { - if (ch == quoteDown && chPrev != '\\') { - quotes--; - if (quotes == 0) { - quoteRep--; - if (quoteUp == quoteDown) { - quotes++; - } - } - if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - } else if (ch == quoteUp && chPrev != '\\') { - quotes++; - } else if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - } - } else if (state == SCE_PL_REGSUBST) { - if (!quoteUp && !isspace(ch)) { - quoteUp = ch; - quoteDown = opposite(ch); - quotes++; - } else { - if (ch == quoteDown && chPrev != '\\') { - quotes--; - if (quotes == 0) { - quoteRep--; - } - if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - if (quoteUp == quoteDown) { - quotes++; - } - } else if (ch == quoteUp && chPrev != '\\') { - quotes++; - } else if (!isalpha(chNext)) { - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - } - } - } else if (state == SCE_PL_LONGQUOTE) { - if (!quoteDown && !isspace(ch)) { - quoteUp = ch; - quoteDown = opposite(quoteUp); - quotes++; - } else if (ch == quoteDown) { - quotes--; - if (quotes == 0) { - quoteRep--; - if (quoteRep <= 0) { - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - state = SCE_PL_DEFAULT; - ch = ' '; - } - if (quoteUp == quoteDown) { - quotes++; - } - } - } else if (ch == quoteUp) { - quotes++; - } - } - - if (state == SCE_PL_DEFAULT) { // One of the above succeeded - if (ch == '#') { - state = SCE_PL_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_PL_STRING; - } else if (ch == '\'') { - state = SCE_PL_CHARACTER; - } else if (iswordstart(ch)) { - state = SCE_PL_WORD; - preferRE = false; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_PL_OPERATOR); - startSeg = i + 1; - } - } - } - chPrev = ch; - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc, state); -} - - -static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } - char chAttr = SCE_C_DEFAULT; - if (wordIsNumber) - chAttr = SCE_C_NUMBER; - else { - if (keywords.InList(s)) { - chAttr = SCE_C_WORD; - if (strcmp(s, "rem") == 0) - chAttr = SCE_C_COMMENTLINE; - } - } - styler.ColourSegment(start, end, chAttr); - if (chAttr == SCE_C_COMMENTLINE) - return SCE_C_COMMENTLINE; - else - return SCE_C_DEFAULT; -} - -static void ColouriseVBDoc(int codePage, int startPos, int length, int initStyle, - WordList &keywords, StylingContext &styler) { - int state = initStyle; - char chNext = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - for (int i = startPos; i < lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; - } - - if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_WORD; - startSeg = i; - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRING; - startSeg = i; - } - } else if (state == SCE_C_WORD) { - if (!iswordchar(ch)) { - state = classifyWordVB(startSeg, i - 1, keywords, styler); - if (state == SCE_C_DEFAULT) { - startSeg = i; - if (ch == '\'') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } - } - } - } else { - if (state == SCE_C_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_STRING) { - // VB doubles quotes to preserve them - if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - startSeg = i; - } - } - if (state == SCE_C_DEFAULT) { // One of the above succeeded - if (ch == '\'') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; - } else if (iswordstart(ch)) { - state = SCE_C_WORD; - } - } - } - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc, state); -} - -static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_P_IDENTIFIER; - if (0 == strcmp(prevWord, "class")) - chAttr = SCE_P_CLASSNAME; - else if (0 == strcmp(prevWord, "def")) - chAttr = SCE_P_DEFNAME; - else if (wordIsNumber) - chAttr = SCE_P_NUMBER; - else if (keywords.InList(s)) - chAttr = SCE_P_WORD; - styler.ColourSegment(start, end, chAttr); - strcpy(prevWord, s); -} - -static void ColourisePyDoc(int codePage, int startPos, int length, int initStyle, WordList &keywords, StylingContext &styler) { - //Platform::DebugPrintf("Python coloured\n"); - bool fold = styler.GetPropSet().GetInt("fold"); - int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level"); - char prevWord[200]; - prevWord[0] = '\0'; - if (length == 0) - return ; - int lineCurrent = styler.GetLine(startPos); - int spaceFlags = 0; - // TODO: Need to check previous line for indentation for both folding and bad indentation - int indentCurrent = IndentAmount(styler, lineCurrent, &spaceFlags); - - int state = initStyle & 31; - char chPrev = ' '; - char chPrev2 = ' '; - char chNext = styler[startPos]; - char chNext2 = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - bool atStartLine = true; - for (int i = startPos; i <= lengthDoc; i++) { - - if (atStartLine) { - if (whingeLevel == 1) { - styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state); - } else if (whingeLevel == 2) { - styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state); - } else if (whingeLevel == 3) { - styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state); - } else if (whingeLevel == 4) { - styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state); - } - atStartLine = false; - } - - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - chNext2 = styler.SafeGetCharAt(i + 2); - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) { - // Perform colourisation of white space and triple quoted strings at end of each line to allow - // tab marking to work inside white space and triple quoted strings - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - } - - int lev = indentCurrent; - int indentNext = IndentAmount(styler, lineCurrent + 1, &spaceFlags); - if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { - // Only non whitespace lines can be headers - if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { - lev |= SC_FOLDLEVELHEADERFLAG; - } - } - indentCurrent = indentNext; - if (fold) { - styler.SetLevel(lineCurrent, lev); - } - lineCurrent++; - atStartLine = true; - } - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - chPrev2 = ' '; - i += 1; - continue; - } - - if (state == SCE_P_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_P_WORD; - startSeg = i; - } else if (ch == '#') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_P_COMMENTLINE; - startSeg = i; - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_P_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_STRING; - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - startSeg = i; - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_P_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_P_OPERATOR); - startSeg = i + 1; - } - } else if (state == SCE_P_WORD) { - if (!iswordchar(ch)) { - classifyWordPy(startSeg, i - 1, keywords, styler, prevWord); - state = SCE_P_DEFAULT; - startSeg = i; - if (ch == '#') { - state = SCE_P_COMMENTLINE; - } else if (ch == '\"') { - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_P_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_STRING; - } - } else if (ch == '\'') { - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_P_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_P_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_P_OPERATOR); - startSeg = i + 1; - } - } - } else { - if (state == SCE_P_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_P_DEFAULT; - startSeg = i; - } - } else if (state == SCE_P_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_P_CHARACTER) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_P_TRIPLE) { - if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } else if (state == SCE_P_TRIPLEDOUBLE) { - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourSegment(startSeg, i, state); - state = SCE_P_DEFAULT; - startSeg = i + 1; - } - } - } - chPrev2 = chPrev; - chPrev = ch; - } - if (startSeg <= lengthDoc) { - if (state == SCE_P_DEFAULT) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_WORD) { - classifyWordPy(startSeg, lengthDoc, keywords, styler, prevWord); - } else if (state == SCE_P_COMMENTLINE) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_STRING) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_CHARACTER) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_TRIPLE) { - styler.ColourSegment(startSeg, lengthDoc, state); - } else if (state == SCE_P_TRIPLEDOUBLE) { - styler.ColourSegment(startSeg, lengthDoc, state); - } - } -} - -static void ColouriseBatchLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - if (0 == strncmp(lineBuffer, "REM", 3)) { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (0 == strncmp(lineBuffer, "rem", 3)) { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (0 == strncmp(lineBuffer, "SET", 3)) { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if (0 == strncmp(lineBuffer, "set", 3)) { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if (lineBuffer[0] == ':') { - styler.ColourSegment(0, lengthLine - 1, 3); - } else { - styler.ColourSegment(0, lengthLine - 1, 0); - } -} - -static void ColouriseBatchDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i < startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - ColouriseBatchLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColouriseBatchLine(lineBuffer, linePos, styler); -} - -enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; -static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) { - char s[100]; - s[0] = '\0'; - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } -Platform::DebugPrintf("Scripting indicator [%s]\n", s); - if (strstr(s, "vbs")) - return eScriptVBS; - if (strstr(s, "pyth")) - return eScriptPython; - if (strstr(s, "javas")) - return eScriptJS; - if (strstr(s, "jscr")) - return eScriptJS; - - return prevValue; -} - -static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || - (styler[start] == '-') || (styler[start] == '#'); - char chAttr = SCE_H_ATTRIBUTEUNKNOWN; - if (wordIsNumber) { - chAttr = SCE_H_NUMBER; - } else { - char s[100]; - s[0] = '\0'; - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } - if (keywords.InList(s)) - chAttr = SCE_H_ATTRIBUTE; - } - styler.ColourTo(end, chAttr); -} - -static int classifyTagHTML(unsigned int start, unsigned int end, - WordList &keywords, StylingContext &styler) { - char s[100]; - // Copy after the '<' - unsigned int i = 0; - for (int cPos=start; cPos <= end && i < 30; cPos++) { - char ch = styler[cPos]; - if (ch != '<') - s[i++] = tolower(ch); - } - s[i] = '\0'; - char chAttr = SCE_H_TAGUNKNOWN; - if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment - chAttr = SCE_H_COMMENT; - } else if (s[0] == '/') { // Closing tag - if (keywords.InList(s + 1)) - chAttr = SCE_H_TAG; - } else { - if (keywords.InList(s)) { - chAttr = SCE_H_TAG; - if (0 == strcmp(s, "script")) - chAttr = SCE_H_SCRIPT; - } - } - styler.ColourTo(end, chAttr); - return chAttr; -} - -static void classifyWordHTJS(unsigned int start, unsigned int end, - WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_HJ_WORD; - if (wordIsNumber) - chAttr = SCE_HJ_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_HJ_KEYWORD; - } - styler.ColourTo(end, chAttr); -} - -static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = tolower(styler[start + i]); - s[i + 1] = '\0'; - } - char chAttr = SCE_HB_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_HB_NUMBER; - else { - if (keywords.InList(s)) { - chAttr = SCE_HB_WORD; - if (strcmp(s, "rem") == 0) - chAttr = SCE_HB_COMMENTLINE; - } - } - styler.ColourTo(end, chAttr); - if (chAttr == SCE_HB_COMMENTLINE) - return SCE_HB_COMMENTLINE; - else - return SCE_HB_DEFAULT; -} - -static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - s[i + 1] = '\0'; - } - char chAttr = SCE_HP_IDENTIFIER; - if (0 == strcmp(prevWord, "class")) - chAttr = SCE_HP_CLASSNAME; - else if (0 == strcmp(prevWord, "def")) - chAttr = SCE_HP_DEFNAME; - else if (wordIsNumber) - chAttr = SCE_HP_NUMBER; - else if (keywords.InList(s)) - chAttr = SCE_HP_WORD; - styler.ColourTo(end, chAttr); - strcpy(prevWord, s); -} - -inline bool ishtmlwordchar(char ch) { - return isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#'; -} - -static bool InTagState(int state) { - return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || - state == SCE_H_SCRIPT || - state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || - state == SCE_H_NUMBER || state == SCE_H_OTHER || - state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING; -} - -static bool isLineEnd(char ch) { - return ch == '\r' || ch == '\n'; -} - -static void ColouriseHyperTextDoc(int codePage, int startPos, int length, - int initStyle, WordList &keywords, WordList &keywords2, WordList &keywords3, WordList &keywords4, - StylingContext &styler) { - - styler.StartAt(startPos, 63); - bool lastTagWasScript = false; - char prevWord[200]; - prevWord[0] = '\0'; - int scriptLanguage = eScriptJS; - int state = initStyle; - // If inside a tag, it may be a script tage, so reread from the start to ensure any language tas are seen - if (InTagState(state)) { - while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) { - startPos--; - } - state = SCE_H_DEFAULT; - } - styler.StartAt(startPos, 63); - - int lineState = eScriptVBS; - int lineCurrent = styler.GetLine(startPos); - if (lineCurrent > 0) - lineState = styler.GetLineState(lineCurrent); - int defaultScript = lineState &0xff; - int beforeASP = (lineState >> 8) &0xff; - int inASP = (lineState >> 16) &0xff; - - char chPrev = ' '; - char chPrev2 = ' '; - styler.StartSegment(startPos); - int lengthDoc = startPos + length; - for (int i = startPos; i <= lengthDoc; i++) { - char ch = styler[i]; - char chNext = styler.SafeGetCharAt(i + 1); - char chNext2 = styler.SafeGetCharAt(i + 2); - - if (IsLeadByte(codePage, ch)) { // dbcs - chPrev2 = ' '; - chPrev = ' '; - i += 1; - continue; - } - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - // New line -> record any line state onto /next/ line - lineCurrent++; - styler.SetLineState(lineCurrent, - defaultScript | (beforeASP << 8) | (inASP << 16)); - } - - // Handle ASP even within other constructs as it is a preprocessor - if ((ch == '<') && (chNext == '%')) { - beforeASP = state; - styler.ColourTo(i - 1, state); - if (chNext2 == '@') { - styler.ColourTo(i + 2, SCE_H_ASP); - state = SCE_H_ASPAT; - i+=2; - } else { - if (defaultScript == eScriptVBS) - state = SCE_HB_START; - else if (defaultScript == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - if (chNext2 == '=') { - styler.ColourTo(i + 2, SCE_H_ASP); - i+=2; - } else { - styler.ColourTo(i + 1, SCE_H_ASP); - i++; - } - } - inASP = 1; - continue; - } - if (inASP && (ch == '%') && (chNext == '>')) { - if (state == SCE_H_ASPAT) - defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript); - // Bounce out of any ASP mode - styler.ColourTo(i - 1, state); - //if (state == SCE_H_ASPAT) - // styler.ColourTo(i+1, SCE_H_ASPAT); - //else - styler.ColourTo(i+1, SCE_H_ASP); - i++; - state = beforeASP; - beforeASP = SCE_H_DEFAULT; - inASP = 0; - continue; - } - - if (state == SCE_H_DEFAULT) { - if (ch == '<') { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - if (chNext == '?') { - styler.ColourTo(i + 1, SCE_H_XMLSTART); - i++; - ch = chNext; - } - } else if (ch == '&') { - styler.ColourTo(i - 1, SCE_H_DEFAULT); - state = SCE_H_ENTITY; - } - } else if (state == SCE_H_COMMENT) { - if ((ch == '>') && (chPrev == '-')) { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_ENTITY) { - if (ch == ';') { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_TAGUNKNOWN) { - if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { - int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); - lastTagWasScript = eClass == SCE_H_SCRIPT; - if (lastTagWasScript) { - scriptLanguage = eScriptJS; - eClass = SCE_H_TAG; - } - if (ch == '>') { - styler.ColourTo(i, SCE_H_TAG); - if (lastTagWasScript) { - if (scriptLanguage == eScriptVBS) - state = SCE_HB_START; - else if (scriptLanguage == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - } else { - state = SCE_H_DEFAULT; - } - } else { - if (eClass == SCE_H_COMMENT) { - state = SCE_H_COMMENT; - } else { - state = SCE_H_OTHER; - } - } - } - } else if (state == SCE_H_ATTRIBUTE) { - if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage); - classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler); - if (ch == '>') { - styler.ColourTo(i, SCE_H_TAG); - if (lastTagWasScript) { - if (scriptLanguage == eScriptVBS) - state = SCE_HB_START; - else if (scriptLanguage == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - } else { - state = SCE_H_DEFAULT; - } - } else { - state = SCE_H_OTHER; - } - } - } else if (state == SCE_H_ASP) { - if ((ch == '>') && (chPrev == '%')) { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_ASPAT) { - if ((ch == '>') && (chPrev == '%')) { - styler.ColourTo(i, state); - state = SCE_H_DEFAULT; - } - } else if (state == SCE_H_OTHER) { - if (ch == '>') { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_H_TAG); - if (lastTagWasScript) { - if (scriptLanguage == eScriptVBS) - state = SCE_HB_START; - else if (scriptLanguage == eScriptPython) - state = SCE_HP_START; - else - state = SCE_HJ_START; - } else { - state = SCE_H_DEFAULT; - } - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - state = SCE_H_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - state = SCE_H_SINGLESTRING; - } else if (ch == '/' && chNext == '>') { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } else if (ch == '?' && chNext == '>') { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_XMLEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } else if (ishtmlwordchar(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_H_ATTRIBUTE; - } - } else if (state == SCE_H_DOUBLESTRING) { - if (ch == '\"') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); - styler.ColourTo(i, SCE_H_DOUBLESTRING); - state = SCE_H_OTHER; - } - } else if (state == SCE_H_SINGLESTRING) { - if (ch == '\'') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); - styler.ColourTo(i, SCE_H_SINGLESTRING); - state = SCE_H_OTHER; - } - } else if (state == SCE_HJ_DEFAULT || state == SCE_HJ_START) { - if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HJ_WORD; - } else if (ch == '/' && chNext == '*') { - styler.ColourTo(i - 1, state); - if (chNext2 == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_SINGLESTRING; - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, state); - state = SCE_HJ_COMMENTLINE; - } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HJ_SYMBOLS); - state = SCE_HJ_DEFAULT; - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HJ_START) { - styler.ColourTo(i - 1, state); - state = SCE_HJ_DEFAULT; - } - } - } else if (state == SCE_HJ_WORD) { - if (!iswordchar(ch)) { - classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler); - //styler.ColourTo(i - 1, eHTJSKeyword); - state = SCE_HJ_DEFAULT; - if (ch == '/' && chNext == '*') { - if (chNext2 == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - state = SCE_HJ_SINGLESTRING; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HJ_SYMBOLS); - state = SCE_HJ_DEFAULT; - } - } - } else if (state == SCE_HJ_COMMENT) { - if (ch == '/' && chPrev == '*') { - state = SCE_HJ_DEFAULT; - styler.ColourTo(i, SCE_HJ_COMMENT); - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } - } else if (state == SCE_HJ_COMMENTDOC) { - if (ch == '/' && chPrev == '*') { - state = SCE_HJ_DEFAULT; - styler.ColourTo(i, SCE_HJ_COMMENTDOC); - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } - } else if (state == SCE_HJ_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); - state = SCE_HJ_DEFAULT; - } else if ((ch == '<') && (chNext == '/')) { - // Common to hide end script tag in comment - styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); - state = SCE_H_TAGUNKNOWN; - } - } else if (state == SCE_HJ_DOUBLESTRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - } - } else if (ch == '\"') { - styler.ColourTo(i, SCE_HJ_DOUBLESTRING); - state = SCE_HJ_DEFAULT; - i++; - ch = chNext; - } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); - state = SCE_HJ_STRINGEOL; - } - } else if (state == SCE_HJ_SINGLESTRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - } - } else if (ch == '\'') { - styler.ColourTo(i, SCE_HJ_SINGLESTRING); - state = SCE_HJ_DEFAULT; - i++; - ch = chNext; - } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); - state = SCE_HJ_STRINGEOL; - } - } else if (state == SCE_HJ_STRINGEOL) { - if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HJ_DEFAULT; - } - } else if (state == SCE_HB_DEFAULT || state == SCE_HB_START) { - if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HB_WORD; - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - state = SCE_HB_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - state = SCE_HB_STRING; - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, state); - state = SCE_HB_COMMENTLINE; - } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HB_DEFAULT); - state = SCE_HB_DEFAULT; - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HB_START) { - styler.ColourTo(i - 1, state); - state = SCE_HB_DEFAULT; - } - } - } else if (state == SCE_HB_WORD) { - if (!iswordchar(ch)) { - state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler); - if (state == SCE_HB_DEFAULT) { - if (ch == '\"') { - state = SCE_HB_STRING; - } else if (ch == '\'') { - state = SCE_HB_COMMENTLINE; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HB_DEFAULT); - state = SCE_HB_DEFAULT; - } - } - } - } else if (state == SCE_HB_STRING) { - if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_HB_DEFAULT; - i++; - ch = chNext; - } else if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_HB_STRINGEOL; - } - } else if (state == SCE_HB_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); - state = SCE_HB_DEFAULT; - } else if ((ch == '<') && (chNext == '/')) { - // Common to hide end script tag in comment - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } - } else if (state == SCE_HB_STRINGEOL) { - if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HB_DEFAULT; - } - } else if (state == SCE_HP_DEFAULT || state == SCE_HP_START) { - if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); - state = SCE_HP_WORD; - } else if ((ch == '<') && (chNext == '/')) { - styler.ColourTo(i - 1, state); - state = SCE_H_TAGUNKNOWN; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, state); - state = SCE_HP_COMMENTLINE; - } else if (ch == '#') { - styler.ColourTo(i - 1, state); - state = SCE_HP_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, state); - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_HP_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_STRING; - } - } else if (ch == '\'') { - styler.ColourTo(i - 1, state); - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_HP_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HP_OPERATOR); - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HP_START) { - styler.ColourTo(i - 1, state); - state = SCE_HP_DEFAULT; - } - } - } else if (state == SCE_HP_WORD) { - if (!iswordchar(ch)) { - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); - state = SCE_HP_DEFAULT; - if (ch == '#') { - state = SCE_HP_COMMENTLINE; - } else if (ch == '\"') { - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_HP_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_STRING; - } - } else if (ch == '\'') { - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_HP_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = styler.SafeGetCharAt(i + 1); - } else { - state = SCE_HP_CHARACTER; - } - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HP_OPERATOR); - } - } - } else { - if (state == SCE_HP_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_CHARACTER) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\'') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_TRIPLE) { - if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } else if (state == SCE_HP_TRIPLEDOUBLE) { - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, state); - state = SCE_HP_DEFAULT; - } - } - } - if (state == SCE_HB_DEFAULT) { // One of the above succeeded - if (ch == '\"') { - state = SCE_HB_STRING; - } else if (ch == '\'') { - state = SCE_HB_COMMENTLINE; - } else if (iswordstart(ch)) { - state = SCE_HB_WORD; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HB_DEFAULT); - } - } - if (state == SCE_HJ_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - state = SCE_HJ_SINGLESTRING; - } else if (iswordstart(ch)) { - state = SCE_HJ_WORD; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HJ_SYMBOLS); - } - } - chPrev2 = chPrev; - chPrev = ch; - } - styler.ColourTo(lengthDoc - 1, state); -} - -static void ColourisePropsLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - int i = 0; - while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces - i++; - if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (lineBuffer[i] == '[') { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if (lineBuffer[i] == '@') { - styler.ColourSegment(0, i, 4); - if (lineBuffer[++i] == '=') - styler.ColourSegment(i, i, 3); - if (++i < lengthLine) - styler.ColourSegment(i, lengthLine - 1, 0); - } else { - while (lineBuffer[i] != '=' && (i < lengthLine)) // Search the '=' character - i++; - if (lineBuffer[i] == '=') { - styler.ColourSegment(0, i - 1, 0); - styler.ColourSegment(i, i, 3); - if (++i < lengthLine) - styler.ColourSegment(i, lengthLine - 1, 0); - } else - styler.ColourSegment(0, lengthLine - 1, 0); - } -} - -static void ColourisePropsDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i <= startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - lineBuffer[linePos] = '\0'; - ColourisePropsLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColourisePropsLine(lineBuffer, linePos, styler); -} - -static void ColouriseMakeLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - int i = 0; - while (isspace(lineBuffer[i]) && (i < lengthLine)) - i++; - if (lineBuffer[i] == '#' || lineBuffer[i] == '!') { - styler.ColourSegment(0, lengthLine - 1, 1); - } else { - styler.ColourSegment(0, lengthLine - 1, 0); - } -} - -static void ColouriseMakeDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i <= startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - ColouriseMakeLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColouriseMakeLine(lineBuffer, linePos, styler); -} - -static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, StylingContext &styler) { - if (lineBuffer[0] == '>') { - // Command or return status - styler.ColourSegment(0, lengthLine - 1, 4); - } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { - styler.ColourSegment(0, lengthLine - 1, 1); - } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { - // Borland error message - styler.ColourSegment(0, lengthLine - 1, 5); - } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { - // Borland warning message - styler.ColourSegment(0, lengthLine - 1, 5); - } else { - // Look for ::message - // Look for (line)message - // Look for (line,pos)message - int state = 0; - for (int i = 0; i < lengthLine; i++) { - if (state == 0 && lineBuffer[i] == ':' && isdigit(lineBuffer[i + 1])) { - state = 1; - } else if (state == 0 && lineBuffer[i] == '(') { - state = 10; - } else if (state == 1 && isdigit(lineBuffer[i])) { - state = 2; - } else if (state == 2 && lineBuffer[i] == ':') { - state = 3; - break; - } else if (state == 2 && !isdigit(lineBuffer[i])) { - state = 99; - } else if (state == 10 && isdigit(lineBuffer[i])) { - state = 11; - } else if (state == 11 && lineBuffer[i] == ',') { - state = 14; - } else if (state == 11 && lineBuffer[i] == ')') { - state = 12; - break; - } else if (state == 12 && lineBuffer[i] == ':') { - state = 13; - } else if (state == 14 && lineBuffer[i] == ')') { - state = 15; - break; - } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { - state = 99; - } - } - if (state == 3) { - styler.ColourSegment(0, lengthLine - 1, 2); - } else if ((state == 14) || (state == 15)) { - styler.ColourSegment(0, lengthLine - 1, 3); - } else { - styler.ColourSegment(0, lengthLine - 1, 0); - } - } -} - -static void ColouriseErrorListDoc(int startPos, int length, int, StylingContext &styler) { - char lineBuffer[1024]; - unsigned int linePos = 0; - for (int i = startPos; i <= startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { - ColouriseErrorListLine(lineBuffer, linePos, styler); - linePos = 0; - } - } - if (linePos > 0) - ColouriseErrorListLine(lineBuffer, linePos, styler); -} - -static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { - char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { - s[i] = toupper(styler[start + i]); - s[i + 1] = '\0'; - } - char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) - chAttr = SCE_C_NUMBER; - else { - if (keywords.InList(s)) - chAttr = SCE_C_WORD; - } - styler.ColourSegment(start, end, chAttr); -} - -static void ColouriseSQLDoc(int codePage, int startPos, int length, - int initStyle, WordList &keywords, StylingContext &styler) { - - bool fold = styler.GetPropSet().GetInt("fold"); - int lineCurrent = styler.GetLine(startPos); - int spaceFlags = 0; - int indentCurrent = 0; - - int state = initStyle; - char chPrev = ' '; - char chNext = styler[startPos]; - int startSeg = startPos; - int lengthDoc = startPos + length; - bool prevCr = false; - for (int i = startPos; i <= lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - indentCurrent = IndentAmount(styler, lineCurrent, &spaceFlags); - int lev = indentCurrent; - if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { - // Only non whitespace lines can be headers - int indentNext = IndentAmount(styler, lineCurrent + 1, &spaceFlags); - if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) { - lev |= SC_FOLDLEVELHEADERFLAG; - } - } - if (fold) { - styler.SetLevel(lineCurrent, lev); - } - } - - if (IsLeadByte(codePage, ch)) { // dbcs - chNext = styler.SafeGetCharAt(i + 2); - chPrev = ' '; - i += 1; - continue; - } - - if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_WORD; - startSeg = i; - } else if (ch == '/' && chNext == '*') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENT; - startSeg = i; - } else if (ch == '-' && chNext == '-') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_COMMENTLINE; - startSeg = i; - } else if (ch == '\'') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_STRING; - startSeg = i; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i - 1, state); - styler.ColourSegment(i, i, SCE_C_OPERATOR); - startSeg = i + 1; - } - } else if (state == SCE_C_WORD) { - if (!iswordchar(ch)) { - classifyWordSQL(startSeg, i - 1, keywords, styler); - state = SCE_C_DEFAULT; - startSeg = i; - if (ch == '/' && chNext == '*') { - state = SCE_C_COMMENT; - } else if (ch == '-' && chNext == '-') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\'') { - state = SCE_C_STRING; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - } - } - } else { - if (state == SCE_C_COMMENT) { - if (ch == '/' && chPrev == '*' && ( - (i > startSeg + 2) || ((initStyle == SCE_C_COMMENT) && (startSeg == startPos)))) { - state = SCE_C_DEFAULT; - styler.ColourSegment(startSeg, i, state); - startSeg = i + 1; - } - } else if (state == SCE_C_COMMENTLINE) { - if (ch == '\r' || ch == '\n') { - styler.ColourSegment(startSeg, i - 1, state); - state = SCE_C_DEFAULT; - startSeg = i; - } - } else if (state == SCE_C_STRING) { - if (ch == '\'') { - if ( chNext == '\'' ) { - i++; - } else { - styler.ColourSegment(startSeg, i, state); - state = SCE_C_DEFAULT; - i++; - startSeg = i; - } - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } - if (state == SCE_C_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - state = SCE_C_COMMENT; - } else if (ch == '-' && chNext == '-') { - state = SCE_C_COMMENTLINE; - } else if (ch == '\'') { - state = SCE_C_STRING; - } else if (iswordstart(ch)) { - state = SCE_C_WORD; - } else if (isoperator(ch)) { - styler.ColourSegment(startSeg, i, SCE_C_OPERATOR); - startSeg = i + 1; - } - } - } - chPrev = ch; - } - if (startSeg < lengthDoc) - styler.ColourSegment(startSeg, lengthDoc - 1, state); -} - -void ColouriseDoc(int codePage, int startPos, int lengthDoc, int initStyle, - int language, WordList *keywordlists[], StylingContext &styler) { - //Platform::DebugPrintf("ColouriseDoc <%s>\n", language); - if (language == SCLEX_PYTHON) { - // Python uses a different mask because bad indentation is marked by oring with 32 - styler.StartAt(startPos, 127); - ColourisePyDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_PERL) { - // Lexer for perl often has to backtrack to start of current style to determine - // which characters are being used as quotes, how deeply nested is the - // start position and what the termination string is for here documents - ColourisePerlDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if ((language == SCLEX_HTML) || (language == SCLEX_XML)) { - // Lexer for HTML requires more lexical states (6 bits worth) than most lexers - ColouriseHyperTextDoc(codePage, startPos, lengthDoc, initStyle, - *keywordlists[0], *keywordlists[1], *keywordlists[2], *keywordlists[3], styler); - } else { - styler.StartAt(startPos); - if (language == SCLEX_CPP) { - ColouriseCppDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_SQL) { - ColouriseSQLDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_VB) { - ColouriseVBDoc(codePage, startPos, lengthDoc, initStyle, *keywordlists[0], styler); - } else if (language == SCLEX_PROPERTIES) { - ColourisePropsDoc(startPos, lengthDoc, initStyle, styler); - } else if (language == SCLEX_ERRORLIST) { - ColouriseErrorListDoc(startPos, lengthDoc, initStyle, styler); - } else if (language == SCLEX_MAKEFILE) { - ColouriseMakeDoc(startPos, lengthDoc, initStyle, styler); - } else if (language == SCLEX_BATCH) { - ColouriseBatchDoc(startPos, lengthDoc, initStyle, styler); - } else { - // Null language means all style bytes are 0 so just mark the end - no need to fill in. - styler.StartAt(startPos + lengthDoc - 1); - styler.ColourSegment(0, 0, 0); - } +LexerModule *LexerModule::base = 0; + +LexerModule::LexerModule(int language_, LexerFunction fn_) : + language(language_), fn(fn_) { + next = base; + base = this; +} + +void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle, + int language, WordList *keywordlists[], StylingContext &styler) { + LexerModule *lm = base; + while (lm) { + if (lm->language == language) { + lm->fn(startPos, lengthDoc, initStyle, keywordlists, styler); + return; + } + lm = lm->next; + } + // Unknown language + // Null language means all style bytes are 0 so just mark the end - no need to fill in. + if (lengthDoc > 0) { + styler.StartAt(startPos + lengthDoc - 1); + styler.StartSegment(startPos + lengthDoc - 1); + styler.ColourTo(startPos + lengthDoc - 1, 0); } } diff --git a/src/stc/scintilla/src/LexCPP.cxx b/src/stc/scintilla/src/LexCPP.cxx new file mode 100644 index 0000000000..3199322ba3 --- /dev/null +++ b/src/stc/scintilla/src/LexCPP.cxx @@ -0,0 +1,255 @@ +// SciTE - Scintilla based Text Editor +// LexCPP.cxx - lexer for C++, C, Java, and Javascript +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + bool wordIsUUID = false; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_C_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_C_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_C_WORD; + wordIsUUID = strcmp(s, "uuid") == 0; + } + } + styler.ColourTo(end, chAttr); + return wordIsUUID; +} + +static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + StylingContext &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + bool fold = styler.GetPropSet().GetInt("fold"); + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + + int state = initStyle; + char chPrev = ' '; + char chNext = styler[startPos]; + unsigned int lengthDoc = startPos + length; + int visChars = 0; + styler.StartSegment(startPos); + bool lastWordWasUUID = false; + for (unsigned int i = startPos; i <= lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if ((fold) && ((ch == '\r' && chNext != '\n') || (ch == '\n'))) { + int lev = levelPrev; + if (visChars == 0) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + styler.SetLevel(lineCurrent, lev); + lineCurrent++; + visChars = 0; + levelPrev = levelCurrent; + } + if (!isspace(ch)) + visChars++; + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_C_STRINGEOL) { + if (ch != '\r' && ch != '\n') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i-1, state); + if (lastWordWasUUID) { + state = SCE_C_UUID; + lastWordWasUUID = false; + } else { + state = SCE_C_WORD; + } + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i-1, state); + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_C_COMMENTDOC; + else + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i-1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i-1, state); + state = SCE_C_STRING; + } else if (ch == '\'') { + styler.ColourTo(i-1, state); + state = SCE_C_CHARACTER; + } else if (ch == '#') { + styler.ColourTo(i-1, state); + state = SCE_C_PREPROCESSOR; + } else if (isoperator(ch)) { + styler.ColourTo(i-1, state); + styler.ColourTo(i, SCE_C_OPERATOR); + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + } else if (state == SCE_C_WORD) { + if (!iswordchar(ch)) { + lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_C_DEFAULT; + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_C_COMMENTDOC; + else + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (ch == '\'') { + state = SCE_C_CHARACTER; + } else if (ch == '#') { + state = SCE_C_PREPROCESSOR; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + } + } else { + if (state == SCE_C_PREPROCESSOR) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_COMMENT) { + if (ch == '/' && chPrev == '*') { + if (((i > styler.GetStartSegment() + 2) || ( + (initStyle == SCE_C_COMMENT) && + (styler.GetStartSegment() == static_cast(startPos))))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTDOC) { + if (ch == '/' && chPrev == '*') { + if (((i > styler.GetStartSegment() + 3) || ( + (initStyle == SCE_C_COMMENTDOC) && + (styler.GetStartSegment() == static_cast(startPos))))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, state); + state = SCE_C_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_C_CHARACTER) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, state); + state = SCE_C_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_C_UUID) { + if (ch == '\r' || ch == '\n' || ch == ')') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } + if (state == SCE_C_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_C_COMMENTDOC; + else + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (ch == '\'') { + state = SCE_C_CHARACTER; + } else if (ch == '#') { + state = SCE_C_PREPROCESSOR; + } else if (iswordstart(ch)) { + state = SCE_C_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + } + } + chPrev = ch; + } + styler.ColourTo(lengthDoc - 1, state); + + // Fill in the real level of the next line, keeping the current flags as they will be filled in later + if (fold) { + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); + styler.SetLevel(lineCurrent, levelPrev | flagsNext); + + } +} + +LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc); diff --git a/src/stc/scintilla/src/LexHTML.cxx b/src/stc/scintilla/src/LexHTML.cxx new file mode 100644 index 0000000000..be30bc4626 --- /dev/null +++ b/src/stc/scintilla/src/LexHTML.cxx @@ -0,0 +1,1139 @@ +// SciTE - Scintilla based Text Editor +// LexHTML.cxx - lexer for HTML +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; +static int segIsScriptingIndicator(StylingContext &styler, unsigned int start, unsigned int end, int prevValue) { + char s[100]; + s[0] = '\0'; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } +//Platform::DebugPrintf("Scripting indicator [%s]\n", s); + if (strstr(s, "vbs")) + return eScriptVBS; + if (strstr(s, "pyth")) + return eScriptPython; + if (strstr(s, "javas")) + return eScriptJS; + if (strstr(s, "jscr")) + return eScriptJS; + + return prevValue; +} + +static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || + (styler[start] == '-') || (styler[start] == '#'); + char chAttr = SCE_H_ATTRIBUTEUNKNOWN; + if (wordIsNumber) { + chAttr = SCE_H_NUMBER; + } else { + char s[100]; + s[0] = '\0'; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + if (keywords.InList(s)) + chAttr = SCE_H_ATTRIBUTE; + } + styler.ColourTo(end, chAttr); +} + +static int classifyTagHTML(unsigned int start, unsigned int end, + WordList &keywords, StylingContext &styler) { + char s[100]; + // Copy after the '<' + unsigned int i = 0; + for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) { + char ch = styler[cPos]; + if (ch != '<') + s[i++] = tolower(ch); + } + s[i] = '\0'; + char chAttr = SCE_H_TAGUNKNOWN; + if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment + chAttr = SCE_H_COMMENT; + } else if (s[0] == '/') { // Closing tag + if (keywords.InList(s + 1)) + chAttr = SCE_H_TAG; + } else { + if (keywords.InList(s)) { + chAttr = SCE_H_TAG; + if (0 == strcmp(s, "script")) + chAttr = SCE_H_SCRIPT; + } + } + styler.ColourTo(end, chAttr); + return chAttr; +} + +static void classifyWordHTJS(unsigned int start, unsigned int end, + WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HJ_WORD; + if (wordIsNumber) + chAttr = SCE_HJ_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_HJ_KEYWORD; + } + styler.ColourTo(end, chAttr); +} + +static void classifyWordHTJSA(unsigned int start, unsigned int end, + WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HJA_WORD; + if (wordIsNumber) + chAttr = SCE_HJA_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_HJA_KEYWORD; + } + styler.ColourTo(end, chAttr); +} + +static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_HB_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_HB_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_HB_WORD; + if (strcmp(s, "rem") == 0) + chAttr = SCE_HB_COMMENTLINE; + } + } + styler.ColourTo(end, chAttr); + if (chAttr == SCE_HB_COMMENTLINE) + return SCE_HB_COMMENTLINE; + else + return SCE_HB_DEFAULT; +} + +static int classifyWordHTVBA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_HBA_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_HBA_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_HBA_WORD; + if (strcmp(s, "rem") == 0) + chAttr = SCE_HBA_COMMENTLINE; + } + } + styler.ColourTo(end, chAttr); + if (chAttr == SCE_HBA_COMMENTLINE) + return SCE_HBA_COMMENTLINE; + else + return SCE_HBA_DEFAULT; +} + +static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HP_IDENTIFIER; + if (0 == strcmp(prevWord, "class")) + chAttr = SCE_HP_CLASSNAME; + else if (0 == strcmp(prevWord, "def")) + chAttr = SCE_HP_DEFNAME; + else if (wordIsNumber) + chAttr = SCE_HP_NUMBER; + else if (keywords.InList(s)) + chAttr = SCE_HP_WORD; + styler.ColourTo(end, chAttr); + strcpy(prevWord, s); +} + +static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_HPA_IDENTIFIER; + if (0 == strcmp(prevWord, "class")) + chAttr = SCE_HPA_CLASSNAME; + else if (0 == strcmp(prevWord, "def")) + chAttr = SCE_HPA_DEFNAME; + else if (wordIsNumber) + chAttr = SCE_HPA_NUMBER; + else if (keywords.InList(s)) + chAttr = SCE_HPA_WORD; + styler.ColourTo(end, chAttr); + strcpy(prevWord, s); +} + +inline bool ishtmlwordchar(char ch) { + return isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#'; +} + +static bool InTagState(int state) { + return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || + state == SCE_H_SCRIPT || + state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || + state == SCE_H_NUMBER || state == SCE_H_OTHER || + state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING; +} + +static bool isLineEnd(char ch) { + return ch == '\r' || ch == '\n'; +} + +static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + StylingContext &styler) { + + WordList &keywords=*keywordlists[0]; + WordList &keywords2=*keywordlists[1]; + WordList &keywords3=*keywordlists[2]; + WordList &keywords4=*keywordlists[3]; + + // Lexer for HTML requires more lexical states (7 bits worth) than most lexers + styler.StartAt(startPos, 127); + bool lastTagWasScript = false; + char prevWord[200]; + prevWord[0] = '\0'; + int scriptLanguage = eScriptJS; + int state = initStyle; + // If inside a tag, it may be a script tage, so reread from the start to ensure any language tas are seen + if (InTagState(state)) { + while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) { + startPos--; + } + state = SCE_H_DEFAULT; + } + styler.StartAt(startPos, 127); + + int lineState = eScriptVBS; + int lineCurrent = styler.GetLine(startPos); + if (lineCurrent > 0) + lineState = styler.GetLineState(lineCurrent); + int defaultScript = lineState &0xff; + int beforeASP = (lineState >> 8) &0xff; + int inASP = (lineState >> 16) &0xff; + + char chPrev = ' '; + char chPrev2 = ' '; + styler.StartSegment(startPos); + int lengthDoc = startPos + length; + for (int i = startPos; i <= lengthDoc; i++) { + char ch = styler[i]; + char chNext = styler.SafeGetCharAt(i + 1); + char chNext2 = styler.SafeGetCharAt(i + 2); + + if (styler.IsLeadByte(ch)) { + chPrev2 = ' '; + chPrev = ' '; + i += 1; + continue; + } + + if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + // New line -> record any line state onto /next/ line + lineCurrent++; + styler.SetLineState(lineCurrent, + defaultScript | (beforeASP << 8) | (inASP << 16)); + } + + // Handle ASP even within other constructs as it is a preprocessor + if ((ch == '<') && (chNext == '%')) { + beforeASP = state; + styler.ColourTo(i - 1, state); + if (chNext2 == '@') { + styler.ColourTo(i + 2, SCE_H_ASP); + state = SCE_H_ASPAT; + i+=2; + } else { + if (defaultScript == eScriptVBS) + state = SCE_HBA_START; + else if (defaultScript == eScriptPython) + state = SCE_HPA_START; + else + state = SCE_HJA_START; + if (chNext2 == '=') { + styler.ColourTo(i + 2, SCE_H_ASP); + i+=2; + } else { + styler.ColourTo(i + 1, SCE_H_ASP); + i++; + } + } + inASP = 1; + continue; + } + if (inASP && (ch == '%') && (chNext == '>')) { + if (state == SCE_H_ASPAT) + defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript); + // Bounce out of any ASP mode + if (state == SCE_HJA_WORD) { + classifyWordHTJSA(styler.GetStartSegment(), i - 1, keywords2, styler); + } else if (state == SCE_HBA_WORD) { + classifyWordHTVBA(styler.GetStartSegment(), i - 1, keywords3, styler); + } else if (state == SCE_HPA_WORD) { + classifyWordHTPyA(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + } else { + styler.ColourTo(i - 1, state); + } + //if (state == SCE_H_ASPAT) + // styler.ColourTo(i+1, SCE_H_ASPAT); + //else + styler.ColourTo(i+1, SCE_H_ASP); + i++; + state = beforeASP; + beforeASP = SCE_H_DEFAULT; + inASP = 0; + continue; + } + + if (state == SCE_H_DEFAULT) { + if (ch == '<') { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + if (chNext == '?') { + styler.ColourTo(i + 1, SCE_H_XMLSTART); + i++; + ch = chNext; + } + } else if (ch == '&') { + styler.ColourTo(i - 1, SCE_H_DEFAULT); + state = SCE_H_ENTITY; + } + } else if (state == SCE_H_COMMENT) { + if ((ch == '>') && (chPrev == '-')) { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_ENTITY) { + if (ch == ';') { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_TAGUNKNOWN) { + if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { + int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); + lastTagWasScript = eClass == SCE_H_SCRIPT; + if (lastTagWasScript) { + scriptLanguage = eScriptJS; + eClass = SCE_H_TAG; + } + if (ch == '>') { + styler.ColourTo(i, SCE_H_TAG); + if (lastTagWasScript) { + if (scriptLanguage == eScriptVBS) + state = SCE_HB_START; + else if (scriptLanguage == eScriptPython) + state = SCE_HP_START; + else + state = SCE_HJ_START; + } else { + state = SCE_H_DEFAULT; + } + } else { + if (eClass == SCE_H_COMMENT) { + state = SCE_H_COMMENT; + } else { + state = SCE_H_OTHER; + } + } + } + } else if (state == SCE_H_ATTRIBUTE) { + if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { + if (lastTagWasScript) + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage); + classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler); + if (ch == '>') { + styler.ColourTo(i, SCE_H_TAG); + if (lastTagWasScript) { + if (scriptLanguage == eScriptVBS) + state = SCE_HB_START; + else if (scriptLanguage == eScriptPython) + state = SCE_HP_START; + else + state = SCE_HJ_START; + } else { + state = SCE_H_DEFAULT; + } + } else { + state = SCE_H_OTHER; + } + } + } else if (state == SCE_H_ASP) { + if ((ch == '>') && (chPrev == '%')) { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_ASPAT) { + if ((ch == '>') && (chPrev == '%')) { + styler.ColourTo(i, state); + state = SCE_H_DEFAULT; + } + } else if (state == SCE_H_OTHER) { + if (ch == '>') { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_H_TAG); + if (lastTagWasScript) { + if (scriptLanguage == eScriptVBS) + state = SCE_HB_START; + else if (scriptLanguage == eScriptPython) + state = SCE_HP_START; + else + state = SCE_HJ_START; + } else { + state = SCE_H_DEFAULT; + } + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_H_DOUBLESTRING; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_H_SINGLESTRING; + } else if (ch == '/' && chNext == '>') { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } else if (ch == '?' && chNext == '>') { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_XMLEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } else if (ishtmlwordchar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_H_ATTRIBUTE; + } + } else if (state == SCE_H_DOUBLESTRING) { + if (ch == '\"') { + if (lastTagWasScript) + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); + styler.ColourTo(i, SCE_H_DOUBLESTRING); + state = SCE_H_OTHER; + } + } else if (state == SCE_H_SINGLESTRING) { + if (ch == '\'') { + if (lastTagWasScript) + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); + styler.ColourTo(i, SCE_H_SINGLESTRING); + state = SCE_H_OTHER; + } + } else if (state == SCE_HJ_DEFAULT || state == SCE_HJ_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJ_WORD; + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + if (chNext2 == '*') + state = SCE_HJ_COMMENTDOC; + else + state = SCE_HJ_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_DOUBLESTRING; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_SINGLESTRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HJ_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HJ_SYMBOLS); + state = SCE_HJ_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HJ_START) { + styler.ColourTo(i - 1, state); + state = SCE_HJ_DEFAULT; + } + } + } else if (state == SCE_HJ_WORD) { + if (!iswordchar(ch)) { + classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler); + //styler.ColourTo(i - 1, eHTJSKeyword); + state = SCE_HJ_DEFAULT; + if (ch == '/' && chNext == '*') { + if (chNext2 == '*') + state = SCE_HJ_COMMENTDOC; + else + state = SCE_HJ_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJ_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJ_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJ_SINGLESTRING; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJ_SYMBOLS); + state = SCE_HJ_DEFAULT; + } + } + } else if (state == SCE_HJ_COMMENT) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJ_DEFAULT; + styler.ColourTo(i, SCE_HJ_COMMENT); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJ_COMMENTDOC) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJ_DEFAULT; + styler.ColourTo(i, SCE_HJ_COMMENTDOC); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJ_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); + state = SCE_HJ_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HJ_DOUBLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\"') { + styler.ColourTo(i, SCE_HJ_DOUBLESTRING); + state = SCE_HJ_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJ_STRINGEOL; + } + } else if (state == SCE_HJ_SINGLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\'') { + styler.ColourTo(i, SCE_HJ_SINGLESTRING); + state = SCE_HJ_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJ_STRINGEOL; + } + } else if (state == SCE_HJ_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJ_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HJ_DEFAULT; + } + } else if (state == SCE_HJA_DEFAULT || state == SCE_HJA_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJA_WORD; + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + if (chNext2 == '*') + state = SCE_HJA_COMMENTDOC; + else + state = SCE_HJA_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_DOUBLESTRING; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_SINGLESTRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HJA_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HJA_SYMBOLS); + state = SCE_HJA_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HJA_START) { + styler.ColourTo(i - 1, state); + state = SCE_HJA_DEFAULT; + } + } + } else if (state == SCE_HJA_WORD) { + if (!iswordchar(ch)) { + classifyWordHTJSA(styler.GetStartSegment(), i - 1, keywords2, styler); + //styler.ColourTo(i - 1, eHTJSKeyword); + state = SCE_HJA_DEFAULT; + if (ch == '/' && chNext == '*') { + if (chNext2 == '*') + state = SCE_HJA_COMMENTDOC; + else + state = SCE_HJA_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJA_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJA_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJA_SINGLESTRING; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJA_SYMBOLS); + state = SCE_HJA_DEFAULT; + } + } + } else if (state == SCE_HJA_COMMENT) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJA_DEFAULT; + styler.ColourTo(i, SCE_HJA_COMMENT); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJA_COMMENTDOC) { + if (ch == '/' && chPrev == '*') { + state = SCE_HJA_DEFAULT; + styler.ColourTo(i, SCE_HJA_COMMENTDOC); + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i + 1, SCE_H_TAGEND); + i++; + ch = chNext; + state = SCE_H_DEFAULT; + } + } else if (state == SCE_HJA_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, SCE_HJA_COMMENTLINE); + state = SCE_HJA_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, SCE_HJA_COMMENTLINE); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HJA_DOUBLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\"') { + styler.ColourTo(i, SCE_HJA_DOUBLESTRING); + state = SCE_HJA_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJA_STRINGEOL; + } + } else if (state == SCE_HJA_SINGLESTRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + } + } else if (ch == '\'') { + styler.ColourTo(i, SCE_HJA_SINGLESTRING); + state = SCE_HJA_DEFAULT; + i++; + ch = chNext; + } else if (isLineEnd(ch)) { + styler.ColourTo(i-1, state); + state = SCE_HJA_STRINGEOL; + } + } else if (state == SCE_HJA_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HJA_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HJA_DEFAULT; + } + } else if (state == SCE_HB_DEFAULT || state == SCE_HB_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HB_WORD; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HB_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HB_STRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HB_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HB_DEFAULT); + state = SCE_HB_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HB_START) { + styler.ColourTo(i - 1, state); + state = SCE_HB_DEFAULT; + } + } + } else if (state == SCE_HB_WORD) { + if (!iswordchar(ch)) { + state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler); + if (state == SCE_HB_DEFAULT) { + if (ch == '\"') { + state = SCE_HB_STRING; + } else if (ch == '\'') { + state = SCE_HB_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HB_DEFAULT); + state = SCE_HB_DEFAULT; + } + } + } + } else if (state == SCE_HB_STRING) { + if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HB_DEFAULT; + i++; + ch = chNext; + } else if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_HB_STRINGEOL; + } + } else if (state == SCE_HB_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HB_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HB_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HB_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HB_DEFAULT; + } + } else if (state == SCE_HBA_DEFAULT || state == SCE_HBA_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HBA_WORD; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_STRING; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HBA_DEFAULT); + state = SCE_HBA_DEFAULT; + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HBA_START) { + styler.ColourTo(i - 1, state); + state = SCE_HBA_DEFAULT; + } + } + } else if (state == SCE_HBA_WORD) { + if (!iswordchar(ch)) { + state = classifyWordHTVBA(styler.GetStartSegment(), i - 1, keywords3, styler); + if (state == SCE_HBA_DEFAULT) { + if (ch == '\"') { + state = SCE_HBA_STRING; + } else if (ch == '\'') { + state = SCE_HBA_COMMENTLINE; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HBA_DEFAULT); + state = SCE_HBA_DEFAULT; + } + } + } + } else if (state == SCE_HBA_STRING) { + if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HBA_DEFAULT; + i++; + ch = chNext; + } else if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_HBA_STRINGEOL; + } + } else if (state == SCE_HBA_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HBA_DEFAULT; + } else if ((ch == '<') && (chNext == '/')) { + // Common to hide end script tag in comment + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } + } else if (state == SCE_HBA_STRINGEOL) { + if (!isLineEnd(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HBA_DEFAULT; + } else if (!isLineEnd(chNext)) { + styler.ColourTo(i, state); + state = SCE_HBA_DEFAULT; + } + } else if (state == SCE_HP_DEFAULT || state == SCE_HP_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HP_WORD; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HP_COMMENTLINE; + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = SCE_HP_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HP_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_STRING; + } + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HP_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HP_OPERATOR); + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HP_START) { + styler.ColourTo(i - 1, state); + state = SCE_HP_DEFAULT; + } + } + } else if (state == SCE_HP_WORD) { + if (!iswordchar(ch)) { + classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + state = SCE_HP_DEFAULT; + if (ch == '#') { + state = SCE_HP_COMMENTLINE; + } else if (ch == '\"') { + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HP_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_STRING; + } + } else if (ch == '\'') { + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HP_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HP_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HP_OPERATOR); + } + } + } else if (state == SCE_HP_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_CHARACTER) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_TRIPLE) { + if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HP_TRIPLEDOUBLE) { + if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { + styler.ColourTo(i, state); + state = SCE_HP_DEFAULT; + } + } else if (state == SCE_HPA_DEFAULT || state == SCE_HPA_START) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_HPA_WORD; + } else if ((ch == '<') && (chNext == '/')) { + styler.ColourTo(i - 1, state); + state = SCE_H_TAGUNKNOWN; + } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, state); + state = SCE_HPA_COMMENTLINE; + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = SCE_HPA_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HPA_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_STRING; + } + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HPA_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_HPA_OPERATOR); + } else if ((ch == ' ') || (ch == '\t')) { + if (state == SCE_HPA_START) { + styler.ColourTo(i - 1, state); + state = SCE_HPA_DEFAULT; + } + } + } else if (state == SCE_HPA_WORD) { + if (!iswordchar(ch)) { + classifyWordHTPyA(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + state = SCE_HPA_DEFAULT; + if (ch == '#') { + state = SCE_HPA_COMMENTLINE; + } else if (ch == '\"') { + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_HPA_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_STRING; + } + } else if (ch == '\'') { + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_HPA_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_HPA_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HPA_OPERATOR); + } + } + } else if (state == SCE_HPA_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_CHARACTER) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_TRIPLE) { + if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } else if (state == SCE_HPA_TRIPLEDOUBLE) { + if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { + styler.ColourTo(i, state); + state = SCE_HPA_DEFAULT; + } + } + if (state == SCE_HB_DEFAULT) { // One of the above succeeded + if (ch == '\"') { + state = SCE_HB_STRING; + } else if (ch == '\'') { + state = SCE_HB_COMMENTLINE; + } else if (iswordstart(ch)) { + state = SCE_HB_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HB_DEFAULT); + } + } + if (state == SCE_HBA_DEFAULT) { // One of the above succeeded + if (ch == '\"') { + state = SCE_HBA_STRING; + } else if (ch == '\'') { + state = SCE_HBA_COMMENTLINE; + } else if (iswordstart(ch)) { + state = SCE_HBA_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HBA_DEFAULT); + } + } + if (state == SCE_HJ_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_HJ_COMMENTDOC; + else + state = SCE_HJ_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJ_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJ_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJ_SINGLESTRING; + } else if (iswordstart(ch)) { + state = SCE_HJ_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJ_SYMBOLS); + } + } + if (state == SCE_HJA_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + if (styler.SafeGetCharAt(i + 2) == '*') + state = SCE_HJA_COMMENTDOC; + else + state = SCE_HJA_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_HJA_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HJA_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_HJA_SINGLESTRING; + } else if (iswordstart(ch)) { + state = SCE_HJA_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_HJA_SYMBOLS); + } + } + chPrev2 = chPrev; + chPrev = ch; + } + styler.ColourTo(lengthDoc - 1, state); +} + +LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc); +LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc); diff --git a/src/stc/scintilla/src/LexOthers.cxx b/src/stc/scintilla/src/LexOthers.cxx new file mode 100644 index 0000000000..6e576c2c8a --- /dev/null +++ b/src/stc/scintilla/src/LexOthers.cxx @@ -0,0 +1,200 @@ +// SciTE - Scintilla based Text Editor +// LexOthers.cxx - lexers for properties files, batch files, make files and error lists +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void ColouriseBatchLine(char *lineBuffer, int endLine, StylingContext &styler) { + if (0 == strncmp(lineBuffer, "REM", 3)) { + styler.ColourTo(endLine, 1); + } else if (0 == strncmp(lineBuffer, "rem", 3)) { + styler.ColourTo(endLine, 1); + } else if (0 == strncmp(lineBuffer, "SET", 3)) { + styler.ColourTo(endLine, 2); + } else if (0 == strncmp(lineBuffer, "set", 3)) { + styler.ColourTo(endLine, 2); + } else if (lineBuffer[0] == ':') { + styler.ColourTo(endLine, 3); + } else { + styler.ColourTo(endLine, 0); + } +} + +static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + for (unsigned int i = startPos; i < startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { + ColouriseBatchLine(lineBuffer, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseBatchLine(lineBuffer, startPos + length, styler); +} + +static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, StylingContext &styler) { + int i = 0; + while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces + i++; + if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { + styler.ColourTo(endPos, 1); + } else if (lineBuffer[i] == '[') { + styler.ColourTo(endPos, 2); + } else if (lineBuffer[i] == '@') { + styler.ColourTo(startLine+i, 4); + if (lineBuffer[++i] == '=') + styler.ColourTo(startLine+i, 3); + styler.ColourTo(endPos, 0); + } else { + while (lineBuffer[i] != '=' && (i < lengthLine)) // Search the '=' character + i++; + if (lineBuffer[i] == '=') { + styler.ColourTo(startLine+i-1, 0); + styler.ColourTo(startLine+i, 3); + styler.ColourTo(endPos, 0); + } else { + styler.ColourTo(endPos, 0); + } + } +} + +static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + int startLine = startPos; + for (unsigned int i = startPos; i <= startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if ((styler[i] == '\r' && styler.SafeGetCharAt(i+1) != '\n') || + styler[i] == '\n' || + (linePos >= sizeof(lineBuffer) - 1)) { + lineBuffer[linePos] = '\0'; + ColourisePropsLine(lineBuffer, linePos, startLine, i, styler); + linePos = 0; + startLine = i+1; + } + } + if (linePos > 0) + ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length, styler); +} + +static void ColouriseMakeLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { + int i = 0; + while (isspace(lineBuffer[i]) && (i < lengthLine)) + i++; + if (lineBuffer[i] == '#' || lineBuffer[i] == '!') { + styler.ColourTo(endPos, 1); + } else { + styler.ColourTo(endPos, 0); + } +} + +static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + for (unsigned int i = startPos; i <= startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { + ColouriseMakeLine(lineBuffer, linePos, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseMakeLine(lineBuffer, linePos, startPos + length, styler); +} + +static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, StylingContext &styler) { + if (lineBuffer[0] == '>') { + // Command or return status + styler.ColourTo(endPos, 4); + } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { + styler.ColourTo(endPos, 1); + } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { + // Borland error message + styler.ColourTo(endPos, 5); + } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { + // Borland warning message + styler.ColourTo(endPos, 5); + } else { + // Look for ::message + // Look for (line)message + // Look for (line,pos)message + int state = 0; + for (int i = 0; i < lengthLine; i++) { + if (state == 0 && lineBuffer[i] == ':' && isdigit(lineBuffer[i + 1])) { + state = 1; + } else if (state == 0 && lineBuffer[i] == '(') { + state = 10; + } else if (state == 1 && isdigit(lineBuffer[i])) { + state = 2; + } else if (state == 2 && lineBuffer[i] == ':') { + state = 3; + break; + } else if (state == 2 && !isdigit(lineBuffer[i])) { + state = 99; + } else if (state == 10 && isdigit(lineBuffer[i])) { + state = 11; + } else if (state == 11 && lineBuffer[i] == ',') { + state = 14; + } else if (state == 11 && lineBuffer[i] == ')') { + state = 12; + break; + } else if (state == 12 && lineBuffer[i] == ':') { + state = 13; + } else if (state == 14 && lineBuffer[i] == ')') { + state = 15; + break; + } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) { + state = 99; + } + } + if (state == 3) { + styler.ColourTo(endPos, 2); + } else if ((state == 14) || (state == 15)) { + styler.ColourTo(endPos, 3); + } else { + styler.ColourTo(endPos, 0); + } + } +} + +static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], StylingContext &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + unsigned int linePos = 0; + for (unsigned int i = startPos; i <= startPos + length; i++) { + lineBuffer[linePos++] = styler[i]; + if (styler[i] == '\r' || styler[i] == '\n' || (linePos >= sizeof(lineBuffer) - 1)) { + ColouriseErrorListLine(lineBuffer, linePos, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseErrorListLine(lineBuffer, linePos, startPos + length, styler); +} + +LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc); +LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc); +LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc); +LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc); diff --git a/src/stc/scintilla/src/LexPerl.cxx b/src/stc/scintilla/src/LexPerl.cxx new file mode 100644 index 0000000000..9ccb207d0f --- /dev/null +++ b/src/stc/scintilla/src/LexPerl.cxx @@ -0,0 +1,488 @@ +// SciTE - Scintilla based Text Editor +// LexPerl.cxx - lexer for subset of Perl +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +inline bool isPerlOperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '\\' || + ch == '(' || ch == ')' || ch == '-' || ch == '+' || + ch == '=' || ch == '|' || ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ':' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || ch == '/' || + ch == '?' || ch == '!' || ch == '.' || ch == '~') + return true; + return false; +} + +static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_PL_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_PL_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_PL_WORD; + } + styler.ColourTo(end, chAttr); + return chAttr; +} + +static bool isEndVar(char ch) { + return !isalnum(ch) && ch != '#' && ch != '$' && + ch != '_' && ch != '\''; +} + +static bool isMatch(StylingContext &styler, int lengthDoc, int pos, const char *val) { + if ((pos + static_cast(strlen(val))) >= lengthDoc) { + return false; + } + while (*val) { + if (*val != styler[pos++]) { + return false; + } + val++; + } + return true; +} + +static bool isOKQuote(char ch) { + if (isalnum(ch)) + return false; + if (isspace(ch)) + return false; + if (iscntrl(ch)) + return false; + return true; +} + +static char opposite(char ch) { + if (ch == '(') + return ')'; + if (ch == '[') + return ']'; + if (ch == '{') + return '}'; + if (ch == '<') + return '>'; + return ch; +} + +static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], StylingContext &styler) { + + // Lexer for perl often has to backtrack to start of current style to determine + // which characters are being used as quotes, how deeply nested is the + // start position and what the termination string is for here documents + + WordList &keywords = *keywordlists[0]; + + char sooked[100]; + int quotes = 0; + char quoteDown = 'd'; + char quoteUp = 'd'; + int quoteRep = 1; + int sookedpos = 0; + bool preferRE = true; + sooked[sookedpos] = '\0'; + int state = initStyle; + int lengthDoc = startPos + length; + // If in a long distance lexical state, seek to the beginning to find quote characters + if (state == SCE_PL_HERE || state == SCE_PL_REGEX || + state == SCE_PL_REGSUBST || state == SCE_PL_LONGQUOTE) { + while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) { + startPos--; + } + state = SCE_PL_DEFAULT; + } + styler.StartAt(startPos); + char chPrev = ' '; + char chNext = styler[startPos]; + styler.StartSegment(startPos); + for (int i = startPos; i <= lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + char chNext2 = styler.SafeGetCharAt(i + 2); + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_PL_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + if (ch == 's' && !isalnum(chNext)) { + state = SCE_PL_REGSUBST; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 2; + } else if (ch == 'm' && !isalnum(chNext)) { + state = SCE_PL_REGEX; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 1; + } else if (ch == 't' && chNext == 'r' && !isalnum(chNext2)) { + state = SCE_PL_REGSUBST; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 2; + i++; + chNext = chNext2; + } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isalnum(chNext2)) { + state = SCE_PL_LONGQUOTE; + i++; + chNext = chNext2; + quotes = 0; + quoteUp = '\0'; + quoteDown = '\0'; + quoteRep = 1; + } else { + state = SCE_PL_WORD; + preferRE = false; + } + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = SCE_PL_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_PL_STRING; + } else if (ch == '\'') { + if (chPrev == '&') { + // Archaic call + styler.ColourTo(i, state); + } else { + styler.ColourTo(i - 1, state); + state = SCE_PL_CHARACTER; + } + } else if (ch == '`') { + styler.ColourTo(i - 1, state); + state = SCE_PL_BACKTICKS; + } else if (ch == '$') { + preferRE = false; + styler.ColourTo(i - 1, state); + if (isalnum(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { + state = SCE_PL_SCALAR; + } else if (chNext != '{' && chNext != '[') { + styler.ColourTo(i, SCE_PL_SCALAR); + i++; + ch = ' '; + chNext = ' '; + } else { + styler.ColourTo(i, SCE_PL_SCALAR); + } + } else if (ch == '@') { + preferRE = false; + styler.ColourTo(i - 1, state); + if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { + state = SCE_PL_ARRAY; + } else if (chNext != '{' && chNext != '[') { + styler.ColourTo(i, SCE_PL_ARRAY); + i++; + ch = ' '; + } else { + styler.ColourTo(i, SCE_PL_ARRAY); + } + } else if (ch == '%') { + preferRE = false; + styler.ColourTo(i - 1, state); + if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') { + state = SCE_PL_HASH; + } else if (chNext != '{' && chNext != '[') { + styler.ColourTo(i, SCE_PL_HASH); + i++; + ch = ' '; + } else { + styler.ColourTo(i, SCE_PL_HASH); + } + } else if (ch == '*') { + styler.ColourTo(i - 1, state); + state = SCE_PL_SYMBOLTABLE; + } else if (ch == '/' && preferRE) { + styler.ColourTo(i - 1, state); + state = SCE_PL_REGEX; + quoteUp = '/'; + quoteDown = '/'; + quotes = 1; + quoteRep = 1; + } else if (ch == '<' && chNext == '<') { + styler.ColourTo(i - 1, state); + state = SCE_PL_HERE; + i++; + ch = chNext; + chNext = chNext2; + quotes = 0; + sookedpos = 0; + sooked[sookedpos] = '\0'; + } else if (ch == '=' && isalpha(chNext)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_POD; + quotes = 0; + sookedpos = 0; + sooked[sookedpos] = '\0'; + } else if (isPerlOperator(ch)) { + if (ch == ')' || ch == ']') + preferRE = false; + else + preferRE = true; + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_PL_OPERATOR); + } + } else if (state == SCE_PL_WORD) { + if (!iswordchar(ch) && ch != '\'') { // Archaic Perl has quotes inside names + if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")) { + styler.ColourTo(i, SCE_PL_DATASECTION); + state = SCE_PL_DATASECTION; + } else if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__")) { + styler.ColourTo(i, SCE_PL_DATASECTION); + state = SCE_PL_DATASECTION; + } else { + if (classifyWordPerl(styler.GetStartSegment(), i - 1, keywords, styler) == SCE_PL_WORD) + preferRE = true; + state = SCE_PL_DEFAULT; + if (ch == '#') { + state = SCE_PL_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_PL_STRING; + } else if (ch == '\'') { + state = SCE_PL_CHARACTER; + } else if (ch == '<' && chNext == '<') { + state = SCE_PL_HERE; + quotes = 0; + sookedpos = 0; + sooked[sookedpos] = '\0'; + } else if (isPerlOperator(ch)) { + if (ch == ')' || ch == ']') + preferRE = false; + else + preferRE = true; + styler.ColourTo(i, SCE_PL_OPERATOR); + state = SCE_PL_DEFAULT; + } + } + } + } else { + if (state == SCE_PL_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_HERE) { + if (isalnum(ch) && quotes < 2) { + sooked[sookedpos++] = ch; + sooked[sookedpos] = '\0'; + if (quotes == 0) + quotes = 1; + } else { + quotes++; + } + + if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked)) { + styler.ColourTo(i + sookedpos - 1, SCE_PL_HERE); + state = SCE_PL_DEFAULT; + i += sookedpos; + chNext = ' '; + } + } else if (state == SCE_PL_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_PL_CHARACTER) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_PL_BACKTICKS) { + if (ch == '`') { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_PL_POD) { + if (ch == '=') { + if (isMatch(styler, lengthDoc, i, "=cut")) { + styler.ColourTo(i - 1 + 4, state); + i += 4; + state = SCE_PL_DEFAULT; + chNext = ' '; + ch = ' '; + } + } + } else if (state == SCE_PL_SCALAR) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_ARRAY) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_HASH) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_SYMBOLTABLE) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_REF) { + if (isEndVar(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PL_DEFAULT; + } + } else if (state == SCE_PL_REGEX) { + if (!quoteUp && !isspace(ch)) { + quoteUp = ch; + quoteDown = opposite(ch); + quotes++; + } else { + if (ch == quoteDown && chPrev != '\\') { + quotes--; + if (quotes == 0) { + quoteRep--; + if (quoteUp == quoteDown) { + quotes++; + } + } + if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + } else if (ch == quoteUp && chPrev != '\\') { + quotes++; + } else if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + } + } else if (state == SCE_PL_REGSUBST) { + if (!quoteUp && !isspace(ch)) { + quoteUp = ch; + quoteDown = opposite(ch); + quotes++; + } else { + if (ch == quoteDown && chPrev != '\\') { + quotes--; + if (quotes == 0) { + quoteRep--; + } + if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + if (quoteUp == quoteDown) { + quotes++; + } + } else if (ch == quoteUp && chPrev != '\\') { + quotes++; + } else if (!isalpha(chNext)) { + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + } + } + } else if (state == SCE_PL_LONGQUOTE) { + if (!quoteDown && !isspace(ch)) { + quoteUp = ch; + quoteDown = opposite(quoteUp); + quotes++; + } else if (ch == quoteDown) { + quotes--; + if (quotes == 0) { + quoteRep--; + if (quoteRep <= 0) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } + if (quoteUp == quoteDown) { + quotes++; + } + } + } else if (ch == quoteUp) { + quotes++; + } + } + + if (state == SCE_PL_DEFAULT) { // One of the above succeeded + if (ch == '#') { + state = SCE_PL_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_PL_STRING; + } else if (ch == '\'') { + state = SCE_PL_CHARACTER; + } else if (iswordstart(ch)) { + state = SCE_PL_WORD; + preferRE = false; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_PL_OPERATOR); + } + } + } + chPrev = ch; + } + styler.ColourTo(lengthDoc, state); +} + +LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc); diff --git a/src/stc/scintilla/src/LexPython.cxx b/src/stc/scintilla/src/LexPython.cxx new file mode 100644 index 0000000000..c6c5e6d342 --- /dev/null +++ b/src/stc/scintilla/src/LexPython.cxx @@ -0,0 +1,254 @@ +// SciTE - Scintilla based Text Editor +// LexPython.cxx - lexer for Python +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void classifyWordPy(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler, char *prevWord) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + char chAttr = SCE_P_IDENTIFIER; + if (0 == strcmp(prevWord, "class")) + chAttr = SCE_P_CLASSNAME; + else if (0 == strcmp(prevWord, "def")) + chAttr = SCE_P_DEFNAME; + else if (wordIsNumber) + chAttr = SCE_P_NUMBER; + else if (keywords.InList(s)) + chAttr = SCE_P_WORD; + styler.ColourTo(end, chAttr); + strcpy(prevWord, s); +} + +static bool IsPyComment(StylingContext &styler, int pos, int len) { + return len>0 && styler[pos]=='#'; +} + +static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], StylingContext &styler) { + + // Python uses a different mask because bad indentation is marked by oring with 32 + styler.StartAt(startPos, 127); + + WordList &keywords = *keywordlists[0]; + + //Platform::DebugPrintf("Python coloured\n"); + bool fold = styler.GetPropSet().GetInt("fold"); + int whingeLevel = styler.GetPropSet().GetInt("tab.timmy.whinge.level"); + char prevWord[200]; + prevWord[0] = '\0'; + if (length == 0) + return ; + int lineCurrent = styler.GetLine(startPos); + int spaceFlags = 0; + // TODO: Need to check previous line for indentation for both folding and bad indentation + int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); + + int state = initStyle & 31; + char chPrev = ' '; + char chPrev2 = ' '; + char chNext = styler[startPos]; + char chNext2 = styler[startPos]; + styler.StartSegment(startPos); + int lengthDoc = startPos + length; + bool atStartLine = true; + for (int i = startPos; i <= lengthDoc; i++) { + + if (atStartLine) { + if (whingeLevel == 1) { + styler.SetFlags((spaceFlags & wsInconsistent) ? 64 : 0, state); + } else if (whingeLevel == 2) { + styler.SetFlags((spaceFlags & wsSpaceTab) ? 64 : 0, state); + } else if (whingeLevel == 3) { + styler.SetFlags((spaceFlags & wsSpace) ? 64 : 0, state); + } else if (whingeLevel == 4) { + styler.SetFlags((spaceFlags & wsTab) ? 64 : 0, state); + } + atStartLine = false; + } + + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + chNext2 = styler.SafeGetCharAt(i + 2); + + if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { + if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) { + // Perform colourisation of white space and triple quoted strings at end of each line to allow + // tab marking to work inside white space and triple quoted strings + styler.ColourTo(i, state); + } + + int lev = indentCurrent; + int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsPyComment); + if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { + // Only non whitespace lines can be headers + if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { + // Line after is blank so check the next - maybe should continue further? + int spaceFlags2 = 0; + int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsPyComment); + if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + } + } + indentCurrent = indentNext; + if (fold) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + atStartLine = true; + } + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + chPrev2 = ' '; + i += 1; + continue; + } + + if (state == SCE_P_STRINGEOL) { + if (ch != '\r' && ch != '\n') { + styler.ColourTo(i - 1, state); + state = SCE_P_DEFAULT; + } + } + if (state == SCE_P_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_P_WORD; + } else if (ch == '#') { + styler.ColourTo(i - 1, state); + state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_P_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_STRING; + } + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_P_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_P_OPERATOR); + } + } else if (state == SCE_P_WORD) { + if (!iswordchar(ch)) { + classifyWordPy(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); + state = SCE_P_DEFAULT; + if (ch == '#') { + state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE; + } else if (ch == '\"') { + if (chNext == '\"' && chNext2 == '\"') { + i += 2; + state = SCE_P_TRIPLEDOUBLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_STRING; + } + } else if (ch == '\'') { + if (chNext == '\'' && chNext2 == '\'') { + i += 2; + state = SCE_P_TRIPLE; + ch = ' '; + chPrev = ' '; + chNext = styler.SafeGetCharAt(i + 1); + } else { + state = SCE_P_CHARACTER; + } + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_P_OPERATOR); + } + } + } else { + if (state == SCE_P_COMMENTLINE || state == SCE_P_COMMENTBLOCK) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_STRING) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i - 1, state); + state = SCE_P_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_CHARACTER) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i - 1, state); + state = SCE_P_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_TRIPLE) { + if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } else if (state == SCE_P_TRIPLEDOUBLE) { + if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { + styler.ColourTo(i, state); + state = SCE_P_DEFAULT; + } + } + } + chPrev2 = chPrev; + chPrev = ch; + } + if (state == SCE_P_WORD) { + classifyWordPy(styler.GetStartSegment(), lengthDoc, keywords, styler, prevWord); + } else { + styler.ColourTo(lengthDoc, state); + } +} + +LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc); diff --git a/src/stc/scintilla/src/LexSQL.cxx b/src/stc/scintilla/src/LexSQL.cxx new file mode 100644 index 0000000000..0f29c83074 --- /dev/null +++ b/src/stc/scintilla/src/LexSQL.cxx @@ -0,0 +1,158 @@ +// SciTE - Scintilla based Text Editor +// LexSQL.cxx - lexer for SQL +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = toupper(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_C_IDENTIFIER; + if (wordIsNumber) + chAttr = SCE_C_NUMBER; + else { + if (keywords.InList(s)) + chAttr = SCE_C_WORD; + } + styler.ColourTo(end, chAttr); +} + +static void ColouriseSQLDoc(unsigned int startPos, int length, + int initStyle, WordList *keywordlists[], StylingContext &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + bool fold = styler.GetPropSet().GetInt("fold"); + int lineCurrent = styler.GetLine(startPos); + int spaceFlags = 0; + int indentCurrent = 0; + + int state = initStyle; + char chPrev = ' '; + char chNext = styler[startPos]; + styler.StartSegment(startPos); + unsigned int lengthDoc = startPos + length; + bool prevCr = false; + for (unsigned int i = startPos; i <= lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); + int lev = indentCurrent; + if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { + // Only non whitespace lines can be headers + int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags); + if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + } + if (fold) { + styler.SetLevel(lineCurrent, lev); + } + } + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_C_WORD; + } else if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + state = SCE_C_COMMENT; + } else if (ch == '-' && chNext == '-') { + styler.ColourTo(i - 1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_C_STRING; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_C_OPERATOR); + } + } else if (state == SCE_C_WORD) { + if (!iswordchar(ch)) { + classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_C_DEFAULT; + if (ch == '/' && chNext == '*') { + state = SCE_C_COMMENT; + } else if (ch == '-' && chNext == '-') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\'') { + state = SCE_C_STRING; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + } + } + } else { + if (state == SCE_C_COMMENT) { + if (ch == '/' && chPrev == '*') { + if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) && + (styler.GetStartSegment() == startPos)))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + if (ch == '\'') { + if ( chNext == '\'' ) { + i++; + } else { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + } + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + if (state == SCE_C_DEFAULT) { // One of the above succeeded + if (ch == '/' && chNext == '*') { + state = SCE_C_COMMENT; + } else if (ch == '-' && chNext == '-') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\'') { + state = SCE_C_STRING; + } else if (iswordstart(ch)) { + state = SCE_C_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + } + } + } + chPrev = ch; + } + styler.ColourTo(lengthDoc - 1, state); +} + +LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc); diff --git a/src/stc/scintilla/src/LexVB.cxx b/src/stc/scintilla/src/LexVB.cxx new file mode 100644 index 0000000000..24f65d0fd9 --- /dev/null +++ b/src/stc/scintilla/src/LexVB.cxx @@ -0,0 +1,118 @@ +// SciTE - Scintilla based Text Editor +// LexVB.cxx - lexer for Visual Basic and VBScript +// Copyright 1998-2000 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { + + char s[100]; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = tolower(styler[start + i]); + s[i + 1] = '\0'; + } + char chAttr = SCE_C_DEFAULT; + if (wordIsNumber) + chAttr = SCE_C_NUMBER; + else { + if (keywords.InList(s)) { + chAttr = SCE_C_WORD; + if (strcmp(s, "rem") == 0) + chAttr = SCE_C_COMMENTLINE; + } + } + styler.ColourTo(end, chAttr); + if (chAttr == SCE_C_COMMENTLINE) + return SCE_C_COMMENTLINE; + else + return SCE_C_DEFAULT; +} + +static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], StylingContext &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + int state = initStyle; + char chNext = styler[startPos]; + styler.StartSegment(startPos); + int lengthDoc = startPos + length; + for (int i = startPos; i < lengthDoc; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + i += 1; + continue; + } + + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_C_WORD; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i - 1, state); + state = SCE_C_STRING; + } + } else if (state == SCE_C_WORD) { + if (!iswordchar(ch)) { + state = classifyWordVB(styler.GetStartSegment(), i - 1, keywords, styler); + if (state == SCE_C_DEFAULT) { + if (ch == '\'') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } + } + } + } else { + if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + // VB doubles quotes to preserve them + if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + if (state == SCE_C_DEFAULT) { // One of the above succeeded + if (ch == '\'') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (iswordstart(ch)) { + state = SCE_C_WORD; + } + } + } + } + styler.ColourTo(lengthDoc, state); +} + +LexerModule lmVB(SCLEX_VB, ColouriseVBDoc); diff --git a/src/stc/scintilla/src/PropSet.cxx b/src/stc/scintilla/src/PropSet.cxx index 7e2a906a47..8582105eac 100644 --- a/src/stc/scintilla/src/PropSet.cxx +++ b/src/stc/scintilla/src/PropSet.cxx @@ -27,6 +27,7 @@ bool EqualCaseInsensitive(const char *a, const char *b) { // Get a line of input. If end of line escaped with '\\' then continue reading. static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { bool continuation = true; + s[0] = '\0'; while ((len > 1) && lenData > 0) { char ch = *fpc; fpc++; @@ -46,6 +47,7 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { } else { continuation = false; *s++ = ch; + *s = '\0'; len--; } } @@ -253,6 +255,9 @@ void PropSet::ReadFromMemory(const char *data, int len) { if (isalpha(linebuf[0])) Set(linebuf); } + // If there is a final line: + if (isalpha(linebuf[0])) + Set(linebuf); } } diff --git a/src/stc/scintilla/src/SVector.h b/src/stc/scintilla/src/SVector.h index 49fc376dda..550dd87ebd 100644 --- a/src/stc/scintilla/src/SVector.h +++ b/src/stc/scintilla/src/SVector.h @@ -30,7 +30,7 @@ class SVector { return; } size = newSize; - for (int i=0; i len) { - if (newLen >= size) { - SizeTo(newLen); + void SetLength(unsigned int newLength) { + if (newLength > len) { + if (newLength >= size) { + SizeTo(newLength); } } - len = newLen; + len = newLength; } int Length() const { return len; diff --git a/src/stc/scintilla/src/ScintillaBase.cxx b/src/stc/scintilla/src/ScintillaBase.cxx index eb68904b79..21f9840444 100644 --- a/src/stc/scintilla/src/ScintillaBase.cxx +++ b/src/stc/scintilla/src/ScintillaBase.cxx @@ -276,15 +276,14 @@ void ScintillaBase::Colourise(int start, int end) { end = lengthDoc; int len = end - start; - PropSet props; - StylingContext styler(wMain.GetID(), props); int styleStart = 0; if (start > 0) styleStart = styler.StyleAt(start - 1); - - ColouriseDoc(pdoc->dbcsCodePage, start, len, styleStart, lexLanguage, keyWordLists, styler); + styler.SetCodePage(pdoc->dbcsCodePage); + + LexerModule::Colourise(start, len, styleStart, lexLanguage, keyWordLists, styler); styler.Flush(); } #endif diff --git a/src/stc/scintilla/src/Style.cxx b/src/stc/scintilla/src/Style.cxx index 56312314ff..4830233216 100644 --- a/src/stc/scintilla/src/Style.cxx +++ b/src/stc/scintilla/src/Style.cxx @@ -10,23 +10,31 @@ #include "Style.h" Style::Style() { - Clear(); + aliasOfDefaultFont = true; + Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), + Platform::DefaultFontSize(), 0, + false, false, false); } - + Style::~Style() { - font.Release(); + if (aliasOfDefaultFont) + font.SetID(0); + else + font.Release(); + aliasOfDefaultFont = false; } Style &Style::operator=(const Style &source) { if (this == &source) return *this; - Clear(); + Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), + 0, 0, + false, false, false); fore.desired = source.fore.desired; back.desired = source.back.desired; bold = source.bold; italic = source.italic; size = source.size; - strcpy(fontName, source.fontName); eolFilled = source.eolFilled; return *this; } @@ -38,18 +46,48 @@ void Style::Clear(Colour fore_, Colour back_, int size_, const char *fontName_, bold = bold_; italic = italic_; size = size_; - strcpy(fontName, fontName_); + fontName = fontName_; eolFilled = eolFilled_; - font.Release(); + if (aliasOfDefaultFont) + font.SetID(0); + else + font.Release(); + aliasOfDefaultFont = false; +} + +bool Style::EquivalentFontTo(const Style *other) const { + if (bold != other->bold || + italic != other->italic || + size != other->size) + return false; + if (fontName == other->fontName) + return true; + if (!fontName) + return false; + if (!other->fontName) + return false; + return strcmp(fontName, other->fontName) == 0; } -void Style::Realise(Surface &surface, int zoomLevel) { +void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle) { int sizeZoomed = size + zoomLevel; if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1 sizeZoomed = 2; - + + if (aliasOfDefaultFont) + font.SetID(0); + else + font.Release(); int deviceHeight = (sizeZoomed * surface.LogPixelsY()) / 72; - font.Create(fontName, deviceHeight, bold, italic); + aliasOfDefaultFont = defaultStyle && + (EquivalentFontTo(defaultStyle) || !fontName); + if (aliasOfDefaultFont) { + font.SetID(defaultStyle->font.GetID()); + } else if (fontName) { + font.Create(fontName, deviceHeight, bold, italic); + } else { + font.SetID(0); + } ascent = surface.Ascent(font); descent = surface.Descent(font); diff --git a/src/stc/scintilla/src/Style.h b/src/stc/scintilla/src/Style.h index 916b646315..a610ff8ba6 100644 --- a/src/stc/scintilla/src/Style.h +++ b/src/stc/scintilla/src/Style.h @@ -10,10 +10,11 @@ class Style { public: ColourPair fore; ColourPair back; + bool aliasOfDefaultFont; bool bold; bool italic; int size; - char fontName[100]; + const char *fontName; bool eolFilled; Font font; @@ -27,11 +28,12 @@ public: Style(); ~Style(); Style &operator=(const Style &source); - void Clear(Colour fore_=Colour(0,0,0), Colour back_=Colour(0xff,0xff,0xff), - int size_=Platform::DefaultFontSize(), - const char *fontName_=Platform::DefaultFont(), - bool bold_=false, bool italic_=false, bool eolFilled_=false); - void Realise(Surface &surface, int zoomLevel); + void Clear(Colour fore_, Colour back_, + int size_, + const char *fontName_, + bool bold_, bool italic_, bool eolFilled_); + bool EquivalentFontTo(const Style *other) const; + void Realise(Surface &surface, int zoomLevel, Style *defaultStyle=0); }; #endif diff --git a/src/stc/scintilla/src/ViewStyle.cxx b/src/stc/scintilla/src/ViewStyle.cxx index 001ecdb319..2188fd03f7 100644 --- a/src/stc/scintilla/src/ViewStyle.cxx +++ b/src/stc/scintilla/src/ViewStyle.cxx @@ -17,14 +17,46 @@ MarginStyle::MarginStyle() : symbol(false), width(16), mask(0xffffffff), sensitive(false) { } +// A list of the fontnames - avoids wasting space in each style +FontNames::FontNames() { + max = 0; +} + +FontNames::~FontNames() { + Clear(); +} + +void FontNames::Clear() { + for (int i=0;i + #include "wx/stc/stc.h" #include "ScintillaWX.h" #include +// The following code forces a reference to all of the Scintilla lexers. +// If we don't do something like this, then the linker tends to "optimize" +// them away. (eric@sourcegear.com) + +int wxForceScintillaLexers(void) +{ + extern LexerModule lmCPP; + extern LexerModule lmHTML; + extern LexerModule lmXML; + extern LexerModule lmProps; + extern LexerModule lmErrorList; + extern LexerModule lmMake; + extern LexerModule lmBatch; + extern LexerModule lmPerl; + extern LexerModule lmPython; + extern LexerModule lmSQL; + extern LexerModule lmVB; + + if ( + &lmCPP + && &lmHTML + && &lmXML + && &lmProps + && &lmErrorList + && &lmMake + && &lmBatch + && &lmPerl + && &lmPython + && &lmSQL + && &lmVB + ) + { + return 1; + } + else + { + return 0; + } +} + //---------------------------------------------------------------------- const wxChar* wxSTCNameStr = "stcwindow"; -- 2.45.2