From d134f1702e983b6588c5783b10a401e8bdb69314 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Fri, 8 Sep 2000 04:06:33 +0000 Subject: [PATCH] Moved from Scintilla version 1.25 to 1.32 Still more changes to be made in the wxSTC wrappers for new functionality... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8293 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/include/wx/stc/stc.h | 4 - contrib/src/stc/Makefile.in | 2 + contrib/src/stc/PlatWX.cpp | 19 + contrib/src/stc/ScintillaWX.cpp | 39 +- contrib/src/stc/ScintillaWX.h | 8 +- contrib/src/stc/makefile.b32 | 2 + contrib/src/stc/makefile.g95 | 2 + contrib/src/stc/makefile.vc | 2 + contrib/src/stc/scintilla/README.txt | 3 +- contrib/src/stc/scintilla/include/Platform.h | 36 +- contrib/src/stc/scintilla/include/PosRegExp.h | 138 ++ contrib/src/stc/scintilla/include/PropSet.h | 164 ++- contrib/src/stc/scintilla/include/SciLexer.h | 57 +- contrib/src/stc/scintilla/include/Scintilla.h | 760 +++++----- .../src/stc/scintilla/include/Scintilla.iface | 446 +++++- .../stc/scintilla/include/ScintillaWidget.h | 46 + contrib/src/stc/scintilla/include/WinDefs.h | 37 +- .../stc/scintilla/include/WindowAccessor.h | 2 +- contrib/src/stc/scintilla/src/Accessor.cxx | 112 -- .../src/stc/scintilla/src/AutoComplete.cxx | 32 +- contrib/src/stc/scintilla/src/AutoComplete.h | 11 +- contrib/src/stc/scintilla/src/CellBuffer.cxx | 132 +- contrib/src/stc/scintilla/src/CellBuffer.h | 10 +- .../stc/scintilla/src/ContractionState.cxx | 12 +- .../src/stc/scintilla/src/ContractionState.h | 4 +- contrib/src/stc/scintilla/src/Document.cxx | 71 +- contrib/src/stc/scintilla/src/Document.h | 13 +- .../stc/scintilla/src/DocumentAccessor.cxx | 14 +- .../src/stc/scintilla/src/DocumentAccessor.h | 2 +- contrib/src/stc/scintilla/src/Editor.cxx | 1163 +++++++++------ contrib/src/stc/scintilla/src/Editor.h | 44 +- contrib/src/stc/scintilla/src/KeyMap.cxx | 96 +- contrib/src/stc/scintilla/src/KeyMap.h | 12 +- contrib/src/stc/scintilla/src/LexCPP.cxx | 100 +- contrib/src/stc/scintilla/src/LexHTML.cxx | 1284 +++++++++-------- contrib/src/stc/scintilla/src/LexLua.cxx | 298 ++++ contrib/src/stc/scintilla/src/LexOthers.cxx | 65 +- contrib/src/stc/scintilla/src/LexPerl.cxx | 48 +- contrib/src/stc/scintilla/src/LexPython.cxx | 7 + contrib/src/stc/scintilla/src/LexVB.cxx | 47 +- contrib/src/stc/scintilla/src/PosRegExp.cxx | 1181 +++++++++++++++ contrib/src/stc/scintilla/src/PropSet.cxx | 628 ++++++-- contrib/src/stc/scintilla/src/SVector.h | 21 +- .../src/stc/scintilla/src/ScintillaBase.cxx | 166 ++- contrib/src/stc/scintilla/src/ScintillaBase.h | 8 +- contrib/src/stc/scintilla/src/Style.cxx | 11 +- contrib/src/stc/scintilla/src/Style.h | 3 +- contrib/src/stc/scintilla/src/ViewStyle.cxx | 14 +- contrib/src/stc/scintilla/src/ViewStyle.h | 6 +- .../src/stc/scintilla/src/WindowAccessor.cxx | 28 +- contrib/src/stc/stc.cpp | 148 +- include/wx/stc/stc.h | 4 - src/stc/Makefile.in | 2 + src/stc/PlatWX.cpp | 19 + src/stc/ScintillaWX.cpp | 39 +- src/stc/ScintillaWX.h | 8 +- src/stc/makefile.b32 | 2 + src/stc/makefile.g95 | 2 + src/stc/makefile.vc | 2 + src/stc/scintilla/README.txt | 3 +- src/stc/scintilla/include/Platform.h | 36 +- src/stc/scintilla/include/PosRegExp.h | 138 ++ src/stc/scintilla/include/PropSet.h | 164 ++- src/stc/scintilla/include/SciLexer.h | 57 +- src/stc/scintilla/include/Scintilla.h | 760 +++++----- src/stc/scintilla/include/Scintilla.iface | 446 +++++- src/stc/scintilla/include/ScintillaWidget.h | 46 + src/stc/scintilla/include/WinDefs.h | 37 +- src/stc/scintilla/include/WindowAccessor.h | 2 +- src/stc/scintilla/src/Accessor.cxx | 112 -- src/stc/scintilla/src/AutoComplete.cxx | 32 +- src/stc/scintilla/src/AutoComplete.h | 11 +- src/stc/scintilla/src/CellBuffer.cxx | 132 +- src/stc/scintilla/src/CellBuffer.h | 10 +- src/stc/scintilla/src/ContractionState.cxx | 12 +- src/stc/scintilla/src/ContractionState.h | 4 +- src/stc/scintilla/src/Document.cxx | 71 +- src/stc/scintilla/src/Document.h | 13 +- src/stc/scintilla/src/DocumentAccessor.cxx | 14 +- src/stc/scintilla/src/DocumentAccessor.h | 2 +- src/stc/scintilla/src/Editor.cxx | 1163 +++++++++------ src/stc/scintilla/src/Editor.h | 44 +- src/stc/scintilla/src/KeyMap.cxx | 96 +- src/stc/scintilla/src/KeyMap.h | 12 +- src/stc/scintilla/src/LexCPP.cxx | 100 +- src/stc/scintilla/src/LexHTML.cxx | 1284 +++++++++-------- src/stc/scintilla/src/LexLua.cxx | 298 ++++ src/stc/scintilla/src/LexOthers.cxx | 65 +- src/stc/scintilla/src/LexPerl.cxx | 48 +- src/stc/scintilla/src/LexPython.cxx | 7 + src/stc/scintilla/src/LexVB.cxx | 47 +- src/stc/scintilla/src/PosRegExp.cxx | 1181 +++++++++++++++ src/stc/scintilla/src/PropSet.cxx | 628 ++++++-- src/stc/scintilla/src/SVector.h | 21 +- src/stc/scintilla/src/ScintillaBase.cxx | 166 ++- src/stc/scintilla/src/ScintillaBase.h | 8 +- src/stc/scintilla/src/Style.cxx | 11 +- src/stc/scintilla/src/Style.h | 3 +- src/stc/scintilla/src/ViewStyle.cxx | 14 +- src/stc/scintilla/src/ViewStyle.h | 6 +- src/stc/scintilla/src/WindowAccessor.cxx | 28 +- src/stc/stc.cpp | 148 +- 102 files changed, 10648 insertions(+), 4468 deletions(-) create mode 100644 contrib/src/stc/scintilla/include/PosRegExp.h create mode 100644 contrib/src/stc/scintilla/include/ScintillaWidget.h delete mode 100644 contrib/src/stc/scintilla/src/Accessor.cxx create mode 100644 contrib/src/stc/scintilla/src/LexLua.cxx create mode 100644 contrib/src/stc/scintilla/src/PosRegExp.cxx create mode 100644 src/stc/scintilla/include/PosRegExp.h create mode 100644 src/stc/scintilla/include/ScintillaWidget.h delete mode 100644 src/stc/scintilla/src/Accessor.cxx create mode 100644 src/stc/scintilla/src/LexLua.cxx create mode 100644 src/stc/scintilla/src/PosRegExp.cxx diff --git a/contrib/include/wx/stc/stc.h b/contrib/include/wx/stc/stc.h index d5925f19be..659e6f2745 100644 --- a/contrib/include/wx/stc/stc.h +++ b/contrib/include/wx/stc/stc.h @@ -254,10 +254,8 @@ public: int GetFirstVisibleLine(); bool GetModified(); int GetLineCount(); - wxRect GetRect(); int GetLineFromPos(int pos); int GetLineStartPos(int line); - int GetLineLengthAtPos(int pos); int GetLineLength(int line); #ifdef SWIG wxString GetCurrentLineText(int* OUTPUT); @@ -266,7 +264,6 @@ public: #endif int GetCurrentLine(); int PositionFromPoint(wxPoint pt); - int LineFromPoint(wxPoint pt); wxPoint PointFromPosition(int pos); int GetCurrentPos(); int GetAnchor(); @@ -283,7 +280,6 @@ public: void ScrollToColumn(int column); void EnsureCaretVisible(); void SetCaretPolicy(int policy, int slop=0); - int GetSelectionType(); int GetLinesOnScreen(); bool IsSelectionRectangle(); void SetUseHorizontalScrollBar(bool use); diff --git a/contrib/src/stc/Makefile.in b/contrib/src/stc/Makefile.in index 73170e98e2..9f1ebcf396 100644 --- a/contrib/src/stc/Makefile.in +++ b/contrib/src/stc/Makefile.in @@ -26,6 +26,7 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ DocumentAccessor.o \ LexCPP.o \ LexHTML.o \ + LexLua.o \ LexOthers.o \ LexPerl.o \ LexPython.o \ @@ -47,6 +48,7 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ ScintillaBase.o \ Style.o \ ViewStyle.o \ + PosRegExp.o \ APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/contrib/include diff --git a/contrib/src/stc/PlatWX.cpp b/contrib/src/stc/PlatWX.cpp index 2bb9ba84eb..63b363ec0e 100644 --- a/contrib/src/stc/PlatWX.cpp +++ b/contrib/src/stc/PlatWX.cpp @@ -458,6 +458,25 @@ void ListBox::Create(Window &parent, int ctrlID) { 0, NULL, wxLB_SINGLE | wxLB_SORT); } +PRectangle ListBox::GetDesiredRect() { + wxSize sz = ((wxListBox*)id)->GetBestSize(); + PRectangle rc; + rc.top = 0; + rc.left = 0; + rc.right = sz.x; + rc.bottom = sz.y; + + return rc; +} + +void ListBox::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + +void ListBox::SetFont(Font &font) { + Window::SetFont(font); +} + void ListBox::Clear() { ((wxListBox*)id)->Clear(); } diff --git a/contrib/src/stc/ScintillaWX.cpp b/contrib/src/stc/ScintillaWX.cpp index 56ac221558..41444aed2d 100644 --- a/contrib/src/stc/ScintillaWX.cpp +++ b/contrib/src/stc/ScintillaWX.cpp @@ -283,18 +283,18 @@ void ScintillaWX::ClaimSelection() { } -LRESULT ScintillaWX::DefWndProc(UINT /*iMessage*/, WPARAM /*wParam*/, LPARAM /*lParam*/) { +long ScintillaWX::DefWndProc(unsigned int /*iMessage*/, unsigned long /*wParam*/, long /*lParam*/) { return 0; } -LRESULT ScintillaWX::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { - switch (iMessage) { - case EM_CANPASTE: - return CanPaste(); - default: +long ScintillaWX::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { +// switch (iMessage) { +// case EM_CANPASTE: +// return CanPaste(); +// default: return ScintillaBase::WndProc(iMessage, wParam, lParam); - } - return 0; +// } +// return 0; } @@ -415,6 +415,29 @@ void ScintillaWX::DoAddChar(char ch) { } int ScintillaWX::DoKeyDown(int key, bool shift, bool ctrl, bool alt) { + switch (key) { + case WXK_DOWN: key = SCK_DOWN; break; + case WXK_UP: key = SCK_UP; break; + case WXK_LEFT: key = SCK_LEFT; break; + case WXK_RIGHT: key = SCK_RIGHT; break; + case WXK_HOME: key = SCK_HOME; break; + case WXK_END: key = SCK_END; break; + case WXK_PRIOR: key = SCK_PRIOR; break; + case WXK_NEXT: key = SCK_NEXT; break; + case WXK_DELETE: key = SCK_DELETE; break; + case WXK_INSERT: key = SCK_INSERT; break; + case WXK_ESCAPE: key = SCK_ESCAPE; break; + case WXK_BACK: key = SCK_BACK; break; + case WXK_TAB: key = SCK_TAB; break; + case WXK_RETURN: key = SCK_RETURN; break; + case WXK_ADD: key = SCK_ADD; break; + case WXK_SUBTRACT: key = SCK_SUBTRACT; break; + case WXK_DIVIDE: key = SCK_DIVIDE; break; + case WXK_CONTROL: key = 0; break; + case WXK_ALT: key = 0; break; + case WXK_SHIFT: key = 0; break; + } + return KeyDown(key, shift, ctrl, alt); } diff --git a/contrib/src/stc/ScintillaWX.h b/contrib/src/stc/ScintillaWX.h index c2087c9682..b773eac3a9 100644 --- a/contrib/src/stc/ScintillaWX.h +++ b/contrib/src/stc/ScintillaWX.h @@ -97,8 +97,12 @@ public: virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual void ClaimSelection(); - virtual LRESULT DefWndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); - virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); + virtual long DefWndProc(unsigned int iMessage, + unsigned long wParam, + long lParam); + virtual long WndProc(unsigned int iMessage, + unsigned long wParam, + long lParam); virtual void NotifyChange(); virtual void NotifyParent(SCNotification scn); diff --git a/contrib/src/stc/makefile.b32 b/contrib/src/stc/makefile.b32 index 6f5703b7dc..0d86478b7c 100644 --- a/contrib/src/stc/makefile.b32 +++ b/contrib/src/stc/makefile.b32 @@ -34,6 +34,7 @@ OBJECTS = \ KeyWords.obj \ LexCPP.obj \ LexHTML.obj \ + LexLua.obj \ LexOthers.obj \ LexPerl.obj \ LexPython.obj \ @@ -41,6 +42,7 @@ OBJECTS = \ LexVB.obj \ LineMarker.obj \ PropSet.obj \ + PosRegExp.obj \ ScintillaBase.obj \ Style.obj \ UniConversion.obj \ diff --git a/contrib/src/stc/makefile.g95 b/contrib/src/stc/makefile.g95 index 640501e22a..5b0cc02089 100644 --- a/contrib/src/stc/makefile.g95 +++ b/contrib/src/stc/makefile.g95 @@ -27,6 +27,7 @@ OBJECTS = \ $(S)/ViewStyle.$(OBJSUFF) \ $(S)/LexCPP.$(OBJSUFF) \ $(S)/LexHTML.$(OBJSUFF) \ + $(S)/LexLua.$(OBJSUFF) \ $(S)/LexOthers.$(OBJSUFF) \ $(S)/LexPerl.$(OBJSUFF) \ $(S)/LexPython.$(OBJSUFF) \ @@ -35,6 +36,7 @@ OBJECTS = \ $(S)/DocumentAccessor.$(OBJSUFF)\ $(S)/UniConversion.$(OBJSUFF) \ $(S)/WindowAccessor.$(OBJSUFF) \ + $(S)/PosRegExp.$(OBJSUFF) \ PlatWX.$(OBJSUFF) \ ScintillaWX.$(OBJSUFF) \ stc.$(OBJSUFF) diff --git a/contrib/src/stc/makefile.vc b/contrib/src/stc/makefile.vc index f7358c3e73..c101bba3f1 100644 --- a/contrib/src/stc/makefile.vc +++ b/contrib/src/stc/makefile.vc @@ -27,12 +27,14 @@ OBJECTS = \ $(D)\KeyWords.obj \ $(D)\LexCPP.obj \ $(D)\LexHTML.obj \ + $(D)\LexLua.obj \ $(D)\LexOthers.obj \ $(D)\LexPerl.obj \ $(D)\LexPython.obj \ $(D)\LexSQL.obj \ $(D)\LexVB.obj \ $(D)\LineMarker.obj \ + $(D)\PosRegExp.obj \ $(D)\PropSet.obj \ $(D)\ScintillaBase.obj \ $(D)\Style.obj \ diff --git a/contrib/src/stc/scintilla/README.txt b/contrib/src/stc/scintilla/README.txt index 409b44c3c2..b88d57495c 100644 --- a/contrib/src/stc/scintilla/README.txt +++ b/contrib/src/stc/scintilla/README.txt @@ -3,6 +3,5 @@ scintilla/include directories from the Scintilla/SCiTE source distribution. All other code needed to implement Scintilla on top of wxWindows is located in the directory above this one. -The current version of the Scintilla code is 1.25+ (from their CVS on -5-19-2000). +The current version of the Scintilla code is 1.32 diff --git a/contrib/src/stc/scintilla/include/Platform.h b/contrib/src/stc/scintilla/include/Platform.h index 5a87c64feb..de9cf202a1 100644 --- a/contrib/src/stc/scintilla/include/Platform.h +++ b/contrib/src/stc/scintilla/include/Platform.h @@ -80,12 +80,6 @@ typedef wxWindow* WindowID; typedef wxMenu* MenuID; #endif -#if PLAT_GTK || PLAT_WX -#define SHIFT_PRESSED 1 -#define LEFT_CTRL_PRESSED 2 -#define LEFT_ALT_PRESSED 4 -#endif - // Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably class Point { @@ -199,6 +193,7 @@ public: }; class Font { +protected: FontID id; #if PLAT_WX int ascent; @@ -208,10 +203,10 @@ class Font { Font &operator=(const Font &) { id=0; return *this; } public: Font(); - ~Font(); + virtual ~Font(); - void Create(const char *faceName, int characterSet, int size, bool bold, bool italic); - void Release(); + virtual void Create(const char *faceName, int characterSet, int size, bool bold, bool italic); + virtual void Release(); FontID GetID() { return id; } // Alias another font - caller guarantees not to Release @@ -327,7 +322,7 @@ public: void Show(bool show=true); void InvalidateAll(); void InvalidateRectangle(PRectangle rc); - void SetFont(Font &font); + virtual void SetFont(Font &font); enum Cursor { cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow }; void SetCursor(Cursor curs); void SetTitle(const char *s); @@ -344,14 +339,17 @@ class ListBox : public Window { WindowID scroller; int current; #endif + int desiredVisibleRows; + unsigned int maxItemCharacters; + unsigned int aveCharWidth; public: ListBox(); virtual ~ListBox(); - ListBox &operator=(WindowID id_) { - id = id_; - return *this; - } void Create(Window &parent, int ctrlID); + virtual void SetFont(Font &font); + void SetAverageCharWidth(int width); + void SetVisibleRows(int rows); + PRectangle GetDesiredRect(); void Clear(); void Append(char *s); int Length(); @@ -396,6 +394,16 @@ public: // These are utility functions not really tied to a platform static int Minimum(int a, int b); static int Maximum(int a, int b); + // Next three assume 16 bit shorts and 32 bit longs + static long LongFromTwoShorts(short a,short b) { + return (a) | ((b) << 16); + } + static short HighShortFromLong(long x) { + return static_cast(x >> 16); + } + static short LowShortFromLong(long x) { + return static_cast(x & 0xffff); + } static void DebugPrintf(const char *format, ...); static int Clamp(int val, int minVal, int maxVal); }; diff --git a/contrib/src/stc/scintilla/include/PosRegExp.h b/contrib/src/stc/scintilla/include/PosRegExp.h new file mode 100644 index 0000000000..b915b1ed49 --- /dev/null +++ b/contrib/src/stc/scintilla/include/PosRegExp.h @@ -0,0 +1,138 @@ +#ifndef POSREGEXP_H +#define POSREGEXP_H + +#define MatchesNum 0x10 + +enum EOps +{ + ReBlockOps = 0x1000, + ReMul, // * + RePlus, // + + ReQuest, // ? + ReNGMul, // *? + ReNGPlus, // +? + ReNGQuest, // ?? + ReRangeN, // {n,} + ReRangeNM, // {n,m} + ReNGRangeN, // {n,}? + ReNGRangeNM, // {n,m}? + ReOr, // | + ReBehind = 0x1100, // ?#n + ReNBehind = 0x1200, // ?~n + ReAhead = 0x1300, // ?= + ReNAhead = 0x1400, // ?! + + ReSymbolOps = 0x2000, + ReEmpty, + ReSymb, // a b \W \s ... + ReEnum, // [] + ReNEnum, // [^] + ReBrackets, // (...) + ReBkTrace = 0x2100, // \yN + ReBkBrack = 0x2200 // \N +}; + +enum ESymbols +{ + ReAnyChr = 0x4000, // . + ReSoL, // ^ + ReEoL, // $ + ReDigit, // \d + ReNDigit, // \D + ReWordSymb, // \w + ReNWordSymb, // \W + ReWSpace, // \s + ReNWSpace, // \S + ReUCase, // \u + ReNUCase , // \l + ReWBound, // \b + ReNWBound, // \B + RePreNW, // \c + ReStart, // \m + ReEnd, // \M + + ReChr = 0x0 // Char in Lower Byte +}; +enum ETempSymb +{ + ReTemp = 0x7000, + ReLBrack, ReRBrack, + ReEnumS, ReEnumE, ReNEnumS, + ReRangeS, ReRangeE, ReNGRangeE, ReFrToEnum +}; + +#define BackSlash '\\' + +typedef union SCharData +{ + int IArr[8]; + char CArr[32]; + void SetBit(unsigned char Bit); + void ClearBit(unsigned char Bit); + bool GetBit(unsigned char Bit); +} *PCharData; + +typedef struct SRegInfo +{ + SRegInfo(); + ~SRegInfo(); + + EOps Op; + union{ + SRegInfo *Param; + int Symb; + PCharData ChrClass; + }un; + int s,e; + SRegInfo *Parent; + SRegInfo *Next; +} *PRegInfo; + +typedef struct SMatches +{ + int s[MatchesNum]; + int e[MatchesNum]; + int CurMatch; +} *PMatches; + +typedef class PosRegExp +{ + PRegInfo Info; + PMatches BkTrace; + bool NoCase,Extend,NoMoves; + bool Error; + int *Exprn; + int posParse; + int posEnd,posStart; + int posBkStr; + int FirstChar; + + bool SetExprLow(const char *Expr); + bool SetStructs(PRegInfo &Info,int st,int end); + void Optimize(); + bool CheckSymb(int Symb,bool Inc); + bool LowParse(PRegInfo Re); + bool LowParseRe(PRegInfo &Next); + bool LowCheckNext(PRegInfo Re); + bool ParseRe(int posStr); + bool QuickCheck(); +public: + PMatches Matches; + int Ok, CurMatch; + + void *param; + char (*CharAt)(int pos, void *param); + + PosRegExp(); + ~PosRegExp(); + + bool isok(); + bool SetNoMoves(bool Moves); + bool SetBkTrace(int posStr,PMatches Trace); + bool SetExpr(const char *Expr); + bool Parse(int posStr, int posStop, PMatches Mtch); + bool Parse(int posStr,int posSol, int posEol, PMatches Mtch, int Moves = -1); + bool Evaluate(char *Expr, int posStr, PMatches Mtch, char **Res); +} *PPosRegExp; + +#endif /* POSREGEXP_H */ diff --git a/contrib/src/stc/scintilla/include/PropSet.h b/contrib/src/stc/scintilla/include/PropSet.h index bc1599f38a..025174f8ab 100644 --- a/contrib/src/stc/scintilla/include/PropSet.h +++ b/contrib/src/stc/scintilla/include/PropSet.h @@ -8,44 +8,92 @@ bool EqualCaseInsensitive(const char *a, const char *b); +#if PLAT_WIN +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +#ifdef __WXMSW__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + // Define another string class. // While it would be 'better' to use std::string, that doubles the executable size. -inline char *StringDup(const char *s) { +inline char *StringDup(const char *s, int len=-1) { if (!s) return 0; - char *sNew = new char[strlen(s) + 1]; - if (sNew) - strcpy(sNew, s); + if (len == -1) + len = strlen(s); + char *sNew = new char[len + 1]; + if (sNew) { + strncpy(sNew, s, len); + sNew[len] = '\0'; + } return sNew; } class SString { char *s; + int ssize; public: + typedef const char* const_iterator; + typedef int size_type; + static size_type npos; + const char* begin(void) const { + return s; + } + const char* end(void) const { + return &s[ssize]; + } + size_type size(void) const { + if (s) + return ssize; + else + return 0; + } + SString &assign(const char* sother, int size_ = -1) { + char *t = s; + s = StringDup(sother,size_); + ssize = (s) ? strlen(s) : 0; + delete []t; + return *this; + } + SString &assign(const SString& sother, int size_ = -1) { + return assign(sother.s,size_); + } + SString &assign(const_iterator ibeg, const_iterator iend) { + return assign(ibeg,iend - ibeg); + } SString() { s = 0; + ssize = 0; } SString(const SString &source) { s = StringDup(source.s); + ssize = (s) ? strlen(s) : 0; } SString(const char *s_) { s = StringDup(s_); + ssize = (s) ? strlen(s) : 0; } SString(int i) { char number[100]; sprintf(number, "%0d", i); - //itoa(i, number, 10); s = StringDup(number); + ssize = (s) ? strlen(s) : 0; } ~SString() { delete []s; s = 0; + ssize = 0; } SString &operator=(const SString &source) { if (this != &source) { delete []s; s = StringDup(source.s); + ssize = (s) ? strlen(s) : 0; } return *this; } @@ -56,6 +104,9 @@ public: return false; return strcmp(s, other.s) == 0; } + bool operator!=(const SString &other) const { + return !operator==(other); + } bool operator==(const char *sother) const { if ((s == 0) && (sother == 0)) return true; @@ -63,6 +114,9 @@ public: return false; return strcmp(s, sother) == 0; } + bool operator!=(const char *sother) const { + return !operator==(sother); + } const char *c_str() const { if (s) return s; @@ -82,99 +136,109 @@ public: return '\0'; } SString &operator +=(const char *sother) { + return append(sother,-1); + } + SString &operator +=(const SString &sother) { + return append(sother.s,sother.ssize); + } + SString &operator +=(char ch) { + return append(&ch,1); + } + SString &append(const char* sother, int lenOther) { int len = length(); - int lenOther = strlen(sother); + if(lenOther < 0) + lenOther = strlen(sother); char *sNew = new char[len + lenOther + 1]; if (sNew) { if (s) memcpy(sNew, s, len); - memcpy(sNew + len, sother, lenOther); + strncpy(&sNew[len], sother, lenOther); sNew[len + lenOther] = '\0'; delete []s; s = sNew; + ssize = (s) ? strlen(s) : 0; } return *this; } int value() const { if (s) return atoi(s); - else + else return 0; } + void substitute(char find, char replace) { + char *t = s; + while (t) { + t = strchr(t, find); + if (t) + *t = replace; + } + } + // I don't think this really belongs here -- Neil + void correctPath() { +#ifdef unix + substitute('\\', '/'); +#else + substitute('/', '\\'); +#endif + } +}; + +struct Property { + unsigned int hash; + char *key; + char *val; + Property *next; + Property() : hash(0), key(0), val(0), next(0) {} }; class PropSet { private: - char **vals; - int size; - int used; + enum { hashRoots=31 }; + Property *props[hashRoots]; public: PropSet *superPS; PropSet(); ~PropSet(); - void EnsureCanAddEntry(); void Set(const char *key, const char *val); void Set(char *keyval); SString Get(const char *key); + SString GetExpanded(const char *key); + SString Expand(const char *withvars); int GetInt(const char *key, int defaultValue=0); SString GetWild(const char *keybase, const char *filename); SString GetNewExpand(const char *keybase, const char *filename); void Clear(); - void ReadFromMemory(const char *data, int len); - void Read(const char *filename); -}; - -// This is a fixed length list of strings suitable for display in combo boxes -// as a memory of user entries -template -class EntryMemory { - SString entries[sz]; -public: - void Insert(SString s) { - for (int i=0;i0;j--) { - entries[j] = entries[j-1]; - } - entries[0] = s; - return; - } - } - for (int k=sz-1;k>0;k--) { - entries[k] = entries[k-1]; - } - entries[0] = s; - } - int Length() const { - int len = 0; - for (int i=0;i?@[\\]^`{|}~", ch) != NULL; +} + #endif diff --git a/contrib/src/stc/scintilla/include/SciLexer.h b/contrib/src/stc/scintilla/include/SciLexer.h index d869758f61..69402ab9ab 100644 --- a/contrib/src/stc/scintilla/include/SciLexer.h +++ b/contrib/src/stc/scintilla/include/SciLexer.h @@ -3,11 +3,15 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +// Most of this file is automatically generated from the Scintilla.iface interface definition +// file which contains any comments about the definitions. HFacer.py does the generation. + #ifndef SCILEXER_H #define SCILEXER_H // SciLexer features - not in standard Scintilla +//++Autogenerated -- start of section automatically generated from Scintilla.iface #define SCLEX_CONTAINER 0 #define SCLEX_NULL 1 #define SCLEX_PYTHON 2 @@ -23,8 +27,8 @@ #define SCLEX_BATCH 12 #define SCLEX_XCODE 13 #define SCLEX_LATEX 14 - -// Lexical states for SCLEX_PYTHON +#define SCLEX_LUA 15 +#define SCLEX_DIFF 16 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 #define SCE_P_NUMBER 2 @@ -39,8 +43,6 @@ #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 #define SCE_C_COMMENT 1 #define SCE_C_COMMENTLINE 2 @@ -54,8 +56,7 @@ #define SCE_C_OPERATOR 10 #define SCE_C_IDENTIFIER 11 #define SCE_C_STRINGEOL 12 - -// Lexical states for SCLEX_HTML, SCLEX_xML +#define SCE_C_VERBATIM 13 #define SCE_H_DEFAULT 0 #define SCE_H_TAG 1 #define SCE_H_TAGUNKNOWN 2 @@ -67,14 +68,15 @@ #define SCE_H_OTHER 8 #define SCE_H_COMMENT 9 #define SCE_H_ENTITY 10 -// XML and ASP #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_H_CDATA 17 +#define SCE_H_QUESTION 18 +#define SCE_H_VALUE 19 #define SCE_HJ_START 40 #define SCE_HJ_DEFAULT 41 #define SCE_HJ_COMMENT 42 @@ -87,7 +89,6 @@ #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 @@ -100,7 +101,6 @@ #define SCE_HJA_SINGLESTRING 64 #define SCE_HJA_SYMBOLS 65 #define SCE_HJA_STRINGEOL 66 -// Embedded VBScript #define SCE_HB_START 70 #define SCE_HB_DEFAULT 71 #define SCE_HB_COMMENTLINE 72 @@ -109,7 +109,6 @@ #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 @@ -118,7 +117,6 @@ #define SCE_HBA_STRING 85 #define SCE_HBA_IDENTIFIER 86 #define SCE_HBA_STRINGEOL 87 -// Embedded Python #define SCE_HP_START 90 #define SCE_HP_DEFAULT 91 #define SCE_HP_COMMENTLINE 92 @@ -132,7 +130,6 @@ #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 @@ -146,8 +143,15 @@ #define SCE_HPA_DEFNAME 115 #define SCE_HPA_OPERATOR 116 #define SCE_HPA_IDENTIFIER 117 - -// Lexical states for SCLEX_PERL +#define SCE_HPHP_DEFAULT 118 +#define SCE_HPHP_HSTRING 119 +#define SCE_HPHP_SIMPLESTRING 120 +#define SCE_HPHP_WORD 121 +#define SCE_HPHP_NUMBER 122 +#define SCE_HPHP_VARIABLE 123 +#define SCE_HPHP_COMMENT 124 +#define SCE_HPHP_COMMENTLINE 125 +#define SCE_HPHP_STRINGEOL 126 #define SCE_PL_DEFAULT 0 #define SCE_PL_HERE 1 #define SCE_PL_COMMENTLINE 2 @@ -170,12 +174,31 @@ #define SCE_PL_LONGQUOTE 19 #define SCE_PL_BACKTICKS 20 #define SCE_PL_DATASECTION 21 - -// Lexical states for SCLEX_LATEX #define SCE_L_DEFAULT 0 #define SCE_L_COMMAND 1 #define SCE_L_TAG 2 #define SCE_L_MATH 3 #define SCE_L_COMMENT 4 +#define SCE_LUA_DEFAULT 0 +#define SCE_LUA_COMMENT 1 +#define SCE_LUA_COMMENTLINE 2 +#define SCE_LUA_COMMENTDOC 3 +#define SCE_LUA_NUMBER 4 +#define SCE_LUA_WORD 5 +#define SCE_LUA_STRING 6 +#define SCE_LUA_CHARACTER 7 +#define SCE_LUA_LITERALSTRING 8 +#define SCE_LUA_PREPROCESSOR 9 +#define SCE_LUA_OPERATOR 10 +#define SCE_LUA_IDENTIFIER 11 +#define SCE_LUA_STRINGEOL 12 +#define SCE_ERR_DEFAULT 0 +#define SCE_ERR_PYTHON 1 +#define SCE_ERR_GCC 2 +#define SCE_ERR_MS 3 +#define SCE_ERR_CMD 4 +#define SCE_ERR_BORLAND 5 +#define SCE_ERR_PERL 6 +//--Autogenerated -- end of section automatically generated from Scintilla.iface #endif diff --git a/contrib/src/stc/scintilla/include/Scintilla.h b/contrib/src/stc/scintilla/include/Scintilla.h index 8e52ba59e2..ca81d135bd 100644 --- a/contrib/src/stc/scintilla/include/Scintilla.h +++ b/contrib/src/stc/scintilla/include/Scintilla.h @@ -3,119 +3,74 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +// Most of this file is automatically generated from the Scintilla.iface interface definition +// file which contains any comments about the definitions. HFacer.py does the generation. + #ifndef SCINTILLA_H #define SCINTILLA_H // Compile-time configuration options #define MACRO_SUPPORT 1 // Comment out to remove macro hooks -#if PLAT_GTK -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject) -#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAS T (klass, scintilla_get_type (), ScintillaClass) -#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ()) - - typedef struct _ScintillaObject ScintillaObject; - typedef struct _ScintillaClass ScintillaClass; - - struct _ScintillaObject - { - GtkFixed vbox; - void *pscin; - }; - - struct _ScintillaClass - { - GtkFixedClass parent_class; - - void (* command) (ScintillaObject *ttt); - void (* notify) (ScintillaObject *ttt); - }; - - guint scintilla_get_type (void); - GtkWidget* scintilla_new (void); - void scintilla_set_id (ScintillaObject *sci,int id); - long scintilla_send_message (ScintillaObject *sci,int iMessage,int wParam,int lParam); - -#include "WinDefs.h" - -#ifdef __cplusplus -} -#endif - +#if PLAT_WIN +#ifdef STATIC_BUILD +void Scintilla_RegisterClasses(HINSTANCE hInstance); #endif - -#if PLAT_WX -#include "WinDefs.h" #endif -// Both GTK and Windows - -#define INVALID_POSITION -1 +typedef long (*SciFnDirect)(long ptr, unsigned int iMessage, unsigned long wParam, long lParam); -// Define start of Scintilla messages to be greater than all edit (EM_*) messages -// as many EM_ messages can be used. +//++Autogenerated -- start of section automatically generated from Scintilla.iface +#define INVALID_POSITION -1 #define SCI_START 2000 #define SCI_OPTIONAL_START 3000 #define SCI_LEXER_START 4000 - -#define SCI_ADDTEXT SCI_START + 1 -#define SCI_ADDSTYLEDTEXT SCI_START + 2 -#define SCI_INSERTTEXT SCI_START + 3 -#define SCI_CLEARALL SCI_START + 4 -#define SCI_GETLENGTH SCI_START + 6 -#define SCI_GETCHARAT SCI_START + 7 -#define SCI_GETCURRENTPOS SCI_START + 8 -#define SCI_GETANCHOR SCI_START + 9 -#define SCI_GETSTYLEAT SCI_START + 10 - -#define SCI_REDO SCI_START + 11 -#define SCI_SETUNDOCOLLECTION SCI_START + 12 -#define SCI_SELECTALL SCI_START + 13 -#define SCI_SETSAVEPOINT SCI_START + 14 -#define SCI_GETSTYLEDTEXT SCI_START + 15 -#define SCI_CANREDO SCI_START + 16 -#define SCI_MARKERLINEFROMHANDLE SCI_START + 17 -#define SCI_MARKERDELETEHANDLE SCI_START + 18 - -#define SC_UNDOCOLLECT_NONE 0 -#define SC_UNDOCOLLECT_AUTOSTART 1 - -#define SCI_GETVIEWWS SCI_START + 20 -#define SCI_SETVIEWWS SCI_START + 21 -#define SCI_GOTOLINE SCI_START + 24 -#define SCI_GOTOPOS SCI_START + 25 -#define SCI_SETANCHOR SCI_START + 26 -#define SCI_GETCURLINE SCI_START + 27 -#define SCI_GETENDSTYLED SCI_START + 28 -#define SCI_CONVERTEOLS SCI_START + 29 - -#define SCI_GETEOLMODE SCI_START + 30 -#define SCI_SETEOLMODE SCI_START + 31 - +#define SCI_ADDTEXT 2001 +#define SCI_ADDSTYLEDTEXT 2002 +#define SCI_INSERTTEXT 2003 +#define SCI_CLEARALL 2004 +#define SCI_CLEARDOCUMENTSTYLE 2005 +#define SCI_GETLENGTH 2006 +#define SCI_GETCHARAT 2007 +#define SCI_GETCURRENTPOS 2008 +#define SCI_GETANCHOR 2009 +#define SCI_GETSTYLEAT 2010 +#define SCI_REDO 2011 +#define SCI_SETUNDOCOLLECTION 2012 +#define SCI_SELECTALL 2013 +#define SCI_SETSAVEPOINT 2014 +#define SCI_GETSTYLEDTEXT 2015 +#define SCI_CANREDO 2016 +#define SCI_MARKERLINEFROMHANDLE 2017 +#define SCI_MARKERDELETEHANDLE 2018 +#define SCI_GETUNDOCOLLECTION 2019 +#define SCWS_INVISIBLE 0 +#define SCWS_VISIBLEALWAYS 1 +#define SCWS_VISIBLEAFTERINDENT 2 +#define SCI_GETVIEWWS 2020 +#define SCI_SETVIEWWS 2021 +#define SCI_POSITIONFROMPOINT 2022 +#define SCI_GOTOLINE 2024 +#define SCI_GOTOPOS 2025 +#define SCI_SETANCHOR 2026 +#define SCI_GETCURLINE 2027 +#define SCI_GETENDSTYLED 2028 +#define SCI_CONVERTEOLS 2029 #define SC_EOL_CRLF 0 #define SC_EOL_CR 1 #define SC_EOL_LF 2 - -#define SCI_STARTSTYLING SCI_START + 32 -#define SCI_SETSTYLING SCI_START + 33 - -// This is the same value as CP_UTF8 in Windows +#define SCI_GETEOLMODE 2030 +#define SCI_SETEOLMODE 2031 +#define SCI_STARTSTYLING 2032 +#define SCI_SETSTYLING 2033 +#define SCI_GETBUFFEREDDRAW 2034 +#define SCI_SETBUFFEREDDRAW 2035 +#define SCI_SETTABWIDTH 2036 +#define SCI_GETTABWIDTH 2121 #define SC_CP_UTF8 65001 - -#define SCI_SETBUFFEREDDRAW SCI_START + 35 -#define SCI_SETTABWIDTH SCI_START + 36 -#define SCI_SETCODEPAGE SCI_START + 37 -#define SCI_SETUSEPALETTE SCI_START + 39 - +#define SCI_SETCODEPAGE 2037 +#define SCI_SETUSEPALETTE 2039 #define MARKER_MAX 31 - #define SC_MARK_CIRCLE 0 #define SC_MARK_ROUNDRECT 1 #define SC_MARK_ARROW 2 @@ -125,255 +80,296 @@ extern "C" { #define SC_MARK_ARROWDOWN 6 #define SC_MARK_MINUS 7 #define SC_MARK_PLUS 8 - -#define SCI_MARKERDEFINE SCI_START + 40 -#define SCI_MARKERSETFORE SCI_START + 41 -#define SCI_MARKERSETBACK SCI_START + 42 -#define SCI_MARKERADD SCI_START + 43 -#define SCI_MARKERDELETE SCI_START + 44 -#define SCI_MARKERDELETEALL SCI_START + 45 -#define SCI_MARKERGET SCI_START + 46 -#define SCI_MARKERNEXT SCI_START + 47 -#define SCI_MARKERPREVIOUS SCI_START + 48 - #define SC_MARKNUM_FOLDER 30 #define SC_MARKNUM_FOLDEROPEN 31 - -#define SC_MASK_FOLDERS ((1< start a category ## fun -> a function ## get -> a property get function -## get -> a property set function +## set -> a property set function ## val -> definition of a constant +## evt -> an event ## All other feature names should be ignored. They may be defined in the future. ## A property may have a set function, a get function or both. Each will have ## "Get" or "Set" in their names and the corresponding name will have the obvious switch. @@ -21,6 +22,7 @@ ## [=,) ## param is [=] ## Additional white space is allowed between elements. +## The syntax for evt is [=[,]*]) ## Feature names that contain an underscore are defined by Windows, so in these ## cases, using the Windows definition is preferred where available. @@ -33,20 +35,27 @@ ## string -> pointer to const character ## stringresult -> pointer to character ## cells -> pointer to array of cells, each cell containing a style byte and character byte -## textrange -> complex structure +## charrange -> range of a min and a max position +## charrangeresult -> like charrange, but output param +## textrange -> charrange + output string ## findtext -> searchrange, text -> foundposition +## findtextex -> searchrange ## keymod -> integer containing key in low half and modifiers in high half ## countedstring ## formatrange ## point -> x,y +## pointresult -> like point, but output param +## rectangle -> left,top,right,bottom ## Client code should ignore definitions containing types it does not understand, except ## for possibly #defining the constants cat Basics ################################################ -## From Scintilla.h +## For Scintilla.h val INVALID_POSITION=-1 +# Define start of Scintilla messages to be greater than all edit (EM_*) messages +# as many EM_ messages can be used although that use is deprecated. val SCI_START=2000 val SCI_OPTIONAL_START=3000 val SCI_LEXER_START=4000 @@ -63,6 +72,9 @@ fun void InsertText=2003(position pos, string text) # Delete all text in the document fun void ClearAll=2004(,) +# Set all style bytes to 0, remove all folding information +fun void ClearDocumentStyle=2005(,) + # The number of characters in the document get int GetLength=2006(,) @@ -81,12 +93,9 @@ get int GetStyleAt=2010(position pos,) # Redoes the next action on the undo history fun void Redo=2011(,) -val SC_UNDOCOLLECT_NONE=0 -val SC_UNDOCOLLECT_AUTOSTART=1 - # Choose between collecting actions into the undo # history and discarding them. -set void SetUndoCollection=2012(int collectUndo,) +set void SetUndoCollection=2012(bool collectUndo,) # Select all the text in the document. fun void SelectAll=2013(,) @@ -108,11 +117,22 @@ fun int MarkerLineFromHandle=2017(int handle,) # Delete a marker. fun void MarkerDeleteHandle=2018(int handle,) +# Is undo history being collected? +get bool GetUndoCollection=2019(,) + +val SCWS_INVISIBLE=0 +val SCWS_VISIBLEALWAYS=1 +val SCWS_VISIBLEAFTERINDENT=2 + # Are white space characters currently visible? -get bool GetViewWS=2020(,) +# Returns one of SCWS_* constants. +get int GetViewWS=2020(,) -# Make white space characters visible or invisible. -set void SetViewWS=2021(bool viewWS,) +# Make white space characters invisible, always visible or visible outside indentation. +set void SetViewWS=2021(int viewWS,) + +# Find the position from a point within the window. +fun int PositionFromPoint=2022(int x, int y) # Set caret to start of a line and ensure it is visible. fun void GotoLine=2024(int line,) @@ -153,6 +173,9 @@ fun void StartStyling=2032(position pos, int mask) # and move the current styling position to after this newly styled segment. fun void SetStyling=2033(int length, int style) +# Is drawing done first into a buffer or direct to the screen. +get bool GetBufferedDraw=2034(,) + # If drawing is buffered then each line of text is drawn into a bitmap buffer # before drawing it to the screen to avoid flicker. set void SetBufferedDraw=2035(bool buffered,) @@ -164,6 +187,8 @@ set void SetTabWidth=2036(int tabWidth,) # Retrieve the visible size of a tab. get int GetTabWidth=2121(,) +# The SC_CP_UTF8 value can be used to enter Unicode mode. +# This is the same value as CP_UTF8 in Windows val SC_CP_UTF8=65001 # Set the code page used to interpret the bytes of the document as characters. @@ -187,7 +212,6 @@ val SC_MARK_PLUS=8 val SC_MARKNUM_FOLDER=30 val SC_MARKNUM_FOLDEROPEN=31 -##val SC_MASK_FOLDERS=1< +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef SCINTILLAWIDGET_H +#define SCINTILLAWIDGET_H + +#if PLAT_GTK + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject) +#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) +#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ()) + +typedef struct _ScintillaObject ScintillaObject; +typedef struct _ScintillaClass ScintillaClass; + +struct _ScintillaObject { + GtkFixed vbox; + void *pscin; +}; + +struct _ScintillaClass { + GtkFixedClass parent_class; + + void (* command) (ScintillaObject *ttt); + void (* notify) (ScintillaObject *ttt); +}; + +guint scintilla_get_type (void); +GtkWidget* scintilla_new (void); +void scintilla_set_id (ScintillaObject *sci,int id); +long scintilla_send_message (ScintillaObject *sci,int iMessage,int wParam,int lParam); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/contrib/src/stc/scintilla/include/WinDefs.h b/contrib/src/stc/scintilla/include/WinDefs.h index d1c25a595a..c56f02d810 100644 --- a/contrib/src/stc/scintilla/include/WinDefs.h +++ b/contrib/src/stc/scintilla/include/WinDefs.h @@ -16,6 +16,7 @@ #define LPSTR char * #define LONG long +//#if 0 /* RTF control */ #define EM_CANPASTE (1074) #define EM_CANUNDO (198) @@ -52,12 +53,10 @@ #define WM_NULL (0) #define WM_CLEAR (771) -#define WM_COMMAND (273) #define WM_COPY (769) #define WM_CUT (768) #define WM_GETTEXT (13) #define WM_GETTEXTLENGTH (14) -#define WM_NOTIFY (78) #define WM_PASTE (770) #define WM_SETTEXT (12) #define WM_UNDO (772) @@ -70,6 +69,9 @@ #define EC_RIGHTMARGIN 2 #define EC_USEFONTINFO 0xffff +//#endif + +#if 0 #if PLAT_GTK #define VK_DOWN GDK_Down #define VK_UP GDK_Up @@ -109,12 +111,16 @@ #define VK_SUBTRACT WXK_SUBTRACT //TODO: #define VK_DIVIDE WXK_DIVIDE +#endif + +#define SHIFT_PRESSED 1 +#define LEFT_CTRL_PRESSED 2 +#define LEFT_ALT_PRESSED 4 // Are these needed any more #define LPSTR char * #define LONG long #define LPDWORD (long *) -#endif /* SELCHANGE structure */ #define SEL_EMPTY (0) @@ -123,15 +129,6 @@ #define SEL_MULTICHAR (4) #define SEL_MULTIOBJECT (8) -/* FINDREPLACE structure */ -#define FR_MATCHCASE (0x4) -#define FR_WHOLEWORD (0x2) -#define FR_DOWN (0x1) - -#define SHIFT_PRESSED 1 -#define LEFT_CTRL_PRESSED 2 -#define LEFT_ALT_PRESSED 4 - struct RECT { LONG left; LONG top; @@ -139,6 +136,15 @@ struct RECT { LONG bottom; }; +/* FINDREPLACE structure */ + +#define FR_MATCHCASE (0x4) +#define FR_WHOLEWORD (0x2) +#define FR_DOWN (0x1) + +#endif + +#if 0 struct CHARRANGE { LONG cpMin; LONG cpMax; @@ -168,9 +174,10 @@ struct FORMATRANGE { RECT rcPage; CHARRANGE chrg; }; +#endif -#define MAKELONG(a, b) ((a) | ((b) << 16)) -#define LOWORD(x) (x & 0xffff) -#define HIWORD(x) (x >> 16) +//#define MAKELONG(a, b) ((a) | ((b) << 16)) +//#define LOWORD(x) (x & 0xffff) +//#define HIWORD(x) (x >> 16) #endif diff --git a/contrib/src/stc/scintilla/include/WindowAccessor.h b/contrib/src/stc/scintilla/include/WindowAccessor.h index 89a542e82d..4f41dfc7ff 100644 --- a/contrib/src/stc/scintilla/include/WindowAccessor.h +++ b/contrib/src/stc/scintilla/include/WindowAccessor.h @@ -22,7 +22,7 @@ protected: public: WindowAccessor(WindowID id_, PropSet &props_) : Accessor(), id(id_), props(props_), - lenDoc(-1), validLen(0), chFlags(0) { + lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { } ~WindowAccessor(); char StyleAt(int position); diff --git a/contrib/src/stc/scintilla/src/Accessor.cxx b/contrib/src/stc/scintilla/src/Accessor.cxx deleted file mode 100644 index 57b7e4dc4e..0000000000 --- a/contrib/src/stc/scintilla/src/Accessor.cxx +++ /dev/null @@ -1,112 +0,0 @@ -// SciTE - Scintilla based Text Editor -// Accessor.cxx - rapid easy access to contents of a Scintilla -// Copyright 1998-2000 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include - -#include "Platform.h" - -#include "PropSet.h" -#include "Accessor.h" -#include "Scintilla.h" - -void Accessor::Fill(int position) { - if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); - startPos = position - slopSize; - if (startPos + bufferSize > lenDoc) - startPos = lenDoc - bufferSize; - if (startPos < 0) - startPos = 0; - endPos = startPos + bufferSize; - if (endPos > lenDoc) - endPos = lenDoc; - - TEXTRANGE tr = {{startPos, endPos}, buf}; - Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast(&tr)); -} - -char Accessor::StyleAt(int position) { - return static_cast(Platform::SendScintilla( - id, SCI_GETSTYLEAT, position, 0)); -} - -int Accessor::GetLine(int position) { - return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); -} - -int Accessor::LineStart(int line) { - return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); -} - -int Accessor::LevelAt(int line) { - return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0); -} - -int Accessor::Length() { - if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); - return lenDoc; -} - -int Accessor::GetLineState(int line) { - return Platform::SendScintilla(id, SCI_GETLINESTATE, line); -} - -int Accessor::SetLineState(int line, int state) { - return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state); -} - -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) { - // 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 (validLen + (end - start + 1) >= bufferSize) - Flush(); - if (validLen + (end - start + 1) >= bufferSize) { - // Too big for buffer so send directly - Platform::SendScintilla(id, SCI_SETSTYLING, end - start + 1, chAttr); - } else { - if (chAttr != chWhile) - chFlags = 0; - chAttr |= chFlags; - for (unsigned int i = start; i <= end; 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; -} - -int StylingContext::GetLine(int position) { - return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); -} - -void StylingContext::SetLevel(int line, int level) { - Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level); -} - -void StylingContext::Flush() { - if (validLen > 0) { - Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, - reinterpret_cast(styleBuf)); - validLen = 0; - } -} diff --git a/contrib/src/stc/scintilla/src/AutoComplete.cxx b/contrib/src/stc/scintilla/src/AutoComplete.cxx index 75e26fe283..5bc50d1efa 100644 --- a/contrib/src/stc/scintilla/src/AutoComplete.cxx +++ b/contrib/src/stc/scintilla/src/AutoComplete.cxx @@ -10,12 +10,16 @@ #include "AutoComplete.h" -AutoComplete::AutoComplete() { - lb = 0; - active = false; - posStart = 0; - strcpy(stopChars, ""); - separator = ' '; +AutoComplete::AutoComplete() : + active(false), + separator(' '), + ignoreCase(false), + chooseSingle(false), + posStart(0), + startLen(0), + cancelAtStartPos(true) { + stopChars[0] = '\0'; + fillUpChars[0] = '\0'; } AutoComplete::~AutoComplete() { @@ -45,6 +49,15 @@ bool AutoComplete::IsStopChar(char ch) { return ch && strchr(stopChars, ch); } +void AutoComplete::SetFillUpChars(const char *fillUpChars_) { + strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars)); + fillUpChars[sizeof(fillUpChars) - 1] = '\0'; +} + +bool AutoComplete::IsFillUpChar(char ch) { + return ch && strchr(fillUpChars, ch); +} + void AutoComplete::SetSeparator(char separator_) { separator = separator_; } @@ -53,8 +66,7 @@ char AutoComplete::GetSeparator() { return separator; } -int AutoComplete::SetList(const char *list) { - int maxStrLen = 12; +void AutoComplete::SetList(const char *list) { lb.Clear(); char *words = new char[strlen(list) + 1]; if (words) { @@ -65,18 +77,15 @@ int AutoComplete::SetList(const char *list) { if (words[i] == separator) { words[i] = '\0'; lb.Append(startword); - maxStrLen = Platform::Maximum(maxStrLen, strlen(startword)); startword = words + i + 1; } } if (startword) { lb.Append(startword); - maxStrLen = Platform::Maximum(maxStrLen, strlen(startword)); } delete []words; } lb.Sort(); - return maxStrLen; } void AutoComplete::Show() { @@ -87,7 +96,6 @@ void AutoComplete::Show() { void AutoComplete::Cancel() { if (lb.Created()) { lb.Destroy(); - lb = 0; active = false; } } diff --git a/contrib/src/stc/scintilla/src/AutoComplete.h b/contrib/src/stc/scintilla/src/AutoComplete.h index e4f8ade0d8..c1789ad7b6 100644 --- a/contrib/src/stc/scintilla/src/AutoComplete.h +++ b/contrib/src/stc/scintilla/src/AutoComplete.h @@ -9,11 +9,16 @@ class AutoComplete { bool active; char stopChars[256]; + char fillUpChars[256]; char separator; public: + bool ignoreCase; + bool chooseSingle; ListBox lb; int posStart; int startLen; + // Should autocompletion be canceled if editor's currentPos <= startPos? + bool cancelAtStartPos; AutoComplete(); ~AutoComplete(); @@ -28,12 +33,16 @@ public: void SetStopChars(const char *stopChars_); bool IsStopChar(char ch); + // The fillup chars are characters which, when typed, fill up the selected word + void SetFillUpChars(const char *fillUpChars_); + bool IsFillUpChar(char ch); + // The separator character is used when interpreting the list in SetList void SetSeparator(char separator_); char GetSeparator(); // The list string contains a sequence of words separated by the separator character - int SetList(const char *list); + void SetList(const char *list); void Show(); void Cancel(); diff --git a/contrib/src/stc/scintilla/src/CellBuffer.cxx b/contrib/src/stc/scintilla/src/CellBuffer.cxx index e6aa4a0134..befec75fc3 100644 --- a/contrib/src/stc/scintilla/src/CellBuffer.cxx +++ b/contrib/src/stc/scintilla/src/CellBuffer.cxx @@ -88,7 +88,7 @@ void MarkerHandleSet::RemoveHandle(int handle) { if (mhn->handle == handle) { *pmhn = mhn->next; delete mhn; - return; + return ; } pmhn = &((*pmhn)->next); } @@ -101,7 +101,7 @@ void MarkerHandleSet::RemoveNumber(int markerNum) { if (mhn->number == markerNum) { *pmhn = mhn->next; delete mhn; - return; + return ; } pmhn = &((*pmhn)->next); } @@ -119,7 +119,11 @@ void MarkerHandleSet::CombineWith(MarkerHandleSet *other) { LineVector::LineVector() { linesData = 0; lines = 0; + size = 0; levels = 0; + sizeLevels = 0; + handleCurrent = 1; + Init(); } @@ -161,6 +165,7 @@ void LineVector::Expand(int sizeNew) { Platform::DebugPrintf("No memory available\n"); // TODO: Blow up } + } void LineVector::ExpandLevels(int sizeNew) { @@ -180,6 +185,13 @@ void LineVector::ExpandLevels(int sizeNew) { Platform::DebugPrintf("No memory available\n"); // TODO: Blow up } + +} + +void LineVector::ClearLevels() { + delete []levels; + levels = 0; + sizeLevels = 0; } void LineVector::InsertValue(int pos, int value) { @@ -202,10 +214,10 @@ void LineVector::InsertValue(int pos, int value) { } if (pos == 0) { levels[pos] = SC_FOLDLEVELBASE; - } else if (pos == (lines-1)) { // Last line will not be a folder + } else if (pos == (lines - 1)) { // Last line will not be a folder levels[pos] = SC_FOLDLEVELBASE; } else { - levels[pos] = levels[pos-1]; + levels[pos] = levels[pos - 1]; } } } @@ -234,10 +246,10 @@ void LineVector::Remove(int pos) { linesData[i] = linesData[i + 1]; } if (levels) { - // Level information merges back onto previous line - int posAbove = pos-1; - if (posAbove < 0) - posAbove = 0; + // Level information merges back onto previous line + int posAbove = pos - 1; + if (posAbove < 0) + posAbove = 0; for (int j = posAbove; j < lines; j++) { levels[j] = levels[j + 1]; } @@ -280,11 +292,12 @@ int LineVector::AddMark(int line, int markerNum) { } void LineVector::MergeMarkers(int pos) { - if (linesData[pos].handleSet || linesData[pos + 1].handleSet) { - if (linesData[pos].handleSet && linesData[pos + 1].handleSet) { - linesData[pos].handleSet->CombineWith(linesData[pos].handleSet); - linesData[pos].handleSet = 0; - } + if (linesData[pos + 1].handleSet != NULL) { + if (linesData[pos].handleSet == NULL ) + linesData[pos].handleSet = new MarkerHandleSet; + linesData[pos].handleSet->CombineWith(linesData[pos + 1].handleSet); + delete linesData[pos + 1].handleSet; + linesData[pos + 1].handleSet = NULL; } } @@ -358,7 +371,7 @@ void Action::Grab(Action *source) { data = source->data; lenData = source->lenData; mayCoalesce = source->mayCoalesce; - + // Ownership of source data transferred to this source->position = 0; source->at = startAction; @@ -367,21 +380,21 @@ void Action::Grab(Action *source) { source->mayCoalesce = true; } -// The undo history stores a sequence of user operations that represent the user's view of the -// commands executed on the text. +// 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 +// 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 +// 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 +// 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 +// 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. @@ -412,7 +425,7 @@ void UndoHistory::EnsureUndoRoom() { int lenActionsNew = lenActions * 2; Action *actionsNew = new Action[lenActionsNew]; if (!actionsNew) - return; + return ; for (int act = 0; act <= currentAction; act++) actionsNew[act].Grab(&actions[act]); delete []actions; @@ -425,11 +438,11 @@ void UndoHistory::EnsureUndoRoom() { 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, + //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 + // 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 @@ -437,22 +450,23 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng currentAction++; } else if (currentAction == savePoint) { currentAction++; - } else if ((at == removeAction) && - ((position + lengthData * 2) != actPrevious.position)) { + } 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))) { + } 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 { // Actions not at top level are always coalesced unless this is after return to top level if (!actions[currentAction].mayCoalesce) currentAction++; - } + } } else { currentAction++; } @@ -487,7 +501,7 @@ void UndoHistory::EndUndoAction() { actions[currentAction].mayCoalesce = false; } } - + void UndoHistory::DropUndoSequence() { undoSequenceDepth = 0; } @@ -517,9 +531,9 @@ int UndoHistory::StartUndo() { // Drop any trailing startAction if (actions[currentAction].at == startAction && currentAction > 0) currentAction--; - + // Count the steps in this action - int act = currentAction; + int act = currentAction; while (actions[act].at != startAction && act > 0) { act--; } @@ -542,9 +556,9 @@ int UndoHistory::StartRedo() { // Drop any leading startAction if (actions[currentAction].at == startAction && currentAction < maxAction) currentAction++; - + // Count the steps in this action - int act = currentAction; + int act = currentAction; while (actions[act].at != startAction && act < maxAction) { act++; } @@ -563,11 +577,11 @@ CellBuffer::CellBuffer(int initialLength) { body = new char[initialLength]; size = initialLength; length = 0; - part1len = 0; + part1len = 0; gaplen = initialLength; part2body = body + gaplen; readOnly = false; - collectingUndo = undoCollectAutoStart; + collectingUndo = true; } CellBuffer::~CellBuffer() { @@ -577,7 +591,7 @@ CellBuffer::~CellBuffer() { void CellBuffer::GapTo(int position) { if (position == part1len) - return; + return ; if (position < part1len) { int diff = part1len - position; //Platform::DebugPrintf("Move gap backwards to %d diff = %d part1len=%d length=%d \n", position,diff, part1len, length); @@ -609,6 +623,7 @@ void CellBuffer::RoomFor(int insertionLength) { size = newSize; //Platform::DebugPrintf("end need room %d %d - size=%d length=%d\n", gaplen, insertionLength,size,length); } + } // To make it easier to write code that uses ByteAt, a position outside the range of the buffer @@ -633,16 +648,16 @@ void CellBuffer::SetByteAt(int position, char ch) { if (position < 0) { //Platform::DebugPrintf("Bad position %d\n",position); - return; + return ; } if (position >= length + 11) { Platform::DebugPrintf("Very Bad position %d of %d\n", position, length); //exit(2); - return; + return ; } if (position >= length) { //Platform::DebugPrintf("Bad position %d of %d\n",position,length); - return; + return ; } if (position < part1len) { @@ -658,20 +673,20 @@ char CellBuffer::CharAt(int position) { void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) { if (lengthRetrieve < 0) - return; + return ; if (position < 0) - return; + return ; int bytePos = position * 2; if ((bytePos + lengthRetrieve * 2) > length) { - Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n",bytePos, - lengthRetrieve, length); - return; + Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", bytePos, + lengthRetrieve, length); + return ; } GapTo(0); // Move the buffer so its easy to subscript into it char *pb = part2body + bytePos; while (lengthRetrieve--) { *buffer++ = *pb; - pb +=2; + pb += 2; } } @@ -706,7 +721,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) { } bool CellBuffer::SetStyleAt(int position, char style, char mask) { - char curVal = ByteAt(position*2 + 1); + char curVal = ByteAt(position * 2 + 1); if ((curVal & mask) != style) { SetByteAt(position*2 + 1, static_cast((curVal & ~mask) | style)); return true; @@ -823,7 +838,7 @@ int CellBuffer::LineFromHandle(int markerHandle) { void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { //Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength); if (insertLength == 0) - return; + return ; RoomFor(insertLength); GapTo(position); @@ -883,7 +898,7 @@ void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { void CellBuffer::BasicDeleteChars(int position, int deleteLength) { //Platform::DebugPrintf("Deleting at %d for %d\n", position, deleteLength); if (deleteLength == 0) - return; + return ; if ((position == 0) && (deleteLength == length)) { // If whole buffer is being deleted, faster to reinitialise lines data @@ -915,6 +930,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { ignoreNL = true; // First \n is not real deletion } + char ch = chNext; for (int i = 0; i < deleteLength; i += 2) { chNext = ' '; @@ -932,6 +948,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { ignoreNL = false; // Further \n are not real deletions } + ch = chNext; } // May have to fix up end if last deletion causes cr to be next to lf @@ -952,7 +969,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { part2body = body + gaplen; } -undoCollectionType CellBuffer::SetUndoCollection(undoCollectionType collectUndo) { +bool CellBuffer::SetUndoCollection(bool collectUndo) { collectingUndo = collectUndo; uh.DropUndoSequence(); return collectingUndo; @@ -994,12 +1011,12 @@ void CellBuffer::PerformUndoStep() { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { styledData[i*2] = actionStep.data[i]; - styledData[i*2+1] = 0; + styledData[i*2 + 1] = 0; } BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } - uh.CompletedUndoStep(); + uh.CompletedUndoStep(); } bool CellBuffer::CanRedo() { @@ -1020,14 +1037,14 @@ void CellBuffer::PerformRedoStep() { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { styledData[i*2] = actionStep.data[i]; - styledData[i*2+1] = 0; + styledData[i*2 + 1] = 0; } BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } - uh.CompletedRedoStep(); + uh.CompletedRedoStep(); } int CellBuffer::SetLineState(int line, int state) { @@ -1043,7 +1060,7 @@ int CellBuffer::GetLineState(int line) { int CellBuffer::GetMaxLineState() { return lineStates.Length(); } - + int CellBuffer::SetLevel(int line, int level) { int prev = 0; if ((line >= 0) && (line < lv.lines)) { @@ -1066,3 +1083,6 @@ int CellBuffer::GetLevel(int line) { } } +void CellBuffer::ClearLevels() { + lv.ClearLevels(); +} diff --git a/contrib/src/stc/scintilla/src/CellBuffer.h b/contrib/src/stc/scintilla/src/CellBuffer.h index 409a8749de..4a1ecb3989 100644 --- a/contrib/src/stc/scintilla/src/CellBuffer.h +++ b/contrib/src/stc/scintilla/src/CellBuffer.h @@ -58,6 +58,7 @@ public: void Expand(int sizeNew); void ExpandLevels(int sizeNew=-1); + void ClearLevels(); void InsertValue(int pos, int value); void SetValue(int pos, int value); void Remove(int pos); @@ -88,8 +89,6 @@ public: void Grab(Action *source); }; -enum undoCollectionType { undoCollectNone, undoCollectAutoStart, undoCollectManualStart }; - class UndoHistory { Action *actions; int lenActions; @@ -141,12 +140,12 @@ private: char *part2body; bool readOnly; - undoCollectionType collectingUndo; + bool collectingUndo; UndoHistory uh; LineVector lv; - SVector lineStates; + SVector lineStates; void GapTo(int position); void RoomFor(int insertionLength); @@ -199,7 +198,7 @@ public: void BasicInsertString(int position, char *s, int insertLength); void BasicDeleteChars(int position, int deleteLength); - undoCollectionType SetUndoCollection(undoCollectionType collectUndo); + bool SetUndoCollection(bool collectUndo); bool IsCollectingUndo(); void BeginUndoAction(); void EndUndoAction(); @@ -222,6 +221,7 @@ public: int SetLevel(int line, int level); int GetLevel(int line); + void ClearLevels(); }; #define CELL_SIZE 2 diff --git a/contrib/src/stc/scintilla/src/ContractionState.cxx b/contrib/src/stc/scintilla/src/ContractionState.cxx index 4569489003..0558b4c365 100644 --- a/contrib/src/stc/scintilla/src/ContractionState.cxx +++ b/contrib/src/stc/scintilla/src/ContractionState.cxx @@ -171,12 +171,6 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible delta += visible ? 1 : -1; lines[line].visible = visible; } - lines[line].displayLine += delta; - } - if (delta != 0) { - for (int line=lineDocEnd+1; line <= linesInDoc; line++) { - lines[line].displayLine += delta; - } } } linesInDisplay += delta; @@ -206,3 +200,9 @@ bool ContractionState::SetExpanded(int lineDoc, bool expanded) { } return false; } + +void ContractionState::ShowAll() { + delete []lines; + lines = 0; + size = 0; +} diff --git a/contrib/src/stc/scintilla/src/ContractionState.h b/contrib/src/stc/scintilla/src/ContractionState.h index 9e17a76937..2c344efeea 100644 --- a/contrib/src/stc/scintilla/src/ContractionState.h +++ b/contrib/src/stc/scintilla/src/ContractionState.h @@ -42,9 +42,11 @@ public: bool GetVisible(int lineDoc) const; bool SetVisible(int lineDocStart, int lineDocEnd, bool visible); - + bool GetExpanded(int lineDoc) const; bool SetExpanded(int lineDoc, bool expanded); + + void ShowAll(); }; #endif diff --git a/contrib/src/stc/scintilla/src/Document.cxx b/contrib/src/stc/scintilla/src/Document.cxx index 6614a7fc98..c883dd253f 100644 --- a/contrib/src/stc/scintilla/src/Document.cxx +++ b/contrib/src/stc/scintilla/src/Document.cxx @@ -54,7 +54,7 @@ int Document::AddRef() { return refCount++; } -// Decrease reference count and return its provius value. +// Decrease reference count and return its previous value. // Delete the document if reference count reaches zero. int Document::Release() { int curRefCount = --refCount; @@ -201,8 +201,8 @@ bool Document::IsCrLf(int pos) { return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } -bool Document::IsDBCS(int pos) { #if PLAT_WIN +bool Document::IsDBCS(int pos) { if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { unsigned char ch = static_cast(cb.CharAt(pos)); @@ -224,10 +224,14 @@ bool Document::IsDBCS(int pos) { } } return false; +} #else +// PLAT_GTK or PLAT_WX +// TODO: support DBCS under GTK+ and WX +bool Document::IsDBCS(int) { return false; -#endif } +#endif int Document::LenChar(int pos) { if (IsCrLf(pos)) { @@ -334,6 +338,8 @@ void Document::ModifiedAt(int pos) { // Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number void Document::DeleteChars(int pos, int len) { + if ((pos + len) > Length()) + return; if (cb.IsReadOnly() && enteredReadOnlyCount==0) { enteredReadOnlyCount++; NotifyModifyAttempt(); @@ -590,6 +596,8 @@ void Document::SetLineIndentation(int line, int indent) { } int Document::GetLineIndentPosition(int line) { + if (line < 0) + return 0; int pos = LineStart(line); int length = Length(); while ((pos < length) && isindentchar(cb.CharAt(pos))) { @@ -598,6 +606,25 @@ int Document::GetLineIndentPosition(int line) { return pos; } +int Document::GetColumn(int pos) { + int column = 0; + int line = LineFromPosition(pos); + if ((line >= 0) && (line < LinesTotal())) { + for (int i=LineStart(line);i= lineTop; line--) { @@ -690,25 +717,29 @@ int Document::NextWordStart(int pos, int delta) { return pos; } -bool Document::IsWordAt(int start, int end) { - int lengthDoc = Length(); - if (start > 0) { - char ch = CharAt(start - 1); - if (IsWordChar(ch)) - return false; +bool Document::IsWordStartAt(int pos) { + if (pos > 0) { + return !IsWordChar(CharAt(pos - 1)); } - if (end < lengthDoc - 1) { - char ch = CharAt(end); - if (IsWordChar(ch)) - return false; + return true; +} + +bool Document::IsWordEndAt(int pos) { + if (pos < Length() - 1) { + return !IsWordChar(CharAt(pos)); } return true; } +bool Document::IsWordAt(int start, int end) { + return IsWordStartAt(start) && IsWordEndAt(end); +} + // Find text in document, supporting both forward and backward // searches (just pass minPos > maxPos to do a backward search) // Has not been tested with backwards DBCS searches yet. -long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word) { +long Document::FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart) { bool forward = minPos <= maxPos; int increment = forward ? 1 : -1; @@ -738,8 +769,10 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitiv found = false; } if (found) { - if ((!word) || IsWordAt(pos, pos + lengthFind)) - return pos; + if ((!word && !wordStart) || + word && IsWordAt(pos, pos + lengthFind) || + wordStart && IsWordStartAt(pos)) + return pos; } } } else { @@ -751,8 +784,10 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitiv found = false; } if (found) { - if ((!word) || IsWordAt(pos, pos + lengthFind)) - return pos; + if (!(word && wordStart) || + word && IsWordAt(pos, pos + lengthFind) || + wordStart && IsWordStartAt(pos)) + return pos; } } } diff --git a/contrib/src/stc/scintilla/src/Document.h b/contrib/src/stc/scintilla/src/Document.h index 92e4ff14fe..af477dd79b 100644 --- a/contrib/src/stc/scintilla/src/Document.h +++ b/contrib/src/stc/scintilla/src/Document.h @@ -113,9 +113,10 @@ public: bool CanUndo() { return cb.CanUndo(); } bool CanRedo() { return cb.CanRedo(); } void DeleteUndoHistory() { cb.DeleteUndoHistory(); } - undoCollectionType SetUndoCollection(undoCollectionType collectUndo) { + bool SetUndoCollection(bool collectUndo) { return cb.SetUndoCollection(collectUndo); } + bool IsCollectingUndo() { return cb.IsCollectingUndo(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void SetSavePoint(); @@ -124,9 +125,11 @@ public: int GetLineIndentation(int line); void SetLineIndentation(int line, int indent); int GetLineIndentPosition(int line); + int GetColumn(int position); void Indent(bool forwards, int lineBottom, int lineTop); void ConvertLineEnds(int eolModeSet); void SetReadOnly(bool set) { cb.SetReadOnly(set); } + bool IsReadOnly() { return cb.IsReadOnly(); } void InsertChar(int pos, char ch); void InsertString(int position, const char *s); @@ -153,6 +156,7 @@ public: int SetLevel(int line, int level); int GetLevel(int line) { return cb.GetLevel(line); } + void ClearLevels() { cb.ClearLevels(); } int GetLastChild(int lineParent, int level=-1); int GetFoldParent(int line); @@ -160,8 +164,9 @@ public: int ExtendWordSelect(int pos, int delta); int NextWordStart(int pos, int delta); int Length() { return cb.Length(); } - long FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word); - long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam); + long FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart); + long FindText(int iMessage, unsigned long wParam, long lParam); int LinesTotal(); void ChangeCase(Range r, bool makeUpperCase); @@ -186,6 +191,8 @@ public: private: bool IsDBCS(int pos); bool IsWordChar(unsigned char ch); + bool IsWordStartAt(int pos); + bool IsWordEndAt(int pos); bool IsWordAt(int start, int end); void ModifiedAt(int pos); diff --git a/contrib/src/stc/scintilla/src/DocumentAccessor.cxx b/contrib/src/stc/scintilla/src/DocumentAccessor.cxx index d28840c166..6828e37c3f 100644 --- a/contrib/src/stc/scintilla/src/DocumentAccessor.cxx +++ b/contrib/src/stc/scintilla/src/DocumentAccessor.cxx @@ -4,6 +4,7 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include #include @@ -20,21 +21,22 @@ DocumentAccessor::~DocumentAccessor() { } +#if PLAT_WIN bool DocumentAccessor::InternalIsLeadByte(char ch) { -#if PLAT_GTK - // TODO: support DBCS under GTK+ - return false; -#elif PLAT_WIN if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the // same so none is considered a lead byte. return false; else return IsDBCSLeadByteEx(codePage, ch); -#elif PLAT_WX +} +#else +// PLAT_GTK or PLAT_WX +// TODO: support DBCS under GTK+ and WX +bool DocumentAccessor::InternalIsLeadByte(char) { return false; -#endif } +#endif void DocumentAccessor::Fill(int position) { if (lenDoc == -1) diff --git a/contrib/src/stc/scintilla/src/DocumentAccessor.h b/contrib/src/stc/scintilla/src/DocumentAccessor.h index 37a9db4149..ccc05fee9f 100644 --- a/contrib/src/stc/scintilla/src/DocumentAccessor.h +++ b/contrib/src/stc/scintilla/src/DocumentAccessor.h @@ -24,7 +24,7 @@ protected: public: DocumentAccessor(Document *pdoc_, PropSet &props_) : Accessor(), pdoc(pdoc_), props(props_), - lenDoc(-1), validLen(0), chFlags(0) { + lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { } ~DocumentAccessor(); char StyleAt(int position); diff --git a/contrib/src/stc/scintilla/src/Editor.cxx b/contrib/src/stc/scintilla/src/Editor.cxx index ad8bab8c5f..6d2676ffbc 100644 --- a/contrib/src/stc/scintilla/src/Editor.cxx +++ b/contrib/src/stc/scintilla/src/Editor.cxx @@ -11,6 +11,11 @@ #include "Platform.h" #include "Scintilla.h" + +#if PLAT_WX || PLAT_GTK +#include "WinDefs.h" +#endif + #include "ContractionState.h" #include "SVector.h" #include "CellBuffer.h" @@ -33,6 +38,9 @@ Editor::Editor() { stylesValid = false; + printMagnification = 0; + printColourMode = SC_PRINT_NORMAL; + hideSelection = false; inOverstrike = false; @@ -58,46 +66,47 @@ Editor::Editor() { selType = selStream; xStartSelect = 0; xEndSelect = 0; + primarySelection = true; caretPolicy = CARET_SLOP; caretSlop = 0; searchAnchor = 0; - + ucWheelScrollLines = 0; cWheelDelta = 0; //wheel delta from roll xOffset = 0; xCaretMargin = 50; horizontalScrollBarVisible = true; - + currentPos = 0; anchor = 0; topLine = 0; posTopLine = 0; - + needUpdateUI = true; - braces[0]=invalidPosition; - braces[1]=invalidPosition; + braces[0] = invalidPosition; + braces[1] = invalidPosition; bracesMatchStyle = STYLE_BRACEBAD; - - edgeState = EDGE_NONE; + highlightGuideColumn = 0; + theEdge = 0; - + paintState = notPainting; - + modEventMask = SC_MODEVENTMASKALL; displayPopupMenu = true; - + pdoc = new Document(); pdoc ->AddRef(); pdoc->AddWatcher(this, 0); #ifdef MACRO_SUPPORT recordingMacro = 0; -#endif +#endif foldFlags = 0; } @@ -113,12 +122,14 @@ Editor::~Editor() { } void Editor::Finalise() { + CancelModes(); } void Editor::DropGraphics() { pixmapLine.Release(); pixmapSelMargin.Release(); pixmapSelPattern.Release(); + pixmapIndentGuide.Release(); } void Editor::InvalidateStyleData() { @@ -185,7 +196,7 @@ int Editor::MaxScrollPos() { return retVal; } -bool IsControlCharacter(char ch) { +static inline bool IsControlCharacter(char ch) { // iscntrl returns true for lots of chars > 127 which are displayable return ch >= 0 && ch < ' '; } @@ -215,12 +226,12 @@ Point Editor::LocationFromPosition(unsigned int pos) { Point pt; pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight? unsigned int posLineStart = pdoc->LineStart(line); + LineLayout ll; + LayoutLine(line, &surface, vs, ll); if ((pos - posLineStart) > LineLayout::maxLineLength) { // very long line so put x at arbitrary large position - pt.x = 30000 + vs.fixedColumnWidth - xOffset; + pt.x = ll.positions[LineLayout::maxLineLength] + vs.fixedColumnWidth - xOffset; } else { - LineLayout ll; - LayoutLine(line, &surface, vs, ll); pt.x = ll.positions[pos - posLineStart] + vs.fixedColumnWidth - xOffset; } return pt; @@ -230,7 +241,7 @@ int Editor::XFromPosition(unsigned int pos) { Point pt = LocationFromPosition(pos); return pt.x - vs.fixedColumnWidth + xOffset; } - + int Editor::LineFromLocation(Point pt) { return cs.DocFromDisplay(pt.y / vs.lineHeight + topLine); } @@ -251,7 +262,7 @@ int Editor::PositionFromLocation(Point pt) { return 0; if (line >= pdoc->LinesTotal()) return pdoc->Length(); -//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); + //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); Surface surface; surface.Init(); surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); @@ -260,8 +271,8 @@ int Editor::PositionFromLocation(Point pt) { LineLayout ll; LayoutLine(line, &surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { - if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { + if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { return i + posLineStart; } } @@ -282,8 +293,8 @@ int Editor::PositionFromLineX(int line, int x) { LineLayout ll; LayoutLine(line, &surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { - if (x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { + if (x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { return i + posLineStart; } } @@ -362,7 +373,7 @@ int Editor::SelectionStart(int line) { //return PositionFromLineX(line, minX + vs.fixedColumnWidth - xOffset); return PositionFromLineX(line, minX); } - } + } } int Editor::SelectionEnd(int line) { @@ -433,10 +444,26 @@ void Editor::SetEmptySelection(int currentPos_) { SetSelection(currentPos_, currentPos_); } +int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { + // Asks document to find a good position and then moves out of any invisible positions + pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd); + int mask = pdoc->stylingBitsMask; + if (moveDir > 0) { + while ((pos < pdoc->Length()) && + (!vs.styles[pdoc->StyleAt(pos - 1) & mask].visible)) + pos++; + } else { + while ((pos > 0) && + (!vs.styles[pdoc->StyleAt(pos - 1) & mask].visible)) + pos--; + } + return pos; +} + int Editor::MovePositionTo(int newPos, bool extend) { int delta = newPos - currentPos; newPos = pdoc->ClampPositionIntoDocument(newPos); - newPos = pdoc->MovePositionOutsideChar(newPos, delta); + newPos = MovePositionOutsideChar(newPos, delta); if (extend) { SetSelection(newPos); } else { @@ -449,7 +476,7 @@ int Editor::MovePositionTo(int newPos, bool extend) { int Editor::MovePositionSoVisible(int pos, int moveDir) { pos = pdoc->ClampPositionIntoDocument(pos); - pos = pdoc->MovePositionOutsideChar(pos, moveDir); + pos = MovePositionOutsideChar(pos, moveDir); int lineDoc = pdoc->LineFromPosition(pos); if (cs.GetVisible(lineDoc)) { return pos; @@ -510,7 +537,7 @@ void Editor::MoveCaretInsideView() { MovePositionTo(PositionFromLocation( Point(lastXChosen, rcClient.top))); } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) { - int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen()-1) * vs.lineHeight; + int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight; MovePositionTo(PositionFromLocation( Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed))); } @@ -532,11 +559,11 @@ void Editor::EnsureCaretVisible(bool useMargin) { int xMargin = Platform::Clamp(xCaretMargin, 2, Platform::Maximum(rcClient.Width() - 10, 4) / 2); if (!useMargin) xMargin = 2; - + // Ensure certain amount of text visible on both sides of caretSo move if caret just on edge rcClient.left = rcClient.left + xMargin; rcClient.right = rcClient.right - xMargin; - + if (!rcClient.Contains(pt) || !rcClient.Contains(ptBottomCaret) || (caretPolicy & CARET_STRICT)) { //Platform::DebugPrintf("EnsureCaretVisible move, (%d,%d) (%d,%d)\n", pt.x, pt.y, rcClient.left, rcClient.right); // It should be possible to scroll the window to show the caret, @@ -546,8 +573,8 @@ void Editor::EnsureCaretVisible(bool useMargin) { SetTopLine(Platform::Clamp(lineCaret - caretSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); - } else if ((lineCaret > topLine + LinesOnScreen() - 1) || - ((caretPolicy & CARET_STRICT) && (lineCaret > topLine + LinesOnScreen() - 1 - caretSlop))) { + } else if ((lineCaret > topLine + LinesOnScreen() - 1) || + ((caretPolicy & CARET_STRICT) && (lineCaret > topLine + LinesOnScreen() - 1 - caretSlop))) { SetTopLine(Platform::Clamp(lineCaret - LinesOnScreen() + 1 + caretSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); @@ -584,7 +611,7 @@ void Editor::ShowCaretAtCurrentPosition() { if (!wMain.HasFocus()) { caret.active = false; caret.on = false; - return; + return ; } caret.active = true; caret.on = true; @@ -605,13 +632,13 @@ void Editor::InvalidateCaret() { void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { if (vs.fixedColumnWidth == 0) - return; + return ; PRectangle rcMargin = GetClientRectangle(); rcMargin.right = vs.fixedColumnWidth; if (!rc.Intersects(rcMargin)) - return; + return ; Surface *surface; if (bufferedDraw) { @@ -623,9 +650,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { PRectangle rcSelMargin = rcMargin; rcSelMargin.right = rcMargin.left; - for (int margin=0; margin < vs.margins; margin++) { + for (int margin = 0; margin < vs.margins; margin++) { if (vs.ms[margin].width > 0) { - + rcSelMargin.left = rcSelMargin.right; rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width; @@ -639,13 +666,13 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { */ if (vs.ms[margin].mask & SC_MASK_FOLDERS) // Required because of special way brush is created for selection margin - surface->FillRectangle(rcSelMargin, pixmapSelPattern); + surface->FillRectangle(rcSelMargin, pixmapSelPattern); else - surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); + surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); } else { surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); } - + int visibleLine = topLine; int line = cs.DocFromDisplay(visibleLine); int yposScreen = 0; @@ -669,7 +696,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { sprintf(number, "%d", line + 1); if (foldFlags & 64) sprintf(number, "%X", pdoc->GetLevel(line)); - PRectangle rcNumber=rcMarker; + PRectangle rcNumber = rcMarker; // Right justify int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number)); int xpos = rcNumber.right - width - 3; @@ -677,11 +704,11 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { if ((visibleLine < cs.LinesDisplayed()) && cs.GetVisible(line)) { surface->DrawText(rcNumber, vs.styles[STYLE_LINENUMBER].font, rcNumber.top + vs.maxAscent, number, strlen(number), - vs.styles[STYLE_LINENUMBER].fore.allocated, - vs.styles[STYLE_LINENUMBER].back.allocated); + vs.styles[STYLE_LINENUMBER].fore.allocated, + vs.styles[STYLE_LINENUMBER].back.allocated); } } - + if (marks) { for (int markBit = 0; (markBit < 32) && marks; markBit++) { if (marks & 1) { @@ -692,7 +719,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { marks >>= 1; } } - + visibleLine++; line = cs.DocFromDisplay(visibleLine); yposScreen += vs.lineHeight; @@ -702,8 +729,8 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { PRectangle rcBlankMargin = rcMargin; rcBlankMargin.left = rcSelMargin.right; - surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back.allocated); - + surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back.allocated); + if (bufferedDraw) { surfWindow->Copy(rcMargin, Point(), pixmapSelMargin); } @@ -729,9 +756,11 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font; char styleByte = 0; int styleMask = pdoc->stylingBitsMask; - for (int charInDoc = posLineStart; - charInDoc < posLineEnd && numCharsInLine < LineLayout::maxLineLength - 1; - charInDoc++) { + ll.xHighlightGuide = 0; + if (posLineEnd > (posLineStart + LineLayout::maxLineLength)) { + posLineEnd = posLineStart + LineLayout::maxLineLength; + } + for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) { char chDoc = pdoc->CharAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc); if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { @@ -741,32 +770,46 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou numCharsInLine++; } } - ll.chars[numCharsInLine] = 0; + // Extra element at the end of the line to hold end x position and act as + ll.chars[numCharsInLine] = 0; // Also triggers processing in the loops as this is a control character ll.styles[numCharsInLine] = styleByte; // For eolFilled ll.indicators[numCharsInLine] = 0; - // Layout the line, determining the position of each character + // Layout the line, determining the position of each character, + // with an extra element at the end for the end of the line. int startseg = 0; int startsegx = 0; ll.positions[0] = 0; unsigned int tabWidth = vstyle.spaceWidth * pdoc->tabInChars; - + for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) { if ((ll.styles[charInLine] != ll.styles[charInLine + 1]) || IsControlCharacter(ll.chars[charInLine]) || IsControlCharacter(ll.chars[charInLine + 1])) { ll.positions[startseg] = 0; - if (IsControlCharacter(ll.chars[charInLine])) { - if (ll.chars[charInLine] == '\t') { - ll.positions[charInLine + 1] = ((((startsegx + 2) / - tabWidth) + 1) * tabWidth) - startsegx; + if (vstyle.styles[ll.styles[charInLine]].visible) { + if (IsControlCharacter(ll.chars[charInLine])) { + if (ll.chars[charInLine] == '\t') { + ll.positions[charInLine + 1] = ((((startsegx + 2) / + tabWidth) + 1) * tabWidth) - startsegx; + } else { + const char *ctrlChar = ControlCharacterString(ll.chars[charInLine]); + // +3 For a blank on front and rounded edge each side: + ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3; + } } else { - const char *ctrlChar = ControlCharacterString(ll.chars[charInLine]); - // +3 For a blank on front and rounded edge each side: - ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3; + int lenSeg = charInLine - startseg + 1; + if ((lenSeg == 1) && (' ' == ll.chars[startseg])) { + // Over half the segments are single characters and of these about half are space characters. + ll.positions[charInLine + 1] = vstyle.styles[ll.styles[charInLine]].spaceWidth; + } else { + surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg, + charInLine - startseg + 1, ll.positions + startseg + 1); + } + } + } else { // invisible + for (int posToZero = startseg; posToZero <= (charInLine + 1); posToZero++) { + ll.positions[posToZero] = 0; } - } else { - surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg, - charInLine - startseg + 1, ll.positions + startseg + 1); } for (int posToIncrease = startseg; posToIncrease <= (charInLine + 1); posToIncrease++) { ll.positions[posToIncrease] += startsegx; @@ -778,10 +821,11 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou ll.numCharsInLine = numCharsInLine; } -void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout &ll) { - +void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, + PRectangle rcLine, LineLayout &ll) { + PRectangle rcSegment = rcLine; - + // Using one font for all control characters so it can be controlled independently to ensure // the box goes around the characters tightly. Seems to be no way to work out what height // is taken by an individual character - internal leading gives varying results. @@ -802,12 +846,14 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, marks = pdoc->GetMark(line) & vsDraw.maskInLine; } + bool inIndentation = true; + int indentWidth = pdoc->indentInChars * vsDraw.spaceWidth; + if (indentWidth == 0) + indentWidth = pdoc->tabInChars * vsDraw.spaceWidth; + int posLineStart = pdoc->LineStart(line); int posLineEnd = pdoc->LineStart(line + 1); - int selStart = SelectionStart(line); - int selEnd = SelectionEnd(line); - int styleMask = pdoc->stylingBitsMask; int startseg = 0; for (int i = 0; i < ll.numCharsInLine; i++) { @@ -816,37 +862,57 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, // If there is the end of a style run for any reason if ((ll.styles[i] != ll.styles[i + 1]) || IsControlCharacter(ll.chars[i]) || IsControlCharacter(ll.chars[i + 1]) || - ((selStart != selEnd) && ((iDoc + 1 == selStart) || (iDoc + 1 == selEnd))) || - (i == (theEdge-1))) { + ((ll.selStart != ll.selEnd) && ((iDoc + 1 == ll.selStart) || (iDoc + 1 == ll.selEnd))) || + (i == (ll.edgeColumn - 1))) { int styleMain = ll.styles[i]; Colour textBack = vsDraw.styles[styleMain].back.allocated; Colour textFore = vsDraw.styles[styleMain].fore.allocated; Font &textFont = vsDraw.styles[styleMain].font; - bool inSelection = (iDoc >= selStart) && (iDoc < selEnd) && (selStart != selEnd); - if (inSelection && !hideSelection) { - if (vsDraw.selbackset) - textBack = vsDraw.selbackground.allocated; + bool inSelection = (iDoc >= ll.selStart) && (iDoc < ll.selEnd) && (ll.selStart != ll.selEnd); + if (inSelection) { + if (vsDraw.selbackset) { + if (primarySelection) + textBack = vsDraw.selbackground.allocated; + else + textBack = vsDraw.selbackground2.allocated; + } if (vsDraw.selforeset) textFore = vsDraw.selforeground.allocated; } else { if (marks) textBack = markBack; - if ((edgeState == EDGE_BACKGROUND) && (i >= theEdge) && (ll.chars[i] != '\n') && (ll.chars[i] != '\r')) - textBack = vs.edgecolour.allocated; + if ((vsDraw.edgeState == EDGE_BACKGROUND) && (i >= ll.edgeColumn) && (ll.chars[i] != '\n') && (ll.chars[i] != '\r')) + textBack = vsDraw.edgecolour.allocated; } // Manage tab display if (ll.chars[i] == '\t') { rcSegment.left = ll.positions[i] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; surface->FillRectangle(rcSegment, textBack); - if (vsDraw.viewWhitespace) { + if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) { surface->PenColour(textFore); - PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, - rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); - DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); } - // Manage control character display - } else if (IsControlCharacter(ll.chars[i])) { + if (inIndentation && vsDraw.viewIndentationGuides) { + for (int xIG = ll.positions[i] / indentWidth * indentWidth; xIG < ll.positions[i + 1]; xIG += indentWidth) { + if (xIG >= ll.positions[i] && xIG > 0) { + Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); + PRectangle rcCopyArea(xIG + xStart + 1, rcSegment.top, xIG + xStart + 2, rcSegment.bottom); + surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == xIG) ? + pixmapIndentGuideHighlight : pixmapIndentGuide); + } + } + } + if (vsDraw.viewWhitespace != wsInvisible) { + if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { + PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, + rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); + DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); + } + } + // Manage control character display + } + else if (IsControlCharacter(ll.chars[i])) { + inIndentation = false; const char *ctrlChar = ControlCharacterString(ll.chars[i]); rcSegment.left = ll.positions[i] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; @@ -865,26 +931,42 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, rcChar.left++; rcChar.right--; surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), - textBack, textFore); - // Manage normal display + rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), + textBack, textFore); + // Manage normal display } else { rcSegment.left = ll.positions[startseg] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; - // Only try to 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, rcSegment.top + vsDraw.maxAscent, ll.chars + startseg, i - startseg + 1, textFore, textBack); - if (vsDraw.viewWhitespace) { + if (vsDraw.viewWhitespace != wsInvisible || + (inIndentation && vsDraw.viewIndentationGuides)) { for (int cpos = 0; cpos <= i - startseg; cpos++) { if (ll.chars[cpos + startseg] == ' ') { - int xmid = (ll.positions[cpos + startseg] + ll.positions[cpos + startseg + 1]) / 2; - PRectangle rcDot(xmid + xStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); - rcDot.right = rcDot.left + 1; - rcDot.bottom = rcDot.top + 1; - surface->FillRectangle(rcDot, textFore); + if (vsDraw.viewWhitespace != wsInvisible) { + if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { + int xmid = (ll.positions[cpos + startseg] + ll.positions[cpos + startseg + 1]) / 2; + PRectangle rcDot(xmid + xStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); + rcDot.right = rcDot.left + 1; + rcDot.bottom = rcDot.top + 1; + surface->FillRectangle(rcDot, textFore); + } + } + if (inIndentation && vsDraw.viewIndentationGuides) { + int startSpace = ll.positions[cpos + startseg]; + if (startSpace > 0 && (startSpace % indentWidth == 0)) { + Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); + PRectangle rcCopyArea(startSpace + xStart + 1, rcSegment.top, startSpace + xStart + 2, rcSegment.bottom); + surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == ll.positions[cpos + startseg]) ? + pixmapIndentGuideHighlight : pixmapIndentGuide); + } + } + } else { + inIndentation = false; } } } @@ -905,10 +987,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, for (int indica = 0; indica <= INDIC_MAX; indica++) indStart[indica] = 0; - for (int indicPos = 0; indicPos <= ll.numCharsInLine; indicPos++) { + for (int indicPos = 0; indicPos < ll.numCharsInLine; indicPos++) { if (ll.indicators[indicPos] != ll.indicators[indicPos + 1]) { int mask = 1 << pdoc->stylingBits; - for (int indicnum = 0; mask <= 0x100; indicnum++) { + for (int indicnum = 0; mask < 0x100; indicnum++) { if ((ll.indicators[indicPos + 1] & mask) && !(ll.indicators[indicPos] & mask)) { indStart[indicnum] = ll.positions[indicPos + 1]; } @@ -930,9 +1012,12 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, int xEol = ll.positions[ll.numCharsInLine]; rcSegment.left = xEol + xStart; rcSegment.right = xEol + vsDraw.aveCharWidth + xStart; - bool eolInSelection = (posLineEnd > selStart) && (posLineEnd <= selEnd) && (selStart != selEnd); - if (eolInSelection && !hideSelection && vsDraw.selbackset && (line < pdoc->LinesTotal()-1)) { - surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); + bool eolInSelection = (posLineEnd > ll.selStart) && (posLineEnd <= ll.selEnd) && (ll.selStart != ll.selEnd); + if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) { + if (primarySelection) + surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); + else + surface->FillRectangle(rcSegment, vsDraw.selbackground2.allocated); } else if (marks) { surface->FillRectangle(rcSegment, markBack); } else { @@ -948,12 +1033,12 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, } else { surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); } - - if (edgeState == EDGE_LINE) { - int edgeX = theEdge * vsDraw.spaceWidth; + + if (vsDraw.edgeState == EDGE_LINE) { + int edgeX = ll.edgeColumn * vsDraw.spaceWidth; rcSegment.left = edgeX + xStart; rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vs.edgecolour.allocated); + surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated); } } @@ -984,6 +1069,22 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { pixmapSelPattern.FillRectangle(rcPattern, vs.selbarlight.allocated); } } + if (!pixmapIndentGuide.Initialised()) { + // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line + pixmapIndentGuide.InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + pixmapIndentGuideHighlight.InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + PRectangle rcIG(0, 0, 1, vs.lineHeight); + pixmapIndentGuide.FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated); + pixmapIndentGuide.PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated); + pixmapIndentGuideHighlight.FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated); + pixmapIndentGuideHighlight.PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated); + for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) { + pixmapIndentGuide.MoveTo(0, stripe); + pixmapIndentGuide.LineTo(2, stripe); + pixmapIndentGuideHighlight.MoveTo(0, stripe); + pixmapIndentGuideHighlight.LineTo(2, stripe); + } + } if (bufferedDraw) { if (!pixmapLine.Initialised()) { @@ -1003,7 +1104,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { int screenLinePaintFirst = rcArea.top / vs.lineHeight; // The area to be painted plus one extra line is styled. // The extra line is to determine when a style change, such as statrting a comment flows on to other lines. - int lineStyleLast = topLine + (rcArea.bottom-1) / vs.lineHeight + 1; + int lineStyleLast = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1; //Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast); int endPosPaint = pdoc->Length(); if (lineStyleLast < cs.LinesDisplayed()) @@ -1022,20 +1123,20 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { NotifyUpdateUI(); needUpdateUI = false; } - + PaintSelMargin(surfaceWindow, rcArea); PRectangle rcRightMargin = rcClient; rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth; if (rcArea.Intersects(rcRightMargin)) { - surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated); + surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated); } if (paintState == paintAbandoned) { // Either styling or NotifyUpdateUI noticed that painting is needed // outside the current painting rectangle //Platform::DebugPrintf("Abandoning paint\n"); - return; + return ; } //Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset); @@ -1062,7 +1163,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { rcTextArea.right -= vs.rightMarginWidth; surfaceWindow->SetClip(rcTextArea); //GTimer *tim=g_timer_new(); - while (visibleLine <= cs.LinesDisplayed() && yposScreen < rcArea.bottom) { + while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) { //g_timer_start(tim); //Platform::DebugPrintf("Painting line %d\n", line); @@ -1078,18 +1179,35 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { // and determine the x position at which each character starts. LineLayout ll; LayoutLine(line, surface, vs, ll); - + // Highlight the current braces if any - if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd)) - ll.styles[braces[0] - posLineStart] = - static_cast(bracesMatchStyle); - if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd)) - ll.styles[braces[1] - posLineStart] = - static_cast(bracesMatchStyle); - + if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd)) { + int braceOffset = braces[0] - posLineStart; + if (braceOffset < ll.numCharsInLine) + ll.styles[braceOffset] = static_cast(bracesMatchStyle); + } + if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd)) { + int braceOffset = braces[1] - posLineStart; + if (braceOffset < ll.numCharsInLine) + ll.styles[braceOffset] = static_cast(bracesMatchStyle); + } + if ((braces[0] >= posLineStart && braces[1] <= posLineEnd) || + (braces[1] >= posLineStart && braces[0] <= posLineEnd)) { + ll.xHighlightGuide = highlightGuideColumn * vs.spaceWidth; + } + + ll.selStart = SelectionStart(line); + ll.selEnd = SelectionEnd(line); + if (hideSelection) { + ll.selStart = -1; + ll.selEnd = -1; + } + // Need to fix this up so takes account of Unicode and DBCS + ll.edgeColumn = theEdge; + // Draw the line if (cs.GetVisible(line)) - DrawLine(surface, vs, line, xStart, rcLine, ll); + DrawLine(surface, vs, line, visibleLine, xStart, rcLine, ll); bool expanded = cs.GetExpanded(line); if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) { @@ -1106,17 +1224,19 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); } } - + // Draw the Caret if (line == lineCaret) { int offset = Platform::Minimum(posCaret - posLineStart, LineLayout::maxLineLength); int xposCaret = ll.positions[offset] + xStart; - int widthOverstrikeCaret = - ll.positions[offset + 1] - ll.positions[offset]; - if (posCaret == pdoc->Length()) // At end of document + int widthOverstrikeCaret; + if (posCaret == pdoc->Length()) { // At end of document widthOverstrikeCaret = vs.aveCharWidth; - if ((posCaret - posLineStart) >= ll.numCharsInLine) // At end of line + } else if ((posCaret - posLineStart) >= ll.numCharsInLine) { // At end of line widthOverstrikeCaret = vs.aveCharWidth; + } else { + widthOverstrikeCaret = ll.positions[offset + 1] - ll.positions[offset]; + } if (widthOverstrikeCaret < 3) // Make sure its visible widthOverstrikeCaret = 3; if (((caret.active && caret.on) || (posDrag >= 0)) && xposCaret >= 0) { @@ -1137,12 +1257,12 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface->FillRectangle(rcCaret, vs.caretcolour.allocated); } } - + if (cs.GetVisible(line)) { if (bufferedDraw) { Point from(vs.fixedColumnWidth, 0); PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen, - rcClient.right, yposScreen + vs.lineHeight); + rcClient.right, yposScreen + vs.lineHeight); surfaceWindow->Copy(rcCopyArea, from, pixmapLine); } } @@ -1159,13 +1279,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { //Platform::DebugPrintf("Paint [%0d] took %g\n", line, g_timer_elapsed(tim, 0)); } //g_timer_destroy(tim); + PRectangle rcBeyondEOF = rcClient; rcBeyondEOF.left = vs.fixedColumnWidth; rcBeyondEOF.right = rcBeyondEOF.right; rcBeyondEOF.top = (cs.LinesDisplayed() - topLine) * vs.lineHeight; if (rcBeyondEOF.top < rcBeyondEOF.bottom) { surfaceWindow->FillRectangle(rcBeyondEOF, vs.styles[STYLE_DEFAULT].back.allocated); - if (edgeState == EDGE_LINE) { + if (vs.edgeState == EDGE_LINE) { int edgeX = theEdge * vs.spaceWidth; rcBeyondEOF.left = edgeX + xStart; rcBeyondEOF.right = rcBeyondEOF.left + 1; @@ -1178,10 +1299,24 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { // Space (3 space characters) between line numbers and text when printing. #define lineNumberPrintSpace " " +Colour InvertedLight(Colour orig) { + unsigned int r = orig.GetRed(); + unsigned int g = orig.GetGreen(); + unsigned int b = orig.GetBlue(); + unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye + unsigned int il = 0xff - l; + if (l == 0) + return Colour(0xff, 0xff, 0xff); + r = r * il / l; + g = g * il / l; + b = b * il / l; + return Colour(Platform::Minimum(r, 0xff), Platform::Minimum(g, 0xff), Platform::Minimum(b, 0xff)); +} + // This is mostly copied from the Paint method but with some things omitted // such as the margin markers, line numbers, selection and caret // Should be merged back into a combined Draw method. -long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { +long Editor::FormatRange(bool draw, RangeToFormat *pfr) { if (!pfr) return 0; @@ -1191,13 +1326,13 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { Surface *surfaceMeasure = new Surface(); surfaceMeasure->Init(pfr->hdcTarget); surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); - + ViewStyle vsPrint(vs); - + // Modify the view style for printing as do not normally want any of the transient features to be printed // Printing supports only the line number margin. int lineNumberIndex = -1; - for (int margin=0; margin < ViewStyle::margins; margin++) { + for (int margin = 0; margin < ViewStyle::margins; margin++) { if ((!vsPrint.ms[margin].symbol) && (vsPrint.ms[margin].width > 0)) { lineNumberIndex = margin; } else { @@ -1206,13 +1341,24 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { } vsPrint.showMarkedLines = false; vsPrint.fixedColumnWidth = 0; - vsPrint.zoomLevel = 0; + vsPrint.zoomLevel = printMagnification; + vsPrint.viewIndentationGuides = false; // Don't show the selection when printing vsPrint.selbackset = false; vsPrint.selforeset = false; // White background for the line numbers - vsPrint.styles[STYLE_LINENUMBER].back.desired = Colour(0xff,0xff,0xff); - + vsPrint.styles[STYLE_LINENUMBER].back.desired = Colour(0xff, 0xff, 0xff); + for (int sty = 0;sty <= STYLE_MAX;sty++) { + if (printColourMode == SC_PRINT_INVERTLIGHT) { + vsPrint.styles[sty].fore.desired = InvertedLight(vsPrint.styles[sty].fore.desired); + vsPrint.styles[sty].back.desired = InvertedLight(vsPrint.styles[sty].back.desired); + } else if (printColourMode == SC_PRINT_BLACKONWHITE) { + vsPrint.styles[sty].fore.desired = Colour(0, 0, 0); + vsPrint.styles[sty].back.desired = Colour(0xff, 0xff, 0xff); + } + } + vsPrint.styles[STYLE_LINENUMBER].back.desired = Colour(0xff, 0xff, 0xff); + vsPrint.Refresh(*surfaceMeasure); // Ensure colours are set up vsPrint.RefreshColourPalette(palette, true); @@ -1220,8 +1366,8 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { // Determining width must hapen after fonts have been realised in Refresh int lineNumberWidth = 0; if (lineNumberIndex >= 0) { - lineNumberWidth = surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, - "9999" lineNumberPrintSpace, 4 + strlen(lineNumberPrintSpace)); + lineNumberWidth = surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, + "9999" lineNumberPrintSpace, 4 + strlen(lineNumberPrintSpace)); vsPrint.ms[lineNumberIndex].width = lineNumberWidth; } @@ -1255,35 +1401,39 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { rcLine.top = ypos; rcLine.right = pfr->rc.right; rcLine.bottom = ypos + vsPrint.lineHeight; - + if (lineNumberWidth) { char number[100]; sprintf(number, "%d" lineNumberPrintSpace, line + 1); PRectangle rcNumber = rcLine; rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify - rcNumber.left -= - surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number)); + 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); + 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 + // 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); - + ll.selStart = -1; + ll.selEnd = -1; + // Need to fix this up so takes account of Unicode and DBCS + ll.edgeColumn = theEdge; + // Draw the line surface->FlushCachedState(); - DrawLine(surface, vsPrint, line, xStart, rcLine, ll); + DrawLine(surface, vsPrint, line, line, xStart, rcLine, ll); ypos += vsPrint.lineHeight; line++; @@ -1297,8 +1447,8 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { } // Empty method is overridden on GTK+ to show / hide scrollbars -void Editor::ReconfigureScrollBars() { -} +void Editor::ReconfigureScrollBars() {} + void Editor::SetScrollBarsTo(PRectangle) { RefreshStyleData(); @@ -1319,6 +1469,7 @@ void Editor::SetScrollBarsTo(PRectangle) { //Platform::DebugPrintf("end max = %d page = %d\n", nMax, nPage); } + void Editor::SetScrollBars() { PRectangle rsClient = GetClientRectangle(); SetScrollBarsTo(rsClient); @@ -1344,6 +1495,8 @@ void Editor::AddCharUTF(char *s, unsigned int len) { pdoc->InsertString(currentPos, s, len); SetEmptySelection(currentPos + len); EnsureCaretVisible(); + // Avoid blinking during rapid typing: + ShowCaretAtCurrentPosition(); SetLastXChosen(); NotifyChar(s[0]); } @@ -1354,7 +1507,7 @@ void Editor::ClearSelection() { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); int startPos = SelectionStart(); - for (int line=lineEnd; line >= lineStart; line--) { + for (int line = lineEnd; line >= lineStart; line--) { startPos = SelectionStart(line); unsigned int chars = SelectionEnd(line) - startPos; if (0 != chars) { @@ -1385,6 +1538,13 @@ void Editor::ClearAll() { SetVerticalScrollPos(); } +void Editor::ClearDocumentStyle() { + pdoc->StartStyling(0, '\377'); + pdoc->SetStyleFor(pdoc->Length(), 0); + cs.ShowAll(); + pdoc->ClearLevels(); +} + void Editor::Cut() { Copy(); ClearSelection(); @@ -1396,9 +1556,9 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) { int xInsert = XFromPosition(currentPos); int line = pdoc->LineFromPosition(currentPos); bool prevCr = false; - for (int i=0; i= pdoc->LinesTotal()) { if (pdoc->eolMode != SC_EOL_LF) @@ -1409,7 +1569,7 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) { currentPos = PositionFromLineX(line, xInsert); prevCr = ptr[i] == '\r'; } else { - pdoc->InsertString(currentPos, ptr+i, 1); + pdoc->InsertString(currentPos, ptr + i, 1); currentPos++; insertPos = currentPos; prevCr = false; @@ -1434,6 +1594,7 @@ void Editor::SelectAll() { void Editor::Undo() { if (pdoc->CanUndo()) { + InvalidateCaret(); int newPos = pdoc->Undo(); SetEmptySelection(newPos); EnsureCaretVisible(); @@ -1450,6 +1611,8 @@ void Editor::Redo() { void Editor::DelChar() { pdoc->DelChar(currentPos); + // Avoid blinking during rapid typing: + ShowCaretAtCurrentPosition(); } void Editor::DelCharBack() { @@ -1460,10 +1623,12 @@ void Editor::DelCharBack() { ClearSelection(); SetEmptySelection(currentPos); } + // Avoid blinking during rapid typing: + ShowCaretAtCurrentPosition(); } -void Editor::NotifyFocus(bool) { -} +void Editor::NotifyFocus(bool) {} + void Editor::NotifyStyleToNeeded(int endStyleNeeded) { SCNotification scn; @@ -1486,9 +1651,9 @@ void Editor::NotifyChar(char ch) { char txt[2]; txt[0] = ch; txt[1] = '\0'; - NotifyMacroRecord(EM_REPLACESEL, 0, (LPARAM) txt); + NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(txt)); } -#endif +#endif } void Editor::NotifySavePoint(bool isSavePoint) { @@ -1522,7 +1687,7 @@ void Editor::NotifyUpdateUI() { bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { int marginClicked = -1; int x = 0; - for (int margin=0; margin < ViewStyle::margins; margin++) { + for (int margin = 0; margin < ViewStyle::margins; margin++) { if ((pt.x > x) && (pt.x < x + vs.ms[margin].width)) marginClicked = margin; x += vs.ms[margin].width; @@ -1555,6 +1720,13 @@ void Editor::NotifyModifyAttempt(Document*, void *) { NotifyModifyAttempt(); } +void Editor::NotifyMove(int position) { + SCNotification scn; + scn.nmhdr.code = SCN_POSCHANGED; + scn.position = position; + NotifyParent(scn); +} + void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) { //Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off"); NotifySavePoint(atSavePoint); @@ -1618,11 +1790,15 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { } } } - if (mh.modificationType & SC_MOD_BEFOREINSERT) { - NotifyNeedShown(mh.position, 0); - } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { - NotifyNeedShown(mh.position, mh.length); - } + if (cs.LinesDisplayed() < cs.LinesInDoc()) { + // Some lines are hidden so may need shown. + // TODO: check if the modified area is hidden. + if (mh.modificationType & SC_MOD_BEFOREINSERT) { + NotifyNeedShown(mh.position, 0); + } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { + NotifyNeedShown(mh.position, mh.length); + } + } if (mh.linesAdded != 0) { // Update contraction state for inserted and removed lines @@ -1641,7 +1817,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { SetVerticalScrollPos(); } } - + //Platform::DebugPrintf("** %x Doc Changed\n", this); // TODO: could invalidate from mh.startModification to end of screen //InvalidateRange(mh.position, mh.position + mh.length); @@ -1661,13 +1837,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { 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) { // Real modification made to text of document. NotifyChange(); // Send EN_CHANGE } + SCNotification scn; scn.nmhdr.code = SCN_MODIFIED; scn.position = mh.position; @@ -1687,15 +1864,15 @@ void Editor::NotifyDeleted(Document *, void *) { } #ifdef MACRO_SUPPORT -void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { +void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam) { // Enumerates all macroable messages switch (iMessage) { - case WM_CUT: - case WM_COPY: - case WM_PASTE: - case WM_CLEAR: - case EM_REPLACESEL: + case SCI_CUT: + case SCI_COPY: + case SCI_PASTE: + case SCI_CLEAR: + case SCI_REPLACESEL: case SCI_ADDTEXT: case SCI_INSERTTEXT: case SCI_CLEARALL: @@ -1747,10 +1924,11 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_UPPERCASE: break; - // Filter out all others (display changes, etc) + // Filter out all others (display changes, etc) default: -// printf("Filtered out %ld of macro recording\n", iMessage); - return; + // printf("Filtered out %ld of macro recording\n", iMessage); + + return ; } // Send notification @@ -1761,13 +1939,13 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { scn.lParam = lParam; NotifyParent(scn); } -#endif +#endif // Force scroll and keep position relative to top of window void Editor::PageMove(int direction, bool extend) { Point pt = LocationFromPosition(currentPos); int topLineNew = Platform::Clamp( - topLine + direction * LinesToScroll(), 0, MaxScrollPos()); + topLine + direction * LinesToScroll(), 0, MaxScrollPos()); int newPos = PositionFromLocation( Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll()))); if (topLineNew != topLine) { @@ -1787,17 +1965,17 @@ void Editor::ChangeCaseOfSelection(bool makeUpperCase) { if (selType == selRectangle) { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); - for (int line=lineEnd; line >= lineStart; line--) { + for (int line = lineEnd; line >= lineStart; line--) { pdoc->ChangeCase( - Range(SelectionStart(line), SelectionEnd(line)), - makeUpperCase); + 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); + pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()), + makeUpperCase); SetSelection(startCurrent, startAnchor); } pdoc->EndUndoAction(); @@ -1807,34 +1985,37 @@ void Editor::ChangeCaseOfSelection(bool makeUpperCase) { void Editor::LineTranspose() { int line = pdoc->LineFromPosition(currentPos); if (line > 0) { - int startPrev = pdoc->LineStart(line-1); - int endPrev = pdoc->LineEnd(line-1); + 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); + 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); + 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); + 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) { +void Editor::CancelModes() {} + + +int Editor::KeyCommand(unsigned int iMessage) { Point pt = LocationFromPosition(currentPos); switch (iMessage) { @@ -1950,10 +2131,11 @@ int Editor::KeyCommand(UINT iMessage) { inOverstrike = !inOverstrike; DropCaret(); ShowCaretAtCurrentPosition(); + NotifyUpdateUI(); break; - case SCI_CANCEL: // Cancel any modes - handled in subclass + case SCI_CANCEL: // Cancel any modes - handled in subclass // Also unselect text - SetEmptySelection(currentPos); + CancelModes(); break; case SCI_DELETEBACK: DelCharBack(); @@ -1962,9 +2144,13 @@ int Editor::KeyCommand(UINT iMessage) { break; case SCI_TAB: Indent(true); + SetLastXChosen(); + EnsureCaretVisible(); break; case SCI_BACKTAB: Indent(false); + SetLastXChosen(); + EnsureCaretVisible(); break; case SCI_NEWLINE: ClearSelection(); @@ -2028,16 +2214,16 @@ int Editor::KeyCommand(UINT iMessage) { lineStart = t; } int start = pdoc->LineStart(lineStart); - int end = pdoc->LineStart(lineEnd+1); - SetSelection(start,end); + 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); + int end = pdoc->LineStart(line + 1); + pdoc->DeleteChars(start, end - start); MovePositionTo(start); } break; @@ -2068,11 +2254,11 @@ int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt) { return KeyDefault(key, modifiers); } -void Editor::SetWhitespaceVisible(bool view) { - vs.viewWhitespace = view; +void Editor::SetWhitespaceVisible(int view) { + vs.viewWhitespace = static_cast(view); } -bool Editor::GetWhitespaceVisible() { +int Editor::GetWhitespaceVisible() { return vs.viewWhitespace; } @@ -2082,9 +2268,15 @@ void Editor::Indent(bool forwards) { int lineCurrentPos = pdoc->LineFromPosition(currentPos); if (lineOfAnchor == lineCurrentPos) { ClearSelection(); - pdoc->InsertChar(currentPos, '\t'); - //pdoc->InsertChar(currentPos++, '\t'); - SetEmptySelection(currentPos + 1); + if (pdoc->useTabs) { + pdoc->InsertChar(currentPos, '\t'); + SetEmptySelection(currentPos + 1); + } else { + for (int i = 0; i < pdoc->tabInChars; i++) { + pdoc->InsertChar(currentPos, ' '); + } + SetEmptySelection(currentPos + pdoc->tabInChars); + } } else { int anchorPosOnLine = anchor - pdoc->LineStart(lineOfAnchor); int currentPosPosOnLine = currentPos - pdoc->LineStart(lineCurrentPos); @@ -2110,12 +2302,13 @@ void Editor::Indent(bool forwards) { } } -long Editor::FindText(UINT iMessage, WPARAM wParam, LPARAM lParam) { - FINDTEXTEX *ft = reinterpret_cast(lParam); +long Editor::FindText(unsigned int iMessage, unsigned long wParam, long lParam) { + TextToFind *ft = reinterpret_cast(lParam); int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText, - wParam & FR_MATCHCASE, wParam & FR_WHOLEWORD); + wParam & SCFIND_MATCHCASE, wParam & SCFIND_WHOLEWORD, + wParam & SCFIND_WORDSTART); if (pos != -1) { - if (iMessage == EM_FINDTEXTEX) { + if (iMessage != EM_FINDTEXT) { ft->chrgText.cpMin = pos; ft->chrgText.cpMax = pos + strlen(ft->lpstrText); } @@ -2123,8 +2316,8 @@ long Editor::FindText(UINT iMessage, WPARAM wParam, LPARAM lParam) { return pos; } -// Relocatable search support : Searches relative to current selection -// point and sets the selection to the found text range with +// Relocatable search support : Searches relative to current selection +// point and sets the selection to the found text range with // each search. // Anchor following searches at current selection start: This allows @@ -2139,18 +2332,20 @@ void Editor::SearchAnchor() { // Accepts both SCI_SEARCHNEXT and SCI_SEARCHPREV. // wParam contains search modes : ORed FR_MATCHCASE and FR_WHOLEWORD. // lParam contains the text to search for. -long Editor::SearchText(UINT iMessage, WPARAM wParam, LPARAM lParam) { +long Editor::SearchText(unsigned int iMessage, unsigned long wParam, long lParam) { const char *txt = reinterpret_cast(lParam); int pos; if (iMessage == SCI_SEARCHNEXT) { - pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, - wParam & FR_MATCHCASE, - wParam & FR_WHOLEWORD); + pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, + wParam & SCFIND_MATCHCASE, + wParam & SCFIND_WHOLEWORD, + wParam & SCFIND_WORDSTART); } else { - pos = pdoc->FindText(searchAnchor, 0, txt, - wParam & FR_MATCHCASE, - wParam & FR_WHOLEWORD); + pos = pdoc->FindText(searchAnchor, 0, txt, + wParam & SCFIND_MATCHCASE, + wParam & SCFIND_WHOLEWORD, + wParam & SCFIND_WORDSTART); } if (pos != -1) { @@ -2198,7 +2393,7 @@ int Editor::SelectionRangeLength() { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); int totalSize = 0; - for (int line=lineStart; line <= lineEnd; line++) { + for (int line = lineStart; line <= lineEnd; line++) { totalSize += SelectionEnd(line) - SelectionStart(line) + 1; if (pdoc->eolMode == SC_EOL_CRLF) totalSize++; @@ -2219,8 +2414,8 @@ char *Editor::CopySelectionRange() { text = new char[totalSize + 1]; if (text) { int j = 0; - for (int line=lineStart; line <= lineEnd; line++) { - for (int i=SelectionStart(line);iCharAt(i); } if (pdoc->eolMode != SC_EOL_LF) @@ -2250,7 +2445,7 @@ void Editor::CopySelectionIntoDrag() { void Editor::SetDragPosition(int newPos) { if (newPos >= 0) { - newPos = pdoc->MovePositionOutsideChar(newPos, 1); + newPos = MovePositionOutsideChar(newPos, 1); posDrop = newPos; } if (posDrag != newPos) { @@ -2268,6 +2463,7 @@ void Editor::StartDrag() { //wDraw.SetCursor(Window::cursorArrow); } + void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) { //Platform::DebugPrintf("DropAt %d\n", inDragDrop); if (inDragDrop) @@ -2275,15 +2471,15 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul int positionWasInSelection = PositionInSelection(position); - bool positionOnEdgeOfSelection = - (position == SelectionStart()) || (position == SelectionEnd()); + bool positionOnEdgeOfSelection = + (position == SelectionStart()) || (position == SelectionEnd()); - if ((!inDragDrop) || !(0 == positionWasInSelection) || - (positionOnEdgeOfSelection && !moving)) { + if ((!inDragDrop) || !(0 == positionWasInSelection) || + (positionOnEdgeOfSelection && !moving)) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); - + pdoc->BeginUndoAction(); int positionAfterDeletion = position; @@ -2292,7 +2488,7 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul if (rectangular) { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); - for (int line=lineStart; line <= lineEnd; line++) { + for (int line = lineStart; line <= lineEnd; line++) { int startPos = SelectionStart(line); int endPos = SelectionEnd(line); if (position >= startPos) { @@ -2311,14 +2507,14 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul ClearSelection(); } position = positionAfterDeletion; - + if (rectangular) { PasteRectangular(position, value, strlen(value)); pdoc->EndUndoAction(); // Should try to select new rectangle but it may not be a rectangle now so just select the drop position - SetSelection(position, position); + SetSelection(position, position); } else { - position = pdoc->MovePositionOutsideChar(position, currentPos - position); + position = MovePositionOutsideChar(position, currentPos - position); pdoc->InsertString(position, value); pdoc->EndUndoAction(); SetSelection(position + strlen(value), position); @@ -2338,7 +2534,7 @@ static int BeforeInOrAfter(int val, int minim, int maxim) { } int Editor::PositionInSelection(int pos) { - pos = pdoc->MovePositionOutsideChar(pos, currentPos - pos); + pos = MovePositionOutsideChar(pos, currentPos - pos); if (selType == selRectangle) { if (pos < SelectionStart()) return -1; @@ -2392,13 +2588,13 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b //Platform::DebugPrintf("Scintilla:ButtonDown %d %d = %d alt=%d\n", curTime, lastClickTime, curTime - lastClickTime, alt); ptMouseLast = pt; int newPos = PositionFromLocation(pt); - newPos = pdoc->MovePositionOutsideChar(newPos, currentPos - newPos); + newPos = MovePositionOutsideChar(newPos, currentPos - newPos); inDragDrop = false; - + bool processed = NotifyMarginClick(pt, shift, ctrl, alt); if (processed) - return; - + return ; + if (shift) { SetSelection(newPos); } @@ -2444,7 +2640,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b if (ctrl) { SelectAll(); lastClickTime = curTime; - return; + return ; } lineAnchor = LineFromLocation(pt); // While experimenting with folding turn off line selection @@ -2491,7 +2687,7 @@ void Editor::ButtonMove(Point pt) { xEndSelect = pt.x - vs.fixedColumnWidth + xOffset; ptMouseLast = pt; int movePos = PositionFromLocation(pt); - movePos = pdoc->MovePositionOutsideChar(movePos, currentPos - movePos); + movePos = MovePositionOutsideChar(movePos, currentPos - movePos); if (posDrag >= 0) { SetDragPosition(movePos); } else { @@ -2511,10 +2707,10 @@ void Editor::ButtonMove(Point pt) { int lineMove = LineFromLocation(pt); if (lineAnchor < lineMove) { SetSelection(pdoc->LineStart(lineMove + 1), - pdoc->LineStart(lineAnchor)); + pdoc->LineStart(lineAnchor)); } else { SetSelection(pdoc->LineStart(lineMove), - pdoc->LineStart(lineAnchor + 1)); + pdoc->LineStart(lineAnchor + 1)); } } } @@ -2523,8 +2719,9 @@ void Editor::ButtonMove(Point pt) { if (vs.fixedColumnWidth > 0) { // There is a margin if (PointInSelMargin(pt)) { wDraw.SetCursor(Window::cursorReverseArrow); - return; // No need to test for selection + return ; // No need to test for selection } + } // Display regular (drag) cursor over selection if (PointInSelection(pt)) @@ -2547,7 +2744,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { ptMouseLast = pt; SetMouseCapture(false); int newPos = PositionFromLocation(pt); - newPos = pdoc->MovePositionOutsideChar(newPos, currentPos - newPos); + newPos = MovePositionOutsideChar(newPos, currentPos - newPos); if (inDragDrop) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); @@ -2609,53 +2806,53 @@ static bool IsIn(int a, int minimum, int maximum) { } static bool IsOverlap(int mina, int maxa, int minb, int maxb) { - return - IsIn(mina, minb, maxb) || - IsIn(maxa, minb, maxb) || - IsIn(minb, mina, maxa) || - IsIn(maxb, mina, maxa); + return + IsIn(mina, minb, maxb) || + IsIn(maxa, minb, maxb) || + IsIn(minb, mina, maxa) || + IsIn(maxb, mina, maxa); } void Editor::CheckForChangeOutsidePaint(Range r) { if (paintState == painting && !paintingAllText) { //Platform::DebugPrintf("Checking range in paint %d-%d\n", r.start, r.end); if (!r.Valid()) - return; - + return ; + PRectangle rcText = GetTextRectangle(); // Determine number of lines displayed including a possible partially displayed last line int linesDisplayed = (rcText.bottom - rcText.top - 1) / vs.lineHeight + 1; int bottomLine = topLine + linesDisplayed - 1; - + int lineRangeStart = cs.DisplayFromDoc(pdoc->LineFromPosition(r.start)); int lineRangeEnd = cs.DisplayFromDoc(pdoc->LineFromPosition(r.end)); if (!IsOverlap(topLine, bottomLine, lineRangeStart, lineRangeEnd)) { //Platform::DebugPrintf("No overlap (%d-%d) with window(%d-%d)\n", // lineRangeStart, lineRangeEnd, topLine, bottomLine); - return; + return ; } - + // Assert rcPaint contained within or equal to rcText if (rcPaint.top > rcText.top) { - // does range intersect rcText.top .. rcPaint.top - int paintTopLine = ((rcPaint.top - rcText.top-1) / vs.lineHeight) + topLine; + // does range intersect rcText.top .. rcPaint.top + int paintTopLine = ((rcPaint.top - rcText.top - 1) / vs.lineHeight) + topLine; // paintTopLine is the top line of the paint rectangle or the line just above if that line is completely inside the paint rectangle if (IsOverlap(topLine, paintTopLine, lineRangeStart, lineRangeEnd)) { - //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n", + //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n", // lineRangeStart, lineRangeEnd, topLine, paintTopLine); paintState = paintAbandoned; - return; + return ; } } if (rcPaint.bottom < rcText.bottom) { // does range intersect rcPaint.bottom .. rcText.bottom - int paintBottomLine = ((rcPaint.bottom - rcText.top-1) / vs.lineHeight + 1) + topLine; + int paintBottomLine = ((rcPaint.bottom - rcText.top - 1) / vs.lineHeight + 1) + topLine; // paintTopLine is the bottom line of the paint rectangle or the line just below if that line is completely inside the paint rectangle if (IsOverlap(paintBottomLine, bottomLine, lineRangeStart, lineRangeEnd)) { - //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n", + //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n", // lineRangeStart, lineRangeEnd, paintBottomLine, bottomLine); paintState = paintAbandoned; - return; + return ; } } } @@ -2663,15 +2860,24 @@ void Editor::CheckForChangeOutsidePaint(Range r) { char BraceOpposite(char ch) { switch (ch) { - case '(': return ')'; - case ')': return '('; - case '[': return ']'; - case ']': return '['; - case '{': return '}'; - case '}': return '{'; - case '<': return '>'; - case '>': return '<'; - default: return '\0'; + case '(': + return ')'; + case ')': + return '('; + case '[': + return ']'; + case ']': + return '['; + case '{': + return '}'; + case '}': + return '{'; + case '<': + return '>'; + case '>': + return '<'; + default: + return '\0'; } } @@ -2684,7 +2890,7 @@ int Editor::BraceMatch(int position, int /*maxReStyle*/) { if (chSeek == '\0') return - 1; char styBrace = static_cast( - pdoc->StyleAt(position) & pdoc->stylingBitsMask); + pdoc->StyleAt(position) & pdoc->stylingBitsMask); int direction = -1; if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') direction = 1; @@ -2708,12 +2914,12 @@ int Editor::BraceMatch(int position, int /*maxReStyle*/) { void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) { if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) { - if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) { + if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) { CheckForChangeOutsidePaint(Range(braces[0])); CheckForChangeOutsidePaint(Range(pos0)); braces[0] = pos0; } - if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) { + if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) { CheckForChangeOutsidePaint(Range(braces[1])); CheckForChangeOutsidePaint(Range(pos1)); braces[1] = pos1; @@ -2737,7 +2943,7 @@ void Editor::SetDocPointer(Document *document) { pdoc->AddRef(); // Reset the contraction state to fully shown. cs.Clear(); - cs.InsertLines(0, pdoc->LinesTotal()-1); + cs.InsertLines(0, pdoc->LinesTotal() - 1); pdoc->AddWatcher(this, 0); Redraw(); @@ -2770,7 +2976,7 @@ void Editor::ToggleContraction(int line) { int lineMaxSubord = pdoc->GetLastChild(line); cs.SetExpanded(line, 0); if (lineMaxSubord > line) { - cs.SetVisible(line+1, lineMaxSubord, false); + cs.SetVisible(line + 1, lineMaxSubord, false); SetScrollBars(); Redraw(); } @@ -2801,35 +3007,37 @@ void Editor::EnsureLineVisible(int line) { } } -static bool ValidMargin(WPARAM wParam) { +static bool ValidMargin(unsigned long wParam) { return wParam < ViewStyle::margins; } -LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { +long Editor::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); // Optional macro recording hook #ifdef MACRO_SUPPORT if (recordingMacro) NotifyMacroRecord(iMessage, wParam, lParam); -#endif +#endif switch (iMessage) { case WM_GETTEXT: + case SCI_GETTEXT: { if (lParam == 0) return 0; char *ptr = reinterpret_cast(lParam); unsigned int iChar = 0; - for (; iChar < wParam-1; iChar++) + for (; iChar < wParam - 1; iChar++) ptr[iChar] = pdoc->CharAt(iChar); ptr[iChar] = '\0'; return iChar; } case WM_SETTEXT: + case SCI_SETTEXT: { if (lParam == 0) return FALSE; @@ -2840,33 +3048,35 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { } case WM_GETTEXTLENGTH: + case SCI_GETTEXTLENGTH: return pdoc->Length(); - case WM_NOTIFY: - //Platform::DebugPrintf("S notify %d %d\n", wParam, lParam); - break; - case WM_CUT: + case SCI_CUT: Cut(); SetLastXChosen(); break; case WM_COPY: + case SCI_COPY: Copy(); break; case WM_PASTE: + case SCI_PASTE: Paste(); SetLastXChosen(); EnsureCaretVisible(); break; case WM_CLEAR: + case SCI_CLEAR: Clear(); SetLastXChosen(); break; case WM_UNDO: + case SCI_UNDO: Undo(); SetLastXChosen(); break; @@ -2922,6 +3132,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { // EM_DISPLAYBAND case EM_CANUNDO: + case SCI_CANUNDO: return pdoc->CanUndo() ? TRUE : FALSE; case EM_UNDO: @@ -2930,10 +3141,12 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case EM_EMPTYUNDOBUFFER: + case SCI_EMPTYUNDOBUFFER: pdoc->DeleteUndoHistory(); return 0; case EM_GETFIRSTVISIBLELINE: + case SCI_GETFIRSTVISIBLELINE: return topLine; case EM_GETLINE: { @@ -2942,7 +3155,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { int lineStart = pdoc->LineStart(wParam); int lineEnd = pdoc->LineStart(wParam + 1); char *ptr = reinterpret_cast(lParam); - WORD *pBufSize = reinterpret_cast(lParam); + short *pBufSize = reinterpret_cast(lParam); if (*pBufSize < lineEnd - lineStart) { ptr[0] = '\0'; // If no characters copied have to put a NUL into buffer return 0; @@ -2953,13 +3166,27 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return iPlace; } + case SCI_GETLINE: { + if (lParam == 0) + return 0; + int lineStart = pdoc->LineStart(wParam); + int lineEnd = pdoc->LineStart(wParam + 1); + char *ptr = reinterpret_cast(lParam); + int iPlace = 0; + for (int iChar = lineStart; iChar < lineEnd; iChar++) + ptr[iPlace++] = pdoc->CharAt(iChar); + return iPlace; + } + case EM_GETLINECOUNT: + case SCI_GETLINECOUNT: if (pdoc->LinesTotal() == 0) return 1; else return pdoc->LinesTotal(); case EM_GETMODIFY: + case SCI_GETMODIFY: return !pdoc->IsSavePoint(); case EM_GETRECT: @@ -2973,24 +3200,28 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { *reinterpret_cast(wParam) = SelectionStart(); if (lParam) *reinterpret_cast(lParam) = SelectionEnd(); - return MAKELONG(SelectionStart(), SelectionEnd()); + return Platform::LongFromTwoShorts( + static_cast(SelectionStart()), + static_cast(SelectionEnd())); case EM_EXGETSEL: { if (lParam == 0) return 0; - CHARRANGE *pCR = reinterpret_cast(lParam); + CharacterRange *pCR = reinterpret_cast(lParam); pCR->cpMin = SelectionStart(); pCR->cpMax = SelectionEnd(); } break; - case EM_SETSEL: { + case EM_SETSEL: + case SCI_SETSEL: { int nStart = static_cast(wParam); int nEnd = static_cast(lParam); if (nEnd < 0) nEnd = pdoc->Length(); if (nStart < 0) nStart = nEnd; // Remove selection + selType = selStream; SetSelection(nEnd, nStart); EnsureCaretVisible(); } @@ -2999,7 +3230,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case EM_EXSETSEL: { if (lParam == 0) return 0; - CHARRANGE *pCR = reinterpret_cast(lParam); + CharacterRange *pCR = reinterpret_cast(lParam); + selType = selStream; if (pCR->cpMax == -1) { SetSelection(pCR->cpMin, pdoc->Length()); } else { @@ -3009,7 +3241,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return pdoc->LineFromPosition(SelectionStart()); } - case EM_GETSELTEXT: { + case EM_GETSELTEXT: + case SCI_GETSELTEXT: { if (lParam == 0) return 0; char *ptr = reinterpret_cast(lParam); @@ -3035,7 +3268,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { lParam = SelectionStart(); // Not specified, but probably OK return pdoc->LineFromPosition(lParam); + case SCI_LINEFROMPOSITION: + if (static_cast(wParam) < 0) + return 0; + return pdoc->LineFromPosition(wParam); + case EM_LINEINDEX: + case SCI_POSITIONFROMLINE: if (static_cast(wParam) < 0) wParam = pdoc->LineFromPosition(SelectionStart()); if (wParam == 0) @@ -3046,8 +3285,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { // return -1; return pdoc->LineStart(wParam); - case EM_LINELENGTH: - { + case EM_LINELENGTH: { if (static_cast(wParam) < 0) // Who use this anyway? return 0; // Should be... Too complex to describe here, see MS specs! if (static_cast(wParam) > pdoc->Length()) // Useful test, anyway... @@ -3068,7 +3306,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return 0; return pdoc->LineStart(wParam + 1) - pdoc->LineStart(wParam); - case EM_REPLACESEL: { + case EM_REPLACESEL: + case SCI_REPLACESEL: { if (lParam == 0) return 0; pdoc->BeginUndoAction(); @@ -3082,19 +3321,26 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case EM_LINESCROLL: + case SCI_LINESCROLL: ScrollTo(topLine + lParam); HorizontalScrollTo(xOffset + wParam * vs.spaceWidth); return TRUE; case EM_SCROLLCARET: + case SCI_SCROLLCARET: EnsureCaretVisible(); break; case EM_SETREADONLY: + case SCI_SETREADONLY: pdoc->SetReadOnly(wParam); return TRUE; + case SCI_GETREADONLY: + return pdoc->IsReadOnly(); + case EM_CANPASTE: + case SCI_CANPASTE: return 1; case EM_CHARFROMPOS: { @@ -3103,7 +3349,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { Point *ppt = reinterpret_cast(lParam); int pos = PositionFromLocation(*ppt); int line = pdoc->LineFromPosition(pos); - return MAKELONG(pos, line); + return Platform::LongFromTwoShorts( + static_cast(pos), static_cast < short > (line)); } case EM_POSFROMCHAR: { @@ -3119,16 +3366,34 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return 0; } + case SCI_POINTXFROMPOSITION: + if (lParam < 0) { + return 0; + } else { + Point pt = LocationFromPosition(lParam); + return pt.x; + } + + case SCI_POINTYFROMPOSITION: + if (lParam < 0) { + return 0; + } else { + Point pt = LocationFromPosition(lParam); + return pt.y; + } + case EM_FINDTEXT: return FindText(iMessage, wParam, lParam); case EM_FINDTEXTEX: + case SCI_FINDTEXT: return FindText(iMessage, wParam, lParam); - case EM_GETTEXTRANGE: { + case EM_GETTEXTRANGE: + case SCI_GETTEXTRANGE: { if (lParam == 0) return 0; - TEXTRANGE *tr = reinterpret_cast(lParam); + TextRange *tr = reinterpret_cast(lParam); int cpMax = tr->chrg.cpMax; if (cpMax == -1) cpMax = pdoc->Length(); @@ -3139,11 +3404,16 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return len; // Not including NUL } + case EM_SELECTIONTYPE: +#ifdef SEL_EMPTY if (currentPos == anchor) return SEL_EMPTY; else return SEL_TEXT; +#else + return 0; +#endif case EM_HIDESELECTION: hideSelection = wParam; @@ -3151,25 +3421,45 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case EM_FORMATRANGE: - return FormatRange(wParam, reinterpret_cast(lParam)); + case SCI_FORMATRANGE: + return FormatRange(wParam, reinterpret_cast(lParam)); case EM_GETMARGINS: - return MAKELONG(vs.leftMarginWidth, vs.rightMarginWidth); - + return Platform::LongFromTwoShorts(static_cast(vs.leftMarginWidth), + static_cast(vs.rightMarginWidth)); + + case SCI_GETMARGINLEFT: + return vs.leftMarginWidth; + + case SCI_GETMARGINRIGHT: + return vs.rightMarginWidth; + case EM_SETMARGINS: +#ifdef EC_LEFTMARGIN if (wParam & EC_LEFTMARGIN) { - vs.leftMarginWidth = LOWORD(lParam); + vs.leftMarginWidth = Platform::LowShortFromLong(lParam); } if (wParam & EC_RIGHTMARGIN) { - vs.rightMarginWidth = HIWORD(lParam); + vs.rightMarginWidth = Platform::HighShortFromLong(lParam); } if (wParam == EC_USEFONTINFO) { vs.leftMarginWidth = vs.aveCharWidth / 2; vs.rightMarginWidth = vs.aveCharWidth / 2; } InvalidateStyleRedraw(); +#endif break; - + + case SCI_SETMARGINLEFT: + vs.leftMarginWidth = lParam; + InvalidateStyleRedraw(); + break; + + case SCI_SETMARGINRIGHT: + vs.rightMarginWidth = lParam; + InvalidateStyleRedraw(); + break; + // Control specific mesages case SCI_ADDTEXT: { @@ -3210,16 +3500,16 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { ClearAll(); return 0; - case SCI_SETUNDOCOLLECTION: - pdoc->SetUndoCollection(static_cast(wParam)); + case SCI_CLEARDOCUMENTSTYLE: + ClearDocumentStyle(); return 0; -#ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_APPENDUNDOSTARTACTION: - // Not just deprecated - now dead - //pdoc->AppendUndoStartAction(); + case SCI_SETUNDOCOLLECTION: + pdoc->SetUndoCollection(wParam); return 0; -#endif + + case SCI_GETUNDOCOLLECTION: + return pdoc->IsCollectingUndo(); case SCI_BEGINUNDOACTION: pdoc->BeginUndoAction(); @@ -3249,12 +3539,48 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETCHARAT: return pdoc->CharAt(wParam); + case SCI_SETCURRENTPOS: + SetSelection(wParam, anchor); + break; + case SCI_GETCURRENTPOS: return currentPos; + case SCI_SETANCHOR: + SetSelection(currentPos, wParam); + break; + case SCI_GETANCHOR: return anchor; + case SCI_SETSELECTIONSTART: + SetSelection(Platform::Maximum(currentPos, wParam), wParam); + break; + + case SCI_GETSELECTIONSTART: + return Platform::Minimum(anchor, currentPos); + + case SCI_SETSELECTIONEND: + SetSelection(wParam, Platform::Minimum(anchor, wParam)); + break; + + case SCI_GETSELECTIONEND: + return Platform::Maximum(anchor, currentPos); + + case SCI_SETPRINTMAGNIFICATION: + printMagnification = wParam; + break; + + case SCI_GETPRINTMAGNIFICATION: + return printMagnification; + + case SCI_SETPRINTCOLOURMODE: + printColourMode = wParam; + break; + + case SCI_GETPRINTCOLOURMODE: + return printColourMode; + case SCI_GETSTYLEAT: if (static_cast(wParam) >= pdoc->Length()) return 0; @@ -3277,7 +3603,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETSTYLEDTEXT: { if (lParam == 0) return 0; - TEXTRANGE *tr = reinterpret_cast(lParam); + TextRange *tr = reinterpret_cast(lParam); int iPlace = 0; for (int iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { tr->lpstrText[iPlace++] = pdoc->CharAt(iChar); @@ -3302,10 +3628,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return vs.viewWhitespace; case SCI_SETVIEWWS: - vs.viewWhitespace = wParam; + vs.viewWhitespace = static_cast(wParam); Redraw(); break; + case SCI_POSITIONFROMPOINT: + return PositionFromLocation(Point(wParam, lParam)); + case SCI_GOTOLINE: GoToLine(wParam); break; @@ -3316,10 +3645,6 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { Redraw(); break; - case SCI_SETANCHOR: - SetSelection(currentPos, wParam); - break; - case SCI_GETCURLINE: { if (lParam == 0) return 0; @@ -3352,25 +3677,19 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { pdoc->SetStyleFor(wParam, static_cast(lParam)); break; - case SCI_SETSTYLINGEX: // Specify a complete styling buffer + case SCI_SETSTYLINGEX: // Specify a complete styling buffer if (lParam == 0) return 0; pdoc->SetStyles(wParam, reinterpret_cast(lParam)); break; -#ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_SETMARGINWIDTH: - if (wParam < 100) { - vs.ms[1].width = wParam; - } - InvalidateStyleRedraw(); - break; -#endif - case SCI_SETBUFFEREDDRAW: bufferedDraw = wParam; break; + case SCI_GETBUFFEREDDRAW: + return bufferedDraw; + case SCI_SETTABWIDTH: if (wParam > 0) pdoc->tabInChars = wParam; @@ -3379,12 +3698,12 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETTABWIDTH: return pdoc->tabInChars; - + case SCI_SETINDENT: pdoc->indentInChars = wParam; InvalidateStyleRedraw(); break; - + case SCI_GETINDENT: return pdoc->indentInChars; @@ -3395,44 +3714,65 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETUSETABS: return pdoc->useTabs; - + case SCI_SETLINEINDENTATION: pdoc->SetLineIndentation(wParam, lParam); break; - + case SCI_GETLINEINDENTATION: return pdoc->GetLineIndentation(wParam); - + case SCI_GETLINEINDENTPOSITION: return pdoc->GetLineIndentPosition(wParam); - + + case SCI_GETCOLUMN: + return pdoc->GetColumn(wParam); + case SCI_SETHSCROLLBAR : horizontalScrollBarVisible = wParam; SetScrollBars(); ReconfigureScrollBars(); break; - + case SCI_GETHSCROLLBAR: return horizontalScrollBarVisible; - - case SCI_SETCODEPAGE: - pdoc->dbcsCodePage = wParam; + + case SCI_SETINDENTATIONGUIDES: + vs.viewIndentationGuides = wParam; + Redraw(); break; -#ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_SETLINENUMBERWIDTH: - if (wParam < 200) { - vs.ms[0].width = wParam; + case SCI_GETINDENTATIONGUIDES: + return vs.viewIndentationGuides; + + case SCI_SETHIGHLIGHTGUIDE: + if ((highlightGuideColumn != static_cast(wParam)) || (wParam > 0)) { + highlightGuideColumn = wParam; + Redraw(); } - InvalidateStyleRedraw(); break; -#endif + + case SCI_GETHIGHLIGHTGUIDE: + return highlightGuideColumn; + + case SCI_GETLINEENDPOSITION: + return pdoc->LineEnd(wParam); + + case SCI_SETCODEPAGE: + pdoc->dbcsCodePage = wParam; + break; + + case SCI_GETCODEPAGE: + return pdoc->dbcsCodePage; case SCI_SETUSEPALETTE: palette.allowRealization = wParam; InvalidateStyleRedraw(); break; + case SCI_GETUSEPALETTE: + return palette.allowRealization; + // Marker definition and setting case SCI_MARKERDEFINE: if (wParam <= MARKER_MAX) @@ -3491,48 +3831,48 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINTYPEN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].symbol ? SC_MARGIN_SYMBOL : SC_MARGIN_NUMBER; else return 0; - + case SCI_SETMARGINWIDTHN: if (ValidMargin(wParam)) { vs.ms[wParam].width = lParam; InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINWIDTHN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].width; else return 0; - + case SCI_SETMARGINMASKN: if (ValidMargin(wParam)) { vs.ms[wParam].mask = lParam; InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINMASKN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].mask; else return 0; - + case SCI_SETMARGINSENSITIVEN: if (ValidMargin(wParam)) { vs.ms[wParam].sensitive = lParam; InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINSENSITIVEN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].sensitive ? 1 : 0; else return 0; @@ -3598,7 +3938,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { InvalidateStyleRedraw(); } break; - + case SCI_STYLESETVISIBLE: + if (wParam <= STYLE_MAX) { + vs.styles[wParam].visible = lParam; + InvalidateStyleRedraw(); + } + break; + case SCI_STYLERESETDEFAULT: vs.ResetDefaultStyle(); InvalidateStyleRedraw(); @@ -3606,24 +3952,24 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_SETSTYLEBITS: pdoc->SetStylingBits(wParam); break; - + case SCI_GETSTYLEBITS: return pdoc->stylingBits; - + case SCI_SETLINESTATE: return pdoc->SetLineState(wParam, lParam); - + case SCI_GETLINESTATE: return pdoc->GetLineState(wParam); - + case SCI_GETMAXLINESTATE: return pdoc->GetMaxLineState(); - - // Folding messages - + + // Folding messages + case SCI_VISIBLEFROMDOCLINE: return cs.DisplayFromDoc(wParam); - + case SCI_DOCLINEFROMVISIBLE: return cs.DocFromDisplay(wParam); @@ -3633,40 +3979,40 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { RedrawSelMargin(); return prev; } - + case SCI_GETFOLDLEVEL: return pdoc->GetLevel(wParam); - + case SCI_GETLASTCHILD: return pdoc->GetLastChild(wParam, lParam); - + case SCI_GETFOLDPARENT: return pdoc->GetFoldParent(wParam); - + case SCI_SHOWLINES: cs.SetVisible(wParam, lParam, true); SetScrollBars(); Redraw(); break; - + case SCI_HIDELINES: cs.SetVisible(wParam, lParam, false); SetScrollBars(); Redraw(); break; - + case SCI_GETLINEVISIBLE: return cs.GetVisible(wParam); - + case SCI_SETFOLDEXPANDED: if (cs.SetExpanded(wParam, lParam)) { RedrawSelMargin(); } break; - + case SCI_GETFOLDEXPANDED: return cs.GetExpanded(wParam); - + case SCI_SETFOLDFLAGS: foldFlags = wParam; Redraw(); @@ -3675,11 +4021,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_TOGGLEFOLD: ToggleContraction(wParam); break; - + case SCI_ENSUREVISIBLE: EnsureLineVisible(wParam); break; - + case SCI_SEARCHANCHOR: SearchAnchor(); break; @@ -3700,40 +4046,6 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { displayPopupMenu = wParam; break; - #ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_SETFORE: - vs.styles[STYLE_DEFAULT].fore.desired = Colour(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETBACK: - vs.styles[STYLE_DEFAULT].back.desired = Colour(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETBOLD: - vs.styles[STYLE_DEFAULT].bold = wParam; - InvalidateStyleRedraw(); - break; - - case SCI_SETITALIC: - vs.styles[STYLE_DEFAULT].italic = wParam; - InvalidateStyleRedraw(); - break; - - case SCI_SETSIZE: - vs.styles[STYLE_DEFAULT].size = wParam; - InvalidateStyleRedraw(); - break; - - case SCI_SETFONT: - if (wParam == 0) - return 0; - strcpy(vs.styles[STYLE_DEFAULT].fontName, reinterpret_cast(wParam)); - InvalidateStyleRedraw(); - break; -#endif - case SCI_SETSELFORE: vs.selforeset = wParam; vs.selforeground.desired = Colour(lParam); @@ -3751,12 +4063,17 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { InvalidateStyleRedraw(); break; + case SCI_GETCARETFORE: + return vs.caretcolour.desired.AsLong(); + case SCI_ASSIGNCMDKEY: - kmap.AssignCmdKey(LOWORD(wParam), HIWORD(wParam), lParam); + kmap.AssignCmdKey(Platform::LowShortFromLong(wParam), + Platform::HighShortFromLong(wParam), lParam); break; case SCI_CLEARCMDKEY: - kmap.AssignCmdKey(LOWORD(wParam), HIWORD(wParam), WM_NULL); + kmap.AssignCmdKey(Platform::LowShortFromLong(wParam), + Platform::HighShortFromLong(wParam), WM_NULL); break; case SCI_CLEARALLCMDKEYS: @@ -3832,7 +4149,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_BRACEHIGHLIGHT: SetBraceHighlight(static_cast(wParam), lParam, STYLE_BRACELIGHT); break; - + case SCI_BRACEBADLIGHT: SetBraceHighlight(static_cast(wParam), -1, STYLE_BRACEBAD); break; @@ -3857,50 +4174,59 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETZOOM: return vs.zoomLevel; - + case SCI_GETEDGECOLUMN: return theEdge; - + case SCI_SETEDGECOLUMN: theEdge = wParam; InvalidateStyleRedraw(); break; - + case SCI_GETEDGEMODE: - return edgeState; - + return vs.edgeState; + case SCI_SETEDGEMODE: - edgeState = wParam; + vs.edgeState = wParam; InvalidateStyleRedraw(); break; - + case SCI_GETEDGECOLOUR: return vs.edgecolour.desired.AsLong(); - + case SCI_SETEDGECOLOUR: vs.edgecolour.desired = Colour(wParam); InvalidateStyleRedraw(); break; - + case SCI_GETDOCPOINTER: - return reinterpret_cast(pdoc); + return reinterpret_cast(pdoc); case SCI_SETDOCPOINTER: SetDocPointer(reinterpret_cast(lParam)); return 0; - case SCI_ADDREFDOC: + case SCI_CREATEDOCUMENT: { + Document *doc = new Document(); + doc->AddRef(); + return reinterpret_cast(doc); + } + + case SCI_ADDREFDOCUMENT: (reinterpret_cast(lParam))->AddRef(); break; - - case SCI_RELEASEDOC: + + case SCI_RELEASEDOCUMENT: (reinterpret_cast(lParam))->Release(); break; - + case SCI_SETMODEVENTMASK: modEventMask = wParam; return 0; - + + case SCI_GETMODEVENTMASK: + return modEventMask; + case SCI_CONVERTEOLS: pdoc->ConvertLineEnds(wParam); SetSelection(currentPos, anchor); // Ensure selection inside document @@ -3909,6 +4235,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_SELECTIONISRECTANGLE: return (selType == selRectangle) ? 1 : 0; + case SCI_SETOVERTYPE: + inOverstrike = wParam; + break; + + case SCI_GETOVERTYPE: + return inOverstrike ? TRUE : FALSE; + #ifdef MACRO_SUPPORT case SCI_STARTRECORD: recordingMacro = 1; @@ -3917,8 +4250,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_STOPRECORD: recordingMacro = 0; return 0; -#endif - +#endif + default: return DefWndProc(iMessage, wParam, lParam); } diff --git a/contrib/src/stc/scintilla/src/Editor.h b/contrib/src/stc/scintilla/src/Editor.h index 808a656be1..83967cfd6a 100644 --- a/contrib/src/stc/scintilla/src/Editor.h +++ b/contrib/src/stc/scintilla/src/Editor.h @@ -31,10 +31,15 @@ public: // Drawing is only performed for maxLineLength characters on each line. enum {maxLineLength = 4000}; int numCharsInLine; - char chars[maxLineLength]; - char styles[maxLineLength]; - char indicators[maxLineLength]; - int positions[maxLineLength]; + int xHighlightGuide; + bool highlightColumn; + int selStart; + int selEnd; + int edgeColumn; + char chars[maxLineLength+1]; + char styles[maxLineLength+1]; + char indicators[maxLineLength+1]; + int positions[maxLineLength+1]; }; class Editor : public DocWatcher { @@ -54,6 +59,8 @@ protected: // ScintillaBase subclass needs access to much of Editor bool stylesValid; ViewStyle vs; Palette palette; + int printMagnification; + int printColourMode; bool hideSelection; bool inOverstrike; @@ -69,6 +76,8 @@ protected: // ScintillaBase subclass needs access to much of Editor Surface pixmapLine; Surface pixmapSelMargin; Surface pixmapSelPattern; + Surface pixmapIndentGuide; + Surface pixmapIndentGuideHighlight; // Intellimouse support - currently only implemented for Windows unsigned int ucWheelScrollLines; int cWheelDelta; //wheel delta from roll @@ -98,8 +107,8 @@ protected: // ScintillaBase subclass needs access to much of Editor bool needUpdateUI; Position braces[2]; int bracesMatchStyle; + int highlightGuideColumn; - int edgeState; int theEdge; enum { notPainting, painting, paintAbandoned } paintState; @@ -114,6 +123,7 @@ protected: // ScintillaBase subclass needs access to much of Editor enum { selStream, selRectangle, selRectangleFixed } selType; int xStartSelect; int xEndSelect; + bool primarySelection; int caretPolicy; int caretSlop; @@ -168,6 +178,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void SetSelection(int currentPos_, int anchor_); void SetSelection(int currentPos_); void SetEmptySelection(int currentPos_); + int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int MovePositionTo(int newPos, bool extend = false); int MovePositionSoVisible(int pos, int moveDir); void SetLastXChosen(); @@ -183,10 +194,10 @@ protected: // ScintillaBase subclass needs access to much of Editor void PaintSelMargin(Surface *surface, PRectangle &rc); void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout &ll); - void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, + void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout &ll); void Paint(Surface *surfaceWindow, PRectangle rcArea); - long FormatRange(bool draw, FORMATRANGE *pfr); + long FormatRange(bool draw, RangeToFormat *pfr); virtual void SetVerticalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0; @@ -199,6 +210,7 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void AddCharUTF(char *s, unsigned int len); void ClearSelection(); void ClearAll(); + void ClearDocumentStyle(); void Cut(); void PasteRectangular(int pos, const char *ptr, int len); virtual void Copy() = 0; @@ -216,6 +228,7 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyStyleToNeeded(int endStyleNeeded); void NotifyChar(char ch); + void NotifyMove(int position); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); virtual void NotifyDoubleClick(Point pt, bool shift); @@ -231,24 +244,25 @@ protected: // ScintillaBase subclass needs access to much of Editor #ifdef MACRO_SUPPORT - void NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam); + void NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam); #endif void PageMove(int direction, bool extend=false); void ChangeCaseOfSelection(bool makeUpperCase); void LineTranspose(); - virtual int KeyCommand(UINT iMessage); + virtual void CancelModes(); + virtual int KeyCommand(unsigned int iMessage); virtual int KeyDefault(int /* key */, int /*modifiers*/); int KeyDown(int key, bool shift, bool ctrl, bool alt); - bool GetWhitespaceVisible(); - void SetWhitespaceVisible(bool view); + int GetWhitespaceVisible(); + void SetWhitespaceVisible(int view); void Indent(bool forwards); - long FindText(UINT iMessage,WPARAM wParam,LPARAM lParam); + long FindText(unsigned int iMessage, unsigned long wParam, long lParam); void SearchAnchor(); - long SearchText(UINT iMessage,WPARAM wParam,LPARAM lParam); + long SearchText(unsigned int iMessage, unsigned long wParam, long lParam); void GoToLine(int lineNo); char *CopyRange(int start, int end); @@ -282,11 +296,11 @@ protected: // ScintillaBase subclass needs access to much of Editor void ToggleContraction(int line); void EnsureLineVisible(int line); - virtual LRESULT DefWndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) = 0; + virtual long DefWndProc(unsigned int iMessage, unsigned long wParam, long lParam) = 0; public: // Public so scintilla_send_message can use it - virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); + virtual long WndProc(unsigned int iMessage, unsigned long wParam, long lParam); // Public so scintilla_set_id can use it int ctrlID; }; diff --git a/contrib/src/stc/scintilla/src/KeyMap.cxx b/contrib/src/stc/scintilla/src/KeyMap.cxx index 3a6a31f974..d2a6660f3c 100644 --- a/contrib/src/stc/scintilla/src/KeyMap.cxx +++ b/contrib/src/stc/scintilla/src/KeyMap.cxx @@ -28,7 +28,7 @@ void KeyMap::Clear() { alloc = 0; } -void KeyMap::AssignCmdKey(int key, int modifiers, UINT msg) { +void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { if ((len+1) >= alloc) { KeyToCommand *ktcNew = new KeyToCommand[alloc + 5]; if (!ktcNew) @@ -51,7 +51,7 @@ void KeyMap::AssignCmdKey(int key, int modifiers, UINT msg) { len++; } -UINT KeyMap::Find(int key, int modifiers) { +unsigned int KeyMap::Find(int key, int modifiers) { for (int i=0; i < len; i++) { if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) { return kmap[i].msg; @@ -61,53 +61,55 @@ UINT KeyMap::Find(int key, int modifiers) { } KeyToCommand KeyMap::MapDefault[] = { - {VK_DOWN, SCI_NORM, SCI_LINEDOWN}, - {VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, - {VK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, - {VK_UP, SCI_NORM, SCI_LINEUP}, - {VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, - {VK_UP, SCI_CTRL, SCI_LINESCROLLUP}, - {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_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_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_ESCAPE, SCI_NORM, SCI_CANCEL}, - {VK_BACK, SCI_NORM, SCI_DELETEBACK}, - {VK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, - {'Z', SCI_CTRL, WM_UNDO}, + {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, + {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, + {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_UP, SCI_NORM, SCI_LINEUP}, + {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, + {SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, + {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, + {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, + {SCK_LEFT, SCI_CTRL, SCI_WORDLEFT}, + {SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND}, + {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, + {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, + {SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT}, + {SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND}, + {SCK_HOME, SCI_NORM, SCI_VCHOME}, + {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, + {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, + {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, + {SCK_END, SCI_NORM, SCI_LINEEND}, + {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, + {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, + {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, + {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, + {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, + {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, + {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, + {SCK_DELETE, SCI_NORM, SCI_CLEAR}, + {SCK_DELETE, SCI_SHIFT, SCI_CUT}, + {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, + {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, + {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, + {SCK_INSERT, SCI_CTRL, SCI_COPY}, + {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, + {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, + {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, + {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, + {SCK_BACK, SCI_ALT, SCI_UNDO}, + {'Z', SCI_CTRL, SCI_UNDO}, {'Y', SCI_CTRL, SCI_REDO}, - {'X', SCI_CTRL, WM_CUT}, - {'C', SCI_CTRL, WM_COPY}, - {'V', SCI_CTRL, WM_PASTE}, + {'X', SCI_CTRL, SCI_CUT}, + {'C', SCI_CTRL, SCI_COPY}, + {'V', SCI_CTRL, SCI_PASTE}, {'A', SCI_CTRL, SCI_SELECTALL}, - {VK_TAB, SCI_NORM, SCI_TAB}, - {VK_TAB, SCI_SHIFT, SCI_BACKTAB}, - {VK_RETURN, SCI_NORM, SCI_NEWLINE}, - {VK_ADD, SCI_CTRL, SCI_ZOOMIN}, - {VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, - {VK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, + {SCK_TAB, SCI_NORM, SCI_TAB}, + {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, + {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, + {SCK_ADD, SCI_CTRL, SCI_ZOOMIN}, + {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, + {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, //'L', SCI_CTRL, SCI_FORMFEED, {'L', SCI_CTRL, SCI_LINECUT}, {'L', SCI_CSHIFT, SCI_LINEDELETE}, diff --git a/contrib/src/stc/scintilla/src/KeyMap.h b/contrib/src/stc/scintilla/src/KeyMap.h index bc435e1970..c843104174 100644 --- a/contrib/src/stc/scintilla/src/KeyMap.h +++ b/contrib/src/stc/scintilla/src/KeyMap.h @@ -7,9 +7,9 @@ #define KEYTOCOMMAND_H #define SCI_NORM 0 -#define SCI_SHIFT SHIFT_PRESSED -#define SCI_CTRL LEFT_CTRL_PRESSED -#define SCI_ALT LEFT_ALT_PRESSED +#define SCI_SHIFT SCMOD_SHIFT +#define SCI_CTRL SCMOD_CTRL +#define SCI_ALT SCMOD_ALT #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) #define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) @@ -17,7 +17,7 @@ class KeyToCommand { public: int key; int modifiers; - UINT msg; + unsigned int msg; }; class KeyMap { @@ -29,8 +29,8 @@ public: KeyMap(); ~KeyMap(); void Clear(); - void AssignCmdKey(int key, int modifiers, UINT msg); - UINT Find(int key, int modifiers); // 0 returned on failure + void AssignCmdKey(int key, int modifiers, unsigned int msg); + unsigned int Find(int key, int modifiers); // 0 returned on failure }; #endif diff --git a/contrib/src/stc/scintilla/src/LexCPP.cxx b/contrib/src/stc/scintilla/src/LexCPP.cxx index 4f042bd61d..b6358ab332 100644 --- a/contrib/src/stc/scintilla/src/LexCPP.cxx +++ b/contrib/src/stc/scintilla/src/LexCPP.cxx @@ -19,14 +19,13 @@ static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &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'; } + bool wordIsUUID = false; char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) + if (isdigit(s[0]) || (s[0] == '.')) chAttr = SCE_C_NUMBER; else { if (keywords.InList(s)) { @@ -46,6 +45,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo styler.StartAt(startPos); bool fold = styler.GetPropertyInt("fold"); + bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor"); int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; @@ -56,7 +56,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; - int visChars = 0; + int visibleChars = 0; styler.StartSegment(startPos); bool lastWordWasUUID = false; for (unsigned int i = startPos; i < lengthDoc; i++) { @@ -64,6 +64,8 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) + // Avoid triggering two times on Dos/Win // End of line if (state == SCE_C_STRINGEOL) { styler.ColourTo(i, state); @@ -71,18 +73,18 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } if (fold) { int lev = levelPrev; - if (visChars == 0) + if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visChars > 0)) + if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); lineCurrent++; - visChars = 0; levelPrev = levelCurrent; } + visibleChars = 0; } if (!isspace(ch)) - visChars++; + visibleChars++; if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); @@ -92,13 +94,19 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { + if (ch == '@' && chNext == '\"') { + styler.ColourTo(i-1, state); + state = SCE_C_VERBATIM; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } else if (iswordstart(ch) || (ch == '@')) { styler.ColourTo(i-1, state); if (lastWordWasUUID) { state = SCE_C_UUID; lastWordWasUUID = false; } else { - state = SCE_C_WORD; + state = SCE_C_IDENTIFIER; } } else if (ch == '/' && chNext == '*') { styler.ColourTo(i-1, state); @@ -115,9 +123,16 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (ch == '\'') { styler.ColourTo(i-1, state); state = SCE_C_CHARACTER; - } else if (ch == '#') { + } else if (ch == '#' && visibleChars == 1) { + // Preprocessor commands are alone on their line styler.ColourTo(i-1, state); state = SCE_C_PREPROCESSOR; + // Skip whitespace between # and preprocessor word + do { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } while (isspace(ch) && (i < lengthDoc)); } else if (isoperator(ch)) { styler.ColourTo(i-1, state); styler.ColourTo(i, SCE_C_OPERATOR); @@ -125,7 +140,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo levelCurrent += (ch == '{') ? 1 : -1; } } - } else if (state == SCE_C_WORD) { + } else if (state == SCE_C_IDENTIFIER) { if (!iswordchar(ch)) { lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_C_DEFAULT; @@ -140,8 +155,6 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo 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 == '}')) { @@ -151,9 +164,16 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } } else { if (state == SCE_C_PREPROCESSOR) { - if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { - styler.ColourTo(i-1, state); - state = SCE_C_DEFAULT; + if (stylingWithinPreprocessor) { + if (isspace(ch)) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else { + if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } } } else if (state == SCE_C_COMMENT) { if (ch == '/' && chPrev == '*') { @@ -188,13 +208,10 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (ch == '\"') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } else if (chNext == '\r' || chNext == '\n') { + } else if (chNext == '\r' || chNext == '\n') { styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; - } + } } else if (state == SCE_C_CHARACTER) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { styler.ColourTo(i-1, SCE_C_STRINGEOL); @@ -208,39 +225,26 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (ch == '\'') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_C_VERBATIM) { + if (ch == '\"') { + if (chNext == '\"') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } else { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } } } else if (state == SCE_C_UUID) { if (ch == '\r' || ch == '\n' || ch == ')') { styler.ColourTo(i-1, state); + if (ch == ')') + styler.ColourTo(i, SCE_C_OPERATOR); 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; } diff --git a/contrib/src/stc/scintilla/src/LexHTML.cxx b/contrib/src/stc/scintilla/src/LexHTML.cxx index 653aa4653f..7868b47fc8 100644 --- a/contrib/src/stc/scintilla/src/LexHTML.cxx +++ b/contrib/src/stc/scintilla/src/LexHTML.cxx @@ -17,15 +17,21 @@ #include "Scintilla.h" #include "SciLexer.h" -enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; +#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START) +#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START) +#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START) + +enum { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML }; +enum { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc }; + static int segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, int prevValue) { - char s[100]; + char s[30 + 1]; s[0] = '\0'; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast(tolower(styler[start + i])); s[i + 1] = '\0'; } -//Platform::DebugPrintf("Scripting indicator [%s]\n", s); + //Platform::DebugPrintf("Scripting indicator [%s]\n", s); if (strstr(s, "vbs")) return eScriptVBS; if (strstr(s, "pyth")) @@ -34,18 +40,93 @@ static int segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigne return eScriptJS; if (strstr(s, "jscr")) return eScriptJS; - + if (strstr(s, "php")) + return eScriptPHP; + if (strstr(s, "xml")) + return eScriptXML; + return prevValue; } -static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || +static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) { + int iResult = 0; + char s[30 + 1]; + s[0] = '\0'; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = static_cast(tolower(styler[start + i])); + s[i + 1] = '\0'; + } + if (0 == strncmp(s, "php", 3)) { + iResult = 3; + } + + return iResult; +} + +//static int ScriptOfState(int state,int defaultScript) +static int ScriptOfState(int state) { + int scriptLanguage; + + if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { + scriptLanguage = eScriptPython; + } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { + scriptLanguage = eScriptVBS; + } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_STRINGEOL)) { + scriptLanguage = eScriptJS; + } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) { + scriptLanguage = eScriptPHP; + } else { + // scriptLanguage = defaultScript; + scriptLanguage = eScriptNone; + } + + return scriptLanguage; +} + +static int statePrintForState(int state, int inScriptType) { + int StateToPrint; + + if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { + StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON); + } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { + StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS); + } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_STRINGEOL)) { + StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS); + } else { + StateToPrint = state; + } + + return StateToPrint; +} + +static int stateForPrintState(int StateToPrint) { + int state; + + if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) { + state = StateToPrint - SCE_HA_PYTHON; + } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) { + state = StateToPrint - SCE_HA_VBS; + } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_STRINGEOL)) { + state = StateToPrint - SCE_HA_JS; + } else { + state = StateToPrint; + } + + return state; +} + +static inline bool IsNumber(unsigned int start, Accessor &styler) { + return isdigit(styler[start]) || (styler[start] == '.') || (styler[start] == '-') || (styler[start] == '#'); +} + +static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { + bool wordIsNumber = IsNumber(start, styler); char chAttr = SCE_H_ATTRIBUTEUNKNOWN; if (wordIsNumber) { chAttr = SCE_H_NUMBER; } else { - char s[100]; + char s[30 + 1]; s[0] = '\0'; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast(tolower(styler[start + i])); @@ -54,15 +135,18 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k if (keywords.InList(s)) chAttr = SCE_H_ATTRIBUTE; } + if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords) + // No keywords -> all are known + chAttr = SCE_H_ATTRIBUTE; styler.ColourTo(end, chAttr); } static int classifyTagHTML(unsigned int start, unsigned int end, - WordList &keywords, Accessor &styler) { - char s[100]; + WordList &keywords, Accessor &styler) { + char s[30 + 1]; // Copy after the '<' unsigned int i = 0; - for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) { + for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) { char ch = styler[cPos]; if (ch != '<') s[i++] = static_cast(tolower(ch)); @@ -71,107 +155,71 @@ static int classifyTagHTML(unsigned int start, unsigned int end, char chAttr = SCE_H_TAGUNKNOWN; if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment chAttr = SCE_H_COMMENT; + } else if (strcmp(s, "![cdata[") == 0) { // In lower case because already converted + chAttr = SCE_H_CDATA; } 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; + } + if (0 == strcmp(s, "script")) { + chAttr = SCE_H_SCRIPT; } } + if ((chAttr == SCE_H_TAGUNKNOWN) && !keywords) + // No keywords -> all are known + chAttr = SCE_H_TAG; styler.ColourTo(end, chAttr); return chAttr; } static void classifyWordHTJS(unsigned int start, unsigned int end, - WordList &keywords, Accessor &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'; - } + WordList &keywords, Accessor &styler, int inScriptType) { char chAttr = SCE_HJ_WORD; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); if (wordIsNumber) chAttr = SCE_HJ_NUMBER; else { + char s[30 + 1]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } if (keywords.InList(s)) chAttr = SCE_HJ_KEYWORD; } - styler.ColourTo(end, chAttr); -} - -static void classifyWordHTJSA(unsigned int start, unsigned int end, - WordList &keywords, Accessor &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); + styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); } -static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &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] = static_cast(tolower(styler[start + i])); - s[i + 1] = '\0'; - } +static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, int inScriptType) { char chAttr = SCE_HB_IDENTIFIER; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); if (wordIsNumber) chAttr = SCE_HB_NUMBER; else { + char s[30 + 1]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = static_cast(tolower(styler[start + i])); + s[i + 1] = '\0'; + } if (keywords.InList(s)) { chAttr = SCE_HB_WORD; if (strcmp(s, "rem") == 0) chAttr = SCE_HB_COMMENTLINE; } } - styler.ColourTo(end, chAttr); + styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); 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, Accessor &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] = static_cast(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, Accessor &styler, char *prevWord) { - char s[100]; +static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, int inScriptType) { bool wordIsNumber = isdigit(styler[start]); + char s[30 + 1]; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; s[i + 1] = '\0'; @@ -185,28 +233,50 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key chAttr = SCE_HP_NUMBER; else if (keywords.InList(s)) chAttr = SCE_HP_WORD; - styler.ColourTo(end, chAttr); + styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); strcpy(prevWord, s); } -static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) { - char s[100]; +// Update the word colour to default or keyword +// Called when in a PHP word +static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { + char chAttr = SCE_HPHP_DEFAULT; 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'; + if (wordIsNumber) + chAttr = SCE_HPHP_NUMBER; + else { + char s[30 + 1]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + if (keywords.InList(s)) + chAttr = SCE_HPHP_WORD; } - 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); +} + +// Return the first state to reach when entering a scripting language +static int StateForScript(int scriptLanguage) { + int Result; + switch (scriptLanguage) { + case eScriptVBS: + Result = SCE_HB_START; + break; + case eScriptPython: + Result = SCE_HP_START; + break; + case eScriptPHP: + Result = SCE_HPHP_DEFAULT; + break; + case eScriptXML: + Result = SCE_H_TAGUNKNOWN; + break; + default : + Result = SCE_HJ_START; + break; + } + return Result; } inline bool ishtmlwordchar(char ch) { @@ -215,32 +285,33 @@ inline bool ishtmlwordchar(char 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; + 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[], - Accessor &styler) { - - WordList &keywords=*keywordlists[0]; - WordList &keywords2=*keywordlists[1]; - WordList &keywords3=*keywordlists[2]; - WordList &keywords4=*keywordlists[3]; - +static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + WordList &keywords4 = *keywordlists[3]; + WordList &keywords5 = *keywordlists[4]; + // 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 + int StateToPrint = initStyle; + int state = stateForPrintState(StateToPrint); + + // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen if (InTagState(state)) { while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) { startPos--; @@ -253,254 +324,419 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty 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; - + int inScriptType = (lineState >> 0) & 0x03; // 2 bits + int defaultScript = (lineState >> 4) & 0x0F; // 4 bits + int beforePreProc = (lineState >> 8) & 0xFF; // 8 bits + + // int scriptLanguage = ScriptOfState(state,defaultScript); + int scriptLanguage = ScriptOfState(state); + + bool fold = styler.GetPropertyInt("fold"); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + int visibleChars = 0; + char chPrev = ' '; - char chPrev2 = ' '; + char ch = ' '; styler.StartSegment(startPos); int lengthDoc = startPos + length; for (int i = startPos; i < lengthDoc; i++) { - char ch = styler[i]; + char chPrev2 = chPrev; + chPrev = ch; + ch = styler[i]; char chNext = styler.SafeGetCharAt(i + 1); char chNext2 = styler.SafeGetCharAt(i + 2); + // Handle DBCS codepages if (styler.IsLeadByte(ch)) { - chPrev2 = ' '; chPrev = ' '; i += 1; continue; } + if (fold && !isspace(ch)) + visibleChars++; + + // handle script folding + if (fold) { + switch (scriptLanguage) { + case eScriptJS: + case eScriptPHP: + //not currently supported case eScriptVBS: + if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC)) { + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + break; + case eScriptPython: + if (state != SCE_HP_COMMENTLINE) { + if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) { + levelCurrent++; + } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) { + // check if the number of tabs is lower than the level + int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8; + for (int j = 0;Findlevel > 0;j++) { + char chTmp = styler.SafeGetCharAt(i + j + 1); + if (chTmp == '\t') { + Findlevel -= 8; + } else if (chTmp == ' ') { + Findlevel--; + } else break; + } + + if (Findlevel > 0) { + levelCurrent -= Findlevel / 8; + if (Findlevel % 8) levelCurrent--; + } + } + } + break; + } + } + + // decide what is the current state to print (depending of the script tag) + StateToPrint = statePrintForState(state, inScriptType); + if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) + // Avoid triggering two times on Dos/Win // New line -> record any line state onto /next/ line + if (fold) { + int lev = levelPrev; + if (visibleChars == 0) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + styler.SetLevel(lineCurrent, lev); + visibleChars = 0; + levelPrev = levelCurrent; + } lineCurrent++; - styler.SetLineState(lineCurrent, - defaultScript | (beforeASP << 8) | (inASP << 16)); + styler.SetLineState(lineCurrent, + ((inScriptType & 0x03) << 0) | + ((defaultScript & 0x0F) << 4) | + ((beforePreProc & 0xFF) << 8)); + } + + // generic end of script processing + else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) { + // Check if it's the end of the script tag (or any other HTML tag) + switch (state) { + // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!) + case SCE_H_DOUBLESTRING: + case SCE_H_SINGLESTRING: + case SCE_HJ_COMMENT: + case SCE_HJ_COMMENTDOC: + case SCE_HJ_COMMENTLINE: + case SCE_HJ_DOUBLESTRING: + case SCE_HJ_SINGLESTRING: + case SCE_HB_STRING: + case SCE_HP_STRING: + case SCE_HP_TRIPLE: + case SCE_HP_TRIPLEDOUBLE: + break; + default : + // maybe we should check here if it's a tag and if it's SCRIPT + + styler.ColourTo(i - 1, StateToPrint); + state = SCE_H_TAGUNKNOWN; + inScriptType = eHtml; + scriptLanguage = eScriptNone; + i += 2; + continue; + } + } + + ///////////////////////////////////// + // handle the start of PHP pre-processor = Non-HTML + else if ((ch == '<') && (chNext == '?')) { + styler.ColourTo(i - 1, StateToPrint); + beforePreProc = state; + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment() + 2, i + 10, eScriptPHP); + i++; + i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 10); + if (scriptLanguage == eScriptXML) + styler.ColourTo(i, SCE_H_XMLSTART); + else + styler.ColourTo(i, SCE_H_QUESTION); + state = StateForScript(scriptLanguage); + if (inScriptType == eNonHtmlScript) + inScriptType = eNonHtmlScriptPreProc; + else + inScriptType = eNonHtmlPreProc; + continue; } - - // Handle ASP even within other constructs as it is a preprocessor - if ((ch == '<') && (chNext == '%')) { - beforeASP = state; - styler.ColourTo(i - 1, state); + + // handle the start of ASP pre-processor = Non-HTML + else if ((ch == '<') && (chNext == '%')) { + styler.ColourTo(i - 1, StateToPrint); + beforePreProc = state; + if (inScriptType == eNonHtmlScript) + inScriptType = eNonHtmlScriptPreProc; + else + inScriptType = eNonHtmlPreProc; + if (chNext2 == '@') { - styler.ColourTo(i + 2, SCE_H_ASP); + i += 2; // place as if it was the second next char treated 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++; + i += 2; // place as if it was the second next char treated + } + else { + i++; // place as if it was the next char treated } + + + state = StateForScript(defaultScript); } - inASP = 1; + styler.ColourTo(i, SCE_H_ASP); continue; } - if (inASP && (ch == '%') && (chNext == '>')) { - if (state == SCE_H_ASPAT) - defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript); + + // handle the end of a pre-processor = Non-HTML + else if (((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && ((ch == '?') || (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); + switch (state) { + case SCE_HJ_WORD: + classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); + break; + case SCE_HB_WORD: + classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); + break; + case SCE_HP_WORD: + classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); + break; + case SCE_HPHP_WORD: + classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); + break; + default : + styler.ColourTo(i - 1, StateToPrint); + break; } - //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; + if (ch == '%') + styler.ColourTo(i, SCE_H_ASP); + else if (scriptLanguage == eScriptXML) + styler.ColourTo(i, SCE_H_XMLEND); + else + styler.ColourTo(i, SCE_H_QUESTION); + state = beforePreProc; + if (inScriptType == eNonHtmlScriptPreProc) + inScriptType = eNonHtmlScript; + else + inScriptType = eHtml; + scriptLanguage = eScriptNone; continue; } - - if (state == SCE_H_DEFAULT) { + ///////////////////////////////////// + + switch (state) { + case 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; - } + styler.ColourTo(i - 1, StateToPrint); + if (chNext == '!' && chNext2 == '-' && styler.SafeGetCharAt(i + 3) == '-') + state = SCE_H_COMMENT; + else + state = SCE_H_TAGUNKNOWN; } 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); + break; + case SCE_H_COMMENT: + if ((ch == '>') && (chPrev == '-') && (chPrev2 == '-')) { + styler.ColourTo(i, StateToPrint); + state = SCE_H_DEFAULT; + } + break; + case SCE_H_CDATA: + if ((ch == '>') && (chPrev == ']') && (chPrev2 == ']')) { + styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; } - } else if (state == SCE_H_ENTITY) { + break; + case SCE_H_ENTITY: if (ch == ';') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; } - } else if (state == SCE_H_TAGUNKNOWN) { - if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { + if (ch != '#' && !isalnum(ch)) { // Should check that '#' follows '&', but it is unlikely anyway... + styler.ColourTo(i, SCE_H_TAGUNKNOWN); + state = SCE_H_DEFAULT; + } + break; + case SCE_H_TAGUNKNOWN: + if (!ishtmlwordchar(ch) && ch != '/' && ch != '-' && ch != '[') { int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); - lastTagWasScript = eClass == SCE_H_SCRIPT; - if (lastTagWasScript) { - scriptLanguage = eScriptJS; + if (eClass == SCE_H_SCRIPT) { + inScriptType = eNonHtmlScript; + scriptLanguage = defaultScript; 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; + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } } else { - if (eClass == SCE_H_COMMENT) { - state = SCE_H_COMMENT; + if (eClass == SCE_H_CDATA) { + state = SCE_H_CDATA; } else { state = SCE_H_OTHER; } } } - } else if (state == SCE_H_ATTRIBUTE) { + break; + case SCE_H_ATTRIBUTE: if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage); + if (inScriptType == eNonHtmlScript) { + 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; + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } + } else if (ch == '=') { + styler.ColourTo(i, SCE_H_OTHER); + state = SCE_H_VALUE; } 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) { + break; + case SCE_H_OTHER: if (ch == '>') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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; + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_H_DOUBLESTRING; } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SINGLESTRING; + } else if (ch == '=') { + styler.ColourTo(i, StateToPrint); + state = SCE_H_VALUE; } else if (ch == '/' && chNext == '>') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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, StateToPrint); styler.ColourTo(i + 1, SCE_H_XMLEND); i++; ch = chNext; state = SCE_H_DEFAULT; } else if (ishtmlwordchar(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_H_ATTRIBUTE; } - } else if (state == SCE_H_DOUBLESTRING) { + break; + case SCE_H_DOUBLESTRING: if (ch == '\"') { - if (lastTagWasScript) + if (inScriptType == eNonHtmlScript) { scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); + } styler.ColourTo(i, SCE_H_DOUBLESTRING); state = SCE_H_OTHER; } - } else if (state == SCE_H_SINGLESTRING) { + break; + case SCE_H_SINGLESTRING: if (ch == '\'') { - if (lastTagWasScript) + if (inScriptType == eNonHtmlScript) { 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) { + break; + case SCE_H_VALUE: + if (!ishtmlwordchar(ch)) { + if (ch == '\"') { + // Should really test for being first character + state = SCE_H_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_H_SINGLESTRING; + } else { + if (IsNumber(styler.GetStartSegment(), styler)) { + styler.ColourTo(i - 1, SCE_H_NUMBER); + } else { + styler.ColourTo(i - 1, StateToPrint); + } + if (ch == '>') { + styler.ColourTo(i, SCE_H_TAG); + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); + } else { + state = SCE_H_DEFAULT; + } + } else { + state = SCE_H_OTHER; + } + } + } + break; + case SCE_HJ_DEFAULT: + case SCE_HJ_START: + case SCE_HJ_SYMBOLS: if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_WORD; } else if (ch == '/' && chNext == '*') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); if (chNext2 == '*') state = SCE_HJ_COMMENTDOC; else state = SCE_HJ_COMMENT; } else if (ch == '/' && chNext == '/') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DOUBLESTRING; } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HJ_SYMBOLS); + styler.ColourTo(i - 1, StateToPrint); + styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); state = SCE_HJ_DEFAULT; } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HJ_START) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DEFAULT; } } - } else if (state == SCE_HJ_WORD) { + break; + case SCE_HJ_WORD: if (!iswordchar(ch)) { - classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler); + classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); //styler.ColourTo(i - 1, eHTJSKeyword); state = SCE_HJ_DEFAULT; if (ch == '/' && chNext == '*') { @@ -514,354 +750,157 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HJ_DOUBLESTRING; } else if (ch == '\'') { state = SCE_HJ_SINGLESTRING; + } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HJ_SYMBOLS); + styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); state = SCE_HJ_DEFAULT; } } - } else if (state == SCE_HJ_COMMENT) { + break; + case SCE_HJ_COMMENT: + case SCE_HJ_COMMENTDOC: if (ch == '/' && chPrev == '*') { + styler.ColourTo(i, StateToPrint); 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) { + break; + case SCE_HJ_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); + styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType)); 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) { + break; + case SCE_HJ_DOUBLESTRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; } } else if (ch == '\"') { - styler.ColourTo(i, SCE_HJ_DOUBLESTRING); + styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; i++; ch = chNext; + } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_STRINGEOL; } - } else if (state == SCE_HJ_SINGLESTRING) { + break; + case SCE_HJ_SINGLESTRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; } } else if (ch == '\'') { - styler.ColourTo(i, SCE_HJ_SINGLESTRING); + styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; i++; ch = chNext; + } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_STRINGEOL; } - } else if (state == SCE_HJ_STRINGEOL) { + break; + case SCE_HJ_STRINGEOL: if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DEFAULT; } else if (!isLineEnd(chNext)) { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HJ_DEFAULT; } - } else if (state == SCE_HJA_DEFAULT || state == SCE_HJA_START) { + break; + case SCE_HB_DEFAULT: + case SCE_HB_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); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_WORD; } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_COMMENTLINE; } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_COMMENTLINE; } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } } - } else if (state == SCE_HB_WORD) { + break; + case SCE_HB_WORD: if (!iswordchar(ch)) { - state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler); + state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); 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); + styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType)); state = SCE_HB_DEFAULT; } } } - } else if (state == SCE_HB_STRING) { + break; + case SCE_HB_STRING: if (ch == '\"') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HB_DEFAULT; i++; ch = chNext; } else if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_STRINGEOL; } - } else if (state == SCE_HB_COMMENTLINE) { + break; + case SCE_HB_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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) { + break; + case SCE_HB_STRINGEOL: if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } else if (!isLineEnd(chNext)) { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HB_DEFAULT; } - } else if (state == SCE_HBA_DEFAULT || state == SCE_HBA_START) { + break; + case SCE_HP_DEFAULT: + case SCE_HP_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); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_COMMENTLINE; } else if (ch == '#') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_COMMENTLINE; } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); if (chNext == '\"' && chNext2 == '\"') { i += 2; state = SCE_HP_TRIPLEDOUBLE; @@ -869,10 +908,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty chPrev = ' '; chNext = styler.SafeGetCharAt(i + 1); } else { + // state = statePrintForState(SCE_HP_STRING,inScriptType); state = SCE_HP_STRING; } } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); if (chNext == '\'' && chNext2 == '\'') { i += 2; state = SCE_HP_TRIPLE; @@ -883,17 +923,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HP_CHARACTER; } } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HP_OPERATOR); + styler.ColourTo(i - 1, StateToPrint); + styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HP_START) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_DEFAULT; } } - } else if (state == SCE_HP_WORD) { + break; + case SCE_HP_WORD: if (!iswordchar(ch)) { - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); state = SCE_HP_DEFAULT; if (ch == '#') { state = SCE_HP_COMMENTLINE; @@ -918,15 +959,17 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HP_CHARACTER; } } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HP_OPERATOR); + styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); } } - } else if (state == SCE_HP_COMMENTLINE) { + break; + case SCE_HP_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_STRING) { + break; + case SCE_HP_STRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; @@ -934,10 +977,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\"') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_CHARACTER) { + break; + case SCE_HP_CHARACTER: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; @@ -945,132 +989,111 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\'') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_TRIPLE) { + break; + case SCE_HP_TRIPLE: if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_TRIPLEDOUBLE) { + break; + case SCE_HP_TRIPLEDOUBLE: if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); 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; + break; + ///////////// start - PHP state handling + case SCE_HPHP_WORD: + if (!iswordstart(ch)) { + classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); + if (ch == '/' && chNext == '*') { + i++; + state = SCE_HPHP_COMMENT; + } else if (ch == '/' && chNext == '/') { + i++; + state = SCE_HPHP_COMMENTLINE; + } else if (ch == '#') { + state = SCE_HPHP_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; - } + state = SCE_HPHP_HSTRING; } 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); + state = SCE_HPHP_SIMPLESTRING; + } else if (ch == '$') { + state = SCE_HPHP_VARIABLE; + } else { + state = SCE_HPHP_DEFAULT; } } - } else if (state == SCE_HPA_COMMENTLINE) { + break; + case SCE_HPHP_NUMBER: + if (!isdigit(ch)) { + styler.ColourTo(i - 1, SCE_HPHP_NUMBER); + state = SCE_HPHP_DEFAULT; + } + break; + case SCE_HPHP_VARIABLE: + if (!iswordstart(ch)) { + styler.ColourTo(i - 1, SCE_HPHP_VARIABLE); + state = SCE_HPHP_DEFAULT; + } + break; + case SCE_HPHP_COMMENT: + if (ch == '/' && chPrev == '*') { + styler.ColourTo(i, StateToPrint); + state = SCE_HPHP_DEFAULT; + } + break; + case SCE_HPHP_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); - state = SCE_HPA_DEFAULT; + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HPHP_DEFAULT; } - } else if (state == SCE_HPA_STRING) { + break; + case SCE_HPHP_HSTRING: if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + // skip the next char i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } } else if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_HPA_DEFAULT; + styler.ColourTo(i, StateToPrint); + state = SCE_HPHP_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; + break; + case SCE_HPHP_SIMPLESTRING: + if (ch == '\'') { + styler.ColourTo(i, StateToPrint); + state = SCE_HPHP_DEFAULT; } - } else if (state == SCE_HPA_TRIPLEDOUBLE) { - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, state); - state = SCE_HPA_DEFAULT; + break; + case SCE_HPHP_DEFAULT: + styler.ColourTo(i - 1, StateToPrint); + if (isdigit(ch)) { + state = SCE_HPHP_NUMBER; + } else if (iswordstart(ch)) { + state = SCE_HPHP_WORD; + } else if (ch == '/' && chNext == '*') { + i++; + state = SCE_HPHP_COMMENT; + } else if (ch == '/' && chNext == '/') { + i++; + state = SCE_HPHP_COMMENTLINE; + } else if (ch == '#') { + state = SCE_HPHP_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HPHP_HSTRING; + } else if (ch == '\'') { + state = SCE_HPHP_SIMPLESTRING; + } else if (ch == '$') { + state = SCE_HPHP_VARIABLE; } + break; + ///////////// end - PHP state handling } + + + if (state == SCE_HB_DEFAULT) { // One of the above succeeded if (ch == '\"') { state = SCE_HB_STRING; @@ -1081,8 +1104,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } else if (isoperator(ch)) { styler.ColourTo(i, SCE_HB_DEFAULT); } - } - if (state == SCE_HBA_DEFAULT) { // One of the above succeeded + } else if (state == SCE_HBA_DEFAULT) { // One of the above succeeded if (ch == '\"') { state = SCE_HBA_STRING; } else if (ch == '\'') { @@ -1092,8 +1114,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } else if (isoperator(ch)) { styler.ColourTo(i, SCE_HBA_DEFAULT); } - } - if (state == SCE_HJ_DEFAULT) { // One of the above succeeded + } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded if (ch == '/' && chNext == '*') { if (styler.SafeGetCharAt(i + 2) == '*') state = SCE_HJ_COMMENTDOC; @@ -1111,29 +1132,20 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty 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); + + StateToPrint = statePrintForState(state, inScriptType); + styler.ColourTo(lengthDoc - 1, StateToPrint); + + // 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 lmHTML(SCLEX_HTML, ColouriseHyperTextDoc); LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc); + diff --git a/contrib/src/stc/scintilla/src/LexLua.cxx b/contrib/src/stc/scintilla/src/LexLua.cxx new file mode 100644 index 0000000000..e6da7668dd --- /dev/null +++ b/contrib/src/stc/scintilla/src/LexLua.cxx @@ -0,0 +1,298 @@ +// LexLua.cxx - lexer for Lua language +// Written by Paul Winwood + +#include +#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 classifyWordLua(unsigned int start, unsigned int end, WordList &keywords, Accessor &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_LUA_IDENTIFIER; + + if (wordIsNumber) + chAttr = SCE_LUA_NUMBER; + else + { + if (keywords.InList(s)) + { + chAttr = SCE_LUA_WORD; + } + } + styler.ColourTo(end, chAttr); +} + +static void ColouriseLuaDoc(unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler) +{ + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + styler.GetLine(startPos); + + int state = initStyle; + char chPrev = ' '; + char chNext = styler[startPos]; + unsigned int lengthDoc = startPos + length; + bool firstChar = true; + int literalString = 0; + + styler.StartSegment(startPos); + for (unsigned int i = startPos; i <= lengthDoc; i++) + { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if (styler.IsLeadByte(ch)) + { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_LUA_STRINGEOL) + { + if (ch != '\r' && ch != '\n') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_DEFAULT; + } + } + + if (state == SCE_LUA_LITERALSTRING && ch == '[' && chNext == '[') + { + literalString++; + } + else + if (state == SCE_LUA_DEFAULT) + { + if (ch == '-' && chNext == '-') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_COMMENTLINE; + } + else + if (ch == '[' && chNext == '[') + { + state = SCE_LUA_LITERALSTRING; + literalString = 1; + } + else + if (iswordstart(ch)) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_WORD; + } + else + if (ch == '\"') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_STRING; + } + else + if (ch == '\'') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_CHARACTER; + } + else + if (ch == '$' && firstChar) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_PREPROCESSOR; + } + else + if (isoperator(ch)) + { + styler.ColourTo(i-1, state); + styler.ColourTo(i, SCE_LUA_OPERATOR); + } + } + else + if (state == SCE_LUA_WORD) + { + if (!iswordchar(ch)) + { + classifyWordLua(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_LUA_DEFAULT; + if (ch == '[' && chNext == '[') + { + literalString = 1; + state = SCE_LUA_LITERALSTRING; + } + else + if (ch == '-' && chNext == '-') + { + state = SCE_LUA_COMMENTLINE; + } + else + if (ch == '\"') + { + state = SCE_LUA_STRING; + } + else + if (ch == '\'') + { + state = SCE_LUA_CHARACTER; + } + else + if (ch == '$' && firstChar) + { + state = SCE_LUA_PREPROCESSOR; + } + else + if (isoperator(ch)) + { + styler.ColourTo(i, SCE_LUA_OPERATOR); + } + } + } + else + { + if (state == SCE_LUA_LITERALSTRING) + { + if (ch == ']' && (chPrev == ']') && (--literalString == 0)) + { + styler.ColourTo(i, state); + state = SCE_LUA_DEFAULT; + } + } + else + if (state == SCE_LUA_PREPROCESSOR) + { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_DEFAULT; + } + } + else + if (state == SCE_LUA_COMMENTLINE) + { + if (ch == '\r' || ch == '\n') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_DEFAULT; + } + } + else + if (state == SCE_LUA_STRING) + { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_STRINGEOL; + } + else + if (ch == '\\') + { + if (chNext == '\"' || chNext == '\\') + { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + else + if (ch == '\"') + { + styler.ColourTo(i, state); + state = SCE_LUA_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + else + if (state == SCE_LUA_CHARACTER) + { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_STRINGEOL; + } + else + if (ch == '\\') + { + if (chNext == '\'' || chNext == '\\') + { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + else + if (ch == '\'') + { + styler.ColourTo(i, state); + state = SCE_LUA_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + + if (state == SCE_LUA_DEFAULT) + { + if (ch == '-' && chNext == '-') + { + state = SCE_LUA_COMMENTLINE; + } + else + if (ch == '\"') + { + state = SCE_LUA_STRING; + } + else + if (ch == '\'') + { + state = SCE_LUA_CHARACTER; + } + else + if (ch == '$' && firstChar) + { + state = SCE_LUA_PREPROCESSOR; + } + else + if (iswordstart(ch)) + { + state = SCE_LUA_WORD; + } + else + if (isoperator(ch)) + { + styler.ColourTo(i, SCE_LUA_OPERATOR); + } + } + } + chPrev = ch; + firstChar = (ch == '\r' || ch == '\n'); + } + styler.ColourTo(lengthDoc - 1, state); +} + +LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc); diff --git a/contrib/src/stc/scintilla/src/LexOthers.cxx b/contrib/src/stc/scintilla/src/LexOthers.cxx index 90f41e3bf3..dd86033687 100644 --- a/contrib/src/stc/scintilla/src/LexOthers.cxx +++ b/contrib/src/stc/scintilla/src/LexOthers.cxx @@ -49,6 +49,46 @@ static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList * ColouriseBatchLine(lineBuffer, startPos + length, styler); } +static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) { + // It is needed to remember the current state to recognize starting + // comment lines before the first "diff " or "--- ". If a real + // difference starts then each line starting with ' ' is a whitespace + // otherwise it is considered a comment (Only in..., Binary file...) + if (0 == strncmp(lineBuffer, "diff ", 3)) { + styler.ColourTo(endLine, 2); + } else if (0 == strncmp(lineBuffer, "--- ", 3)) { + styler.ColourTo(endLine, 3); + } else if (0 == strncmp(lineBuffer, "+++ ", 3)) { + styler.ColourTo(endLine, 3); + } else if (lineBuffer[0] == '@') { + styler.ColourTo(endLine, 4); + } else if (lineBuffer[0] == '-') { + styler.ColourTo(endLine, 5); + } else if (lineBuffer[0] == '+') { + styler.ColourTo(endLine, 6); + } else if (lineBuffer[0] != ' ') { + styler.ColourTo(endLine, 1); + } else { + styler.ColourTo(endLine, 0); + } +} + +static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &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)) { + ColouriseDiffLine(lineBuffer, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseDiffLine(lineBuffer, startPos + length, styler); +} + static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, Accessor &styler) { int i = 0; while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces @@ -126,15 +166,21 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, Accessor &styler) { if (lineBuffer[0] == '>') { // Command or return status - styler.ColourTo(endPos, 4); + styler.ColourTo(endPos, SCE_ERR_CMD); } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { - styler.ColourTo(endPos, 1); + styler.ColourTo(endPos, SCE_ERR_PYTHON); } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { // Borland error message - styler.ColourTo(endPos, 5); + styler.ColourTo(endPos, SCE_ERR_BORLAND); } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { // Borland warning message - styler.ColourTo(endPos, 5); + styler.ColourTo(endPos, SCE_ERR_BORLAND); + } else if (strstr(lineBuffer, " at " ) && + strstr(lineBuffer, " at " ) < lineBuffer+lengthLine && + strstr(lineBuffer, " line ") && + strstr(lineBuffer, " line ") < lineBuffer+lengthLine) { + // perl error message + styler.ColourTo(endPos, SCE_ERR_PERL); } else { // Look for ::message // Look for (line)message @@ -168,11 +214,11 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, } } if (state == 3) { - styler.ColourTo(endPos, 2); + styler.ColourTo(endPos, SCE_ERR_GCC); } else if ((state == 13) || (state == 14) || (state == 15)) { - styler.ColourTo(endPos, 3); + styler.ColourTo(endPos, SCE_ERR_MS); } else { - styler.ColourTo(endPos, 0); + styler.ColourTo(endPos, SCE_ERR_DEFAULT); } } } @@ -297,8 +343,9 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, styler.ColourTo(lengthDoc, state); } +LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc); +LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc); LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc); -LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc); LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc); -LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc); +LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc); LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc); diff --git a/contrib/src/stc/scintilla/src/LexPerl.cxx b/contrib/src/stc/scintilla/src/LexPerl.cxx index 3c9972e2d6..a7186fe552 100644 --- a/contrib/src/stc/scintilla/src/LexPerl.cxx +++ b/contrib/src/stc/scintilla/src/LexPerl.cxx @@ -107,7 +107,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, state = SCE_PL_DEFAULT; } styler.StartAt(startPos); - char chPrev = ' '; + char chPrev = styler.SafeGetCharAt(startPos - 1); char chNext = styler[startPos]; styler.StartSegment(startPos); for (int i = startPos; i < lengthDoc; i++) { @@ -230,7 +230,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, quotes = 0; sookedpos = 0; sooked[sookedpos] = '\0'; - } else if (ch == '=' && isalpha(chNext)) { + } else if (ch == '=' && (chPrev == '\r' || chPrev == '\n') && isalpha(chNext)) { styler.ColourTo(i - 1, state); state = SCE_PL_POD; quotes = 0; @@ -284,7 +284,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, state = SCE_PL_DEFAULT; } } else if (state == SCE_PL_HERE) { - if (isalnum(ch) && quotes < 2) { + if ((isalnum(ch) || ch == '_') && quotes < 2) { sooked[sookedpos++] = ch; sooked[sookedpos] = '\0'; if (quotes == 0) @@ -292,14 +292,17 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, } else { quotes++; } - if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked) && (chPrev == '\n' || chPrev == '\r') ) { - styler.ColourTo(i + sookedpos - 1, SCE_PL_HERE); + if ((quotes > 1) && + (chPrev == '\n' || chPrev == '\r') && + isMatch(styler, lengthDoc, i, sooked)) { i += sookedpos; chNext = styler.SafeGetCharAt(i); if (chNext == '\n' || chNext == '\r') { + styler.ColourTo(i - 1, SCE_PL_HERE); state = SCE_PL_DEFAULT; } - chNext = ' '; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); } } else if (state == SCE_PL_STRING) { if (ch == '\\') { @@ -338,13 +341,13 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, chNext = styler.SafeGetCharAt(i + 1); } } else if (state == SCE_PL_POD) { - if (ch == '=') { + if (ch == '=' && (chPrev == '\r' || chPrev == '\n')) { if (isMatch(styler, lengthDoc, i, "=cut")) { styler.ColourTo(i - 1 + 4, state); i += 4; state = SCE_PL_DEFAULT; - chNext = ' '; - ch = ' '; + ch = styler.SafeGetCharAt(i); + chNext = styler.SafeGetCharAt(i + 1); } } } else if (state == SCE_PL_SCALAR) { @@ -409,7 +412,32 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, quoteDown = opposite(ch); quotes++; } else { - if (ch == quoteDown && chPrev != '\\') { + if (quotes == 0 && quoteRep == 1) { + /* We matched something like s(...) or tr{...} + * and are looking for the next matcher characters, + * which could be either bracketed ({...}) or non-bracketed + * (/.../). + * + * Number-signs are problematic. If they occur after + * the close of the first part, treat them like + * a quoteUp char, even if they actually start comments. + * + * If we find an alnum, we end the regsubst, and punt. + * + * Eric Promislow ericp@activestate.com Aug 9,2000 + */ + if (isspace(ch)) { + // Keep going + } else if (isalnum(ch)) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } else { + quoteUp = ch; + quoteDown = opposite(ch); + quotes++; + } + } else if (ch == quoteDown && chPrev != '\\') { quotes--; if (quotes == 0) { quoteRep--; diff --git a/contrib/src/stc/scintilla/src/LexPython.cxx b/contrib/src/stc/scintilla/src/LexPython.cxx index df8b7085bf..492d21c7d9 100644 --- a/contrib/src/stc/scintilla/src/LexPython.cxx +++ b/contrib/src/stc/scintilla/src/LexPython.cxx @@ -33,6 +33,13 @@ static void ClassifyWordPy(unsigned int start, unsigned int end, WordList &keywo chAttr = SCE_P_NUMBER; else if (keywords.InList(s)) chAttr = SCE_P_WORD; + // make sure that dot-qualifiers inside the word are lexed correct + else for (unsigned int i = 0; i < end - start + 1; i++) { + if (styler[start + i] == '.') { + styler.ColourTo(start + i - 1, chAttr); + styler.ColourTo(start + i, SCE_P_OPERATOR); + } + } styler.ColourTo(end, chAttr); strcpy(prevWord, s); } diff --git a/contrib/src/stc/scintilla/src/LexVB.cxx b/contrib/src/stc/scintilla/src/LexVB.cxx index acc3b0d548..67dfa78427 100644 --- a/contrib/src/stc/scintilla/src/LexVB.cxx +++ b/contrib/src/stc/scintilla/src/LexVB.cxx @@ -20,20 +20,21 @@ static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || + (styler[start] == '&' && tolower(styler[start+1]) == 'h'); + unsigned int i; + for (i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast(tolower(styler[start + i])); - s[i + 1] = '\0'; } + s[i] = '\0'; char chAttr = SCE_C_DEFAULT; if (wordIsNumber) chAttr = SCE_C_NUMBER; else { - if (keywords.InList(s)) { + if (strcmp(s, "rem") == 0) + chAttr = SCE_C_COMMENTLINE; + 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) @@ -49,6 +50,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, styler.StartAt(startPos); + int visibleChars = 0; int state = initStyle; char chNext = styler[startPos]; styler.StartSegment(startPos); @@ -63,6 +65,17 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, continue; } + if (ch == '\r' || ch == '\n') { + // End of line + if (state == SCE_C_COMMENTLINE || state == SCE_C_PREPROCESSOR) { + styler.ColourTo(i - 1, state); + state = SCE_C_DEFAULT; + } + visibleChars = 0; + } + if (!isspace(ch)) + visibleChars++; + if (state == SCE_C_DEFAULT) { if (iswordstart(ch)) { styler.ColourTo(i - 1, state); @@ -73,6 +86,16 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, } else if (ch == '\"') { styler.ColourTo(i - 1, state); state = SCE_C_STRING; + } else if (ch == '#' && visibleChars == 1) { + // Preprocessor commands are alone on their line + styler.ColourTo(i - 1, state); + state = SCE_C_PREPROCESSOR; + } else if (ch == '&' && tolower(chNext) == 'h') { + styler.ColourTo(i - 1, state); + state = SCE_C_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_C_OPERATOR); } } else if (state == SCE_C_WORD) { if (!iswordchar(ch)) { @@ -82,16 +105,14 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, state = SCE_C_COMMENTLINE; } else if (ch == '\"') { state = SCE_C_STRING; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_C_OPERATOR); } } } } 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 (state == SCE_C_STRING) { // VB doubles quotes to preserve them if (ch == '\"') { styler.ColourTo(i, state); diff --git a/contrib/src/stc/scintilla/src/PosRegExp.cxx b/contrib/src/stc/scintilla/src/PosRegExp.cxx new file mode 100644 index 0000000000..ea719b7c28 --- /dev/null +++ b/contrib/src/stc/scintilla/src/PosRegExp.cxx @@ -0,0 +1,1181 @@ +#include +#include +#include +#include + +#include "PosRegExp.h" + +//Up: /[A-Z \x80-\x9f \xf0 ]/x +//Lo: /[a-z \xa0-\xaf \xe0-\xef \xf1 ]/x +//Wd: /[\d _ A-Z a-z \xa0-\xaf \xe0-\xf1 \x80-\x9f]/x +//* // Dos866 +SCharData UCData = {0x0, 0x0, 0x7fffffe, 0x0, 0xffffffff, 0x0, 0x0, 0x10000}, + LCData = {0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0xffff, 0x0, 0x2ffff}, + WdData = {0x0, 0x3ff0000, 0x87fffffe, 0x7fffffe, 0xffffffff, 0xffff, 0x0, 0x3ffff}, + DigData = {0x0, 0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/*/ // cp1251 +SCharData UCData = {0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0xffffffff, 0x0}, + LCData = {0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0xffffffff}, + WdData = {0x0, 0x3ff0000, 0x87fffffe, 0x7fffffe, 0x0, 0x0, 0xffffffff, 0xffffffff}, + DigData = {0x0, 0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +//*/ + +/////////////////////////////////////////////// + +int GetNumber(int *str,int s,int e) { + int r = 1, num = 0; + if (e < s) return -1; + for(int i = e-1; i >= s; i--) { + if (str[i] > '9' || str[i] < '0') return -1; + num += (str[i] - 0x30)*r; + r *= 10; + }; + return num; + /* + char tmp[20]; + double Res; + if (e == s) return -1; + for (int i = s;i < e;i++) + tmp[i-s] = (char)Str[i]; + tmp[e-s] = 0; + GetNumber(tmp,&Res); + return (int)Res; + */ +}; + +bool IsDigit(char Symb) { + return DigData.GetBit(Symb); +}; +bool IsWord(char Symb) { + return WdData.GetBit(Symb); +}; +bool IsUpperCase(char Symb) { + return UCData.GetBit(Symb); +}; +bool IsLowerCase(char Symb) { + return LCData.GetBit(Symb); +}; +char LowCase(char Chr) { + if (UCData.GetBit(Chr)) + return Chr+0x20; + return Chr; +}; + +/////////////////////////////////////////////// + +SRegInfo::SRegInfo() { + Next = Parent = 0; + un.Param = 0; + Op = ReEmpty; +}; +SRegInfo::~SRegInfo() { + if (Next) delete Next; + if (un.Param) + switch(Op) { + case ReEnum: + case ReNEnum: + delete un.ChrClass; + break; + default: + if (Op > ReBlockOps && Op < ReSymbolOps || Op == ReBrackets) + delete un.Param; + break; + }; +}; + +/////////////////////////////////////////////// + +void SCharData::SetBit(unsigned char Bit) { + int p = Bit/8; + CArr[p] |= (1 << Bit%8); +}; +void SCharData::ClearBit(unsigned char Bit) { + int p = Bit/8; + CArr[p] &= ~(1 << Bit%8); +}; +bool SCharData::GetBit(unsigned char Bit) { + int p = (unsigned char)Bit/8; + return (CArr[p] & (1 << Bit%8))!=0; +}; + +///////////////////////////////////////////////////////////////// +////////////////////// RegExp Class /////////////////////////// +///////////////////////////////////////////////////////////////// + +PosRegExp::PosRegExp() { + Info = 0; + Exprn = 0; + NoMoves = false; + Error = true; + FirstChar = 0; + CurMatch = 0; +}; +PosRegExp::~PosRegExp() { + if (Info) delete Info; +}; + +bool PosRegExp::SetExpr(const char *Expr) { + if (!this) return false; + Error = true; + CurMatch = 0; + if (SetExprLow(Expr)) Error = false; + return !Error; +}; +bool PosRegExp::isok() { + return !Error; +}; + + +bool PosRegExp::SetExprLow(const char *Expr) { + int Len = strlen(Expr); + bool Ok = false; + int i,j,s = 0,pos,tmp; + int EnterBr = 0,EnterGr = 0,EnterFg = 0; + + if (Info) delete Info; + Info = new SRegInfo; + Exprn = new int[Len]; + + NoCase = false; + Extend = false; + if (Expr[0] == '/') s++; + else return false; + + for (i = Len; i > 0 && !Ok;i--) + if (Expr[i] == '/') { + Len = i-s; + Ok = true; + for (int j = i+1; Expr[j]; j++) { + if (Expr[j] == 'i') NoCase = true; + if (Expr[j] == 'x') Extend = true; + }; + }; + if (!Ok) return false; + + //////////////////////////////// + for (j = 0,pos = 0; j < Len; j++,pos++) { + if (Extend && Expr[j+s] == ' ') { + pos--; + continue; + }; + + Exprn[pos] = (int)(unsigned char)Expr[j+s]; + + if (Expr[j+s] == BackSlash) { + switch (Expr[j+s+1]) { + case 'd': + Exprn[pos] = ReDigit; + break; + case 'D': + Exprn[pos] = ReNDigit; + break; + case 'w': + Exprn[pos] = ReWordSymb; + break; + case 'W': + Exprn[pos] = ReNWordSymb; + break; + case 's': + Exprn[pos] = ReWSpace; + break; + case 'S': + Exprn[pos] = ReNWSpace; + break; + case 'u': + Exprn[pos] = ReUCase; + break; + case 'l': + Exprn[pos] = ReNUCase; + break; + case 't': + Exprn[pos] = '\t'; + break; + case 'n': + Exprn[pos] = '\n'; + break; + case 'r': + Exprn[pos] = '\r'; + break; + case 'b': + Exprn[pos] = ReWBound; + break; + case 'B': + Exprn[pos] = ReNWBound; + break; + case 'c': + Exprn[pos] = RePreNW; + break; + case 'm': + Exprn[pos] = ReStart; + break; + case 'M': + Exprn[pos] = ReEnd; + break; + case 'x': + tmp = toupper(Expr[j+s+2])-0x30; + tmp = (tmp>9?tmp-7:tmp)<<4; + tmp += (toupper(Expr[j+s+3])-0x30)>9?toupper(Expr[j+s+3])-0x37:(toupper(Expr[j+s+3])-0x30); + Exprn[pos] = tmp; + j+=2; + break; + case 'y': + tmp = Expr[j+s+2] - 0x30; + if (tmp >= 0 && tmp <= 9) { + if (tmp == 1) { + tmp = 10 + Expr[j+s+3] - 0x30; + if (tmp >= 10 && tmp <= 19) j++; + else tmp = 1; + }; + Exprn[pos] = ReBkTrace + tmp; + j++; + break; + }; + default: + tmp = Expr[j+s+1] - 0x30; + if (tmp >= 0 && tmp <= 9) { + if (tmp == 1) { + tmp = 10 + Expr[j+s+2] - 0x30; + if (tmp >= 10 && tmp <= 19) j++; + else tmp = 1; + }; + Exprn[pos] = ReBkBrack + tmp; + break; + } else + Exprn[pos] = Expr[j+s+1]; + break; + }; + j++; + continue; + }; + if (Expr[j+s] == ']') { + Exprn[pos] = ReEnumE; + if (EnterFg || !EnterGr) return false; + EnterGr--; + }; + if (Expr[j+s] == '-' && EnterGr) Exprn[pos] = ReFrToEnum; + + if (EnterGr) continue; + + if (Expr[j+s] == '[' && Expr[j+s+1] == '^') { + Exprn[pos] = ReNEnumS; + if (EnterFg) return false; + EnterGr++; + j++; + continue; + }; + if (Expr[j+s] == '*' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGMul; + j++; + continue; + }; + if (Expr[j+s] == '+' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGPlus; + j++; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGQuest; + j++; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '#' && + Expr[j+s+2]>='0' && Expr[j+s+2]<='9') { + Exprn[pos] = ReBehind+Expr[j+s+2]-0x30; + j+=2; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '~' && + Expr[j+s+2]>='0' && Expr[j+s+2]<='9') { + Exprn[pos] = ReNBehind+Expr[j+s+2]-0x30; + j+=2; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '=') { + Exprn[pos] = ReAhead; + j++; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '!') { + Exprn[pos] = ReNAhead; + j++; + continue; + }; + + if (Expr[j+s] == '(') { + Exprn[pos] = ReLBrack; + if (EnterFg) return false; + EnterBr++; + }; + if (Expr[j+s] == ')') { + Exprn[pos] = ReRBrack; + if (!EnterBr || EnterFg) return false; + EnterBr--; + }; + if (Expr[j+s] == '[') { + Exprn[pos] = ReEnumS; + if (EnterFg) return false; + EnterGr++; + }; + if (Expr[j+s] == '{') { + Exprn[pos] = ReRangeS; + if (EnterFg) return false; + EnterFg++; + }; + if (Expr[j+s] == '}' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGRangeE; + if (!EnterFg) return false; + EnterFg--; + j++; + continue; + }; + if (Expr[j+s] == '}') { + Exprn[pos] = ReRangeE; + if (!EnterFg) return false; + EnterFg--; + }; + + if (Expr[j+s] == '^') Exprn[pos] = ReSoL; + if (Expr[j+s] == '$') Exprn[pos] = ReEoL; + if (Expr[j+s] == '.') Exprn[pos] = ReAnyChr; + if (Expr[j+s] == '*') Exprn[pos] = ReMul; + if (Expr[j+s] == '+') Exprn[pos] = RePlus; + if (Expr[j+s] == '?') Exprn[pos] = ReQuest; + if (Expr[j+s] == '|') Exprn[pos] = ReOr; + }; + if (EnterGr || EnterBr || EnterFg) return false; + + Info->Op = ReBrackets; + Info->un.Param = new SRegInfo; + Info->s = CurMatch++; + + if (!SetStructs(Info->un.Param,0,pos)) return false; + Optimize(); + delete Exprn; + return true; +}; + +void PosRegExp::Optimize() { + PRegInfo Next = Info; + FirstChar = 0; + while(Next) { + if (Next->Op == ReBrackets || Next->Op == RePlus || Next->Op == ReNGPlus) { + Next = Next->un.Param; + continue; + }; + if (Next->Op == ReSymb) { + if (Next->un.Symb & 0xFF00 && Next->un.Symb != ReSoL && Next->un.Symb != ReWBound) + break; + FirstChar = Next->un.Symb; + break; + }; + break; + }; +}; + +bool PosRegExp::SetStructs(PRegInfo &re,int start,int end) { + PRegInfo Next,Prev,Prev2; + int comma,st,en,ng,i, j,k; + int EnterBr; + bool Add; + + if (end - start < 0) return false; + Next = re; + for (i = start; i < end; i++) { + Add = false; + // Ops + if (Exprn[i] > ReBlockOps && Exprn[i] < ReSymbolOps) { + Next->un.Param = 0; + Next->Op = (EOps)Exprn[i]; + Add = true; + }; + // {n,m} + if (Exprn[i] == ReRangeS) { + st = i; + en = -1; + comma = -1; + ng = 0; + for (j = i;j < end;j++) { + if (Exprn[j] == ReNGRangeE) { + en = j; + ng = 1; + break; + }; + if (Exprn[j] == ReRangeE) { + en = j; + break; + }; + if ((char)Exprn[j] == ',') + comma = j; + }; + if (en == -1) return false; + if (comma == -1) comma = en; + Next->s = (char)GetNumber(Exprn,st+1,comma); + if (comma != en) + Next->e = (char)GetNumber(Exprn,comma+1,en); + else + Next->e = Next->s; + Next->un.Param = 0; + Next->Op = ng?ReNGRangeNM:ReRangeNM; + if (en-comma == 1) { + Next->e = -1; + Next->Op = ng?ReNGRangeN:ReRangeN; + }; + i=j; + Add = true; + }; + // [] [^] + if (Exprn[i] == ReEnumS || Exprn[i] == ReNEnumS) { + Next->Op = (Exprn[i] == ReEnumS)?ReEnum:ReNEnum; + for (j = i+1;j < end;j++) { + if (Exprn[j] == ReEnumE) + break; + }; + if (j == end) return false; + Next->un.ChrClass = new SCharData; + memset(Next->un.ChrClass, 0, 32); + for (j = i+1;Exprn[j] != ReEnumE;j++) { + if (Exprn[j+1] == ReFrToEnum) { + for (i = (Exprn[j]&0xFF); i < (Exprn[j+2]&0xFF);i++) + Next->un.ChrClass->SetBit(i&0xFF); + j++; + continue; + }; + switch(Exprn[j]) { + case ReDigit: + for (k = 0x30;k < 0x40;k++) + if (IsDigit((char)k)) + Next->un.ChrClass->SetBit(k); + break; + case ReNDigit: + for (k = 0x30;k < 0x40;k++) + if (!IsDigit((char)k)) + Next->un.ChrClass->SetBit(k); + Next->un.ChrClass->ClearBit(0x0a); + Next->un.ChrClass->ClearBit(0x0d); + break; + case ReWordSymb: + for (k = 0;k < 256;k++) + if (IsWord((char)k)) + Next->un.ChrClass->SetBit(k); + break; + case ReNWordSymb: + for (k = 0;k < 256;k++) + if (!IsWord((char)k)) + Next->un.ChrClass->SetBit(k); + Next->un.ChrClass->ClearBit(0x0a); + Next->un.ChrClass->ClearBit(0x0d); + break; + case ReWSpace: + Next->un.ChrClass->SetBit(0x20); + Next->un.ChrClass->SetBit(0x09); + break; + case ReNWSpace: + memset(Next->un.ChrClass->IArr, 0xFF, 32); + Next->un.ChrClass->ClearBit(0x20); + Next->un.ChrClass->ClearBit(0x09); + Next->un.ChrClass->ClearBit(0x0a); + Next->un.ChrClass->ClearBit(0x0d); + break; + default: + if (!(Exprn[j]&0xFF00)) + Next->un.ChrClass->SetBit(Exprn[j]&0xFF); + break; + }; + }; + Add = true; + i=j; + }; + // ( ... ) + if (Exprn[i] == ReLBrack) { + EnterBr = 1; + for (j = i+1;j < end;j++) { + if (Exprn[j] == ReLBrack) EnterBr++; + if (Exprn[j] == ReRBrack) EnterBr--; + if (!EnterBr) break; + }; + if (EnterBr) return false; + Next->Op = ReBrackets; + Next->un.Param = new SRegInfo; + Next->un.Param->Parent = Next; + Next->s = CurMatch++; + if (CurMatch > MatchesNum) CurMatch = MatchesNum; + if (!SetStructs(Next->un.Param,i+1,j)) return false; + Add = true; + i=j; + }; + if ((Exprn[i]&0xFF00) == ReBkTrace) { + Next->Op = ReBkTrace; + Next->un.Symb = Exprn[i]&0xFF; + Add = true; + }; + if ((Exprn[i]&0xFF00) == ReBkBrack) { + Next->Op = ReBkBrack; + Next->un.Symb = Exprn[i]&0xFF; + Add = true; + }; + if ((Exprn[i]&0xFF00) == ReBehind) { + Next->Op = ReBehind; + Next->s = Exprn[i]&0xFF; + Add = true; + }; + if ((Exprn[i]&0xFF00) == ReNBehind) { + Next->Op = ReNBehind; + Next->s = Exprn[i]&0xFF; + Add = true; + }; + // Chars + if (Exprn[i] >= ReAnyChr && Exprn[i] < ReTemp || Exprn[i] < 0x100) { + Next->Op = ReSymb; + Next->un.Symb = Exprn[i]; + Add = true; + }; + // Next + if (Add && i != end-1) { + Next->Next = new SRegInfo; + Next->Next->Parent = Next->Parent; + Next = Next->Next; + }; + }; + Next = re; + Prev = Prev2 = 0; + while(Next) { + if (Next->Op > ReBlockOps && Next->Op < ReSymbolOps) { + if (!Prev) return false; + if (!Prev2) re = Next; + else Prev2->Next = Next; + //if (Prev->Op > ReBlockOps && Prev->Op < ReSymbolOps) return false; + Prev->Parent = Next; + Prev->Next = 0; + Next->un.Param = Prev; + Prev = Prev2; + }; + Prev2 = Prev; + Prev = Next; + Next = Next->Next; + }; + + return true; +}; + +///////////////////////////////////////////////////////////////// +///////////////////////// Parsing ///////////////////////////// +///////////////////////////////////////////////////////////////// + +bool PosRegExp::CheckSymb(int Symb,bool Inc) { + bool Res; + char ch; + switch(Symb) { + case ReAnyChr: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReSoL: + if (posStart == posParse) + return true; + ch = CharAt(posParse-1,param); + return ch == '\n' || ch == '\r'; + case ReEoL: + if (posEnd == posParse) + return true; + ch = CharAt(posParse,param); + return ch == '\n' || ch == '\r'; + case ReDigit: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = (ch >= 0x30 && ch <= 0x39); + if (Res && Inc) posParse++; + return Res; + case ReNDigit: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = !(ch >= 0x30 && ch <= 0x39) && ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReWordSymb: + if (posParse >= posEnd) return false; + Res = IsWord(CharAt(posParse,param)); + if (Res && Inc) posParse++; + return Res; + case ReNWordSymb: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = !IsWord(ch) && ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReWSpace: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = (ch == 0x20 || ch == '\t'); + if (Res && Inc) posParse++; + return Res; + case ReNWSpace: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = !(ch == 0x20 || ch == '\t') && ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReUCase: + if (posParse >= posEnd) return false; + Res = IsUpperCase(CharAt(posParse,param)); + if (Res && Inc) posParse++; + return Res; + case ReNUCase: + if (posParse >= posEnd) return false; + Res = IsLowerCase(CharAt(posParse,param)); + if (Res && Inc) posParse++; + return Res; + case ReWBound: + if (posParse >= posEnd) return true; + ch = CharAt(posParse,param); + return IsWord(CharAt(posParse,param)) && (posParse == posStart || !IsWord(CharAt(posParse-1,param))); + case ReNWBound: + if (posParse >= posEnd) return true; + return !IsWord(CharAt(posParse,param)) && IsWord(CharAt(posParse-1,param)); + case RePreNW: + if (posParse >= posEnd) return true; + return (posParse == posStart || !IsWord(CharAt(posParse-1,param))); + case ReStart: + Matches->s[0] = (posParse-posStart); + return true; + case ReEnd: + Matches->e[0] = (posParse-posStart); + return true; + default: + if ((Symb & 0xFF00) || posParse >= posEnd) return false; + if (NoCase) { + if (LowCase(CharAt(posParse,param)) != LowCase((char)Symb&0xFF)) return false; + } else + if (CharAt(posParse,param) != (char)(Symb&0xFF)) return false; + if (Inc) posParse++; + return true; + }; +} + +bool PosRegExp::LowParseRe(PRegInfo &Next) { + PRegInfo OrNext; + int i,match,sv; + int posStr; + + switch(Next->Op) { + case ReSymb: + if (!CheckSymb(Next->un.Symb,true)) return false; + break; + case ReEmpty: + break; + case ReBkTrace: + if (!posBkStr | !BkTrace) return false; + sv = Next->un.Symb; + posStr = posParse; + for (i = BkTrace->s[sv]; i < BkTrace->e[sv]; i++) { + if (CharAt(posStr,param) != CharAt(posBkStr+i,param) || posEnd == posStr) return false; + posStr++; + }; + posParse = posStr; + break; + case ReBkBrack: + sv = Next->un.Symb; + posStr = posParse; + if (Matches->s[sv] == -1 || Matches->e[sv] == -1) return false; + for (i = Matches->s[sv]; i < Matches->e[sv]; i++) { + if (CharAt(posStr,param) != CharAt(posStart+i,param) || posEnd == posStr) return false; + posStr++; + }; + posParse = posStr; + break; + case ReBehind: + sv = Next->s; + posStr = posParse; + posParse -= sv; + if (!LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReNBehind: + sv = Next->s; + posStr = posParse; + posParse -= sv; + if (LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReAhead: + posStr = posParse; + if (!LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReNAhead: + posStr = posParse; + if (LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReEnum: + if (posParse >= posEnd) return false; + if (!Next->un.ChrClass->GetBit(CharAt(posParse,param))) return false; + posParse++; + break; + case ReNEnum: + if (posParse >= posEnd) return false; + if (Next->un.ChrClass->GetBit(CharAt(posParse,param))) return false; + posParse++; + break; + case ReBrackets: + match = Next->s; + sv = posParse-posStart; + posStr = posParse; + if (LowParse(Next->un.Param)) { + if (match || (Matches->s[match] == -1)) + Matches->s[match] = sv; + if (match || (Matches->e[match] == -1)) + Matches->e[match] = posParse-posStart; + return true; + }; + posParse = posStr; + return false; + case ReMul: + posStr = posParse; + while (LowParse(Next->un.Param)); + while(!LowCheckNext(Next) && posStr < posParse) posParse--; + break; + case ReNGMul: + do { + if (LowCheckNext(Next)) break; + } while (LowParse(Next->un.Param)); + break; + case RePlus: + posStr = posParse; + match = false; + while (LowParse(Next->un.Param)) + match = true; + if (!match) return false; + while(!LowCheckNext(Next) && posStr < posParse) posParse--; + break; + case ReNGPlus: + if (!LowParse(Next->un.Param)) return false; + do { + if (LowCheckNext(Next)) break; + } while (LowParse(Next->un.Param)); + break; + case ReQuest: + LowParse(Next->un.Param); + break; + case ReNGQuest: + if (LowCheckNext(Next)) break; + if (!LowParse(Next->un.Param)) return false; + break; + case ReOr: + OrNext = Next; + // posStr = posParse; + if (LowParse(Next->un.Param)) { + while (OrNext && OrNext->Op == ReOr) + OrNext = OrNext->Next; + /*if (!LowCheckNext(OrNext)){ + posParse = posStr; + OrNext = Next; + };*/ + }; + Next = OrNext; + break; + case ReRangeN: + posStr = posParse; + i = 0; + while (LowParse(Next->un.Param)) i++; // ??? + do { + if (i < Next->s) { + posParse = posStr; + return false; + }; + i--; + } while(!LowCheckNext(Next) && posStr < posParse--); + break; + case ReNGRangeN: + posStr = posParse; + i = 0; + while (LowParse(Next->un.Param)) { + i++; + if (i >= Next->s && LowCheckNext(Next)) // ??? + break; + }; + if (i < Next->s) { + posParse = posStr; + return false; + }; + break; + case ReRangeNM: + posStr = posParse; + i = 0; + while (i < Next->s && LowParse(Next->un.Param)) // ??? + i++; + if (i < Next->s) { + posParse = posStr; + return false; + }; + while (i < Next->e && LowParse(Next->un.Param)) // ??? + i++; + + while(!LowCheckNext(Next)) { + i--; + posParse--; + if (i < Next->s) { + posParse = posStr; + return false; + }; + }; + break; + case ReNGRangeNM: + posStr = posParse; + i = 0; + while (i < Next->s && LowParse(Next->un.Param)) // ??? + i++; + if (i < Next->s) { + posParse = posStr; + return false; + }; + while(!LowCheckNext(Next)) { + i++; + if (!LowParse(Next->un.Param) || i > Next->e) { // ??? + posParse = posStr; + return false; + }; + }; + break; + }; + return true; +}; + +bool PosRegExp::LowCheckNext(PRegInfo Re) { + PRegInfo Next; + int tmp = posParse; + Next = Re; + do { + if (Next && Next->Op == ReOr) + while (Next && Next->Op == ReOr) + Next = Next->Next; + if (Next->Next && !LowParse(Next->Next)) { + posParse = tmp; + Ok = false; + return false; + }; + Next = Next->Parent; + } while(Next); + posParse = tmp; + if (Ok != false) Ok = true; + return true; +}; + +bool PosRegExp::LowParse(PRegInfo Re) { + while(Re && posParse <= posEnd) { + if (!LowParseRe(Re)) return false; + if (Re) Re = Re->Next; + }; + return true; +}; + +bool PosRegExp::QuickCheck() { + if (!NoMoves || !FirstChar) + return true; + switch(FirstChar) { + case ReSoL: + if (posParse != posStart) return false; + return true; + case ReWBound: + return IsWord(CharAt(posParse,param)) && (posParse == posStart || !IsWord(CharAt(posParse-1,param))); + default: + if (NoCase && LowCase(CharAt(posParse,param)) != LowCase(FirstChar)) return false; + if (!NoCase && CharAt(posParse,param) != (char)FirstChar) return false; + return true; + }; +}; + +bool PosRegExp::ParseRe(int posStr) { + if (Error) return false; + + posParse = posStr; + if (!QuickCheck()) return false; + + for (int i = 0; i < MatchesNum; i++) + Matches->s[i] = Matches->e[i] = -1; + Matches->CurMatch = CurMatch; + + Ok = -1; + //try{ + do { + if (!LowParse(Info)) { + if (NoMoves) return false; + } else + return true; + posParse = ++posStr; + } while(posParse != posEnd+1); + return false; + //}__except(){ + // return true; + //}; +} +; + +bool PosRegExp::Parse(int posStr,int posSol, int posEol, PMatches Mtch, int Moves) { + if (!this) return false; + + bool s = NoMoves; + if (Moves != -1) NoMoves = Moves!=0; + posStart = posSol; + posEnd = posEol; + Matches = Mtch; + bool r = ParseRe(posStr); + NoMoves = s; + return r; +}; + +bool PosRegExp::Parse(int posStr, int posStop, PMatches Mtch) { + if (!this) return false; + posStart = posStr; + posEnd = posStop; + Matches = Mtch; + return ParseRe(posStr); +}; + +bool PosRegExp::SetNoMoves(bool Moves) { + NoMoves = Moves; + return true; +}; + +bool PosRegExp::SetBkTrace(int posStr,PMatches Trace) { + BkTrace = Trace; + posBkStr = posStr; + return true; +}; + +#define EVAL_MATCHES 16 +#define EVAL_CHUNKSIZE 256 + +#define EVAL_LOWERCASE 1 +#define EVAL_UPPERCASE 2 +#define EVAL_LOWERCASE_NEXT 4 +#define EVAL_UPPERCASE_NEXT 8 + +bool PosRegExp::Evaluate(char *Expr, int posStr, PMatches Mtch, char **Res) { + int length, + newlength, + chunklength, + value, + size, + src, + end; + unsigned flag; + char ch, + *dest, + *pool; + + size = EVAL_CHUNKSIZE; + pool = (char*) malloc (size); + dest = pool; + length = 0; + flag = 0; + while (*Expr) { + switch (ch = *Expr++) { + case '\\': + switch (ch = *Expr++) { + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + ch -= ('A' - '0'); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + value = ch - '0'; + if (Mtch->s[value] != -1 && value < EVAL_MATCHES) { + chunklength = Mtch->e[value] - Mtch->s[value]; + if (chunklength) { + newlength = chunklength + length; + if (newlength > size) { + do + size += EVAL_CHUNKSIZE; + while (size < newlength); + pool = (char*) realloc (pool, size); + dest = pool + length; + } + length = newlength; + src = posStr + Mtch->s[value]; + end = posStr + Mtch->e[value]; + if (flag & EVAL_UPPERCASE) { + if (flag & EVAL_LOWERCASE_NEXT) { + *dest++ = tolower (CharAt(src++,param)); + flag &= ~EVAL_LOWERCASE_NEXT; + } + while (src < end) + *dest++ = toupper (CharAt(src++,param)); + } else if (flag & EVAL_LOWERCASE) { + if (flag & EVAL_UPPERCASE_NEXT) { + *dest++ = toupper (CharAt(src++,param)); + flag &= ~EVAL_UPPERCASE_NEXT; + } + while (src < end) + *dest++ = tolower (CharAt(src++,param)); + } else { + if (flag & EVAL_LOWERCASE_NEXT) { + *dest++ = tolower (CharAt(src++,param)); + flag &= ~EVAL_LOWERCASE_NEXT; + } else if (flag & EVAL_UPPERCASE_NEXT) { + *dest++ = toupper (CharAt(src++,param)); + flag &= ~EVAL_UPPERCASE_NEXT; + } + while (src < end) + *dest++ = CharAt(src++,param); + } + } + } else + goto error; + continue; + case '\0': + goto error; + case 'r': + ch = '\r'; + break; + case 'n': + ch = '\n'; + break; + case 'b': + ch = '\b'; + break; + case 'a': + ch = '\a'; + break; + case 't': + ch = '\t'; + break; + case 'U': + flag |= EVAL_UPPERCASE; + continue; + case 'u': + flag |= EVAL_UPPERCASE_NEXT; + continue; + case 'L': + flag |= EVAL_LOWERCASE; + continue; + case 'l': + flag |= EVAL_LOWERCASE_NEXT; + continue; + case 'Q': + case 'q': + flag &= ~(EVAL_UPPERCASE | EVAL_LOWERCASE); + continue; + case 'x': + { + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + value = value + '0' - 'A' + 10; + if (value > 15) + goto error; + ch = value << 4; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + value = value + '0' - 'A' + 10; + if (value > 15) + goto error; + Expr++; + ch |= value; + break; + } + case 'd': + { + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch = value * 100; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch += value * 10; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch += value; + Expr++; + break; + } + case 'o': + { + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch = value << 6; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch += value << 3; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch |= value; + Expr++; + /* break; */ + } + /* default: + break; */ + } + default: + if (++length > size) { + do + size += EVAL_CHUNKSIZE; + while (size < length); + pool = (char*) realloc (pool, size); + dest = pool + length - 1; + } + if (flag & EVAL_LOWERCASE_NEXT) { + *dest++ = tolower (ch); + flag &= ~EVAL_LOWERCASE_NEXT; + } else if (flag & EVAL_UPPERCASE_NEXT) { + *dest++ = toupper (ch); + flag &= ~EVAL_UPPERCASE_NEXT; + } else if (flag & EVAL_UPPERCASE) + *dest++ = toupper (ch); + else if (flag & EVAL_LOWERCASE) + *dest++ = tolower (ch); + else + *dest++ = ch; + } + } + if (++length > size) { + do + size += EVAL_CHUNKSIZE; + while (size < length); + pool = (char*) realloc (pool, size); + dest = pool + length - 1; + } + *dest = '\0'; + *Res = pool; + return true; +error: + free (pool); + return false; +} diff --git a/contrib/src/stc/scintilla/src/PropSet.cxx b/contrib/src/stc/scintilla/src/PropSet.cxx index d3dbabaf3b..a58d143164 100644 --- a/contrib/src/stc/scintilla/src/PropSet.cxx +++ b/contrib/src/stc/scintilla/src/PropSet.cxx @@ -24,6 +24,18 @@ bool EqualCaseInsensitive(const char *a, const char *b) { #endif } +SString::size_type SString::npos = -1; + +inline unsigned int HashString(const char *s) { + unsigned int ret = 0; + while (*s) { + ret <<= 4; + ret ^= *s; + s++; + } + return ret; +} + // 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; @@ -56,47 +68,39 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { PropSet::PropSet() { superPS = 0; - size = 10; - used = 0; - vals = new char * [size]; + for (int root=0; root < hashRoots; root++) + props[root] = 0; } PropSet::~PropSet() { superPS = 0; Clear(); - delete []vals; -} - -void PropSet::EnsureCanAddEntry() { - if (used >= size - 2) { - int newsize = size + 10; - char **newvals = new char * [newsize]; - - for (int i = 0; i < used; i++) { - newvals[i] = vals[i]; - } - delete []vals; - vals = newvals; - size = newsize; - } } void PropSet::Set(const char *key, const char *val) { - EnsureCanAddEntry(); - for (int i = 0; i < used; i += 2) { - if (EqualCaseInsensitive(vals[i], key)) { + unsigned int hash = HashString(key); + for (Property *p=props[hash % hashRoots]; p; p=p->next) { + if ((hash == p->hash) && (0 == strcmp(p->key, key))) { // Replace current value - delete [](vals[i + 1]); - vals[i + 1] = StringDup(val); + delete [](p->val); + p->val = StringDup(val); return; } } // Not found - vals[used++] = StringDup(key); - vals[used++] = StringDup(val); + Property *pNew = new Property; + if (pNew) { + pNew->hash = HashString(key); + pNew->key = StringDup(key); + pNew->val = StringDup(val); + pNew->next = props[hash % hashRoots]; + props[hash % hashRoots] = pNew; + } } void PropSet::Set(char *keyval) { + while (isspace(*keyval)) + keyval++; char *eqat = strchr(keyval, '='); if (eqat) { *eqat = '\0'; @@ -106,11 +110,12 @@ void PropSet::Set(char *keyval) { } SString PropSet::Get(const char *key) { - for (int i = 0; i < used; i += 2) { - if (EqualCaseInsensitive(vals[i], key)) { - return vals[i + 1]; - } - } + unsigned int hash = HashString(key); + for (Property *p=props[hash % hashRoots]; p; p=p->next) { + if ((hash == p->hash) && (0 == strcmp(p->key, key))) { + return p->val; + } + } if (superPS) { // Failed here, so try in base property set return superPS->Get(key); @@ -119,6 +124,36 @@ SString PropSet::Get(const char *key) { } } +SString PropSet::GetExpanded(const char *key) { + SString val = Get(key); + return Expand(val.c_str()); +} + +SString PropSet::Expand(const char *withvars) { + char *base = StringDup(withvars); + char *cpvar = strstr(base, "$("); + while (cpvar) { + char *cpendvar = strchr(cpvar, ')'); + if (cpendvar) { + int lenvar = cpendvar - cpvar - 2; // Subtract the $() + char *var = StringDup(cpvar+2, lenvar); + SString val = GetExpanded(var); + int newlenbase = strlen(base) + val.length() - lenvar; + char *newbase = new char[newlenbase]; + strncpy(newbase, base, cpvar - base); + strcpy(newbase + (cpvar - base), val.c_str()); + strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1); + delete []var; + delete []base; + base = newbase; + } + cpvar = strstr(base, "$("); + } + SString sret = base; + delete []base; + return sret; +} + int PropSet::GetInt(const char *key, int defaultValue) { SString val = Get(key); if (val.length()) @@ -127,9 +162,9 @@ int PropSet::GetInt(const char *key, int defaultValue) { return defaultValue; } -bool isprefix(const char *target, const char *prefix) { +inline bool isprefix(const char *target, const char *prefix) { while (*target && *prefix) { - if (toupper(*target) != toupper(*prefix)) + if (*target != *prefix) return false; target++; prefix++; @@ -146,64 +181,63 @@ bool issuffix(const char *target, const char *suffix) { if (lensuffix > lentarget) return false; for (int i = lensuffix - 1; i >= 0; i--) { - if (toupper(target[i + lentarget - lensuffix]) != toupper(suffix[i])) + if (target[i + lentarget - lensuffix] != suffix[i]) return false; } return true; } SString PropSet::GetWild(const char *keybase, const char *filename) { - for (int i = 0; i < used; i += 2) { - if (isprefix(vals[i], keybase)) { - char *orgkeyfile = vals[i] + strlen(keybase); - char *keyfile = NULL; - - if (strstr(orgkeyfile, "$(") == orgkeyfile) { - char *cpendvar = strchr(orgkeyfile, ')'); - if (cpendvar) { - int lenvar = cpendvar - orgkeyfile - 2; // Subtract the $() - char *var = static_cast(malloc(lenvar + 1)); - strncpy(var, orgkeyfile + 2, lenvar); - var[lenvar] = '\0'; - SString s = Get(var); - free(var); - keyfile = strdup(s.c_str()); - } - } - char *keyptr = keyfile; - - if (keyfile == NULL) - keyfile = orgkeyfile; - - for (; ; ) { - char *del = strchr(keyfile, ';'); - if (del == NULL) - del = keyfile + strlen(keyfile); - char delchr = *del; - *del = '\0'; - if (*keyfile == '*') { - if (issuffix(filename, keyfile + 1)) { - *del = delchr; - free(keyptr); - return vals[i + 1]; - } - } else if (EqualCaseInsensitive(keyfile, filename)) { - *del = delchr; - free(keyptr); - return vals[i + 1]; - } - if (delchr == '\0') - break; - *del = delchr; - keyfile = del + 1; - } - free(keyptr); - - if (EqualCaseInsensitive(vals[i], keybase)) { - return vals[i + 1]; - } - } - } + for (int root=0; root < hashRoots; root++) { + for (Property *p=props[root]; p; p=p->next) { + if (isprefix(p->key, keybase)) { + char *orgkeyfile = p->key + strlen(keybase); + char *keyfile = NULL; + + if (strstr(orgkeyfile, "$(") == orgkeyfile) { + char *cpendvar = strchr(orgkeyfile, ')'); + if (cpendvar) { + *cpendvar = '\0'; + SString s = Get(orgkeyfile + 2); + *cpendvar= ')'; + keyfile = strdup(s.c_str()); + } + } + char *keyptr = keyfile; + + if (keyfile == NULL) + keyfile = orgkeyfile; + + for (; ; ) { + char *del = strchr(keyfile, ';'); + if (del == NULL) + del = keyfile + strlen(keyfile); + char delchr = *del; + *del = '\0'; + if (*keyfile == '*') { + if (issuffix(filename, keyfile + 1)) { + *del = delchr; + free(keyptr); + return p->val; + } + } else if (0 == strcmp(keyfile, filename)) { + *del = delchr; + free(keyptr); + return p->val; + } + if (delchr == '\0') + break; + *del = delchr; + keyfile = del + 1; + } + free(keyptr); + + if (0 == strcmp(p->key, keybase)) { + return p->val; + } + } + } + } if (superPS) { // Failed here, so try in base property set return superPS->GetWild(keybase, filename); @@ -219,9 +253,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() - char *var = new char[lenvar + 1]; - strncpy(var, cpvar + 2, lenvar); - var[lenvar] = '\0'; + char *var = StringDup(cpvar+2, lenvar); SString val = GetWild(var, filename); int newlenbase = strlen(base) + val.length() - lenvar; char *newbase = new char[newlenbase]; @@ -240,36 +272,54 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { } void PropSet::Clear() { - for (int i = 0; i < used; i++) { - delete [](vals[i]); - vals[i] = 0; - } - used = 0; + for (int root=0; root < hashRoots; root++) { + Property *p=props[root]; + while (p) { + Property *pNext=p->next; + p->hash = 0; + delete p->key; + p->key = 0; + delete p->val; + p->val = 0; + delete p; + p = pNext; + } + props[root] = 0; + } } -void PropSet::ReadFromMemory(const char *data, int len) { - if (len > 0) { - const char *pd = data; - char linebuf[60000]; - while (GetFullLine(pd, len, linebuf, sizeof(linebuf))) { - if (isalpha(linebuf[0])) - Set(linebuf); - } - // If there is a final line: - if (isalpha(linebuf[0])) +void PropSet::ReadFromMemory(const char *data, int len, const char *directoryForImports) { + const char *pd = data; + char linebuf[60000]; + bool ifIsTrue = true; + while (len > 0) { + GetFullLine(pd, len, linebuf, sizeof(linebuf)); + if (isalpha(linebuf[0])) // If clause ends with first non-indented line + ifIsTrue = true; + if (isprefix(linebuf, "if ")) { + const char *expr = linebuf + strlen("if") + 1; + ifIsTrue = GetInt(expr); + } else if (isprefix(linebuf, "import ") && directoryForImports) { + char importPath[1024]; + strcpy(importPath, directoryForImports); + strcat(importPath, linebuf + strlen("import") + 1); + strcat(importPath, ".properties"); + Read(importPath,directoryForImports); + } else if (isalpha(linebuf[0])) { Set(linebuf); + } else if (isspace(linebuf[0]) && ifIsTrue) { + Set(linebuf); + } } } -void PropSet::Read(const char *filename) { - //printf("Opening properties <%s>\n", filename); - Clear(); +void PropSet::Read(const char *filename, const char *directoryForImports) { char propsData[60000]; FILE *rcfile = fopen(filename, "rb"); if (rcfile) { int lenFile = fread(propsData, 1, sizeof(propsData), rcfile); fclose(rcfile); - ReadFromMemory(propsData, lenFile); + ReadFromMemory(propsData, lenFile, directoryForImports); } else { //printf("Could not open <%s>\n", filename); } @@ -285,7 +335,8 @@ static bool iswordsep(char ch, bool onlyLineEnds) { // Creates an array that points into each word in the string and puts \0 terminators // after each word. -static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) { +static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) { +#if 1 char prev = '\n'; int words = 0; for (int j = 0; wordlist[j]; j++) { @@ -297,8 +348,8 @@ static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) { if (keywords) { words = 0; prev = '\0'; - int len = strlen(wordlist); - for (int k = 0; k < len; k++) { + int slen = strlen(wordlist); + for (int k = 0; k < slen; k++) { if (!iswordsep(wordlist[k], onlyLineEnds)) { if (!prev) { keywords[words] = &wordlist[k]; @@ -309,25 +360,69 @@ static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) { } prev = wordlist[k]; } - keywords[words] = &wordlist[len]; + keywords[words] = &wordlist[slen]; + *len = words; + } else { + *len = 0; } +#else + int words = 0; // length of the returned buffer of pointers + #undef APICHUNK // how many pointers will be pre-allocated (to avoid buffer reallocation on each new pointer) + #define APICHUNK 256 + int size = APICHUNK; // real size of the returned buffer of pointers + char **keywords; // buffer for the pointers returned + int slen = strlen(wordlist); //length of the buffer with api file + keywords = (char**) malloc((size + 1) * sizeof (*keywords)); + words = 0; + for (int k = 0;;) { + while (iswordsep(wordlist[k], onlyLineEnds)) + wordlist[k++] = '\0'; + if (k >= slen) + break; + if (words >= size) { + do + size += APICHUNK; + while (size <= words); + keywords = (char**) realloc(keywords, (size + 1) * sizeof (*keywords)); + } + keywords[words++] = wordlist + k; + do + if (k < slen) + k++; + else + goto out; + while (!iswordsep(wordlist[k], onlyLineEnds)); + } +out: + keywords[words] = wordlist + slen; + *len = words; +#endif return keywords; } void WordList::Clear() { if (words) { - delete []words; delete []list; +#if 1 + delete []words; +#else + free(words); +#endif + free(wordsNoCase); } words = 0; + wordsNoCase = 0; list = 0; len = 0; + sorted = false; } void WordList::Set(const char *s) { - len = 0; list = StringDup(s); - words = ArrayFromWordList(list, onlyLineEnds); + sorted = false; + words = ArrayFromWordList(list, &len, onlyLineEnds); + wordsNoCase = (char**) malloc ((len + 1) * sizeof (*wordsNoCase)); + memcpy(wordsNoCase, words, (len + 1) * sizeof (*words)); } char *WordList::Allocate(int size) { @@ -337,45 +432,35 @@ char *WordList::Allocate(int size) { } void WordList::SetFromAllocated() { - len = 0; - words = ArrayFromWordList(list, onlyLineEnds); + sorted = false; + words = ArrayFromWordList(list, &len, onlyLineEnds); + wordsNoCase = (char**) malloc ((len + 1) * sizeof (*wordsNoCase)); + memcpy(wordsNoCase, words, (len + 1) * sizeof (*words)); } -// Shell sort based upon public domain C implementation by Raymond Gardner 1991 -// Used here because of problems with mingw qsort. -static void SortWordList(char **words, unsigned int len) { - unsigned int gap = len / 2; - - while (gap > 0) { - unsigned int i = gap; - while (i < len) { - unsigned int j = i; - char **a = words + j; - do { - j -= gap; - char **b = a; - a -= gap; - if (strcmp(*a, *b) > 0) { - char *tmp = *a; - *a = *b; - *b = tmp; - } else { - break; - } - } while (j >= gap); - i++; - } - gap = gap / 2; - } +int cmpString(const void *a1, const void *a2) { + // Can't work out the correct incantation to use modern casts here + return strcmp(*(char**)(a1), *(char**)(a2)); +} + +int cmpStringNoCase(const void *a1, const void *a2) { + // Can't work out the correct incantation to use modern casts here + return strcasecmp(*(char**)(a1), *(char**)(a2)); } +static void SortWordList(char **words, char **wordsNoCase, unsigned int len) { + qsort(reinterpret_cast(words), len, sizeof(*words), + cmpString); + qsort(reinterpret_cast(wordsNoCase), len, sizeof(*wordsNoCase), + cmpStringNoCase); +} + bool WordList::InList(const char *s) { if (0 == words) return false; - if (len == 0) { - for (int i = 0; words[i][0]; i++) - len++; - SortWordList(words, len); + if (!sorted) { + sorted = true; + SortWordList(words, wordsNoCase, len); for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) starts[k] = -1; for (int l = len - 1; l >= 0; l--) { @@ -402,3 +487,256 @@ bool WordList::InList(const char *s) { } return false; } + +/** + * Returns an element (complete) of the wordlist array which has the beginning + * the same as the passed string. The length of the word to compare is passed + * too. Letter case can be ignored or preserved (default). + */ +const char *WordList::GetNearestWord(const char *wordStart, int searchLen /*= -1*/, bool ignoreCase /*= false*/) { + int start = 0; // lower bound of the api array block to search + int end = len - 1; // upper bound of the api array block to search + int pivot; // index of api array element just being compared + int cond; // comparison result (in the sense of strcmp() result) + const char *word; // api array element just being compared + + if (0 == words) + return NULL; + if (!sorted) { + sorted = true; + SortWordList(words, wordsNoCase, len); + } + if (ignoreCase) + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = wordsNoCase[pivot]; + cond = strncasecmp(wordStart, word, searchLen); + if (!cond && nonFuncChar(word[searchLen])) // maybe there should be a "non-word character" test here? + return word; // result must not be freed with free() + else if (cond < 0) + end = pivot - 1; + else if (cond > 0) + start = pivot + 1; + } + else // preserve the letter case + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = words[pivot]; + cond = strncmp(wordStart, word, searchLen); + if (!cond && nonFuncChar(word[searchLen])) // maybe there should be a "non-word character" test here? + return word; // result must not be freed with free() + else if (cond >= 0) + start = pivot + 1; + else if (cond < 0) + end = pivot - 1; + } + return NULL; +} + +/** + * Returns elements (first words of them) of the wordlist array which have + * the beginning the same as the passed string. The length of the word to + * compare is passed too. Letter case can be ignored or preserved (default). + * If there are more words meeting the condition they are returned all of + * them in the ascending order separated with spaces. + * + * NOTE: returned buffer has to be freed with a free() call. + */ +char *WordList::GetNearestWords(const char *wordStart, int searchLen /*= -1*/, bool ignoreCase /*= false*/) { + int wordlen; // length of the word part (before the '(' brace) of the api array element + int length = 0; // length of the returned buffer of words (string) + int newlength; // length of the new buffer before the reallocating itself + #undef WORDCHUNK // how many characters will be pre-allocated (to avoid buffer reallocation on each new word) + #define WORDCHUNK 100 + int size = WORDCHUNK; // real size of the returned buffer of words + char *buffer; // buffer for the words returned + int start = 0; // lower bound of the api array block to search + int end = len - 1; // upper bound of the api array block to search + int pivot; // index of api array element just being compared + int cond; // comparison result (in the sense of strcmp() result) + int oldpivot; // pivot storage to be able to browse the api array upwards and then downwards + const char *word; // api array element just being compared + const char *brace; // position of the opening brace in the api array element just being compared + + if (0 == words) + return NULL; + if (!sorted) { + sorted = true; + SortWordList(words, wordsNoCase, len); + } + buffer = (char*) malloc(size); + *buffer = '\0'; + if (ignoreCase) + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = wordsNoCase[pivot]; + cond = strncasecmp(wordStart, word, searchLen); + if (!cond) { + oldpivot = pivot; + do { // browse sequentially the rest after the hit + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + if (++pivot > end) + break; + word = wordsNoCase[pivot]; + } while (!strncasecmp(wordStart, word, searchLen)); + + pivot = oldpivot; + for (;;) { // browse sequentially the rest before the hit + if (--pivot < start) + break; + word = wordsNoCase[pivot]; + if (strncasecmp(wordStart, word, searchLen)) + break; + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) + { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + } + return buffer; // result has to be freed with free() + } + else if (cond < 0) + end = pivot - 1; + else if (cond > 0) + start = pivot + 1; + } + else // preserve the letter case + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = words[pivot]; + cond = strncmp(wordStart, word, searchLen); + if (!cond) { + oldpivot = pivot; + do { // browse sequentially the rest after the hit + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) + { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + if (++pivot > end) + break; + word = words[pivot]; + } while (!strncmp(wordStart, word, searchLen)); + + pivot = oldpivot; + for (;;) { // browse sequentially the rest before the hit + if (--pivot < start) + break; + word = words[pivot]; + if (strncmp(wordStart, word, searchLen)) + break; + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) + { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + } + return buffer; // result has to be freed with free() + } + else if (cond < 0) + end = pivot - 1; + else if (cond > 0) + start = pivot + 1; + } + free(buffer); + return NULL; +} diff --git a/contrib/src/stc/scintilla/src/SVector.h b/contrib/src/stc/scintilla/src/SVector.h index 550dd87ebd..d4d49c717d 100644 --- a/contrib/src/stc/scintilla/src/SVector.h +++ b/contrib/src/stc/scintilla/src/SVector.h @@ -6,13 +6,12 @@ #ifndef SVECTOR_H #define SVECTOR_H -// A simple expandable vector. -// T must support assignment. +// A simple expandable integer vector. // Storage not allocated for elements until an element is used. // This makes it very lightweight unless used so is a good match for optional features. -template + class SVector { - T *v; + int *v; unsigned int size; // Number of elements allocated unsigned int len; // Number of elements in vector bool allocFailure; // A memory allocation call has failed @@ -20,19 +19,23 @@ class SVector { // Internally allocate more elements than the user wants to avoid // thrashng the memory allocator void SizeTo(int newSize) { - if (newSize < sizeIncrement) - newSize += sizeIncrement; + if (newSize < 4000) + newSize += 4000; else newSize = (newSize * 3) / 2; - T* newv = new T[newSize]; + int* newv = new int[newSize]; if (!newv) { allocFailure = true; return; } size = newSize; - for (unsigned int i=0; i= len) { if (i >= size) { SizeTo(i); diff --git a/contrib/src/stc/scintilla/src/ScintillaBase.cxx b/contrib/src/stc/scintilla/src/ScintillaBase.cxx index 87b84f7064..4f182850ad 100644 --- a/contrib/src/stc/scintilla/src/ScintillaBase.cxx +++ b/contrib/src/stc/scintilla/src/ScintillaBase.cxx @@ -11,9 +11,9 @@ #include "Platform.h" #include "Scintilla.h" +#include "PropSet.h" #ifdef SCI_LEXER #include "SciLexer.h" -#include "PropSet.h" #include "Accessor.h" #include "WindowAccessor.h" #include "DocumentAccessor.h" @@ -41,9 +41,15 @@ ScintillaBase::ScintillaBase() { #endif } -ScintillaBase::~ScintillaBase() {} +ScintillaBase::~ScintillaBase() { +#ifdef SCI_LEXER + for (int wl=0;wlDeleteChars(currentPos, lenEntered); + SetEmptySelection(currentPos); + pdoc->InsertString(currentPos, list); + SetEmptySelection(currentPos + strlen(list)); + } else { + SetEmptySelection(currentPos); + pdoc->InsertString(currentPos, list + lenEntered); + SetEmptySelection(currentPos + strlen(list + lenEntered)); + } + return; + } + } ac.Start(wDraw, idAutoComplete, currentPos, lenEntered); PRectangle rcClient = GetClientRectangle(); Point pt = LocationFromPosition(currentPos-lenEntered); - //Platform::DebugPrintf("Auto complete %x\n", lbAutoComplete); int heightLB = 100; int widthLB = 100; if (pt.x >= rcClient.right - widthLB) { @@ -188,16 +213,18 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { rcac.right = rcac.left + widthLB; rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom); ac.lb.SetPositionRelative(rcac, wMain); - ac.lb.SetFont(vs.styles[0].font); + ac.lb.SetFont(vs.styles[STYLE_DEFAULT].font); + ac.lb.SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth); - int maxStrLen = ac.SetList(list); + ac.SetList(list); // Fiddle the position of the list so it is right next to the target and wide enough for all its strings - PRectangle rcList = ac.lb.GetPosition(); + PRectangle rcList = ac.lb.GetDesiredRect(); int heightAlloced = rcList.bottom - rcList.top; + widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left); // Make an allowance for large strings in list rcList.left = pt.x - 5; - rcList.right = rcList.left + Platform::Maximum(widthLB, maxStrLen * 8 + 16); + rcList.right = rcList.left + widthLB; if (pt.y >= rcClient.bottom - heightLB && // Wont fit below. pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above. rcList.top = pt.y - heightAlloced; @@ -206,8 +233,10 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { } rcList.bottom = rcList.top + heightAlloced; ac.lb.SetPositionRelative(rcList, wMain); - //lbAutoComplete.SetPosition(rcList); ac.Show(); + if (lenEntered != 0) { + AutoCompleteMoveToCurrentWord(); + } } void ScintillaBase::AutoCompleteCancel() { @@ -218,36 +247,63 @@ void ScintillaBase::AutoCompleteMove(int delta) { ac.Move(delta); } +void ScintillaBase::AutoCompleteMoveToCurrentWord() { + char wordCurrent[1000]; + int i; + int startWord = ac.posStart - ac.startLen; + for (i = startWord; i < currentPos; i++) + wordCurrent[i - startWord] = pdoc->CharAt(i); + wordCurrent[i - startWord] = '\0'; + ac.Select(wordCurrent); +} + void ScintillaBase::AutoCompleteChanged(char ch) { - if (currentPos <= ac.posStart) { + if (ac.IsFillUpChar(ch)) { + AutoCompleteCompleted(ch); + } else if (currentPos <= ac.posStart - ac.startLen) { + ac.Cancel(); + } else if (ac.cancelAtStartPos && currentPos <= ac.posStart) { ac.Cancel(); } else if (ac.IsStopChar(ch)) { ac.Cancel(); } else { - char wordCurrent[1000]; - int i; - int startWord = ac.posStart - ac.startLen; - for (i = startWord; i < currentPos; i++) - wordCurrent[i - startWord] = pdoc->CharAt(i); - wordCurrent[i - startWord] = '\0'; - ac.Select(wordCurrent); + AutoCompleteMoveToCurrentWord(); } } -void ScintillaBase::AutoCompleteCompleted() { +void ScintillaBase::AutoCompleteCompleted(char fillUp/*='\0'*/) { int item = ac.lb.GetSelection(); - char selected[200]; + char selected[1000]; if (item != -1) { ac.lb.GetValue(item, selected, sizeof(selected)); } ac.Cancel(); - if (currentPos != ac.posStart) { - pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart); - } - SetEmptySelection(ac.posStart); - if (item != -1) { - pdoc->InsertString(currentPos, selected + ac.startLen); - SetEmptySelection(currentPos + strlen(selected + ac.startLen)); + + if (ac.ignoreCase) { + if (currentPos != ac.posStart) { + pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart); + } + SetEmptySelection(ac.posStart - ac.startLen); + pdoc->DeleteChars(ac.posStart - ac.startLen, ac.startLen); + if (item != -1) { + SString piece = selected; + if (fillUp) + piece += fillUp; + pdoc->InsertString(currentPos, piece.c_str()); + SetEmptySelection(currentPos + piece.length()); + } + } else { + if (currentPos != ac.posStart) { + pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart); + } + SetEmptySelection(ac.posStart); + if (item != -1) { + SString piece = selected + ac.startLen; + if (fillUp) + piece += fillUp; + pdoc->InsertString(currentPos, piece.c_str()); + SetEmptySelection(currentPos + piece.length()); + } } } @@ -258,16 +314,21 @@ void ScintillaBase::ContextMenu(Point pt) { AddToPopUp(""); AddToPopUp("Cut", idcmdCut, currentPos != anchor); AddToPopUp("Copy", idcmdCopy, currentPos != anchor); - AddToPopUp("Paste", idcmdPaste, WndProc(EM_CANPASTE, 0, 0)); + AddToPopUp("Paste", idcmdPaste, WndProc(SCI_CANPASTE, 0, 0)); AddToPopUp("Delete", idcmdDelete, currentPos != anchor); AddToPopUp(""); AddToPopUp("Select All", idcmdSelectAll); popup.Show(pt, wMain); } -void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { +void ScintillaBase::CancelModes() { AutoCompleteCancel(); ct.CallTipCancel(); + Editor::CancelModes(); +} + +void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { + CancelModes(); Editor::ButtonDown(pt, curTime, shift, ctrl, alt); } @@ -295,8 +356,8 @@ void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { #ifdef SCI_LEXER if (lexLanguage != SCLEX_CONTAINER) { int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0); - int lineEndStyled = Platform::SendScintilla(wMain.GetID(), EM_LINEFROMCHAR, endStyled, 0); - endStyled = Platform::SendScintilla(wMain.GetID(), EM_LINEINDEX, lineEndStyled, 0); + int lineEndStyled = Platform::SendScintilla(wMain.GetID(), SCI_LINEFROMPOSITION, endStyled, 0); + endStyled = Platform::SendScintilla(wMain.GetID(), SCI_POSITIONFROMLINE, lineEndStyled, 0); Colourise(endStyled, endStyleNeeded); return; } @@ -304,7 +365,7 @@ void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { Editor::NotifyStyleToNeeded(endStyleNeeded); } -LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { +long ScintillaBase::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { switch (iMessage) { case SCI_AUTOCSHOW: AutoCompleteStart(wParam, reinterpret_cast(lParam)); @@ -325,7 +386,7 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case SCI_AUTOCSETSEPARATOR: - ac.SetSeparator(wParam); + ac.SetSeparator(static_cast(wParam)); break; case SCI_AUTOCGETSEPARATOR: @@ -338,13 +399,38 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_AUTOCSELECT: ac.Select(reinterpret_cast(lParam)); break; + + case SCI_AUTOCSETCANCELATSTART: + ac.cancelAtStartPos = wParam; + break; + + case SCI_AUTOCGETCANCELATSTART: + return ac.cancelAtStartPos; + + case SCI_AUTOCSETFILLUPS: + ac.SetFillUpChars(reinterpret_cast(lParam)); + break; + + case SCI_AUTOCSETCHOOSESINGLE: + ac.chooseSingle = wParam; + break; + case SCI_AUTOCGETCHOOSESINGLE: + return ac.chooseSingle; + + case SCI_AUTOCSETIGNORECASE: + ac.ignoreCase = wParam; + break; + + case SCI_AUTOCGETIGNORECASE: + return ac.ignoreCase; + case SCI_CALLTIPSHOW: { AutoCompleteCancel(); if (!ct.wCallTip.Created()) { PRectangle rc = ct.CallTipStart(currentPos, LocationFromPosition(wParam), reinterpret_cast(lParam), - vs.styles[0].fontName, vs.styles[0].size); + vs.styles[STYLE_DEFAULT].fontName, vs.styles[STYLE_DEFAULT].size); // If the call-tip window would be out of the client // space, adjust so it displays above the text. PRectangle rcClient = GetClientRectangle(); diff --git a/contrib/src/stc/scintilla/src/ScintillaBase.h b/contrib/src/stc/scintilla/src/ScintillaBase.h index 6344b17a34..e630ba1aac 100644 --- a/contrib/src/stc/scintilla/src/ScintillaBase.h +++ b/contrib/src/stc/scintilla/src/ScintillaBase.h @@ -47,13 +47,15 @@ protected: virtual void AddCharUTF(char *s, unsigned int len); void Command(int cmdId); - virtual int KeyCommand(UINT iMessage); + virtual void CancelModes(); + virtual int KeyCommand(unsigned int iMessage); void AutoCompleteStart(int lenEntered, const char *list); void AutoCompleteCancel(); void AutoCompleteMove(int delta); void AutoCompleteChanged(char ch=0); - void AutoCompleteCompleted(); + void AutoCompleteCompleted(char fillUp='\0'); + void AutoCompleteMoveToCurrentWord(); virtual void CreateCallTipWindow(PRectangle rc) = 0; @@ -65,7 +67,7 @@ protected: virtual void NotifyStyleToNeeded(int endStyleNeeded); public: // Public so scintilla_send_message can use it - virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); + virtual long WndProc(unsigned int iMessage, unsigned long wParam, long lParam); }; #endif diff --git a/contrib/src/stc/scintilla/src/Style.cxx b/contrib/src/stc/scintilla/src/Style.cxx index 7aa44c0eb9..0a52ed41a3 100644 --- a/contrib/src/stc/scintilla/src/Style.cxx +++ b/contrib/src/stc/scintilla/src/Style.cxx @@ -14,13 +14,13 @@ Style::Style() { aliasOfDefaultFont = true; Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, - false, false, false, false); + false, false, false, false, true); } Style::Style(const Style &source) { Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), 0, 0, 0, - false, false, false, false); + false, false, false, false, true); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -29,6 +29,7 @@ Style::Style(const Style &source) { size = source.size; eolFilled = source.eolFilled; underline = source.underline; + visible = source.visible; } Style::~Style() { @@ -44,7 +45,7 @@ Style &Style::operator=(const Style &source) { return *this; Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), 0, 0, SC_CHARSET_DEFAULT, - false, false, false, false); + false, false, false, false, true); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -53,12 +54,13 @@ Style &Style::operator=(const Style &source) { size = source.size; eolFilled = source.eolFilled; underline = source.underline; + visible = source.visible; return *this; } void Style::Clear(Colour fore_, Colour back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, bool underline_) { + bool bold_, bool italic_, bool eolFilled_, bool underline_, bool visible_) { fore.desired = fore_; back.desired = back_; characterSet = characterSet_; @@ -68,6 +70,7 @@ void Style::Clear(Colour fore_, Colour back_, int size_, fontName = fontName_; eolFilled = eolFilled_; underline = underline_; + visible = visible_; if (aliasOfDefaultFont) font.SetID(0); else diff --git a/contrib/src/stc/scintilla/src/Style.h b/contrib/src/stc/scintilla/src/Style.h index dc643d08d2..9a2b4586a3 100644 --- a/contrib/src/stc/scintilla/src/Style.h +++ b/contrib/src/stc/scintilla/src/Style.h @@ -18,6 +18,7 @@ public: int characterSet; bool eolFilled; bool underline; + bool visible; Font font; unsigned int lineHeight; @@ -34,7 +35,7 @@ public: void Clear(Colour fore_, Colour back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, bool underline_); + bool bold_, bool italic_, bool eolFilled_, bool underline_, bool visible_); bool EquivalentFontTo(const Style *other) const; void Realise(Surface &surface, int zoomLevel, Style *defaultStyle=0); }; diff --git a/contrib/src/stc/scintilla/src/ViewStyle.cxx b/contrib/src/stc/scintilla/src/ViewStyle.cxx index 580ecc71ff..9b7a8535e9 100644 --- a/contrib/src/stc/scintilla/src/ViewStyle.cxx +++ b/contrib/src/stc/scintilla/src/ViewStyle.cxx @@ -69,10 +69,12 @@ ViewStyle::ViewStyle(const ViewStyle &source) { selforeground.desired = source.selforeground.desired; selbackset = source.selbackset; selbackground.desired = source.selbackground.desired; + selbackground2.desired = source.selbackground2.desired; selbar.desired = source.selbar.desired; selbarlight.desired = source.selbarlight.desired; caretcolour.desired = source.caretcolour.desired; edgecolour.desired = source.edgecolour.desired; + edgeState = source.edgeState; leftMarginWidth = source.leftMarginWidth; rightMarginWidth = source.rightMarginWidth; for (int i=0;i < margins; i++) { @@ -83,6 +85,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) { fixedColumnWidth = source.fixedColumnWidth; zoomLevel = source.zoomLevel; viewWhitespace = source.viewWhitespace; + viewIndentationGuides = source.viewIndentationGuides; viewEOL = source.viewEOL; showMarkedLines = source.showMarkedLines; } @@ -111,6 +114,7 @@ void ViewStyle::Init() { selforeground.desired = Colour(0xff, 0, 0); selbackset = true; selbackground.desired = Colour(0xc0, 0xc0, 0xc0); + selbackground2.desired = Colour(0xb0, 0xb0, 0xb0); selbar.desired = Platform::Chrome(); selbarlight.desired = Platform::ChromeHighlight(); styles[STYLE_LINENUMBER].fore.desired = Colour(0, 0, 0); @@ -118,6 +122,7 @@ void ViewStyle::Init() { //caretcolour.desired = Colour(0xff, 0, 0); caretcolour.desired = Colour(0, 0, 0); edgecolour.desired = Colour(0xc0, 0xc0, 0xc0); + edgeState = EDGE_NONE; leftMarginWidth = 1; rightMarginWidth = 1; @@ -142,7 +147,8 @@ void ViewStyle::Init() { maskInLine &= ~ms[margin].mask; } zoomLevel = 0; - viewWhitespace = false; + viewWhitespace = wsInvisible; + viewIndentationGuides = false; viewEOL = false; showMarkedLines = true; } @@ -162,6 +168,7 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { } pal.WantFind(selforeground, want); pal.WantFind(selbackground, want); + pal.WantFind(selbackground2, want); pal.WantFind(selbar, want); pal.WantFind(selbarlight, want); pal.WantFind(caretcolour, want); @@ -203,7 +210,7 @@ void ViewStyle::ResetDefaultStyle() { styles[STYLE_DEFAULT].Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), SC_CHARSET_DEFAULT, - false, false, false, false); + false, false, false, false, true); } void ViewStyle::ClearStyles() { @@ -219,7 +226,8 @@ void ViewStyle::ClearStyles() { styles[STYLE_DEFAULT].bold, styles[STYLE_DEFAULT].italic, styles[STYLE_DEFAULT].eolFilled, - styles[STYLE_DEFAULT].underline); + styles[STYLE_DEFAULT].underline, + styles[STYLE_DEFAULT].visible); } } styles[STYLE_LINENUMBER].back.desired = Platform::Chrome(); diff --git a/contrib/src/stc/scintilla/src/ViewStyle.h b/contrib/src/stc/scintilla/src/ViewStyle.h index 4436e83ff4..5b0ab1925f 100644 --- a/contrib/src/stc/scintilla/src/ViewStyle.h +++ b/contrib/src/stc/scintilla/src/ViewStyle.h @@ -26,6 +26,7 @@ public: const char *Save(const char *name); }; +enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; class ViewStyle { public: FontNames fontNames; @@ -41,6 +42,7 @@ public: ColourPair selforeground; bool selbackset; ColourPair selbackground; + ColourPair selbackground2; ColourPair selbar; ColourPair selbarlight; // Margins are ordered: Line Numbers, Selection Margin, Spacing Margin @@ -52,11 +54,13 @@ public: MarginStyle ms[margins]; int fixedColumnWidth; int zoomLevel; - bool viewWhitespace; + WhiteSpaceVisibility viewWhitespace; + bool viewIndentationGuides; bool viewEOL; bool showMarkedLines; ColourPair caretcolour; ColourPair edgecolour; + int edgeState; ViewStyle(); ViewStyle(const ViewStyle &source); diff --git a/contrib/src/stc/scintilla/src/WindowAccessor.cxx b/contrib/src/stc/scintilla/src/WindowAccessor.cxx index 059c877bda..5f3deac7db 100644 --- a/contrib/src/stc/scintilla/src/WindowAccessor.cxx +++ b/contrib/src/stc/scintilla/src/WindowAccessor.cxx @@ -4,6 +4,7 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include #include @@ -17,25 +18,26 @@ WindowAccessor::~WindowAccessor() { } +#if PLAT_WIN bool WindowAccessor::InternalIsLeadByte(char ch) { -#if PLAT_GTK - // TODO: support DBCS under GTK+ - return false; -#elif PLAT_WIN if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the // same so none is considered a lead byte. return false; else return IsDBCSLeadByteEx(codePage, ch); -#elif PLAT_WX +} +#else +// PLAT_GTK or PLAT_WX +// TODO: support DBCS under GTK+ and WX +bool WindowAccessor::InternalIsLeadByte(char) { return false; -#endif } +#endif void WindowAccessor::Fill(int position) { if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); + lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0); startPos = position - slopSize; if (startPos + bufferSize > lenDoc) startPos = lenDoc - bufferSize; @@ -45,8 +47,8 @@ void WindowAccessor::Fill(int position) { if (endPos > lenDoc) endPos = lenDoc; - TEXTRANGE tr = {{startPos, endPos}, buf}; - Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast(&tr)); + TextRange tr = {{startPos, endPos}, buf}; + Platform::SendScintilla(id, SCI_GETTEXTRANGE, 0, reinterpret_cast(&tr)); } char WindowAccessor::StyleAt(int position) { @@ -55,11 +57,11 @@ char WindowAccessor::StyleAt(int position) { } int WindowAccessor::GetLine(int position) { - return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); + return Platform::SendScintilla(id, SCI_LINEFROMPOSITION, position, 0); } int WindowAccessor::LineStart(int line) { - return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); + return Platform::SendScintilla(id, SCI_POSITIONFROMLINE, line, 0); } int WindowAccessor::LevelAt(int line) { @@ -68,7 +70,7 @@ int WindowAccessor::LevelAt(int line) { int WindowAccessor::Length() { if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); + lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0); return lenDoc; } @@ -121,7 +123,7 @@ void WindowAccessor::Flush() { lenDoc = -1; if (validLen > 0) { Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, - reinterpret_cast(styleBuf)); + reinterpret_cast(styleBuf)); validLen = 0; } } diff --git a/contrib/src/stc/stc.cpp b/contrib/src/stc/stc.cpp index aa7bf8dd98..3fde7ae05d 100644 --- a/contrib/src/stc/stc.cpp +++ b/contrib/src/stc/stc.cpp @@ -26,7 +26,7 @@ // If we don't do something like this, then the linker tends to "optimize" // them away. (eric@sourcegear.com) -int wxForceScintillaLexers(void) +static int wxForceScintillaLexers(void) { extern LexerModule lmCPP; extern LexerModule lmHTML; @@ -39,6 +39,7 @@ int wxForceScintillaLexers(void) extern LexerModule lmPython; extern LexerModule lmSQL; extern LexerModule lmVB; + extern LexerModule lmLua; if ( &lmCPP @@ -52,14 +53,11 @@ int wxForceScintillaLexers(void) && &lmPython && &lmSQL && &lmVB + && &lmLua ) { return 1; } - else - { - return 0; - } } //---------------------------------------------------------------------- @@ -131,7 +129,7 @@ wxString wxStyledTextCtrl::GetText() { int len = GetTextLength(); char* buff = text.GetWriteBuf(len+1); - SendMsg(WM_GETTEXT, len, (long)buff); + SendMsg(SCI_GETTEXT, len, (long)buff); buff[len] = 0; text.UngetWriteBuf(); return text; @@ -139,7 +137,7 @@ wxString wxStyledTextCtrl::GetText() { bool wxStyledTextCtrl::SetText(const wxString& text) { - return SendMsg(WM_SETTEXT, 0, (long)text.c_str()) != 0; + return SendMsg(SCI_SETTEXT, 0, (long)text.c_str()) != 0; } @@ -148,8 +146,7 @@ wxString wxStyledTextCtrl::GetLine(int line) { int len = GetLineLength(line); char* buff = text.GetWriteBuf(len+1); - *((WORD*)buff) = len; - SendMsg(EM_GETLINE, line, (long)buff); + SendMsg(SCI_GETLINE, line, (long)buff); buff[len] = 0; text.UngetWriteBuf(); return text; @@ -157,12 +154,12 @@ wxString wxStyledTextCtrl::GetLine(int line) { void wxStyledTextCtrl::ReplaceSelection(const wxString& text) { - SendMsg(EM_REPLACESEL, 0, (long)text.c_str()); + SendMsg(SCI_REPLACESEL, 0, (long)text.c_str()); } void wxStyledTextCtrl::SetReadOnly(bool readOnly) { - SendMsg(EM_SETREADONLY, (long)readOnly); + SendMsg(SCI_SETREADONLY, (long)readOnly); m_readOnly = readOnly; } @@ -175,18 +172,18 @@ bool wxStyledTextCtrl::GetReadOnly() { void wxStyledTextCtrl::GetTextRange(int startPos, int endPos, char* buff) { - TEXTRANGE tr; + TextRange tr; tr.lpstrText = buff; tr.chrg.cpMin = startPos; tr.chrg.cpMax = endPos; - SendMsg(EM_GETTEXTRANGE, 0, (long)&tr); + SendMsg(SCI_GETTEXTRANGE, 0, (long)&tr); } wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) { wxString text; int len = endPos - startPos; - char* buff = text.GetWriteBuf(len); + char* buff = text.GetWriteBuf(len+1); GetTextRange(startPos, endPos, buff); text.UngetWriteBuf(); return text; @@ -194,7 +191,7 @@ wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) { void wxStyledTextCtrl::GetStyledTextRange(int startPos, int endPos, char* buff) { - TEXTRANGE tr; + TextRange tr; tr.lpstrText = buff; tr.chrg.cpMin = startPos; tr.chrg.cpMax = endPos; @@ -205,7 +202,7 @@ void wxStyledTextCtrl::GetStyledTextRange(int startPos, int endPos, char* buff) wxString wxStyledTextCtrl::GetStyledTextRange(int startPos, int endPos) { wxString text; int len = endPos - startPos; - char* buff = text.GetWriteBuf(len*2); + char* buff = text.GetWriteBuf(len*2+1); GetStyledTextRange(startPos, endPos, buff); text.UngetWriteBuf(len*2); return text; @@ -257,27 +254,27 @@ int wxStyledTextCtrl::GetStyleBits() { void wxStyledTextCtrl::Cut() { - SendMsg(WM_CUT); + SendMsg(SCI_CUT); } void wxStyledTextCtrl::Copy() { - SendMsg(WM_COPY); + SendMsg(SCI_COPY); } void wxStyledTextCtrl::Paste() { - SendMsg(WM_PASTE); + SendMsg(SCI_PASTE); } bool wxStyledTextCtrl::CanPaste() { - return SendMsg(EM_CANPASTE) != 0; + return SendMsg(SCI_CANPASTE) != 0; } void wxStyledTextCtrl::ClearClipbrd() { - SendMsg(WM_CLEAR); + SendMsg(SCI_CLEAR); } @@ -286,17 +283,17 @@ void wxStyledTextCtrl::ClearClipbrd() { // Undo and Redo void wxStyledTextCtrl::Undo() { - SendMsg(WM_UNDO); + SendMsg(SCI_UNDO); } bool wxStyledTextCtrl::CanUndo() { - return SendMsg(EM_CANUNDO) != 0; + return SendMsg(SCI_CANUNDO) != 0; } void wxStyledTextCtrl::EmptyUndoBuffer() { - SendMsg(EM_EMPTYUNDOBUFFER); + SendMsg(SCI_EMPTYUNDOBUFFER); } @@ -340,12 +337,14 @@ void wxStyledTextCtrl::EndUndoAction() { void wxStyledTextCtrl::GetSelection(int* startPos, int* endPos) { - SendMsg(EM_GETSEL, (long)startPos, (long)endPos); +// SendMsg(EM_GETSEL, (long)startPos, (long)endPos); + *startPos = SendMsg(SCI_GETSELECTIONSTART); + *endPos = SendMsg(SCI_GETSELECTIONEND); } void wxStyledTextCtrl::SetSelection(int startPos, int endPos) { - SendMsg(EM_SETSEL, startPos, endPos); + SendMsg(SCI_SETSEL, startPos, endPos); } @@ -356,16 +355,16 @@ wxString wxStyledTextCtrl::GetSelectedText() { GetSelection(&start, &end); int len = end - start; - char* buff = text.GetWriteBuf(len); + char* buff = text.GetWriteBuf(len+1); - SendMsg(EM_GETSELTEXT, 0, (long)buff); + SendMsg(SCI_GETSELTEXT, 0, (long)buff); text.UngetWriteBuf(); return text; } void wxStyledTextCtrl::HideSelection(bool hide) { - SendMsg(EM_HIDESELECTION, hide); + SendMsg(SCI_HIDESELECTION, hide); } @@ -375,46 +374,32 @@ bool wxStyledTextCtrl::GetHideSelection() { int wxStyledTextCtrl::GetTextLength() { - return SendMsg(WM_GETTEXTLENGTH); + return SendMsg(SCI_GETTEXTLENGTH); } int wxStyledTextCtrl::GetFirstVisibleLine() { - return SendMsg(EM_GETFIRSTVISIBLELINE); + return SendMsg(SCI_GETFIRSTVISIBLELINE); } int wxStyledTextCtrl::GetLineCount() { - return SendMsg(EM_GETLINECOUNT); + return SendMsg(SCI_GETLINECOUNT); } bool wxStyledTextCtrl::GetModified() { - return SendMsg(EM_GETMODIFY) != 0; -} - - -wxRect wxStyledTextCtrl::GetRect() { - PRectangle pr; - SendMsg(EM_GETRECT, 0, (long)&pr); - - wxRect rect = wxRectFromPRectangle(pr); - return rect; + return SendMsg(SCI_GETMODIFY) != 0; } int wxStyledTextCtrl::GetLineFromPos(int pos) { - return SendMsg(EM_LINEFROMCHAR, pos); + return SendMsg(SCI_LINEFROMPOSITION, pos); } int wxStyledTextCtrl::GetLineStartPos(int line) { - return SendMsg(EM_LINEINDEX, line); -} - - -int wxStyledTextCtrl::GetLineLengthAtPos(int pos) { - return SendMsg(EM_LINELENGTH, pos); + return SendMsg(SCI_POSITIONFROMLINE, line); } @@ -445,23 +430,14 @@ wxString wxStyledTextCtrl::GetCurrentLineText(int* linePos) { int wxStyledTextCtrl::PositionFromPoint(wxPoint pt) { - Point spt(pt.x, pt.y); - long rv = SendMsg(EM_CHARFROMPOS, 0, (long)&spt); - return LOWORD(rv); -} - - -int wxStyledTextCtrl::LineFromPoint(wxPoint pt) { - Point spt(pt.x, pt.y); - long rv = SendMsg(EM_CHARFROMPOS, 0, (long)&spt); - return HIWORD(rv); + return SendMsg(SCI_POSITIONFROMPOINT, pt.x, pt.y); } wxPoint wxStyledTextCtrl::PointFromPosition(int pos) { - Point pt; - SendMsg(EM_POSFROMCHAR, (long)&pt, pos); - return wxPoint(pt.x, pt.y); + int x = SendMsg(SCI_POINTXFROMPOSITION, 0, pos); + int y = SendMsg(SCI_POINTYFROMPOSITION, 0, pos); + return wxPoint(x, y); } @@ -513,7 +489,7 @@ void wxStyledTextCtrl::PageMove(int cmdKey, bool extendSelection) { void wxStyledTextCtrl::ScrollBy(int columnDelta, int lineDelta) { - SendMsg(EM_LINESCROLL, columnDelta, lineDelta); + SendMsg(SCI_LINESCROLL, columnDelta, lineDelta); } void wxStyledTextCtrl::ScrollToLine(int line) { @@ -527,7 +503,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) { void wxStyledTextCtrl::EnsureCaretVisible() { - SendMsg(EM_SCROLLCARET); + SendMsg(SCI_SCROLLCARET); } @@ -536,11 +512,6 @@ void wxStyledTextCtrl::SetCaretPolicy(int policy, int slop) { } -int wxStyledTextCtrl::GetSelectionType() { - return SendMsg(EM_SELECTIONTYPE); -} - - int wxStyledTextCtrl::GetLinesOnScreen() { return SendMsg(SCI_LINESONSCREEN); } @@ -568,18 +539,18 @@ bool wxStyledTextCtrl::GetUseHorizontalScrollBar() { // Searching int wxStyledTextCtrl::FindText(int minPos, int maxPos, - const wxString& text, - bool caseSensitive, bool wholeWord) { - FINDTEXTEX ft; + const wxString& text, + bool caseSensitive, bool wholeWord) { + TextToFind ft; int flags = 0; - flags |= caseSensitive ? FR_MATCHCASE : 0; - flags |= wholeWord ? FR_WHOLEWORD : 0; + flags |= caseSensitive ? SCFIND_MATCHCASE : 0; + flags |= wholeWord ? SCFIND_WHOLEWORD : 0; ft.chrg.cpMin = minPos; ft.chrg.cpMax = maxPos; ft.lpstrText = (char*)text.c_str(); - return SendMsg(EM_FINDTEXT, flags, (long)&ft); + return SendMsg(SCI_FINDTEXT, flags, (long)&ft); } @@ -590,8 +561,8 @@ void wxStyledTextCtrl::SearchAnchor() { int wxStyledTextCtrl::SearchNext(const wxString& text, bool caseSensitive, bool wholeWord) { int flags = 0; - flags |= caseSensitive ? FR_MATCHCASE : 0; - flags |= wholeWord ? FR_WHOLEWORD : 0; + flags |= caseSensitive ? SCFIND_MATCHCASE : 0; + flags |= wholeWord ? SCFIND_WHOLEWORD : 0; return SendMsg(SCI_SEARCHNEXT, flags, (long)text.c_str()); } @@ -599,8 +570,8 @@ int wxStyledTextCtrl::SearchNext(const wxString& text, bool caseSensitive, bool int wxStyledTextCtrl::SearchPrev(const wxString& text, bool caseSensitive, bool wholeWord) { int flags = 0; - flags |= caseSensitive ? FR_MATCHCASE : 0; - flags |= wholeWord ? FR_WHOLEWORD : 0; + flags |= caseSensitive ? SCFIND_MATCHCASE : 0; + flags |= wholeWord ? SCFIND_WHOLEWORD : 0; return SendMsg(SCI_SEARCHPREV, flags, (long)text.c_str()); } @@ -836,29 +807,24 @@ void wxStyledTextCtrl::StyleSetUnderline(int styleNum, bool underline) { // Margins in the edit area int wxStyledTextCtrl::GetLeftMargin() { - return LOWORD(SendMsg(EM_GETMARGINS)); + return SendMsg(SCI_GETMARGINLEFT); } int wxStyledTextCtrl::GetRightMargin() { - return HIWORD(SendMsg(EM_GETMARGINS)); + return SendMsg(SCI_GETMARGINRIGHT); } void wxStyledTextCtrl::SetMargins(int left, int right) { int flag = 0; - int val = 0; if (right != -1) { - flag |= EC_RIGHTMARGIN; - val = right << 16; + SendMsg(SCI_SETMARGINRIGHT, 0, right); } if (left != -1) { - flag |= EC_LEFTMARGIN; - val |= (left & 0xffff); + SendMsg(SCI_SETMARGINLEFT, 0, left); } - - SendMsg(EM_SETMARGINS, flag, val); } @@ -1180,6 +1146,8 @@ void wxStyledTextCtrl::CallTipSetBackground(const wxColour& colour) { //---------------------------------------------------------------------- // Key bindings +#define MAKELONG(a, b) ((a) | ((b) << 16)) + void wxStyledTextCtrl::CmdKeyAssign(int key, int modifiers, int cmd) { SendMsg(SCI_ASSIGNCMDKEY, MAKELONG(key, modifiers), cmd); } @@ -1212,7 +1180,7 @@ wxStyledTextCtrl::FormatRange(bool doDraw, wxDC* target, // Why does it use two? Can they be the same? wxRect renderRect, wxRect pageRect) { - FORMATRANGE fr; + RangeToFormat fr; fr.hdc = draw; fr.hdcTarget = target; @@ -1227,7 +1195,7 @@ wxStyledTextCtrl::FormatRange(bool doDraw, fr.chrg.cpMin = startPos; fr.chrg.cpMax = endPos; - return SendMsg(EM_FORMATRANGE, doDraw, (long)&fr); + return SendMsg(SCI_FORMATRANGE, doDraw, (long)&fr); } diff --git a/include/wx/stc/stc.h b/include/wx/stc/stc.h index d5925f19be..659e6f2745 100644 --- a/include/wx/stc/stc.h +++ b/include/wx/stc/stc.h @@ -254,10 +254,8 @@ public: int GetFirstVisibleLine(); bool GetModified(); int GetLineCount(); - wxRect GetRect(); int GetLineFromPos(int pos); int GetLineStartPos(int line); - int GetLineLengthAtPos(int pos); int GetLineLength(int line); #ifdef SWIG wxString GetCurrentLineText(int* OUTPUT); @@ -266,7 +264,6 @@ public: #endif int GetCurrentLine(); int PositionFromPoint(wxPoint pt); - int LineFromPoint(wxPoint pt); wxPoint PointFromPosition(int pos); int GetCurrentPos(); int GetAnchor(); @@ -283,7 +280,6 @@ public: void ScrollToColumn(int column); void EnsureCaretVisible(); void SetCaretPolicy(int policy, int slop=0); - int GetSelectionType(); int GetLinesOnScreen(); bool IsSelectionRectangle(); void SetUseHorizontalScrollBar(bool use); diff --git a/src/stc/Makefile.in b/src/stc/Makefile.in index 73170e98e2..9f1ebcf396 100644 --- a/src/stc/Makefile.in +++ b/src/stc/Makefile.in @@ -26,6 +26,7 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ DocumentAccessor.o \ LexCPP.o \ LexHTML.o \ + LexLua.o \ LexOthers.o \ LexPerl.o \ LexPython.o \ @@ -47,6 +48,7 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \ ScintillaBase.o \ Style.o \ ViewStyle.o \ + PosRegExp.o \ APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/contrib/include diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 2bb9ba84eb..63b363ec0e 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -458,6 +458,25 @@ void ListBox::Create(Window &parent, int ctrlID) { 0, NULL, wxLB_SINGLE | wxLB_SORT); } +PRectangle ListBox::GetDesiredRect() { + wxSize sz = ((wxListBox*)id)->GetBestSize(); + PRectangle rc; + rc.top = 0; + rc.left = 0; + rc.right = sz.x; + rc.bottom = sz.y; + + return rc; +} + +void ListBox::SetAverageCharWidth(int width) { + aveCharWidth = width; +} + +void ListBox::SetFont(Font &font) { + Window::SetFont(font); +} + void ListBox::Clear() { ((wxListBox*)id)->Clear(); } diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index 56ac221558..41444aed2d 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -283,18 +283,18 @@ void ScintillaWX::ClaimSelection() { } -LRESULT ScintillaWX::DefWndProc(UINT /*iMessage*/, WPARAM /*wParam*/, LPARAM /*lParam*/) { +long ScintillaWX::DefWndProc(unsigned int /*iMessage*/, unsigned long /*wParam*/, long /*lParam*/) { return 0; } -LRESULT ScintillaWX::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { - switch (iMessage) { - case EM_CANPASTE: - return CanPaste(); - default: +long ScintillaWX::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { +// switch (iMessage) { +// case EM_CANPASTE: +// return CanPaste(); +// default: return ScintillaBase::WndProc(iMessage, wParam, lParam); - } - return 0; +// } +// return 0; } @@ -415,6 +415,29 @@ void ScintillaWX::DoAddChar(char ch) { } int ScintillaWX::DoKeyDown(int key, bool shift, bool ctrl, bool alt) { + switch (key) { + case WXK_DOWN: key = SCK_DOWN; break; + case WXK_UP: key = SCK_UP; break; + case WXK_LEFT: key = SCK_LEFT; break; + case WXK_RIGHT: key = SCK_RIGHT; break; + case WXK_HOME: key = SCK_HOME; break; + case WXK_END: key = SCK_END; break; + case WXK_PRIOR: key = SCK_PRIOR; break; + case WXK_NEXT: key = SCK_NEXT; break; + case WXK_DELETE: key = SCK_DELETE; break; + case WXK_INSERT: key = SCK_INSERT; break; + case WXK_ESCAPE: key = SCK_ESCAPE; break; + case WXK_BACK: key = SCK_BACK; break; + case WXK_TAB: key = SCK_TAB; break; + case WXK_RETURN: key = SCK_RETURN; break; + case WXK_ADD: key = SCK_ADD; break; + case WXK_SUBTRACT: key = SCK_SUBTRACT; break; + case WXK_DIVIDE: key = SCK_DIVIDE; break; + case WXK_CONTROL: key = 0; break; + case WXK_ALT: key = 0; break; + case WXK_SHIFT: key = 0; break; + } + return KeyDown(key, shift, ctrl, alt); } diff --git a/src/stc/ScintillaWX.h b/src/stc/ScintillaWX.h index c2087c9682..b773eac3a9 100644 --- a/src/stc/ScintillaWX.h +++ b/src/stc/ScintillaWX.h @@ -97,8 +97,12 @@ public: virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual void ClaimSelection(); - virtual LRESULT DefWndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); - virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); + virtual long DefWndProc(unsigned int iMessage, + unsigned long wParam, + long lParam); + virtual long WndProc(unsigned int iMessage, + unsigned long wParam, + long lParam); virtual void NotifyChange(); virtual void NotifyParent(SCNotification scn); diff --git a/src/stc/makefile.b32 b/src/stc/makefile.b32 index 6f5703b7dc..0d86478b7c 100644 --- a/src/stc/makefile.b32 +++ b/src/stc/makefile.b32 @@ -34,6 +34,7 @@ OBJECTS = \ KeyWords.obj \ LexCPP.obj \ LexHTML.obj \ + LexLua.obj \ LexOthers.obj \ LexPerl.obj \ LexPython.obj \ @@ -41,6 +42,7 @@ OBJECTS = \ LexVB.obj \ LineMarker.obj \ PropSet.obj \ + PosRegExp.obj \ ScintillaBase.obj \ Style.obj \ UniConversion.obj \ diff --git a/src/stc/makefile.g95 b/src/stc/makefile.g95 index 640501e22a..5b0cc02089 100644 --- a/src/stc/makefile.g95 +++ b/src/stc/makefile.g95 @@ -27,6 +27,7 @@ OBJECTS = \ $(S)/ViewStyle.$(OBJSUFF) \ $(S)/LexCPP.$(OBJSUFF) \ $(S)/LexHTML.$(OBJSUFF) \ + $(S)/LexLua.$(OBJSUFF) \ $(S)/LexOthers.$(OBJSUFF) \ $(S)/LexPerl.$(OBJSUFF) \ $(S)/LexPython.$(OBJSUFF) \ @@ -35,6 +36,7 @@ OBJECTS = \ $(S)/DocumentAccessor.$(OBJSUFF)\ $(S)/UniConversion.$(OBJSUFF) \ $(S)/WindowAccessor.$(OBJSUFF) \ + $(S)/PosRegExp.$(OBJSUFF) \ PlatWX.$(OBJSUFF) \ ScintillaWX.$(OBJSUFF) \ stc.$(OBJSUFF) diff --git a/src/stc/makefile.vc b/src/stc/makefile.vc index f7358c3e73..c101bba3f1 100644 --- a/src/stc/makefile.vc +++ b/src/stc/makefile.vc @@ -27,12 +27,14 @@ OBJECTS = \ $(D)\KeyWords.obj \ $(D)\LexCPP.obj \ $(D)\LexHTML.obj \ + $(D)\LexLua.obj \ $(D)\LexOthers.obj \ $(D)\LexPerl.obj \ $(D)\LexPython.obj \ $(D)\LexSQL.obj \ $(D)\LexVB.obj \ $(D)\LineMarker.obj \ + $(D)\PosRegExp.obj \ $(D)\PropSet.obj \ $(D)\ScintillaBase.obj \ $(D)\Style.obj \ diff --git a/src/stc/scintilla/README.txt b/src/stc/scintilla/README.txt index 409b44c3c2..b88d57495c 100644 --- a/src/stc/scintilla/README.txt +++ b/src/stc/scintilla/README.txt @@ -3,6 +3,5 @@ scintilla/include directories from the Scintilla/SCiTE source distribution. All other code needed to implement Scintilla on top of wxWindows is located in the directory above this one. -The current version of the Scintilla code is 1.25+ (from their CVS on -5-19-2000). +The current version of the Scintilla code is 1.32 diff --git a/src/stc/scintilla/include/Platform.h b/src/stc/scintilla/include/Platform.h index 5a87c64feb..de9cf202a1 100644 --- a/src/stc/scintilla/include/Platform.h +++ b/src/stc/scintilla/include/Platform.h @@ -80,12 +80,6 @@ typedef wxWindow* WindowID; typedef wxMenu* MenuID; #endif -#if PLAT_GTK || PLAT_WX -#define SHIFT_PRESSED 1 -#define LEFT_CTRL_PRESSED 2 -#define LEFT_ALT_PRESSED 4 -#endif - // Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably class Point { @@ -199,6 +193,7 @@ public: }; class Font { +protected: FontID id; #if PLAT_WX int ascent; @@ -208,10 +203,10 @@ class Font { Font &operator=(const Font &) { id=0; return *this; } public: Font(); - ~Font(); + virtual ~Font(); - void Create(const char *faceName, int characterSet, int size, bool bold, bool italic); - void Release(); + virtual void Create(const char *faceName, int characterSet, int size, bool bold, bool italic); + virtual void Release(); FontID GetID() { return id; } // Alias another font - caller guarantees not to Release @@ -327,7 +322,7 @@ public: void Show(bool show=true); void InvalidateAll(); void InvalidateRectangle(PRectangle rc); - void SetFont(Font &font); + virtual void SetFont(Font &font); enum Cursor { cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow }; void SetCursor(Cursor curs); void SetTitle(const char *s); @@ -344,14 +339,17 @@ class ListBox : public Window { WindowID scroller; int current; #endif + int desiredVisibleRows; + unsigned int maxItemCharacters; + unsigned int aveCharWidth; public: ListBox(); virtual ~ListBox(); - ListBox &operator=(WindowID id_) { - id = id_; - return *this; - } void Create(Window &parent, int ctrlID); + virtual void SetFont(Font &font); + void SetAverageCharWidth(int width); + void SetVisibleRows(int rows); + PRectangle GetDesiredRect(); void Clear(); void Append(char *s); int Length(); @@ -396,6 +394,16 @@ public: // These are utility functions not really tied to a platform static int Minimum(int a, int b); static int Maximum(int a, int b); + // Next three assume 16 bit shorts and 32 bit longs + static long LongFromTwoShorts(short a,short b) { + return (a) | ((b) << 16); + } + static short HighShortFromLong(long x) { + return static_cast(x >> 16); + } + static short LowShortFromLong(long x) { + return static_cast(x & 0xffff); + } static void DebugPrintf(const char *format, ...); static int Clamp(int val, int minVal, int maxVal); }; diff --git a/src/stc/scintilla/include/PosRegExp.h b/src/stc/scintilla/include/PosRegExp.h new file mode 100644 index 0000000000..b915b1ed49 --- /dev/null +++ b/src/stc/scintilla/include/PosRegExp.h @@ -0,0 +1,138 @@ +#ifndef POSREGEXP_H +#define POSREGEXP_H + +#define MatchesNum 0x10 + +enum EOps +{ + ReBlockOps = 0x1000, + ReMul, // * + RePlus, // + + ReQuest, // ? + ReNGMul, // *? + ReNGPlus, // +? + ReNGQuest, // ?? + ReRangeN, // {n,} + ReRangeNM, // {n,m} + ReNGRangeN, // {n,}? + ReNGRangeNM, // {n,m}? + ReOr, // | + ReBehind = 0x1100, // ?#n + ReNBehind = 0x1200, // ?~n + ReAhead = 0x1300, // ?= + ReNAhead = 0x1400, // ?! + + ReSymbolOps = 0x2000, + ReEmpty, + ReSymb, // a b \W \s ... + ReEnum, // [] + ReNEnum, // [^] + ReBrackets, // (...) + ReBkTrace = 0x2100, // \yN + ReBkBrack = 0x2200 // \N +}; + +enum ESymbols +{ + ReAnyChr = 0x4000, // . + ReSoL, // ^ + ReEoL, // $ + ReDigit, // \d + ReNDigit, // \D + ReWordSymb, // \w + ReNWordSymb, // \W + ReWSpace, // \s + ReNWSpace, // \S + ReUCase, // \u + ReNUCase , // \l + ReWBound, // \b + ReNWBound, // \B + RePreNW, // \c + ReStart, // \m + ReEnd, // \M + + ReChr = 0x0 // Char in Lower Byte +}; +enum ETempSymb +{ + ReTemp = 0x7000, + ReLBrack, ReRBrack, + ReEnumS, ReEnumE, ReNEnumS, + ReRangeS, ReRangeE, ReNGRangeE, ReFrToEnum +}; + +#define BackSlash '\\' + +typedef union SCharData +{ + int IArr[8]; + char CArr[32]; + void SetBit(unsigned char Bit); + void ClearBit(unsigned char Bit); + bool GetBit(unsigned char Bit); +} *PCharData; + +typedef struct SRegInfo +{ + SRegInfo(); + ~SRegInfo(); + + EOps Op; + union{ + SRegInfo *Param; + int Symb; + PCharData ChrClass; + }un; + int s,e; + SRegInfo *Parent; + SRegInfo *Next; +} *PRegInfo; + +typedef struct SMatches +{ + int s[MatchesNum]; + int e[MatchesNum]; + int CurMatch; +} *PMatches; + +typedef class PosRegExp +{ + PRegInfo Info; + PMatches BkTrace; + bool NoCase,Extend,NoMoves; + bool Error; + int *Exprn; + int posParse; + int posEnd,posStart; + int posBkStr; + int FirstChar; + + bool SetExprLow(const char *Expr); + bool SetStructs(PRegInfo &Info,int st,int end); + void Optimize(); + bool CheckSymb(int Symb,bool Inc); + bool LowParse(PRegInfo Re); + bool LowParseRe(PRegInfo &Next); + bool LowCheckNext(PRegInfo Re); + bool ParseRe(int posStr); + bool QuickCheck(); +public: + PMatches Matches; + int Ok, CurMatch; + + void *param; + char (*CharAt)(int pos, void *param); + + PosRegExp(); + ~PosRegExp(); + + bool isok(); + bool SetNoMoves(bool Moves); + bool SetBkTrace(int posStr,PMatches Trace); + bool SetExpr(const char *Expr); + bool Parse(int posStr, int posStop, PMatches Mtch); + bool Parse(int posStr,int posSol, int posEol, PMatches Mtch, int Moves = -1); + bool Evaluate(char *Expr, int posStr, PMatches Mtch, char **Res); +} *PPosRegExp; + +#endif /* POSREGEXP_H */ diff --git a/src/stc/scintilla/include/PropSet.h b/src/stc/scintilla/include/PropSet.h index bc1599f38a..025174f8ab 100644 --- a/src/stc/scintilla/include/PropSet.h +++ b/src/stc/scintilla/include/PropSet.h @@ -8,44 +8,92 @@ bool EqualCaseInsensitive(const char *a, const char *b); +#if PLAT_WIN +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +#ifdef __WXMSW__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + // Define another string class. // While it would be 'better' to use std::string, that doubles the executable size. -inline char *StringDup(const char *s) { +inline char *StringDup(const char *s, int len=-1) { if (!s) return 0; - char *sNew = new char[strlen(s) + 1]; - if (sNew) - strcpy(sNew, s); + if (len == -1) + len = strlen(s); + char *sNew = new char[len + 1]; + if (sNew) { + strncpy(sNew, s, len); + sNew[len] = '\0'; + } return sNew; } class SString { char *s; + int ssize; public: + typedef const char* const_iterator; + typedef int size_type; + static size_type npos; + const char* begin(void) const { + return s; + } + const char* end(void) const { + return &s[ssize]; + } + size_type size(void) const { + if (s) + return ssize; + else + return 0; + } + SString &assign(const char* sother, int size_ = -1) { + char *t = s; + s = StringDup(sother,size_); + ssize = (s) ? strlen(s) : 0; + delete []t; + return *this; + } + SString &assign(const SString& sother, int size_ = -1) { + return assign(sother.s,size_); + } + SString &assign(const_iterator ibeg, const_iterator iend) { + return assign(ibeg,iend - ibeg); + } SString() { s = 0; + ssize = 0; } SString(const SString &source) { s = StringDup(source.s); + ssize = (s) ? strlen(s) : 0; } SString(const char *s_) { s = StringDup(s_); + ssize = (s) ? strlen(s) : 0; } SString(int i) { char number[100]; sprintf(number, "%0d", i); - //itoa(i, number, 10); s = StringDup(number); + ssize = (s) ? strlen(s) : 0; } ~SString() { delete []s; s = 0; + ssize = 0; } SString &operator=(const SString &source) { if (this != &source) { delete []s; s = StringDup(source.s); + ssize = (s) ? strlen(s) : 0; } return *this; } @@ -56,6 +104,9 @@ public: return false; return strcmp(s, other.s) == 0; } + bool operator!=(const SString &other) const { + return !operator==(other); + } bool operator==(const char *sother) const { if ((s == 0) && (sother == 0)) return true; @@ -63,6 +114,9 @@ public: return false; return strcmp(s, sother) == 0; } + bool operator!=(const char *sother) const { + return !operator==(sother); + } const char *c_str() const { if (s) return s; @@ -82,99 +136,109 @@ public: return '\0'; } SString &operator +=(const char *sother) { + return append(sother,-1); + } + SString &operator +=(const SString &sother) { + return append(sother.s,sother.ssize); + } + SString &operator +=(char ch) { + return append(&ch,1); + } + SString &append(const char* sother, int lenOther) { int len = length(); - int lenOther = strlen(sother); + if(lenOther < 0) + lenOther = strlen(sother); char *sNew = new char[len + lenOther + 1]; if (sNew) { if (s) memcpy(sNew, s, len); - memcpy(sNew + len, sother, lenOther); + strncpy(&sNew[len], sother, lenOther); sNew[len + lenOther] = '\0'; delete []s; s = sNew; + ssize = (s) ? strlen(s) : 0; } return *this; } int value() const { if (s) return atoi(s); - else + else return 0; } + void substitute(char find, char replace) { + char *t = s; + while (t) { + t = strchr(t, find); + if (t) + *t = replace; + } + } + // I don't think this really belongs here -- Neil + void correctPath() { +#ifdef unix + substitute('\\', '/'); +#else + substitute('/', '\\'); +#endif + } +}; + +struct Property { + unsigned int hash; + char *key; + char *val; + Property *next; + Property() : hash(0), key(0), val(0), next(0) {} }; class PropSet { private: - char **vals; - int size; - int used; + enum { hashRoots=31 }; + Property *props[hashRoots]; public: PropSet *superPS; PropSet(); ~PropSet(); - void EnsureCanAddEntry(); void Set(const char *key, const char *val); void Set(char *keyval); SString Get(const char *key); + SString GetExpanded(const char *key); + SString Expand(const char *withvars); int GetInt(const char *key, int defaultValue=0); SString GetWild(const char *keybase, const char *filename); SString GetNewExpand(const char *keybase, const char *filename); void Clear(); - void ReadFromMemory(const char *data, int len); - void Read(const char *filename); -}; - -// This is a fixed length list of strings suitable for display in combo boxes -// as a memory of user entries -template -class EntryMemory { - SString entries[sz]; -public: - void Insert(SString s) { - for (int i=0;i0;j--) { - entries[j] = entries[j-1]; - } - entries[0] = s; - return; - } - } - for (int k=sz-1;k>0;k--) { - entries[k] = entries[k-1]; - } - entries[0] = s; - } - int Length() const { - int len = 0; - for (int i=0;i?@[\\]^`{|}~", ch) != NULL; +} + #endif diff --git a/src/stc/scintilla/include/SciLexer.h b/src/stc/scintilla/include/SciLexer.h index d869758f61..69402ab9ab 100644 --- a/src/stc/scintilla/include/SciLexer.h +++ b/src/stc/scintilla/include/SciLexer.h @@ -3,11 +3,15 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +// Most of this file is automatically generated from the Scintilla.iface interface definition +// file which contains any comments about the definitions. HFacer.py does the generation. + #ifndef SCILEXER_H #define SCILEXER_H // SciLexer features - not in standard Scintilla +//++Autogenerated -- start of section automatically generated from Scintilla.iface #define SCLEX_CONTAINER 0 #define SCLEX_NULL 1 #define SCLEX_PYTHON 2 @@ -23,8 +27,8 @@ #define SCLEX_BATCH 12 #define SCLEX_XCODE 13 #define SCLEX_LATEX 14 - -// Lexical states for SCLEX_PYTHON +#define SCLEX_LUA 15 +#define SCLEX_DIFF 16 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 #define SCE_P_NUMBER 2 @@ -39,8 +43,6 @@ #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 #define SCE_C_COMMENT 1 #define SCE_C_COMMENTLINE 2 @@ -54,8 +56,7 @@ #define SCE_C_OPERATOR 10 #define SCE_C_IDENTIFIER 11 #define SCE_C_STRINGEOL 12 - -// Lexical states for SCLEX_HTML, SCLEX_xML +#define SCE_C_VERBATIM 13 #define SCE_H_DEFAULT 0 #define SCE_H_TAG 1 #define SCE_H_TAGUNKNOWN 2 @@ -67,14 +68,15 @@ #define SCE_H_OTHER 8 #define SCE_H_COMMENT 9 #define SCE_H_ENTITY 10 -// XML and ASP #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_H_CDATA 17 +#define SCE_H_QUESTION 18 +#define SCE_H_VALUE 19 #define SCE_HJ_START 40 #define SCE_HJ_DEFAULT 41 #define SCE_HJ_COMMENT 42 @@ -87,7 +89,6 @@ #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 @@ -100,7 +101,6 @@ #define SCE_HJA_SINGLESTRING 64 #define SCE_HJA_SYMBOLS 65 #define SCE_HJA_STRINGEOL 66 -// Embedded VBScript #define SCE_HB_START 70 #define SCE_HB_DEFAULT 71 #define SCE_HB_COMMENTLINE 72 @@ -109,7 +109,6 @@ #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 @@ -118,7 +117,6 @@ #define SCE_HBA_STRING 85 #define SCE_HBA_IDENTIFIER 86 #define SCE_HBA_STRINGEOL 87 -// Embedded Python #define SCE_HP_START 90 #define SCE_HP_DEFAULT 91 #define SCE_HP_COMMENTLINE 92 @@ -132,7 +130,6 @@ #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 @@ -146,8 +143,15 @@ #define SCE_HPA_DEFNAME 115 #define SCE_HPA_OPERATOR 116 #define SCE_HPA_IDENTIFIER 117 - -// Lexical states for SCLEX_PERL +#define SCE_HPHP_DEFAULT 118 +#define SCE_HPHP_HSTRING 119 +#define SCE_HPHP_SIMPLESTRING 120 +#define SCE_HPHP_WORD 121 +#define SCE_HPHP_NUMBER 122 +#define SCE_HPHP_VARIABLE 123 +#define SCE_HPHP_COMMENT 124 +#define SCE_HPHP_COMMENTLINE 125 +#define SCE_HPHP_STRINGEOL 126 #define SCE_PL_DEFAULT 0 #define SCE_PL_HERE 1 #define SCE_PL_COMMENTLINE 2 @@ -170,12 +174,31 @@ #define SCE_PL_LONGQUOTE 19 #define SCE_PL_BACKTICKS 20 #define SCE_PL_DATASECTION 21 - -// Lexical states for SCLEX_LATEX #define SCE_L_DEFAULT 0 #define SCE_L_COMMAND 1 #define SCE_L_TAG 2 #define SCE_L_MATH 3 #define SCE_L_COMMENT 4 +#define SCE_LUA_DEFAULT 0 +#define SCE_LUA_COMMENT 1 +#define SCE_LUA_COMMENTLINE 2 +#define SCE_LUA_COMMENTDOC 3 +#define SCE_LUA_NUMBER 4 +#define SCE_LUA_WORD 5 +#define SCE_LUA_STRING 6 +#define SCE_LUA_CHARACTER 7 +#define SCE_LUA_LITERALSTRING 8 +#define SCE_LUA_PREPROCESSOR 9 +#define SCE_LUA_OPERATOR 10 +#define SCE_LUA_IDENTIFIER 11 +#define SCE_LUA_STRINGEOL 12 +#define SCE_ERR_DEFAULT 0 +#define SCE_ERR_PYTHON 1 +#define SCE_ERR_GCC 2 +#define SCE_ERR_MS 3 +#define SCE_ERR_CMD 4 +#define SCE_ERR_BORLAND 5 +#define SCE_ERR_PERL 6 +//--Autogenerated -- end of section automatically generated from Scintilla.iface #endif diff --git a/src/stc/scintilla/include/Scintilla.h b/src/stc/scintilla/include/Scintilla.h index 8e52ba59e2..ca81d135bd 100644 --- a/src/stc/scintilla/include/Scintilla.h +++ b/src/stc/scintilla/include/Scintilla.h @@ -3,119 +3,74 @@ // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. +// Most of this file is automatically generated from the Scintilla.iface interface definition +// file which contains any comments about the definitions. HFacer.py does the generation. + #ifndef SCINTILLA_H #define SCINTILLA_H // Compile-time configuration options #define MACRO_SUPPORT 1 // Comment out to remove macro hooks -#if PLAT_GTK -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject) -#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAS T (klass, scintilla_get_type (), ScintillaClass) -#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ()) - - typedef struct _ScintillaObject ScintillaObject; - typedef struct _ScintillaClass ScintillaClass; - - struct _ScintillaObject - { - GtkFixed vbox; - void *pscin; - }; - - struct _ScintillaClass - { - GtkFixedClass parent_class; - - void (* command) (ScintillaObject *ttt); - void (* notify) (ScintillaObject *ttt); - }; - - guint scintilla_get_type (void); - GtkWidget* scintilla_new (void); - void scintilla_set_id (ScintillaObject *sci,int id); - long scintilla_send_message (ScintillaObject *sci,int iMessage,int wParam,int lParam); - -#include "WinDefs.h" - -#ifdef __cplusplus -} -#endif - +#if PLAT_WIN +#ifdef STATIC_BUILD +void Scintilla_RegisterClasses(HINSTANCE hInstance); #endif - -#if PLAT_WX -#include "WinDefs.h" #endif -// Both GTK and Windows - -#define INVALID_POSITION -1 +typedef long (*SciFnDirect)(long ptr, unsigned int iMessage, unsigned long wParam, long lParam); -// Define start of Scintilla messages to be greater than all edit (EM_*) messages -// as many EM_ messages can be used. +//++Autogenerated -- start of section automatically generated from Scintilla.iface +#define INVALID_POSITION -1 #define SCI_START 2000 #define SCI_OPTIONAL_START 3000 #define SCI_LEXER_START 4000 - -#define SCI_ADDTEXT SCI_START + 1 -#define SCI_ADDSTYLEDTEXT SCI_START + 2 -#define SCI_INSERTTEXT SCI_START + 3 -#define SCI_CLEARALL SCI_START + 4 -#define SCI_GETLENGTH SCI_START + 6 -#define SCI_GETCHARAT SCI_START + 7 -#define SCI_GETCURRENTPOS SCI_START + 8 -#define SCI_GETANCHOR SCI_START + 9 -#define SCI_GETSTYLEAT SCI_START + 10 - -#define SCI_REDO SCI_START + 11 -#define SCI_SETUNDOCOLLECTION SCI_START + 12 -#define SCI_SELECTALL SCI_START + 13 -#define SCI_SETSAVEPOINT SCI_START + 14 -#define SCI_GETSTYLEDTEXT SCI_START + 15 -#define SCI_CANREDO SCI_START + 16 -#define SCI_MARKERLINEFROMHANDLE SCI_START + 17 -#define SCI_MARKERDELETEHANDLE SCI_START + 18 - -#define SC_UNDOCOLLECT_NONE 0 -#define SC_UNDOCOLLECT_AUTOSTART 1 - -#define SCI_GETVIEWWS SCI_START + 20 -#define SCI_SETVIEWWS SCI_START + 21 -#define SCI_GOTOLINE SCI_START + 24 -#define SCI_GOTOPOS SCI_START + 25 -#define SCI_SETANCHOR SCI_START + 26 -#define SCI_GETCURLINE SCI_START + 27 -#define SCI_GETENDSTYLED SCI_START + 28 -#define SCI_CONVERTEOLS SCI_START + 29 - -#define SCI_GETEOLMODE SCI_START + 30 -#define SCI_SETEOLMODE SCI_START + 31 - +#define SCI_ADDTEXT 2001 +#define SCI_ADDSTYLEDTEXT 2002 +#define SCI_INSERTTEXT 2003 +#define SCI_CLEARALL 2004 +#define SCI_CLEARDOCUMENTSTYLE 2005 +#define SCI_GETLENGTH 2006 +#define SCI_GETCHARAT 2007 +#define SCI_GETCURRENTPOS 2008 +#define SCI_GETANCHOR 2009 +#define SCI_GETSTYLEAT 2010 +#define SCI_REDO 2011 +#define SCI_SETUNDOCOLLECTION 2012 +#define SCI_SELECTALL 2013 +#define SCI_SETSAVEPOINT 2014 +#define SCI_GETSTYLEDTEXT 2015 +#define SCI_CANREDO 2016 +#define SCI_MARKERLINEFROMHANDLE 2017 +#define SCI_MARKERDELETEHANDLE 2018 +#define SCI_GETUNDOCOLLECTION 2019 +#define SCWS_INVISIBLE 0 +#define SCWS_VISIBLEALWAYS 1 +#define SCWS_VISIBLEAFTERINDENT 2 +#define SCI_GETVIEWWS 2020 +#define SCI_SETVIEWWS 2021 +#define SCI_POSITIONFROMPOINT 2022 +#define SCI_GOTOLINE 2024 +#define SCI_GOTOPOS 2025 +#define SCI_SETANCHOR 2026 +#define SCI_GETCURLINE 2027 +#define SCI_GETENDSTYLED 2028 +#define SCI_CONVERTEOLS 2029 #define SC_EOL_CRLF 0 #define SC_EOL_CR 1 #define SC_EOL_LF 2 - -#define SCI_STARTSTYLING SCI_START + 32 -#define SCI_SETSTYLING SCI_START + 33 - -// This is the same value as CP_UTF8 in Windows +#define SCI_GETEOLMODE 2030 +#define SCI_SETEOLMODE 2031 +#define SCI_STARTSTYLING 2032 +#define SCI_SETSTYLING 2033 +#define SCI_GETBUFFEREDDRAW 2034 +#define SCI_SETBUFFEREDDRAW 2035 +#define SCI_SETTABWIDTH 2036 +#define SCI_GETTABWIDTH 2121 #define SC_CP_UTF8 65001 - -#define SCI_SETBUFFEREDDRAW SCI_START + 35 -#define SCI_SETTABWIDTH SCI_START + 36 -#define SCI_SETCODEPAGE SCI_START + 37 -#define SCI_SETUSEPALETTE SCI_START + 39 - +#define SCI_SETCODEPAGE 2037 +#define SCI_SETUSEPALETTE 2039 #define MARKER_MAX 31 - #define SC_MARK_CIRCLE 0 #define SC_MARK_ROUNDRECT 1 #define SC_MARK_ARROW 2 @@ -125,255 +80,296 @@ extern "C" { #define SC_MARK_ARROWDOWN 6 #define SC_MARK_MINUS 7 #define SC_MARK_PLUS 8 - -#define SCI_MARKERDEFINE SCI_START + 40 -#define SCI_MARKERSETFORE SCI_START + 41 -#define SCI_MARKERSETBACK SCI_START + 42 -#define SCI_MARKERADD SCI_START + 43 -#define SCI_MARKERDELETE SCI_START + 44 -#define SCI_MARKERDELETEALL SCI_START + 45 -#define SCI_MARKERGET SCI_START + 46 -#define SCI_MARKERNEXT SCI_START + 47 -#define SCI_MARKERPREVIOUS SCI_START + 48 - #define SC_MARKNUM_FOLDER 30 #define SC_MARKNUM_FOLDEROPEN 31 - -#define SC_MASK_FOLDERS ((1< start a category ## fun -> a function ## get -> a property get function -## get -> a property set function +## set -> a property set function ## val -> definition of a constant +## evt -> an event ## All other feature names should be ignored. They may be defined in the future. ## A property may have a set function, a get function or both. Each will have ## "Get" or "Set" in their names and the corresponding name will have the obvious switch. @@ -21,6 +22,7 @@ ## [=,) ## param is [=] ## Additional white space is allowed between elements. +## The syntax for evt is [=[,]*]) ## Feature names that contain an underscore are defined by Windows, so in these ## cases, using the Windows definition is preferred where available. @@ -33,20 +35,27 @@ ## string -> pointer to const character ## stringresult -> pointer to character ## cells -> pointer to array of cells, each cell containing a style byte and character byte -## textrange -> complex structure +## charrange -> range of a min and a max position +## charrangeresult -> like charrange, but output param +## textrange -> charrange + output string ## findtext -> searchrange, text -> foundposition +## findtextex -> searchrange ## keymod -> integer containing key in low half and modifiers in high half ## countedstring ## formatrange ## point -> x,y +## pointresult -> like point, but output param +## rectangle -> left,top,right,bottom ## Client code should ignore definitions containing types it does not understand, except ## for possibly #defining the constants cat Basics ################################################ -## From Scintilla.h +## For Scintilla.h val INVALID_POSITION=-1 +# Define start of Scintilla messages to be greater than all edit (EM_*) messages +# as many EM_ messages can be used although that use is deprecated. val SCI_START=2000 val SCI_OPTIONAL_START=3000 val SCI_LEXER_START=4000 @@ -63,6 +72,9 @@ fun void InsertText=2003(position pos, string text) # Delete all text in the document fun void ClearAll=2004(,) +# Set all style bytes to 0, remove all folding information +fun void ClearDocumentStyle=2005(,) + # The number of characters in the document get int GetLength=2006(,) @@ -81,12 +93,9 @@ get int GetStyleAt=2010(position pos,) # Redoes the next action on the undo history fun void Redo=2011(,) -val SC_UNDOCOLLECT_NONE=0 -val SC_UNDOCOLLECT_AUTOSTART=1 - # Choose between collecting actions into the undo # history and discarding them. -set void SetUndoCollection=2012(int collectUndo,) +set void SetUndoCollection=2012(bool collectUndo,) # Select all the text in the document. fun void SelectAll=2013(,) @@ -108,11 +117,22 @@ fun int MarkerLineFromHandle=2017(int handle,) # Delete a marker. fun void MarkerDeleteHandle=2018(int handle,) +# Is undo history being collected? +get bool GetUndoCollection=2019(,) + +val SCWS_INVISIBLE=0 +val SCWS_VISIBLEALWAYS=1 +val SCWS_VISIBLEAFTERINDENT=2 + # Are white space characters currently visible? -get bool GetViewWS=2020(,) +# Returns one of SCWS_* constants. +get int GetViewWS=2020(,) -# Make white space characters visible or invisible. -set void SetViewWS=2021(bool viewWS,) +# Make white space characters invisible, always visible or visible outside indentation. +set void SetViewWS=2021(int viewWS,) + +# Find the position from a point within the window. +fun int PositionFromPoint=2022(int x, int y) # Set caret to start of a line and ensure it is visible. fun void GotoLine=2024(int line,) @@ -153,6 +173,9 @@ fun void StartStyling=2032(position pos, int mask) # and move the current styling position to after this newly styled segment. fun void SetStyling=2033(int length, int style) +# Is drawing done first into a buffer or direct to the screen. +get bool GetBufferedDraw=2034(,) + # If drawing is buffered then each line of text is drawn into a bitmap buffer # before drawing it to the screen to avoid flicker. set void SetBufferedDraw=2035(bool buffered,) @@ -164,6 +187,8 @@ set void SetTabWidth=2036(int tabWidth,) # Retrieve the visible size of a tab. get int GetTabWidth=2121(,) +# The SC_CP_UTF8 value can be used to enter Unicode mode. +# This is the same value as CP_UTF8 in Windows val SC_CP_UTF8=65001 # Set the code page used to interpret the bytes of the document as characters. @@ -187,7 +212,6 @@ val SC_MARK_PLUS=8 val SC_MARKNUM_FOLDER=30 val SC_MARKNUM_FOLDEROPEN=31 -##val SC_MASK_FOLDERS=1< +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef SCINTILLAWIDGET_H +#define SCINTILLAWIDGET_H + +#if PLAT_GTK + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject) +#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) +#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ()) + +typedef struct _ScintillaObject ScintillaObject; +typedef struct _ScintillaClass ScintillaClass; + +struct _ScintillaObject { + GtkFixed vbox; + void *pscin; +}; + +struct _ScintillaClass { + GtkFixedClass parent_class; + + void (* command) (ScintillaObject *ttt); + void (* notify) (ScintillaObject *ttt); +}; + +guint scintilla_get_type (void); +GtkWidget* scintilla_new (void); +void scintilla_set_id (ScintillaObject *sci,int id); +long scintilla_send_message (ScintillaObject *sci,int iMessage,int wParam,int lParam); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/src/stc/scintilla/include/WinDefs.h b/src/stc/scintilla/include/WinDefs.h index d1c25a595a..c56f02d810 100644 --- a/src/stc/scintilla/include/WinDefs.h +++ b/src/stc/scintilla/include/WinDefs.h @@ -16,6 +16,7 @@ #define LPSTR char * #define LONG long +//#if 0 /* RTF control */ #define EM_CANPASTE (1074) #define EM_CANUNDO (198) @@ -52,12 +53,10 @@ #define WM_NULL (0) #define WM_CLEAR (771) -#define WM_COMMAND (273) #define WM_COPY (769) #define WM_CUT (768) #define WM_GETTEXT (13) #define WM_GETTEXTLENGTH (14) -#define WM_NOTIFY (78) #define WM_PASTE (770) #define WM_SETTEXT (12) #define WM_UNDO (772) @@ -70,6 +69,9 @@ #define EC_RIGHTMARGIN 2 #define EC_USEFONTINFO 0xffff +//#endif + +#if 0 #if PLAT_GTK #define VK_DOWN GDK_Down #define VK_UP GDK_Up @@ -109,12 +111,16 @@ #define VK_SUBTRACT WXK_SUBTRACT //TODO: #define VK_DIVIDE WXK_DIVIDE +#endif + +#define SHIFT_PRESSED 1 +#define LEFT_CTRL_PRESSED 2 +#define LEFT_ALT_PRESSED 4 // Are these needed any more #define LPSTR char * #define LONG long #define LPDWORD (long *) -#endif /* SELCHANGE structure */ #define SEL_EMPTY (0) @@ -123,15 +129,6 @@ #define SEL_MULTICHAR (4) #define SEL_MULTIOBJECT (8) -/* FINDREPLACE structure */ -#define FR_MATCHCASE (0x4) -#define FR_WHOLEWORD (0x2) -#define FR_DOWN (0x1) - -#define SHIFT_PRESSED 1 -#define LEFT_CTRL_PRESSED 2 -#define LEFT_ALT_PRESSED 4 - struct RECT { LONG left; LONG top; @@ -139,6 +136,15 @@ struct RECT { LONG bottom; }; +/* FINDREPLACE structure */ + +#define FR_MATCHCASE (0x4) +#define FR_WHOLEWORD (0x2) +#define FR_DOWN (0x1) + +#endif + +#if 0 struct CHARRANGE { LONG cpMin; LONG cpMax; @@ -168,9 +174,10 @@ struct FORMATRANGE { RECT rcPage; CHARRANGE chrg; }; +#endif -#define MAKELONG(a, b) ((a) | ((b) << 16)) -#define LOWORD(x) (x & 0xffff) -#define HIWORD(x) (x >> 16) +//#define MAKELONG(a, b) ((a) | ((b) << 16)) +//#define LOWORD(x) (x & 0xffff) +//#define HIWORD(x) (x >> 16) #endif diff --git a/src/stc/scintilla/include/WindowAccessor.h b/src/stc/scintilla/include/WindowAccessor.h index 89a542e82d..4f41dfc7ff 100644 --- a/src/stc/scintilla/include/WindowAccessor.h +++ b/src/stc/scintilla/include/WindowAccessor.h @@ -22,7 +22,7 @@ protected: public: WindowAccessor(WindowID id_, PropSet &props_) : Accessor(), id(id_), props(props_), - lenDoc(-1), validLen(0), chFlags(0) { + lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { } ~WindowAccessor(); char StyleAt(int position); diff --git a/src/stc/scintilla/src/Accessor.cxx b/src/stc/scintilla/src/Accessor.cxx deleted file mode 100644 index 57b7e4dc4e..0000000000 --- a/src/stc/scintilla/src/Accessor.cxx +++ /dev/null @@ -1,112 +0,0 @@ -// SciTE - Scintilla based Text Editor -// Accessor.cxx - rapid easy access to contents of a Scintilla -// Copyright 1998-2000 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include - -#include "Platform.h" - -#include "PropSet.h" -#include "Accessor.h" -#include "Scintilla.h" - -void Accessor::Fill(int position) { - if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); - startPos = position - slopSize; - if (startPos + bufferSize > lenDoc) - startPos = lenDoc - bufferSize; - if (startPos < 0) - startPos = 0; - endPos = startPos + bufferSize; - if (endPos > lenDoc) - endPos = lenDoc; - - TEXTRANGE tr = {{startPos, endPos}, buf}; - Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast(&tr)); -} - -char Accessor::StyleAt(int position) { - return static_cast(Platform::SendScintilla( - id, SCI_GETSTYLEAT, position, 0)); -} - -int Accessor::GetLine(int position) { - return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); -} - -int Accessor::LineStart(int line) { - return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); -} - -int Accessor::LevelAt(int line) { - return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0); -} - -int Accessor::Length() { - if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); - return lenDoc; -} - -int Accessor::GetLineState(int line) { - return Platform::SendScintilla(id, SCI_GETLINESTATE, line); -} - -int Accessor::SetLineState(int line, int state) { - return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state); -} - -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) { - // 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 (validLen + (end - start + 1) >= bufferSize) - Flush(); - if (validLen + (end - start + 1) >= bufferSize) { - // Too big for buffer so send directly - Platform::SendScintilla(id, SCI_SETSTYLING, end - start + 1, chAttr); - } else { - if (chAttr != chWhile) - chFlags = 0; - chAttr |= chFlags; - for (unsigned int i = start; i <= end; 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; -} - -int StylingContext::GetLine(int position) { - return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); -} - -void StylingContext::SetLevel(int line, int level) { - Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level); -} - -void StylingContext::Flush() { - if (validLen > 0) { - Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, - reinterpret_cast(styleBuf)); - validLen = 0; - } -} diff --git a/src/stc/scintilla/src/AutoComplete.cxx b/src/stc/scintilla/src/AutoComplete.cxx index 75e26fe283..5bc50d1efa 100644 --- a/src/stc/scintilla/src/AutoComplete.cxx +++ b/src/stc/scintilla/src/AutoComplete.cxx @@ -10,12 +10,16 @@ #include "AutoComplete.h" -AutoComplete::AutoComplete() { - lb = 0; - active = false; - posStart = 0; - strcpy(stopChars, ""); - separator = ' '; +AutoComplete::AutoComplete() : + active(false), + separator(' '), + ignoreCase(false), + chooseSingle(false), + posStart(0), + startLen(0), + cancelAtStartPos(true) { + stopChars[0] = '\0'; + fillUpChars[0] = '\0'; } AutoComplete::~AutoComplete() { @@ -45,6 +49,15 @@ bool AutoComplete::IsStopChar(char ch) { return ch && strchr(stopChars, ch); } +void AutoComplete::SetFillUpChars(const char *fillUpChars_) { + strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars)); + fillUpChars[sizeof(fillUpChars) - 1] = '\0'; +} + +bool AutoComplete::IsFillUpChar(char ch) { + return ch && strchr(fillUpChars, ch); +} + void AutoComplete::SetSeparator(char separator_) { separator = separator_; } @@ -53,8 +66,7 @@ char AutoComplete::GetSeparator() { return separator; } -int AutoComplete::SetList(const char *list) { - int maxStrLen = 12; +void AutoComplete::SetList(const char *list) { lb.Clear(); char *words = new char[strlen(list) + 1]; if (words) { @@ -65,18 +77,15 @@ int AutoComplete::SetList(const char *list) { if (words[i] == separator) { words[i] = '\0'; lb.Append(startword); - maxStrLen = Platform::Maximum(maxStrLen, strlen(startword)); startword = words + i + 1; } } if (startword) { lb.Append(startword); - maxStrLen = Platform::Maximum(maxStrLen, strlen(startword)); } delete []words; } lb.Sort(); - return maxStrLen; } void AutoComplete::Show() { @@ -87,7 +96,6 @@ void AutoComplete::Show() { void AutoComplete::Cancel() { if (lb.Created()) { lb.Destroy(); - lb = 0; active = false; } } diff --git a/src/stc/scintilla/src/AutoComplete.h b/src/stc/scintilla/src/AutoComplete.h index e4f8ade0d8..c1789ad7b6 100644 --- a/src/stc/scintilla/src/AutoComplete.h +++ b/src/stc/scintilla/src/AutoComplete.h @@ -9,11 +9,16 @@ class AutoComplete { bool active; char stopChars[256]; + char fillUpChars[256]; char separator; public: + bool ignoreCase; + bool chooseSingle; ListBox lb; int posStart; int startLen; + // Should autocompletion be canceled if editor's currentPos <= startPos? + bool cancelAtStartPos; AutoComplete(); ~AutoComplete(); @@ -28,12 +33,16 @@ public: void SetStopChars(const char *stopChars_); bool IsStopChar(char ch); + // The fillup chars are characters which, when typed, fill up the selected word + void SetFillUpChars(const char *fillUpChars_); + bool IsFillUpChar(char ch); + // The separator character is used when interpreting the list in SetList void SetSeparator(char separator_); char GetSeparator(); // The list string contains a sequence of words separated by the separator character - int SetList(const char *list); + void SetList(const char *list); void Show(); void Cancel(); diff --git a/src/stc/scintilla/src/CellBuffer.cxx b/src/stc/scintilla/src/CellBuffer.cxx index e6aa4a0134..befec75fc3 100644 --- a/src/stc/scintilla/src/CellBuffer.cxx +++ b/src/stc/scintilla/src/CellBuffer.cxx @@ -88,7 +88,7 @@ void MarkerHandleSet::RemoveHandle(int handle) { if (mhn->handle == handle) { *pmhn = mhn->next; delete mhn; - return; + return ; } pmhn = &((*pmhn)->next); } @@ -101,7 +101,7 @@ void MarkerHandleSet::RemoveNumber(int markerNum) { if (mhn->number == markerNum) { *pmhn = mhn->next; delete mhn; - return; + return ; } pmhn = &((*pmhn)->next); } @@ -119,7 +119,11 @@ void MarkerHandleSet::CombineWith(MarkerHandleSet *other) { LineVector::LineVector() { linesData = 0; lines = 0; + size = 0; levels = 0; + sizeLevels = 0; + handleCurrent = 1; + Init(); } @@ -161,6 +165,7 @@ void LineVector::Expand(int sizeNew) { Platform::DebugPrintf("No memory available\n"); // TODO: Blow up } + } void LineVector::ExpandLevels(int sizeNew) { @@ -180,6 +185,13 @@ void LineVector::ExpandLevels(int sizeNew) { Platform::DebugPrintf("No memory available\n"); // TODO: Blow up } + +} + +void LineVector::ClearLevels() { + delete []levels; + levels = 0; + sizeLevels = 0; } void LineVector::InsertValue(int pos, int value) { @@ -202,10 +214,10 @@ void LineVector::InsertValue(int pos, int value) { } if (pos == 0) { levels[pos] = SC_FOLDLEVELBASE; - } else if (pos == (lines-1)) { // Last line will not be a folder + } else if (pos == (lines - 1)) { // Last line will not be a folder levels[pos] = SC_FOLDLEVELBASE; } else { - levels[pos] = levels[pos-1]; + levels[pos] = levels[pos - 1]; } } } @@ -234,10 +246,10 @@ void LineVector::Remove(int pos) { linesData[i] = linesData[i + 1]; } if (levels) { - // Level information merges back onto previous line - int posAbove = pos-1; - if (posAbove < 0) - posAbove = 0; + // Level information merges back onto previous line + int posAbove = pos - 1; + if (posAbove < 0) + posAbove = 0; for (int j = posAbove; j < lines; j++) { levels[j] = levels[j + 1]; } @@ -280,11 +292,12 @@ int LineVector::AddMark(int line, int markerNum) { } void LineVector::MergeMarkers(int pos) { - if (linesData[pos].handleSet || linesData[pos + 1].handleSet) { - if (linesData[pos].handleSet && linesData[pos + 1].handleSet) { - linesData[pos].handleSet->CombineWith(linesData[pos].handleSet); - linesData[pos].handleSet = 0; - } + if (linesData[pos + 1].handleSet != NULL) { + if (linesData[pos].handleSet == NULL ) + linesData[pos].handleSet = new MarkerHandleSet; + linesData[pos].handleSet->CombineWith(linesData[pos + 1].handleSet); + delete linesData[pos + 1].handleSet; + linesData[pos + 1].handleSet = NULL; } } @@ -358,7 +371,7 @@ void Action::Grab(Action *source) { data = source->data; lenData = source->lenData; mayCoalesce = source->mayCoalesce; - + // Ownership of source data transferred to this source->position = 0; source->at = startAction; @@ -367,21 +380,21 @@ void Action::Grab(Action *source) { source->mayCoalesce = true; } -// The undo history stores a sequence of user operations that represent the user's view of the -// commands executed on the text. +// 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 +// 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 +// 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 +// 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 +// 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. @@ -412,7 +425,7 @@ void UndoHistory::EnsureUndoRoom() { int lenActionsNew = lenActions * 2; Action *actionsNew = new Action[lenActionsNew]; if (!actionsNew) - return; + return ; for (int act = 0; act <= currentAction; act++) actionsNew[act].Grab(&actions[act]); delete []actions; @@ -425,11 +438,11 @@ void UndoHistory::EnsureUndoRoom() { 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, + //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 + // 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 @@ -437,22 +450,23 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng currentAction++; } else if (currentAction == savePoint) { currentAction++; - } else if ((at == removeAction) && - ((position + lengthData * 2) != actPrevious.position)) { + } 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))) { + } 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 { // Actions not at top level are always coalesced unless this is after return to top level if (!actions[currentAction].mayCoalesce) currentAction++; - } + } } else { currentAction++; } @@ -487,7 +501,7 @@ void UndoHistory::EndUndoAction() { actions[currentAction].mayCoalesce = false; } } - + void UndoHistory::DropUndoSequence() { undoSequenceDepth = 0; } @@ -517,9 +531,9 @@ int UndoHistory::StartUndo() { // Drop any trailing startAction if (actions[currentAction].at == startAction && currentAction > 0) currentAction--; - + // Count the steps in this action - int act = currentAction; + int act = currentAction; while (actions[act].at != startAction && act > 0) { act--; } @@ -542,9 +556,9 @@ int UndoHistory::StartRedo() { // Drop any leading startAction if (actions[currentAction].at == startAction && currentAction < maxAction) currentAction++; - + // Count the steps in this action - int act = currentAction; + int act = currentAction; while (actions[act].at != startAction && act < maxAction) { act++; } @@ -563,11 +577,11 @@ CellBuffer::CellBuffer(int initialLength) { body = new char[initialLength]; size = initialLength; length = 0; - part1len = 0; + part1len = 0; gaplen = initialLength; part2body = body + gaplen; readOnly = false; - collectingUndo = undoCollectAutoStart; + collectingUndo = true; } CellBuffer::~CellBuffer() { @@ -577,7 +591,7 @@ CellBuffer::~CellBuffer() { void CellBuffer::GapTo(int position) { if (position == part1len) - return; + return ; if (position < part1len) { int diff = part1len - position; //Platform::DebugPrintf("Move gap backwards to %d diff = %d part1len=%d length=%d \n", position,diff, part1len, length); @@ -609,6 +623,7 @@ void CellBuffer::RoomFor(int insertionLength) { size = newSize; //Platform::DebugPrintf("end need room %d %d - size=%d length=%d\n", gaplen, insertionLength,size,length); } + } // To make it easier to write code that uses ByteAt, a position outside the range of the buffer @@ -633,16 +648,16 @@ void CellBuffer::SetByteAt(int position, char ch) { if (position < 0) { //Platform::DebugPrintf("Bad position %d\n",position); - return; + return ; } if (position >= length + 11) { Platform::DebugPrintf("Very Bad position %d of %d\n", position, length); //exit(2); - return; + return ; } if (position >= length) { //Platform::DebugPrintf("Bad position %d of %d\n",position,length); - return; + return ; } if (position < part1len) { @@ -658,20 +673,20 @@ char CellBuffer::CharAt(int position) { void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) { if (lengthRetrieve < 0) - return; + return ; if (position < 0) - return; + return ; int bytePos = position * 2; if ((bytePos + lengthRetrieve * 2) > length) { - Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n",bytePos, - lengthRetrieve, length); - return; + Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", bytePos, + lengthRetrieve, length); + return ; } GapTo(0); // Move the buffer so its easy to subscript into it char *pb = part2body + bytePos; while (lengthRetrieve--) { *buffer++ = *pb; - pb +=2; + pb += 2; } } @@ -706,7 +721,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) { } bool CellBuffer::SetStyleAt(int position, char style, char mask) { - char curVal = ByteAt(position*2 + 1); + char curVal = ByteAt(position * 2 + 1); if ((curVal & mask) != style) { SetByteAt(position*2 + 1, static_cast((curVal & ~mask) | style)); return true; @@ -823,7 +838,7 @@ int CellBuffer::LineFromHandle(int markerHandle) { void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { //Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength); if (insertLength == 0) - return; + return ; RoomFor(insertLength); GapTo(position); @@ -883,7 +898,7 @@ void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { void CellBuffer::BasicDeleteChars(int position, int deleteLength) { //Platform::DebugPrintf("Deleting at %d for %d\n", position, deleteLength); if (deleteLength == 0) - return; + return ; if ((position == 0) && (deleteLength == length)) { // If whole buffer is being deleted, faster to reinitialise lines data @@ -915,6 +930,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { ignoreNL = true; // First \n is not real deletion } + char ch = chNext; for (int i = 0; i < deleteLength; i += 2) { chNext = ' '; @@ -932,6 +948,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { ignoreNL = false; // Further \n are not real deletions } + ch = chNext; } // May have to fix up end if last deletion causes cr to be next to lf @@ -952,7 +969,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { part2body = body + gaplen; } -undoCollectionType CellBuffer::SetUndoCollection(undoCollectionType collectUndo) { +bool CellBuffer::SetUndoCollection(bool collectUndo) { collectingUndo = collectUndo; uh.DropUndoSequence(); return collectingUndo; @@ -994,12 +1011,12 @@ void CellBuffer::PerformUndoStep() { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { styledData[i*2] = actionStep.data[i]; - styledData[i*2+1] = 0; + styledData[i*2 + 1] = 0; } BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } - uh.CompletedUndoStep(); + uh.CompletedUndoStep(); } bool CellBuffer::CanRedo() { @@ -1020,14 +1037,14 @@ void CellBuffer::PerformRedoStep() { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { styledData[i*2] = actionStep.data[i]; - styledData[i*2+1] = 0; + styledData[i*2 + 1] = 0; } BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } - uh.CompletedRedoStep(); + uh.CompletedRedoStep(); } int CellBuffer::SetLineState(int line, int state) { @@ -1043,7 +1060,7 @@ int CellBuffer::GetLineState(int line) { int CellBuffer::GetMaxLineState() { return lineStates.Length(); } - + int CellBuffer::SetLevel(int line, int level) { int prev = 0; if ((line >= 0) && (line < lv.lines)) { @@ -1066,3 +1083,6 @@ int CellBuffer::GetLevel(int line) { } } +void CellBuffer::ClearLevels() { + lv.ClearLevels(); +} diff --git a/src/stc/scintilla/src/CellBuffer.h b/src/stc/scintilla/src/CellBuffer.h index 409a8749de..4a1ecb3989 100644 --- a/src/stc/scintilla/src/CellBuffer.h +++ b/src/stc/scintilla/src/CellBuffer.h @@ -58,6 +58,7 @@ public: void Expand(int sizeNew); void ExpandLevels(int sizeNew=-1); + void ClearLevels(); void InsertValue(int pos, int value); void SetValue(int pos, int value); void Remove(int pos); @@ -88,8 +89,6 @@ public: void Grab(Action *source); }; -enum undoCollectionType { undoCollectNone, undoCollectAutoStart, undoCollectManualStart }; - class UndoHistory { Action *actions; int lenActions; @@ -141,12 +140,12 @@ private: char *part2body; bool readOnly; - undoCollectionType collectingUndo; + bool collectingUndo; UndoHistory uh; LineVector lv; - SVector lineStates; + SVector lineStates; void GapTo(int position); void RoomFor(int insertionLength); @@ -199,7 +198,7 @@ public: void BasicInsertString(int position, char *s, int insertLength); void BasicDeleteChars(int position, int deleteLength); - undoCollectionType SetUndoCollection(undoCollectionType collectUndo); + bool SetUndoCollection(bool collectUndo); bool IsCollectingUndo(); void BeginUndoAction(); void EndUndoAction(); @@ -222,6 +221,7 @@ public: int SetLevel(int line, int level); int GetLevel(int line); + void ClearLevels(); }; #define CELL_SIZE 2 diff --git a/src/stc/scintilla/src/ContractionState.cxx b/src/stc/scintilla/src/ContractionState.cxx index 4569489003..0558b4c365 100644 --- a/src/stc/scintilla/src/ContractionState.cxx +++ b/src/stc/scintilla/src/ContractionState.cxx @@ -171,12 +171,6 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible delta += visible ? 1 : -1; lines[line].visible = visible; } - lines[line].displayLine += delta; - } - if (delta != 0) { - for (int line=lineDocEnd+1; line <= linesInDoc; line++) { - lines[line].displayLine += delta; - } } } linesInDisplay += delta; @@ -206,3 +200,9 @@ bool ContractionState::SetExpanded(int lineDoc, bool expanded) { } return false; } + +void ContractionState::ShowAll() { + delete []lines; + lines = 0; + size = 0; +} diff --git a/src/stc/scintilla/src/ContractionState.h b/src/stc/scintilla/src/ContractionState.h index 9e17a76937..2c344efeea 100644 --- a/src/stc/scintilla/src/ContractionState.h +++ b/src/stc/scintilla/src/ContractionState.h @@ -42,9 +42,11 @@ public: bool GetVisible(int lineDoc) const; bool SetVisible(int lineDocStart, int lineDocEnd, bool visible); - + bool GetExpanded(int lineDoc) const; bool SetExpanded(int lineDoc, bool expanded); + + void ShowAll(); }; #endif diff --git a/src/stc/scintilla/src/Document.cxx b/src/stc/scintilla/src/Document.cxx index 6614a7fc98..c883dd253f 100644 --- a/src/stc/scintilla/src/Document.cxx +++ b/src/stc/scintilla/src/Document.cxx @@ -54,7 +54,7 @@ int Document::AddRef() { return refCount++; } -// Decrease reference count and return its provius value. +// Decrease reference count and return its previous value. // Delete the document if reference count reaches zero. int Document::Release() { int curRefCount = --refCount; @@ -201,8 +201,8 @@ bool Document::IsCrLf(int pos) { return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } -bool Document::IsDBCS(int pos) { #if PLAT_WIN +bool Document::IsDBCS(int pos) { if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { unsigned char ch = static_cast(cb.CharAt(pos)); @@ -224,10 +224,14 @@ bool Document::IsDBCS(int pos) { } } return false; +} #else +// PLAT_GTK or PLAT_WX +// TODO: support DBCS under GTK+ and WX +bool Document::IsDBCS(int) { return false; -#endif } +#endif int Document::LenChar(int pos) { if (IsCrLf(pos)) { @@ -334,6 +338,8 @@ void Document::ModifiedAt(int pos) { // Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number void Document::DeleteChars(int pos, int len) { + if ((pos + len) > Length()) + return; if (cb.IsReadOnly() && enteredReadOnlyCount==0) { enteredReadOnlyCount++; NotifyModifyAttempt(); @@ -590,6 +596,8 @@ void Document::SetLineIndentation(int line, int indent) { } int Document::GetLineIndentPosition(int line) { + if (line < 0) + return 0; int pos = LineStart(line); int length = Length(); while ((pos < length) && isindentchar(cb.CharAt(pos))) { @@ -598,6 +606,25 @@ int Document::GetLineIndentPosition(int line) { return pos; } +int Document::GetColumn(int pos) { + int column = 0; + int line = LineFromPosition(pos); + if ((line >= 0) && (line < LinesTotal())) { + for (int i=LineStart(line);i= lineTop; line--) { @@ -690,25 +717,29 @@ int Document::NextWordStart(int pos, int delta) { return pos; } -bool Document::IsWordAt(int start, int end) { - int lengthDoc = Length(); - if (start > 0) { - char ch = CharAt(start - 1); - if (IsWordChar(ch)) - return false; +bool Document::IsWordStartAt(int pos) { + if (pos > 0) { + return !IsWordChar(CharAt(pos - 1)); } - if (end < lengthDoc - 1) { - char ch = CharAt(end); - if (IsWordChar(ch)) - return false; + return true; +} + +bool Document::IsWordEndAt(int pos) { + if (pos < Length() - 1) { + return !IsWordChar(CharAt(pos)); } return true; } +bool Document::IsWordAt(int start, int end) { + return IsWordStartAt(start) && IsWordEndAt(end); +} + // Find text in document, supporting both forward and backward // searches (just pass minPos > maxPos to do a backward search) // Has not been tested with backwards DBCS searches yet. -long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word) { +long Document::FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart) { bool forward = minPos <= maxPos; int increment = forward ? 1 : -1; @@ -738,8 +769,10 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitiv found = false; } if (found) { - if ((!word) || IsWordAt(pos, pos + lengthFind)) - return pos; + if ((!word && !wordStart) || + word && IsWordAt(pos, pos + lengthFind) || + wordStart && IsWordStartAt(pos)) + return pos; } } } else { @@ -751,8 +784,10 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitiv found = false; } if (found) { - if ((!word) || IsWordAt(pos, pos + lengthFind)) - return pos; + if (!(word && wordStart) || + word && IsWordAt(pos, pos + lengthFind) || + wordStart && IsWordStartAt(pos)) + return pos; } } } diff --git a/src/stc/scintilla/src/Document.h b/src/stc/scintilla/src/Document.h index 92e4ff14fe..af477dd79b 100644 --- a/src/stc/scintilla/src/Document.h +++ b/src/stc/scintilla/src/Document.h @@ -113,9 +113,10 @@ public: bool CanUndo() { return cb.CanUndo(); } bool CanRedo() { return cb.CanRedo(); } void DeleteUndoHistory() { cb.DeleteUndoHistory(); } - undoCollectionType SetUndoCollection(undoCollectionType collectUndo) { + bool SetUndoCollection(bool collectUndo) { return cb.SetUndoCollection(collectUndo); } + bool IsCollectingUndo() { return cb.IsCollectingUndo(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void SetSavePoint(); @@ -124,9 +125,11 @@ public: int GetLineIndentation(int line); void SetLineIndentation(int line, int indent); int GetLineIndentPosition(int line); + int GetColumn(int position); void Indent(bool forwards, int lineBottom, int lineTop); void ConvertLineEnds(int eolModeSet); void SetReadOnly(bool set) { cb.SetReadOnly(set); } + bool IsReadOnly() { return cb.IsReadOnly(); } void InsertChar(int pos, char ch); void InsertString(int position, const char *s); @@ -153,6 +156,7 @@ public: int SetLevel(int line, int level); int GetLevel(int line) { return cb.GetLevel(line); } + void ClearLevels() { cb.ClearLevels(); } int GetLastChild(int lineParent, int level=-1); int GetFoldParent(int line); @@ -160,8 +164,9 @@ public: int ExtendWordSelect(int pos, int delta); int NextWordStart(int pos, int delta); int Length() { return cb.Length(); } - long FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word); - long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam); + long FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart); + long FindText(int iMessage, unsigned long wParam, long lParam); int LinesTotal(); void ChangeCase(Range r, bool makeUpperCase); @@ -186,6 +191,8 @@ public: private: bool IsDBCS(int pos); bool IsWordChar(unsigned char ch); + bool IsWordStartAt(int pos); + bool IsWordEndAt(int pos); bool IsWordAt(int start, int end); void ModifiedAt(int pos); diff --git a/src/stc/scintilla/src/DocumentAccessor.cxx b/src/stc/scintilla/src/DocumentAccessor.cxx index d28840c166..6828e37c3f 100644 --- a/src/stc/scintilla/src/DocumentAccessor.cxx +++ b/src/stc/scintilla/src/DocumentAccessor.cxx @@ -4,6 +4,7 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include #include @@ -20,21 +21,22 @@ DocumentAccessor::~DocumentAccessor() { } +#if PLAT_WIN bool DocumentAccessor::InternalIsLeadByte(char ch) { -#if PLAT_GTK - // TODO: support DBCS under GTK+ - return false; -#elif PLAT_WIN if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the // same so none is considered a lead byte. return false; else return IsDBCSLeadByteEx(codePage, ch); -#elif PLAT_WX +} +#else +// PLAT_GTK or PLAT_WX +// TODO: support DBCS under GTK+ and WX +bool DocumentAccessor::InternalIsLeadByte(char) { return false; -#endif } +#endif void DocumentAccessor::Fill(int position) { if (lenDoc == -1) diff --git a/src/stc/scintilla/src/DocumentAccessor.h b/src/stc/scintilla/src/DocumentAccessor.h index 37a9db4149..ccc05fee9f 100644 --- a/src/stc/scintilla/src/DocumentAccessor.h +++ b/src/stc/scintilla/src/DocumentAccessor.h @@ -24,7 +24,7 @@ protected: public: DocumentAccessor(Document *pdoc_, PropSet &props_) : Accessor(), pdoc(pdoc_), props(props_), - lenDoc(-1), validLen(0), chFlags(0) { + lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { } ~DocumentAccessor(); char StyleAt(int position); diff --git a/src/stc/scintilla/src/Editor.cxx b/src/stc/scintilla/src/Editor.cxx index ad8bab8c5f..6d2676ffbc 100644 --- a/src/stc/scintilla/src/Editor.cxx +++ b/src/stc/scintilla/src/Editor.cxx @@ -11,6 +11,11 @@ #include "Platform.h" #include "Scintilla.h" + +#if PLAT_WX || PLAT_GTK +#include "WinDefs.h" +#endif + #include "ContractionState.h" #include "SVector.h" #include "CellBuffer.h" @@ -33,6 +38,9 @@ Editor::Editor() { stylesValid = false; + printMagnification = 0; + printColourMode = SC_PRINT_NORMAL; + hideSelection = false; inOverstrike = false; @@ -58,46 +66,47 @@ Editor::Editor() { selType = selStream; xStartSelect = 0; xEndSelect = 0; + primarySelection = true; caretPolicy = CARET_SLOP; caretSlop = 0; searchAnchor = 0; - + ucWheelScrollLines = 0; cWheelDelta = 0; //wheel delta from roll xOffset = 0; xCaretMargin = 50; horizontalScrollBarVisible = true; - + currentPos = 0; anchor = 0; topLine = 0; posTopLine = 0; - + needUpdateUI = true; - braces[0]=invalidPosition; - braces[1]=invalidPosition; + braces[0] = invalidPosition; + braces[1] = invalidPosition; bracesMatchStyle = STYLE_BRACEBAD; - - edgeState = EDGE_NONE; + highlightGuideColumn = 0; + theEdge = 0; - + paintState = notPainting; - + modEventMask = SC_MODEVENTMASKALL; displayPopupMenu = true; - + pdoc = new Document(); pdoc ->AddRef(); pdoc->AddWatcher(this, 0); #ifdef MACRO_SUPPORT recordingMacro = 0; -#endif +#endif foldFlags = 0; } @@ -113,12 +122,14 @@ Editor::~Editor() { } void Editor::Finalise() { + CancelModes(); } void Editor::DropGraphics() { pixmapLine.Release(); pixmapSelMargin.Release(); pixmapSelPattern.Release(); + pixmapIndentGuide.Release(); } void Editor::InvalidateStyleData() { @@ -185,7 +196,7 @@ int Editor::MaxScrollPos() { return retVal; } -bool IsControlCharacter(char ch) { +static inline bool IsControlCharacter(char ch) { // iscntrl returns true for lots of chars > 127 which are displayable return ch >= 0 && ch < ' '; } @@ -215,12 +226,12 @@ Point Editor::LocationFromPosition(unsigned int pos) { Point pt; pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight? unsigned int posLineStart = pdoc->LineStart(line); + LineLayout ll; + LayoutLine(line, &surface, vs, ll); if ((pos - posLineStart) > LineLayout::maxLineLength) { // very long line so put x at arbitrary large position - pt.x = 30000 + vs.fixedColumnWidth - xOffset; + pt.x = ll.positions[LineLayout::maxLineLength] + vs.fixedColumnWidth - xOffset; } else { - LineLayout ll; - LayoutLine(line, &surface, vs, ll); pt.x = ll.positions[pos - posLineStart] + vs.fixedColumnWidth - xOffset; } return pt; @@ -230,7 +241,7 @@ int Editor::XFromPosition(unsigned int pos) { Point pt = LocationFromPosition(pos); return pt.x - vs.fixedColumnWidth + xOffset; } - + int Editor::LineFromLocation(Point pt) { return cs.DocFromDisplay(pt.y / vs.lineHeight + topLine); } @@ -251,7 +262,7 @@ int Editor::PositionFromLocation(Point pt) { return 0; if (line >= pdoc->LinesTotal()) return pdoc->Length(); -//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); + //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); Surface surface; surface.Init(); surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); @@ -260,8 +271,8 @@ int Editor::PositionFromLocation(Point pt) { LineLayout ll; LayoutLine(line, &surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { - if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { + if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { return i + posLineStart; } } @@ -282,8 +293,8 @@ int Editor::PositionFromLineX(int line, int x) { LineLayout ll; LayoutLine(line, &surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { - if (x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { + if (x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { return i + posLineStart; } } @@ -362,7 +373,7 @@ int Editor::SelectionStart(int line) { //return PositionFromLineX(line, minX + vs.fixedColumnWidth - xOffset); return PositionFromLineX(line, minX); } - } + } } int Editor::SelectionEnd(int line) { @@ -433,10 +444,26 @@ void Editor::SetEmptySelection(int currentPos_) { SetSelection(currentPos_, currentPos_); } +int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { + // Asks document to find a good position and then moves out of any invisible positions + pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd); + int mask = pdoc->stylingBitsMask; + if (moveDir > 0) { + while ((pos < pdoc->Length()) && + (!vs.styles[pdoc->StyleAt(pos - 1) & mask].visible)) + pos++; + } else { + while ((pos > 0) && + (!vs.styles[pdoc->StyleAt(pos - 1) & mask].visible)) + pos--; + } + return pos; +} + int Editor::MovePositionTo(int newPos, bool extend) { int delta = newPos - currentPos; newPos = pdoc->ClampPositionIntoDocument(newPos); - newPos = pdoc->MovePositionOutsideChar(newPos, delta); + newPos = MovePositionOutsideChar(newPos, delta); if (extend) { SetSelection(newPos); } else { @@ -449,7 +476,7 @@ int Editor::MovePositionTo(int newPos, bool extend) { int Editor::MovePositionSoVisible(int pos, int moveDir) { pos = pdoc->ClampPositionIntoDocument(pos); - pos = pdoc->MovePositionOutsideChar(pos, moveDir); + pos = MovePositionOutsideChar(pos, moveDir); int lineDoc = pdoc->LineFromPosition(pos); if (cs.GetVisible(lineDoc)) { return pos; @@ -510,7 +537,7 @@ void Editor::MoveCaretInsideView() { MovePositionTo(PositionFromLocation( Point(lastXChosen, rcClient.top))); } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) { - int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen()-1) * vs.lineHeight; + int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight; MovePositionTo(PositionFromLocation( Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed))); } @@ -532,11 +559,11 @@ void Editor::EnsureCaretVisible(bool useMargin) { int xMargin = Platform::Clamp(xCaretMargin, 2, Platform::Maximum(rcClient.Width() - 10, 4) / 2); if (!useMargin) xMargin = 2; - + // Ensure certain amount of text visible on both sides of caretSo move if caret just on edge rcClient.left = rcClient.left + xMargin; rcClient.right = rcClient.right - xMargin; - + if (!rcClient.Contains(pt) || !rcClient.Contains(ptBottomCaret) || (caretPolicy & CARET_STRICT)) { //Platform::DebugPrintf("EnsureCaretVisible move, (%d,%d) (%d,%d)\n", pt.x, pt.y, rcClient.left, rcClient.right); // It should be possible to scroll the window to show the caret, @@ -546,8 +573,8 @@ void Editor::EnsureCaretVisible(bool useMargin) { SetTopLine(Platform::Clamp(lineCaret - caretSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); - } else if ((lineCaret > topLine + LinesOnScreen() - 1) || - ((caretPolicy & CARET_STRICT) && (lineCaret > topLine + LinesOnScreen() - 1 - caretSlop))) { + } else if ((lineCaret > topLine + LinesOnScreen() - 1) || + ((caretPolicy & CARET_STRICT) && (lineCaret > topLine + LinesOnScreen() - 1 - caretSlop))) { SetTopLine(Platform::Clamp(lineCaret - LinesOnScreen() + 1 + caretSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); @@ -584,7 +611,7 @@ void Editor::ShowCaretAtCurrentPosition() { if (!wMain.HasFocus()) { caret.active = false; caret.on = false; - return; + return ; } caret.active = true; caret.on = true; @@ -605,13 +632,13 @@ void Editor::InvalidateCaret() { void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { if (vs.fixedColumnWidth == 0) - return; + return ; PRectangle rcMargin = GetClientRectangle(); rcMargin.right = vs.fixedColumnWidth; if (!rc.Intersects(rcMargin)) - return; + return ; Surface *surface; if (bufferedDraw) { @@ -623,9 +650,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { PRectangle rcSelMargin = rcMargin; rcSelMargin.right = rcMargin.left; - for (int margin=0; margin < vs.margins; margin++) { + for (int margin = 0; margin < vs.margins; margin++) { if (vs.ms[margin].width > 0) { - + rcSelMargin.left = rcSelMargin.right; rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width; @@ -639,13 +666,13 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { */ if (vs.ms[margin].mask & SC_MASK_FOLDERS) // Required because of special way brush is created for selection margin - surface->FillRectangle(rcSelMargin, pixmapSelPattern); + surface->FillRectangle(rcSelMargin, pixmapSelPattern); else - surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); + surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); } else { surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); } - + int visibleLine = topLine; int line = cs.DocFromDisplay(visibleLine); int yposScreen = 0; @@ -669,7 +696,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { sprintf(number, "%d", line + 1); if (foldFlags & 64) sprintf(number, "%X", pdoc->GetLevel(line)); - PRectangle rcNumber=rcMarker; + PRectangle rcNumber = rcMarker; // Right justify int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number)); int xpos = rcNumber.right - width - 3; @@ -677,11 +704,11 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { if ((visibleLine < cs.LinesDisplayed()) && cs.GetVisible(line)) { surface->DrawText(rcNumber, vs.styles[STYLE_LINENUMBER].font, rcNumber.top + vs.maxAscent, number, strlen(number), - vs.styles[STYLE_LINENUMBER].fore.allocated, - vs.styles[STYLE_LINENUMBER].back.allocated); + vs.styles[STYLE_LINENUMBER].fore.allocated, + vs.styles[STYLE_LINENUMBER].back.allocated); } } - + if (marks) { for (int markBit = 0; (markBit < 32) && marks; markBit++) { if (marks & 1) { @@ -692,7 +719,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { marks >>= 1; } } - + visibleLine++; line = cs.DocFromDisplay(visibleLine); yposScreen += vs.lineHeight; @@ -702,8 +729,8 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { PRectangle rcBlankMargin = rcMargin; rcBlankMargin.left = rcSelMargin.right; - surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back.allocated); - + surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back.allocated); + if (bufferedDraw) { surfWindow->Copy(rcMargin, Point(), pixmapSelMargin); } @@ -729,9 +756,11 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font; char styleByte = 0; int styleMask = pdoc->stylingBitsMask; - for (int charInDoc = posLineStart; - charInDoc < posLineEnd && numCharsInLine < LineLayout::maxLineLength - 1; - charInDoc++) { + ll.xHighlightGuide = 0; + if (posLineEnd > (posLineStart + LineLayout::maxLineLength)) { + posLineEnd = posLineStart + LineLayout::maxLineLength; + } + for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) { char chDoc = pdoc->CharAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc); if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { @@ -741,32 +770,46 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou numCharsInLine++; } } - ll.chars[numCharsInLine] = 0; + // Extra element at the end of the line to hold end x position and act as + ll.chars[numCharsInLine] = 0; // Also triggers processing in the loops as this is a control character ll.styles[numCharsInLine] = styleByte; // For eolFilled ll.indicators[numCharsInLine] = 0; - // Layout the line, determining the position of each character + // Layout the line, determining the position of each character, + // with an extra element at the end for the end of the line. int startseg = 0; int startsegx = 0; ll.positions[0] = 0; unsigned int tabWidth = vstyle.spaceWidth * pdoc->tabInChars; - + for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) { if ((ll.styles[charInLine] != ll.styles[charInLine + 1]) || IsControlCharacter(ll.chars[charInLine]) || IsControlCharacter(ll.chars[charInLine + 1])) { ll.positions[startseg] = 0; - if (IsControlCharacter(ll.chars[charInLine])) { - if (ll.chars[charInLine] == '\t') { - ll.positions[charInLine + 1] = ((((startsegx + 2) / - tabWidth) + 1) * tabWidth) - startsegx; + if (vstyle.styles[ll.styles[charInLine]].visible) { + if (IsControlCharacter(ll.chars[charInLine])) { + if (ll.chars[charInLine] == '\t') { + ll.positions[charInLine + 1] = ((((startsegx + 2) / + tabWidth) + 1) * tabWidth) - startsegx; + } else { + const char *ctrlChar = ControlCharacterString(ll.chars[charInLine]); + // +3 For a blank on front and rounded edge each side: + ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3; + } } else { - const char *ctrlChar = ControlCharacterString(ll.chars[charInLine]); - // +3 For a blank on front and rounded edge each side: - ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3; + int lenSeg = charInLine - startseg + 1; + if ((lenSeg == 1) && (' ' == ll.chars[startseg])) { + // Over half the segments are single characters and of these about half are space characters. + ll.positions[charInLine + 1] = vstyle.styles[ll.styles[charInLine]].spaceWidth; + } else { + surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg, + charInLine - startseg + 1, ll.positions + startseg + 1); + } + } + } else { // invisible + for (int posToZero = startseg; posToZero <= (charInLine + 1); posToZero++) { + ll.positions[posToZero] = 0; } - } else { - surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg, - charInLine - startseg + 1, ll.positions + startseg + 1); } for (int posToIncrease = startseg; posToIncrease <= (charInLine + 1); posToIncrease++) { ll.positions[posToIncrease] += startsegx; @@ -778,10 +821,11 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou ll.numCharsInLine = numCharsInLine; } -void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout &ll) { - +void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, + PRectangle rcLine, LineLayout &ll) { + PRectangle rcSegment = rcLine; - + // Using one font for all control characters so it can be controlled independently to ensure // the box goes around the characters tightly. Seems to be no way to work out what height // is taken by an individual character - internal leading gives varying results. @@ -802,12 +846,14 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, marks = pdoc->GetMark(line) & vsDraw.maskInLine; } + bool inIndentation = true; + int indentWidth = pdoc->indentInChars * vsDraw.spaceWidth; + if (indentWidth == 0) + indentWidth = pdoc->tabInChars * vsDraw.spaceWidth; + int posLineStart = pdoc->LineStart(line); int posLineEnd = pdoc->LineStart(line + 1); - int selStart = SelectionStart(line); - int selEnd = SelectionEnd(line); - int styleMask = pdoc->stylingBitsMask; int startseg = 0; for (int i = 0; i < ll.numCharsInLine; i++) { @@ -816,37 +862,57 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, // If there is the end of a style run for any reason if ((ll.styles[i] != ll.styles[i + 1]) || IsControlCharacter(ll.chars[i]) || IsControlCharacter(ll.chars[i + 1]) || - ((selStart != selEnd) && ((iDoc + 1 == selStart) || (iDoc + 1 == selEnd))) || - (i == (theEdge-1))) { + ((ll.selStart != ll.selEnd) && ((iDoc + 1 == ll.selStart) || (iDoc + 1 == ll.selEnd))) || + (i == (ll.edgeColumn - 1))) { int styleMain = ll.styles[i]; Colour textBack = vsDraw.styles[styleMain].back.allocated; Colour textFore = vsDraw.styles[styleMain].fore.allocated; Font &textFont = vsDraw.styles[styleMain].font; - bool inSelection = (iDoc >= selStart) && (iDoc < selEnd) && (selStart != selEnd); - if (inSelection && !hideSelection) { - if (vsDraw.selbackset) - textBack = vsDraw.selbackground.allocated; + bool inSelection = (iDoc >= ll.selStart) && (iDoc < ll.selEnd) && (ll.selStart != ll.selEnd); + if (inSelection) { + if (vsDraw.selbackset) { + if (primarySelection) + textBack = vsDraw.selbackground.allocated; + else + textBack = vsDraw.selbackground2.allocated; + } if (vsDraw.selforeset) textFore = vsDraw.selforeground.allocated; } else { if (marks) textBack = markBack; - if ((edgeState == EDGE_BACKGROUND) && (i >= theEdge) && (ll.chars[i] != '\n') && (ll.chars[i] != '\r')) - textBack = vs.edgecolour.allocated; + if ((vsDraw.edgeState == EDGE_BACKGROUND) && (i >= ll.edgeColumn) && (ll.chars[i] != '\n') && (ll.chars[i] != '\r')) + textBack = vsDraw.edgecolour.allocated; } // Manage tab display if (ll.chars[i] == '\t') { rcSegment.left = ll.positions[i] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; surface->FillRectangle(rcSegment, textBack); - if (vsDraw.viewWhitespace) { + if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) { surface->PenColour(textFore); - PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, - rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); - DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); } - // Manage control character display - } else if (IsControlCharacter(ll.chars[i])) { + if (inIndentation && vsDraw.viewIndentationGuides) { + for (int xIG = ll.positions[i] / indentWidth * indentWidth; xIG < ll.positions[i + 1]; xIG += indentWidth) { + if (xIG >= ll.positions[i] && xIG > 0) { + Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); + PRectangle rcCopyArea(xIG + xStart + 1, rcSegment.top, xIG + xStart + 2, rcSegment.bottom); + surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == xIG) ? + pixmapIndentGuideHighlight : pixmapIndentGuide); + } + } + } + if (vsDraw.viewWhitespace != wsInvisible) { + if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { + PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, + rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); + DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); + } + } + // Manage control character display + } + else if (IsControlCharacter(ll.chars[i])) { + inIndentation = false; const char *ctrlChar = ControlCharacterString(ll.chars[i]); rcSegment.left = ll.positions[i] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; @@ -865,26 +931,42 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, rcChar.left++; rcChar.right--; surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), - textBack, textFore); - // Manage normal display + rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), + textBack, textFore); + // Manage normal display } else { rcSegment.left = ll.positions[startseg] + xStart; rcSegment.right = ll.positions[i + 1] + xStart; - // Only try to 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, rcSegment.top + vsDraw.maxAscent, ll.chars + startseg, i - startseg + 1, textFore, textBack); - if (vsDraw.viewWhitespace) { + if (vsDraw.viewWhitespace != wsInvisible || + (inIndentation && vsDraw.viewIndentationGuides)) { for (int cpos = 0; cpos <= i - startseg; cpos++) { if (ll.chars[cpos + startseg] == ' ') { - int xmid = (ll.positions[cpos + startseg] + ll.positions[cpos + startseg + 1]) / 2; - PRectangle rcDot(xmid + xStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); - rcDot.right = rcDot.left + 1; - rcDot.bottom = rcDot.top + 1; - surface->FillRectangle(rcDot, textFore); + if (vsDraw.viewWhitespace != wsInvisible) { + if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { + int xmid = (ll.positions[cpos + startseg] + ll.positions[cpos + startseg + 1]) / 2; + PRectangle rcDot(xmid + xStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); + rcDot.right = rcDot.left + 1; + rcDot.bottom = rcDot.top + 1; + surface->FillRectangle(rcDot, textFore); + } + } + if (inIndentation && vsDraw.viewIndentationGuides) { + int startSpace = ll.positions[cpos + startseg]; + if (startSpace > 0 && (startSpace % indentWidth == 0)) { + Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); + PRectangle rcCopyArea(startSpace + xStart + 1, rcSegment.top, startSpace + xStart + 2, rcSegment.bottom); + surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == ll.positions[cpos + startseg]) ? + pixmapIndentGuideHighlight : pixmapIndentGuide); + } + } + } else { + inIndentation = false; } } } @@ -905,10 +987,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, for (int indica = 0; indica <= INDIC_MAX; indica++) indStart[indica] = 0; - for (int indicPos = 0; indicPos <= ll.numCharsInLine; indicPos++) { + for (int indicPos = 0; indicPos < ll.numCharsInLine; indicPos++) { if (ll.indicators[indicPos] != ll.indicators[indicPos + 1]) { int mask = 1 << pdoc->stylingBits; - for (int indicnum = 0; mask <= 0x100; indicnum++) { + for (int indicnum = 0; mask < 0x100; indicnum++) { if ((ll.indicators[indicPos + 1] & mask) && !(ll.indicators[indicPos] & mask)) { indStart[indicnum] = ll.positions[indicPos + 1]; } @@ -930,9 +1012,12 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, int xEol = ll.positions[ll.numCharsInLine]; rcSegment.left = xEol + xStart; rcSegment.right = xEol + vsDraw.aveCharWidth + xStart; - bool eolInSelection = (posLineEnd > selStart) && (posLineEnd <= selEnd) && (selStart != selEnd); - if (eolInSelection && !hideSelection && vsDraw.selbackset && (line < pdoc->LinesTotal()-1)) { - surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); + bool eolInSelection = (posLineEnd > ll.selStart) && (posLineEnd <= ll.selEnd) && (ll.selStart != ll.selEnd); + if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) { + if (primarySelection) + surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); + else + surface->FillRectangle(rcSegment, vsDraw.selbackground2.allocated); } else if (marks) { surface->FillRectangle(rcSegment, markBack); } else { @@ -948,12 +1033,12 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, } else { surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); } - - if (edgeState == EDGE_LINE) { - int edgeX = theEdge * vsDraw.spaceWidth; + + if (vsDraw.edgeState == EDGE_LINE) { + int edgeX = ll.edgeColumn * vsDraw.spaceWidth; rcSegment.left = edgeX + xStart; rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vs.edgecolour.allocated); + surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated); } } @@ -984,6 +1069,22 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { pixmapSelPattern.FillRectangle(rcPattern, vs.selbarlight.allocated); } } + if (!pixmapIndentGuide.Initialised()) { + // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line + pixmapIndentGuide.InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + pixmapIndentGuideHighlight.InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + PRectangle rcIG(0, 0, 1, vs.lineHeight); + pixmapIndentGuide.FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated); + pixmapIndentGuide.PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated); + pixmapIndentGuideHighlight.FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated); + pixmapIndentGuideHighlight.PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated); + for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) { + pixmapIndentGuide.MoveTo(0, stripe); + pixmapIndentGuide.LineTo(2, stripe); + pixmapIndentGuideHighlight.MoveTo(0, stripe); + pixmapIndentGuideHighlight.LineTo(2, stripe); + } + } if (bufferedDraw) { if (!pixmapLine.Initialised()) { @@ -1003,7 +1104,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { int screenLinePaintFirst = rcArea.top / vs.lineHeight; // The area to be painted plus one extra line is styled. // The extra line is to determine when a style change, such as statrting a comment flows on to other lines. - int lineStyleLast = topLine + (rcArea.bottom-1) / vs.lineHeight + 1; + int lineStyleLast = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1; //Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast); int endPosPaint = pdoc->Length(); if (lineStyleLast < cs.LinesDisplayed()) @@ -1022,20 +1123,20 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { NotifyUpdateUI(); needUpdateUI = false; } - + PaintSelMargin(surfaceWindow, rcArea); PRectangle rcRightMargin = rcClient; rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth; if (rcArea.Intersects(rcRightMargin)) { - surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated); + surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated); } if (paintState == paintAbandoned) { // Either styling or NotifyUpdateUI noticed that painting is needed // outside the current painting rectangle //Platform::DebugPrintf("Abandoning paint\n"); - return; + return ; } //Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset); @@ -1062,7 +1163,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { rcTextArea.right -= vs.rightMarginWidth; surfaceWindow->SetClip(rcTextArea); //GTimer *tim=g_timer_new(); - while (visibleLine <= cs.LinesDisplayed() && yposScreen < rcArea.bottom) { + while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) { //g_timer_start(tim); //Platform::DebugPrintf("Painting line %d\n", line); @@ -1078,18 +1179,35 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { // and determine the x position at which each character starts. LineLayout ll; LayoutLine(line, surface, vs, ll); - + // Highlight the current braces if any - if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd)) - ll.styles[braces[0] - posLineStart] = - static_cast(bracesMatchStyle); - if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd)) - ll.styles[braces[1] - posLineStart] = - static_cast(bracesMatchStyle); - + if ((braces[0] >= posLineStart) && (braces[0] < posLineEnd)) { + int braceOffset = braces[0] - posLineStart; + if (braceOffset < ll.numCharsInLine) + ll.styles[braceOffset] = static_cast(bracesMatchStyle); + } + if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd)) { + int braceOffset = braces[1] - posLineStart; + if (braceOffset < ll.numCharsInLine) + ll.styles[braceOffset] = static_cast(bracesMatchStyle); + } + if ((braces[0] >= posLineStart && braces[1] <= posLineEnd) || + (braces[1] >= posLineStart && braces[0] <= posLineEnd)) { + ll.xHighlightGuide = highlightGuideColumn * vs.spaceWidth; + } + + ll.selStart = SelectionStart(line); + ll.selEnd = SelectionEnd(line); + if (hideSelection) { + ll.selStart = -1; + ll.selEnd = -1; + } + // Need to fix this up so takes account of Unicode and DBCS + ll.edgeColumn = theEdge; + // Draw the line if (cs.GetVisible(line)) - DrawLine(surface, vs, line, xStart, rcLine, ll); + DrawLine(surface, vs, line, visibleLine, xStart, rcLine, ll); bool expanded = cs.GetExpanded(line); if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) { @@ -1106,17 +1224,19 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated); } } - + // Draw the Caret if (line == lineCaret) { int offset = Platform::Minimum(posCaret - posLineStart, LineLayout::maxLineLength); int xposCaret = ll.positions[offset] + xStart; - int widthOverstrikeCaret = - ll.positions[offset + 1] - ll.positions[offset]; - if (posCaret == pdoc->Length()) // At end of document + int widthOverstrikeCaret; + if (posCaret == pdoc->Length()) { // At end of document widthOverstrikeCaret = vs.aveCharWidth; - if ((posCaret - posLineStart) >= ll.numCharsInLine) // At end of line + } else if ((posCaret - posLineStart) >= ll.numCharsInLine) { // At end of line widthOverstrikeCaret = vs.aveCharWidth; + } else { + widthOverstrikeCaret = ll.positions[offset + 1] - ll.positions[offset]; + } if (widthOverstrikeCaret < 3) // Make sure its visible widthOverstrikeCaret = 3; if (((caret.active && caret.on) || (posDrag >= 0)) && xposCaret >= 0) { @@ -1137,12 +1257,12 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { surface->FillRectangle(rcCaret, vs.caretcolour.allocated); } } - + if (cs.GetVisible(line)) { if (bufferedDraw) { Point from(vs.fixedColumnWidth, 0); PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen, - rcClient.right, yposScreen + vs.lineHeight); + rcClient.right, yposScreen + vs.lineHeight); surfaceWindow->Copy(rcCopyArea, from, pixmapLine); } } @@ -1159,13 +1279,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { //Platform::DebugPrintf("Paint [%0d] took %g\n", line, g_timer_elapsed(tim, 0)); } //g_timer_destroy(tim); + PRectangle rcBeyondEOF = rcClient; rcBeyondEOF.left = vs.fixedColumnWidth; rcBeyondEOF.right = rcBeyondEOF.right; rcBeyondEOF.top = (cs.LinesDisplayed() - topLine) * vs.lineHeight; if (rcBeyondEOF.top < rcBeyondEOF.bottom) { surfaceWindow->FillRectangle(rcBeyondEOF, vs.styles[STYLE_DEFAULT].back.allocated); - if (edgeState == EDGE_LINE) { + if (vs.edgeState == EDGE_LINE) { int edgeX = theEdge * vs.spaceWidth; rcBeyondEOF.left = edgeX + xStart; rcBeyondEOF.right = rcBeyondEOF.left + 1; @@ -1178,10 +1299,24 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { // Space (3 space characters) between line numbers and text when printing. #define lineNumberPrintSpace " " +Colour InvertedLight(Colour orig) { + unsigned int r = orig.GetRed(); + unsigned int g = orig.GetGreen(); + unsigned int b = orig.GetBlue(); + unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye + unsigned int il = 0xff - l; + if (l == 0) + return Colour(0xff, 0xff, 0xff); + r = r * il / l; + g = g * il / l; + b = b * il / l; + return Colour(Platform::Minimum(r, 0xff), Platform::Minimum(g, 0xff), Platform::Minimum(b, 0xff)); +} + // This is mostly copied from the Paint method but with some things omitted // such as the margin markers, line numbers, selection and caret // Should be merged back into a combined Draw method. -long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { +long Editor::FormatRange(bool draw, RangeToFormat *pfr) { if (!pfr) return 0; @@ -1191,13 +1326,13 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { Surface *surfaceMeasure = new Surface(); surfaceMeasure->Init(pfr->hdcTarget); surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); - + ViewStyle vsPrint(vs); - + // Modify the view style for printing as do not normally want any of the transient features to be printed // Printing supports only the line number margin. int lineNumberIndex = -1; - for (int margin=0; margin < ViewStyle::margins; margin++) { + for (int margin = 0; margin < ViewStyle::margins; margin++) { if ((!vsPrint.ms[margin].symbol) && (vsPrint.ms[margin].width > 0)) { lineNumberIndex = margin; } else { @@ -1206,13 +1341,24 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { } vsPrint.showMarkedLines = false; vsPrint.fixedColumnWidth = 0; - vsPrint.zoomLevel = 0; + vsPrint.zoomLevel = printMagnification; + vsPrint.viewIndentationGuides = false; // Don't show the selection when printing vsPrint.selbackset = false; vsPrint.selforeset = false; // White background for the line numbers - vsPrint.styles[STYLE_LINENUMBER].back.desired = Colour(0xff,0xff,0xff); - + vsPrint.styles[STYLE_LINENUMBER].back.desired = Colour(0xff, 0xff, 0xff); + for (int sty = 0;sty <= STYLE_MAX;sty++) { + if (printColourMode == SC_PRINT_INVERTLIGHT) { + vsPrint.styles[sty].fore.desired = InvertedLight(vsPrint.styles[sty].fore.desired); + vsPrint.styles[sty].back.desired = InvertedLight(vsPrint.styles[sty].back.desired); + } else if (printColourMode == SC_PRINT_BLACKONWHITE) { + vsPrint.styles[sty].fore.desired = Colour(0, 0, 0); + vsPrint.styles[sty].back.desired = Colour(0xff, 0xff, 0xff); + } + } + vsPrint.styles[STYLE_LINENUMBER].back.desired = Colour(0xff, 0xff, 0xff); + vsPrint.Refresh(*surfaceMeasure); // Ensure colours are set up vsPrint.RefreshColourPalette(palette, true); @@ -1220,8 +1366,8 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { // Determining width must hapen after fonts have been realised in Refresh int lineNumberWidth = 0; if (lineNumberIndex >= 0) { - lineNumberWidth = surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, - "9999" lineNumberPrintSpace, 4 + strlen(lineNumberPrintSpace)); + lineNumberWidth = surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, + "9999" lineNumberPrintSpace, 4 + strlen(lineNumberPrintSpace)); vsPrint.ms[lineNumberIndex].width = lineNumberWidth; } @@ -1255,35 +1401,39 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { rcLine.top = ypos; rcLine.right = pfr->rc.right; rcLine.bottom = ypos + vsPrint.lineHeight; - + if (lineNumberWidth) { char number[100]; sprintf(number, "%d" lineNumberPrintSpace, line + 1); PRectangle rcNumber = rcLine; rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify - rcNumber.left -= - surface->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number)); + 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); + 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 + // 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); - + ll.selStart = -1; + ll.selEnd = -1; + // Need to fix this up so takes account of Unicode and DBCS + ll.edgeColumn = theEdge; + // Draw the line surface->FlushCachedState(); - DrawLine(surface, vsPrint, line, xStart, rcLine, ll); + DrawLine(surface, vsPrint, line, line, xStart, rcLine, ll); ypos += vsPrint.lineHeight; line++; @@ -1297,8 +1447,8 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) { } // Empty method is overridden on GTK+ to show / hide scrollbars -void Editor::ReconfigureScrollBars() { -} +void Editor::ReconfigureScrollBars() {} + void Editor::SetScrollBarsTo(PRectangle) { RefreshStyleData(); @@ -1319,6 +1469,7 @@ void Editor::SetScrollBarsTo(PRectangle) { //Platform::DebugPrintf("end max = %d page = %d\n", nMax, nPage); } + void Editor::SetScrollBars() { PRectangle rsClient = GetClientRectangle(); SetScrollBarsTo(rsClient); @@ -1344,6 +1495,8 @@ void Editor::AddCharUTF(char *s, unsigned int len) { pdoc->InsertString(currentPos, s, len); SetEmptySelection(currentPos + len); EnsureCaretVisible(); + // Avoid blinking during rapid typing: + ShowCaretAtCurrentPosition(); SetLastXChosen(); NotifyChar(s[0]); } @@ -1354,7 +1507,7 @@ void Editor::ClearSelection() { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); int startPos = SelectionStart(); - for (int line=lineEnd; line >= lineStart; line--) { + for (int line = lineEnd; line >= lineStart; line--) { startPos = SelectionStart(line); unsigned int chars = SelectionEnd(line) - startPos; if (0 != chars) { @@ -1385,6 +1538,13 @@ void Editor::ClearAll() { SetVerticalScrollPos(); } +void Editor::ClearDocumentStyle() { + pdoc->StartStyling(0, '\377'); + pdoc->SetStyleFor(pdoc->Length(), 0); + cs.ShowAll(); + pdoc->ClearLevels(); +} + void Editor::Cut() { Copy(); ClearSelection(); @@ -1396,9 +1556,9 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) { int xInsert = XFromPosition(currentPos); int line = pdoc->LineFromPosition(currentPos); bool prevCr = false; - for (int i=0; i= pdoc->LinesTotal()) { if (pdoc->eolMode != SC_EOL_LF) @@ -1409,7 +1569,7 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) { currentPos = PositionFromLineX(line, xInsert); prevCr = ptr[i] == '\r'; } else { - pdoc->InsertString(currentPos, ptr+i, 1); + pdoc->InsertString(currentPos, ptr + i, 1); currentPos++; insertPos = currentPos; prevCr = false; @@ -1434,6 +1594,7 @@ void Editor::SelectAll() { void Editor::Undo() { if (pdoc->CanUndo()) { + InvalidateCaret(); int newPos = pdoc->Undo(); SetEmptySelection(newPos); EnsureCaretVisible(); @@ -1450,6 +1611,8 @@ void Editor::Redo() { void Editor::DelChar() { pdoc->DelChar(currentPos); + // Avoid blinking during rapid typing: + ShowCaretAtCurrentPosition(); } void Editor::DelCharBack() { @@ -1460,10 +1623,12 @@ void Editor::DelCharBack() { ClearSelection(); SetEmptySelection(currentPos); } + // Avoid blinking during rapid typing: + ShowCaretAtCurrentPosition(); } -void Editor::NotifyFocus(bool) { -} +void Editor::NotifyFocus(bool) {} + void Editor::NotifyStyleToNeeded(int endStyleNeeded) { SCNotification scn; @@ -1486,9 +1651,9 @@ void Editor::NotifyChar(char ch) { char txt[2]; txt[0] = ch; txt[1] = '\0'; - NotifyMacroRecord(EM_REPLACESEL, 0, (LPARAM) txt); + NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(txt)); } -#endif +#endif } void Editor::NotifySavePoint(bool isSavePoint) { @@ -1522,7 +1687,7 @@ void Editor::NotifyUpdateUI() { bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { int marginClicked = -1; int x = 0; - for (int margin=0; margin < ViewStyle::margins; margin++) { + for (int margin = 0; margin < ViewStyle::margins; margin++) { if ((pt.x > x) && (pt.x < x + vs.ms[margin].width)) marginClicked = margin; x += vs.ms[margin].width; @@ -1555,6 +1720,13 @@ void Editor::NotifyModifyAttempt(Document*, void *) { NotifyModifyAttempt(); } +void Editor::NotifyMove(int position) { + SCNotification scn; + scn.nmhdr.code = SCN_POSCHANGED; + scn.position = position; + NotifyParent(scn); +} + void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) { //Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off"); NotifySavePoint(atSavePoint); @@ -1618,11 +1790,15 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { } } } - if (mh.modificationType & SC_MOD_BEFOREINSERT) { - NotifyNeedShown(mh.position, 0); - } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { - NotifyNeedShown(mh.position, mh.length); - } + if (cs.LinesDisplayed() < cs.LinesInDoc()) { + // Some lines are hidden so may need shown. + // TODO: check if the modified area is hidden. + if (mh.modificationType & SC_MOD_BEFOREINSERT) { + NotifyNeedShown(mh.position, 0); + } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { + NotifyNeedShown(mh.position, mh.length); + } + } if (mh.linesAdded != 0) { // Update contraction state for inserted and removed lines @@ -1641,7 +1817,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { SetVerticalScrollPos(); } } - + //Platform::DebugPrintf("** %x Doc Changed\n", this); // TODO: could invalidate from mh.startModification to end of screen //InvalidateRange(mh.position, mh.position + mh.length); @@ -1661,13 +1837,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { 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) { // Real modification made to text of document. NotifyChange(); // Send EN_CHANGE } + SCNotification scn; scn.nmhdr.code = SCN_MODIFIED; scn.position = mh.position; @@ -1687,15 +1864,15 @@ void Editor::NotifyDeleted(Document *, void *) { } #ifdef MACRO_SUPPORT -void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { +void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam) { // Enumerates all macroable messages switch (iMessage) { - case WM_CUT: - case WM_COPY: - case WM_PASTE: - case WM_CLEAR: - case EM_REPLACESEL: + case SCI_CUT: + case SCI_COPY: + case SCI_PASTE: + case SCI_CLEAR: + case SCI_REPLACESEL: case SCI_ADDTEXT: case SCI_INSERTTEXT: case SCI_CLEARALL: @@ -1747,10 +1924,11 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_UPPERCASE: break; - // Filter out all others (display changes, etc) + // Filter out all others (display changes, etc) default: -// printf("Filtered out %ld of macro recording\n", iMessage); - return; + // printf("Filtered out %ld of macro recording\n", iMessage); + + return ; } // Send notification @@ -1761,13 +1939,13 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { scn.lParam = lParam; NotifyParent(scn); } -#endif +#endif // Force scroll and keep position relative to top of window void Editor::PageMove(int direction, bool extend) { Point pt = LocationFromPosition(currentPos); int topLineNew = Platform::Clamp( - topLine + direction * LinesToScroll(), 0, MaxScrollPos()); + topLine + direction * LinesToScroll(), 0, MaxScrollPos()); int newPos = PositionFromLocation( Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll()))); if (topLineNew != topLine) { @@ -1787,17 +1965,17 @@ void Editor::ChangeCaseOfSelection(bool makeUpperCase) { if (selType == selRectangle) { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); - for (int line=lineEnd; line >= lineStart; line--) { + for (int line = lineEnd; line >= lineStart; line--) { pdoc->ChangeCase( - Range(SelectionStart(line), SelectionEnd(line)), - makeUpperCase); + 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); + pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()), + makeUpperCase); SetSelection(startCurrent, startAnchor); } pdoc->EndUndoAction(); @@ -1807,34 +1985,37 @@ void Editor::ChangeCaseOfSelection(bool makeUpperCase) { void Editor::LineTranspose() { int line = pdoc->LineFromPosition(currentPos); if (line > 0) { - int startPrev = pdoc->LineStart(line-1); - int endPrev = pdoc->LineEnd(line-1); + 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); + 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); + 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); + 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) { +void Editor::CancelModes() {} + + +int Editor::KeyCommand(unsigned int iMessage) { Point pt = LocationFromPosition(currentPos); switch (iMessage) { @@ -1950,10 +2131,11 @@ int Editor::KeyCommand(UINT iMessage) { inOverstrike = !inOverstrike; DropCaret(); ShowCaretAtCurrentPosition(); + NotifyUpdateUI(); break; - case SCI_CANCEL: // Cancel any modes - handled in subclass + case SCI_CANCEL: // Cancel any modes - handled in subclass // Also unselect text - SetEmptySelection(currentPos); + CancelModes(); break; case SCI_DELETEBACK: DelCharBack(); @@ -1962,9 +2144,13 @@ int Editor::KeyCommand(UINT iMessage) { break; case SCI_TAB: Indent(true); + SetLastXChosen(); + EnsureCaretVisible(); break; case SCI_BACKTAB: Indent(false); + SetLastXChosen(); + EnsureCaretVisible(); break; case SCI_NEWLINE: ClearSelection(); @@ -2028,16 +2214,16 @@ int Editor::KeyCommand(UINT iMessage) { lineStart = t; } int start = pdoc->LineStart(lineStart); - int end = pdoc->LineStart(lineEnd+1); - SetSelection(start,end); + 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); + int end = pdoc->LineStart(line + 1); + pdoc->DeleteChars(start, end - start); MovePositionTo(start); } break; @@ -2068,11 +2254,11 @@ int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt) { return KeyDefault(key, modifiers); } -void Editor::SetWhitespaceVisible(bool view) { - vs.viewWhitespace = view; +void Editor::SetWhitespaceVisible(int view) { + vs.viewWhitespace = static_cast(view); } -bool Editor::GetWhitespaceVisible() { +int Editor::GetWhitespaceVisible() { return vs.viewWhitespace; } @@ -2082,9 +2268,15 @@ void Editor::Indent(bool forwards) { int lineCurrentPos = pdoc->LineFromPosition(currentPos); if (lineOfAnchor == lineCurrentPos) { ClearSelection(); - pdoc->InsertChar(currentPos, '\t'); - //pdoc->InsertChar(currentPos++, '\t'); - SetEmptySelection(currentPos + 1); + if (pdoc->useTabs) { + pdoc->InsertChar(currentPos, '\t'); + SetEmptySelection(currentPos + 1); + } else { + for (int i = 0; i < pdoc->tabInChars; i++) { + pdoc->InsertChar(currentPos, ' '); + } + SetEmptySelection(currentPos + pdoc->tabInChars); + } } else { int anchorPosOnLine = anchor - pdoc->LineStart(lineOfAnchor); int currentPosPosOnLine = currentPos - pdoc->LineStart(lineCurrentPos); @@ -2110,12 +2302,13 @@ void Editor::Indent(bool forwards) { } } -long Editor::FindText(UINT iMessage, WPARAM wParam, LPARAM lParam) { - FINDTEXTEX *ft = reinterpret_cast(lParam); +long Editor::FindText(unsigned int iMessage, unsigned long wParam, long lParam) { + TextToFind *ft = reinterpret_cast(lParam); int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText, - wParam & FR_MATCHCASE, wParam & FR_WHOLEWORD); + wParam & SCFIND_MATCHCASE, wParam & SCFIND_WHOLEWORD, + wParam & SCFIND_WORDSTART); if (pos != -1) { - if (iMessage == EM_FINDTEXTEX) { + if (iMessage != EM_FINDTEXT) { ft->chrgText.cpMin = pos; ft->chrgText.cpMax = pos + strlen(ft->lpstrText); } @@ -2123,8 +2316,8 @@ long Editor::FindText(UINT iMessage, WPARAM wParam, LPARAM lParam) { return pos; } -// Relocatable search support : Searches relative to current selection -// point and sets the selection to the found text range with +// Relocatable search support : Searches relative to current selection +// point and sets the selection to the found text range with // each search. // Anchor following searches at current selection start: This allows @@ -2139,18 +2332,20 @@ void Editor::SearchAnchor() { // Accepts both SCI_SEARCHNEXT and SCI_SEARCHPREV. // wParam contains search modes : ORed FR_MATCHCASE and FR_WHOLEWORD. // lParam contains the text to search for. -long Editor::SearchText(UINT iMessage, WPARAM wParam, LPARAM lParam) { +long Editor::SearchText(unsigned int iMessage, unsigned long wParam, long lParam) { const char *txt = reinterpret_cast(lParam); int pos; if (iMessage == SCI_SEARCHNEXT) { - pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, - wParam & FR_MATCHCASE, - wParam & FR_WHOLEWORD); + pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, + wParam & SCFIND_MATCHCASE, + wParam & SCFIND_WHOLEWORD, + wParam & SCFIND_WORDSTART); } else { - pos = pdoc->FindText(searchAnchor, 0, txt, - wParam & FR_MATCHCASE, - wParam & FR_WHOLEWORD); + pos = pdoc->FindText(searchAnchor, 0, txt, + wParam & SCFIND_MATCHCASE, + wParam & SCFIND_WHOLEWORD, + wParam & SCFIND_WORDSTART); } if (pos != -1) { @@ -2198,7 +2393,7 @@ int Editor::SelectionRangeLength() { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); int totalSize = 0; - for (int line=lineStart; line <= lineEnd; line++) { + for (int line = lineStart; line <= lineEnd; line++) { totalSize += SelectionEnd(line) - SelectionStart(line) + 1; if (pdoc->eolMode == SC_EOL_CRLF) totalSize++; @@ -2219,8 +2414,8 @@ char *Editor::CopySelectionRange() { text = new char[totalSize + 1]; if (text) { int j = 0; - for (int line=lineStart; line <= lineEnd; line++) { - for (int i=SelectionStart(line);iCharAt(i); } if (pdoc->eolMode != SC_EOL_LF) @@ -2250,7 +2445,7 @@ void Editor::CopySelectionIntoDrag() { void Editor::SetDragPosition(int newPos) { if (newPos >= 0) { - newPos = pdoc->MovePositionOutsideChar(newPos, 1); + newPos = MovePositionOutsideChar(newPos, 1); posDrop = newPos; } if (posDrag != newPos) { @@ -2268,6 +2463,7 @@ void Editor::StartDrag() { //wDraw.SetCursor(Window::cursorArrow); } + void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) { //Platform::DebugPrintf("DropAt %d\n", inDragDrop); if (inDragDrop) @@ -2275,15 +2471,15 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul int positionWasInSelection = PositionInSelection(position); - bool positionOnEdgeOfSelection = - (position == SelectionStart()) || (position == SelectionEnd()); + bool positionOnEdgeOfSelection = + (position == SelectionStart()) || (position == SelectionEnd()); - if ((!inDragDrop) || !(0 == positionWasInSelection) || - (positionOnEdgeOfSelection && !moving)) { + if ((!inDragDrop) || !(0 == positionWasInSelection) || + (positionOnEdgeOfSelection && !moving)) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); - + pdoc->BeginUndoAction(); int positionAfterDeletion = position; @@ -2292,7 +2488,7 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul if (rectangular) { int lineStart = pdoc->LineFromPosition(SelectionStart()); int lineEnd = pdoc->LineFromPosition(SelectionEnd()); - for (int line=lineStart; line <= lineEnd; line++) { + for (int line = lineStart; line <= lineEnd; line++) { int startPos = SelectionStart(line); int endPos = SelectionEnd(line); if (position >= startPos) { @@ -2311,14 +2507,14 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul ClearSelection(); } position = positionAfterDeletion; - + if (rectangular) { PasteRectangular(position, value, strlen(value)); pdoc->EndUndoAction(); // Should try to select new rectangle but it may not be a rectangle now so just select the drop position - SetSelection(position, position); + SetSelection(position, position); } else { - position = pdoc->MovePositionOutsideChar(position, currentPos - position); + position = MovePositionOutsideChar(position, currentPos - position); pdoc->InsertString(position, value); pdoc->EndUndoAction(); SetSelection(position + strlen(value), position); @@ -2338,7 +2534,7 @@ static int BeforeInOrAfter(int val, int minim, int maxim) { } int Editor::PositionInSelection(int pos) { - pos = pdoc->MovePositionOutsideChar(pos, currentPos - pos); + pos = MovePositionOutsideChar(pos, currentPos - pos); if (selType == selRectangle) { if (pos < SelectionStart()) return -1; @@ -2392,13 +2588,13 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b //Platform::DebugPrintf("Scintilla:ButtonDown %d %d = %d alt=%d\n", curTime, lastClickTime, curTime - lastClickTime, alt); ptMouseLast = pt; int newPos = PositionFromLocation(pt); - newPos = pdoc->MovePositionOutsideChar(newPos, currentPos - newPos); + newPos = MovePositionOutsideChar(newPos, currentPos - newPos); inDragDrop = false; - + bool processed = NotifyMarginClick(pt, shift, ctrl, alt); if (processed) - return; - + return ; + if (shift) { SetSelection(newPos); } @@ -2444,7 +2640,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b if (ctrl) { SelectAll(); lastClickTime = curTime; - return; + return ; } lineAnchor = LineFromLocation(pt); // While experimenting with folding turn off line selection @@ -2491,7 +2687,7 @@ void Editor::ButtonMove(Point pt) { xEndSelect = pt.x - vs.fixedColumnWidth + xOffset; ptMouseLast = pt; int movePos = PositionFromLocation(pt); - movePos = pdoc->MovePositionOutsideChar(movePos, currentPos - movePos); + movePos = MovePositionOutsideChar(movePos, currentPos - movePos); if (posDrag >= 0) { SetDragPosition(movePos); } else { @@ -2511,10 +2707,10 @@ void Editor::ButtonMove(Point pt) { int lineMove = LineFromLocation(pt); if (lineAnchor < lineMove) { SetSelection(pdoc->LineStart(lineMove + 1), - pdoc->LineStart(lineAnchor)); + pdoc->LineStart(lineAnchor)); } else { SetSelection(pdoc->LineStart(lineMove), - pdoc->LineStart(lineAnchor + 1)); + pdoc->LineStart(lineAnchor + 1)); } } } @@ -2523,8 +2719,9 @@ void Editor::ButtonMove(Point pt) { if (vs.fixedColumnWidth > 0) { // There is a margin if (PointInSelMargin(pt)) { wDraw.SetCursor(Window::cursorReverseArrow); - return; // No need to test for selection + return ; // No need to test for selection } + } // Display regular (drag) cursor over selection if (PointInSelection(pt)) @@ -2547,7 +2744,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { ptMouseLast = pt; SetMouseCapture(false); int newPos = PositionFromLocation(pt); - newPos = pdoc->MovePositionOutsideChar(newPos, currentPos - newPos); + newPos = MovePositionOutsideChar(newPos, currentPos - newPos); if (inDragDrop) { int selStart = SelectionStart(); int selEnd = SelectionEnd(); @@ -2609,53 +2806,53 @@ static bool IsIn(int a, int minimum, int maximum) { } static bool IsOverlap(int mina, int maxa, int minb, int maxb) { - return - IsIn(mina, minb, maxb) || - IsIn(maxa, minb, maxb) || - IsIn(minb, mina, maxa) || - IsIn(maxb, mina, maxa); + return + IsIn(mina, minb, maxb) || + IsIn(maxa, minb, maxb) || + IsIn(minb, mina, maxa) || + IsIn(maxb, mina, maxa); } void Editor::CheckForChangeOutsidePaint(Range r) { if (paintState == painting && !paintingAllText) { //Platform::DebugPrintf("Checking range in paint %d-%d\n", r.start, r.end); if (!r.Valid()) - return; - + return ; + PRectangle rcText = GetTextRectangle(); // Determine number of lines displayed including a possible partially displayed last line int linesDisplayed = (rcText.bottom - rcText.top - 1) / vs.lineHeight + 1; int bottomLine = topLine + linesDisplayed - 1; - + int lineRangeStart = cs.DisplayFromDoc(pdoc->LineFromPosition(r.start)); int lineRangeEnd = cs.DisplayFromDoc(pdoc->LineFromPosition(r.end)); if (!IsOverlap(topLine, bottomLine, lineRangeStart, lineRangeEnd)) { //Platform::DebugPrintf("No overlap (%d-%d) with window(%d-%d)\n", // lineRangeStart, lineRangeEnd, topLine, bottomLine); - return; + return ; } - + // Assert rcPaint contained within or equal to rcText if (rcPaint.top > rcText.top) { - // does range intersect rcText.top .. rcPaint.top - int paintTopLine = ((rcPaint.top - rcText.top-1) / vs.lineHeight) + topLine; + // does range intersect rcText.top .. rcPaint.top + int paintTopLine = ((rcPaint.top - rcText.top - 1) / vs.lineHeight) + topLine; // paintTopLine is the top line of the paint rectangle or the line just above if that line is completely inside the paint rectangle if (IsOverlap(topLine, paintTopLine, lineRangeStart, lineRangeEnd)) { - //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n", + //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n", // lineRangeStart, lineRangeEnd, topLine, paintTopLine); paintState = paintAbandoned; - return; + return ; } } if (rcPaint.bottom < rcText.bottom) { // does range intersect rcPaint.bottom .. rcText.bottom - int paintBottomLine = ((rcPaint.bottom - rcText.top-1) / vs.lineHeight + 1) + topLine; + int paintBottomLine = ((rcPaint.bottom - rcText.top - 1) / vs.lineHeight + 1) + topLine; // paintTopLine is the bottom line of the paint rectangle or the line just below if that line is completely inside the paint rectangle if (IsOverlap(paintBottomLine, bottomLine, lineRangeStart, lineRangeEnd)) { - //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n", + //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n", // lineRangeStart, lineRangeEnd, paintBottomLine, bottomLine); paintState = paintAbandoned; - return; + return ; } } } @@ -2663,15 +2860,24 @@ void Editor::CheckForChangeOutsidePaint(Range r) { char BraceOpposite(char ch) { switch (ch) { - case '(': return ')'; - case ')': return '('; - case '[': return ']'; - case ']': return '['; - case '{': return '}'; - case '}': return '{'; - case '<': return '>'; - case '>': return '<'; - default: return '\0'; + case '(': + return ')'; + case ')': + return '('; + case '[': + return ']'; + case ']': + return '['; + case '{': + return '}'; + case '}': + return '{'; + case '<': + return '>'; + case '>': + return '<'; + default: + return '\0'; } } @@ -2684,7 +2890,7 @@ int Editor::BraceMatch(int position, int /*maxReStyle*/) { if (chSeek == '\0') return - 1; char styBrace = static_cast( - pdoc->StyleAt(position) & pdoc->stylingBitsMask); + pdoc->StyleAt(position) & pdoc->stylingBitsMask); int direction = -1; if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') direction = 1; @@ -2708,12 +2914,12 @@ int Editor::BraceMatch(int position, int /*maxReStyle*/) { void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) { if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) { - if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) { + if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) { CheckForChangeOutsidePaint(Range(braces[0])); CheckForChangeOutsidePaint(Range(pos0)); braces[0] = pos0; } - if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) { + if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) { CheckForChangeOutsidePaint(Range(braces[1])); CheckForChangeOutsidePaint(Range(pos1)); braces[1] = pos1; @@ -2737,7 +2943,7 @@ void Editor::SetDocPointer(Document *document) { pdoc->AddRef(); // Reset the contraction state to fully shown. cs.Clear(); - cs.InsertLines(0, pdoc->LinesTotal()-1); + cs.InsertLines(0, pdoc->LinesTotal() - 1); pdoc->AddWatcher(this, 0); Redraw(); @@ -2770,7 +2976,7 @@ void Editor::ToggleContraction(int line) { int lineMaxSubord = pdoc->GetLastChild(line); cs.SetExpanded(line, 0); if (lineMaxSubord > line) { - cs.SetVisible(line+1, lineMaxSubord, false); + cs.SetVisible(line + 1, lineMaxSubord, false); SetScrollBars(); Redraw(); } @@ -2801,35 +3007,37 @@ void Editor::EnsureLineVisible(int line) { } } -static bool ValidMargin(WPARAM wParam) { +static bool ValidMargin(unsigned long wParam) { return wParam < ViewStyle::margins; } -LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { +long Editor::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); // Optional macro recording hook #ifdef MACRO_SUPPORT if (recordingMacro) NotifyMacroRecord(iMessage, wParam, lParam); -#endif +#endif switch (iMessage) { case WM_GETTEXT: + case SCI_GETTEXT: { if (lParam == 0) return 0; char *ptr = reinterpret_cast(lParam); unsigned int iChar = 0; - for (; iChar < wParam-1; iChar++) + for (; iChar < wParam - 1; iChar++) ptr[iChar] = pdoc->CharAt(iChar); ptr[iChar] = '\0'; return iChar; } case WM_SETTEXT: + case SCI_SETTEXT: { if (lParam == 0) return FALSE; @@ -2840,33 +3048,35 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { } case WM_GETTEXTLENGTH: + case SCI_GETTEXTLENGTH: return pdoc->Length(); - case WM_NOTIFY: - //Platform::DebugPrintf("S notify %d %d\n", wParam, lParam); - break; - case WM_CUT: + case SCI_CUT: Cut(); SetLastXChosen(); break; case WM_COPY: + case SCI_COPY: Copy(); break; case WM_PASTE: + case SCI_PASTE: Paste(); SetLastXChosen(); EnsureCaretVisible(); break; case WM_CLEAR: + case SCI_CLEAR: Clear(); SetLastXChosen(); break; case WM_UNDO: + case SCI_UNDO: Undo(); SetLastXChosen(); break; @@ -2922,6 +3132,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { // EM_DISPLAYBAND case EM_CANUNDO: + case SCI_CANUNDO: return pdoc->CanUndo() ? TRUE : FALSE; case EM_UNDO: @@ -2930,10 +3141,12 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case EM_EMPTYUNDOBUFFER: + case SCI_EMPTYUNDOBUFFER: pdoc->DeleteUndoHistory(); return 0; case EM_GETFIRSTVISIBLELINE: + case SCI_GETFIRSTVISIBLELINE: return topLine; case EM_GETLINE: { @@ -2942,7 +3155,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { int lineStart = pdoc->LineStart(wParam); int lineEnd = pdoc->LineStart(wParam + 1); char *ptr = reinterpret_cast(lParam); - WORD *pBufSize = reinterpret_cast(lParam); + short *pBufSize = reinterpret_cast(lParam); if (*pBufSize < lineEnd - lineStart) { ptr[0] = '\0'; // If no characters copied have to put a NUL into buffer return 0; @@ -2953,13 +3166,27 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return iPlace; } + case SCI_GETLINE: { + if (lParam == 0) + return 0; + int lineStart = pdoc->LineStart(wParam); + int lineEnd = pdoc->LineStart(wParam + 1); + char *ptr = reinterpret_cast(lParam); + int iPlace = 0; + for (int iChar = lineStart; iChar < lineEnd; iChar++) + ptr[iPlace++] = pdoc->CharAt(iChar); + return iPlace; + } + case EM_GETLINECOUNT: + case SCI_GETLINECOUNT: if (pdoc->LinesTotal() == 0) return 1; else return pdoc->LinesTotal(); case EM_GETMODIFY: + case SCI_GETMODIFY: return !pdoc->IsSavePoint(); case EM_GETRECT: @@ -2973,24 +3200,28 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { *reinterpret_cast(wParam) = SelectionStart(); if (lParam) *reinterpret_cast(lParam) = SelectionEnd(); - return MAKELONG(SelectionStart(), SelectionEnd()); + return Platform::LongFromTwoShorts( + static_cast(SelectionStart()), + static_cast(SelectionEnd())); case EM_EXGETSEL: { if (lParam == 0) return 0; - CHARRANGE *pCR = reinterpret_cast(lParam); + CharacterRange *pCR = reinterpret_cast(lParam); pCR->cpMin = SelectionStart(); pCR->cpMax = SelectionEnd(); } break; - case EM_SETSEL: { + case EM_SETSEL: + case SCI_SETSEL: { int nStart = static_cast(wParam); int nEnd = static_cast(lParam); if (nEnd < 0) nEnd = pdoc->Length(); if (nStart < 0) nStart = nEnd; // Remove selection + selType = selStream; SetSelection(nEnd, nStart); EnsureCaretVisible(); } @@ -2999,7 +3230,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case EM_EXSETSEL: { if (lParam == 0) return 0; - CHARRANGE *pCR = reinterpret_cast(lParam); + CharacterRange *pCR = reinterpret_cast(lParam); + selType = selStream; if (pCR->cpMax == -1) { SetSelection(pCR->cpMin, pdoc->Length()); } else { @@ -3009,7 +3241,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return pdoc->LineFromPosition(SelectionStart()); } - case EM_GETSELTEXT: { + case EM_GETSELTEXT: + case SCI_GETSELTEXT: { if (lParam == 0) return 0; char *ptr = reinterpret_cast(lParam); @@ -3035,7 +3268,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { lParam = SelectionStart(); // Not specified, but probably OK return pdoc->LineFromPosition(lParam); + case SCI_LINEFROMPOSITION: + if (static_cast(wParam) < 0) + return 0; + return pdoc->LineFromPosition(wParam); + case EM_LINEINDEX: + case SCI_POSITIONFROMLINE: if (static_cast(wParam) < 0) wParam = pdoc->LineFromPosition(SelectionStart()); if (wParam == 0) @@ -3046,8 +3285,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { // return -1; return pdoc->LineStart(wParam); - case EM_LINELENGTH: - { + case EM_LINELENGTH: { if (static_cast(wParam) < 0) // Who use this anyway? return 0; // Should be... Too complex to describe here, see MS specs! if (static_cast(wParam) > pdoc->Length()) // Useful test, anyway... @@ -3068,7 +3306,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return 0; return pdoc->LineStart(wParam + 1) - pdoc->LineStart(wParam); - case EM_REPLACESEL: { + case EM_REPLACESEL: + case SCI_REPLACESEL: { if (lParam == 0) return 0; pdoc->BeginUndoAction(); @@ -3082,19 +3321,26 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case EM_LINESCROLL: + case SCI_LINESCROLL: ScrollTo(topLine + lParam); HorizontalScrollTo(xOffset + wParam * vs.spaceWidth); return TRUE; case EM_SCROLLCARET: + case SCI_SCROLLCARET: EnsureCaretVisible(); break; case EM_SETREADONLY: + case SCI_SETREADONLY: pdoc->SetReadOnly(wParam); return TRUE; + case SCI_GETREADONLY: + return pdoc->IsReadOnly(); + case EM_CANPASTE: + case SCI_CANPASTE: return 1; case EM_CHARFROMPOS: { @@ -3103,7 +3349,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { Point *ppt = reinterpret_cast(lParam); int pos = PositionFromLocation(*ppt); int line = pdoc->LineFromPosition(pos); - return MAKELONG(pos, line); + return Platform::LongFromTwoShorts( + static_cast(pos), static_cast < short > (line)); } case EM_POSFROMCHAR: { @@ -3119,16 +3366,34 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return 0; } + case SCI_POINTXFROMPOSITION: + if (lParam < 0) { + return 0; + } else { + Point pt = LocationFromPosition(lParam); + return pt.x; + } + + case SCI_POINTYFROMPOSITION: + if (lParam < 0) { + return 0; + } else { + Point pt = LocationFromPosition(lParam); + return pt.y; + } + case EM_FINDTEXT: return FindText(iMessage, wParam, lParam); case EM_FINDTEXTEX: + case SCI_FINDTEXT: return FindText(iMessage, wParam, lParam); - case EM_GETTEXTRANGE: { + case EM_GETTEXTRANGE: + case SCI_GETTEXTRANGE: { if (lParam == 0) return 0; - TEXTRANGE *tr = reinterpret_cast(lParam); + TextRange *tr = reinterpret_cast(lParam); int cpMax = tr->chrg.cpMax; if (cpMax == -1) cpMax = pdoc->Length(); @@ -3139,11 +3404,16 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return len; // Not including NUL } + case EM_SELECTIONTYPE: +#ifdef SEL_EMPTY if (currentPos == anchor) return SEL_EMPTY; else return SEL_TEXT; +#else + return 0; +#endif case EM_HIDESELECTION: hideSelection = wParam; @@ -3151,25 +3421,45 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case EM_FORMATRANGE: - return FormatRange(wParam, reinterpret_cast(lParam)); + case SCI_FORMATRANGE: + return FormatRange(wParam, reinterpret_cast(lParam)); case EM_GETMARGINS: - return MAKELONG(vs.leftMarginWidth, vs.rightMarginWidth); - + return Platform::LongFromTwoShorts(static_cast(vs.leftMarginWidth), + static_cast(vs.rightMarginWidth)); + + case SCI_GETMARGINLEFT: + return vs.leftMarginWidth; + + case SCI_GETMARGINRIGHT: + return vs.rightMarginWidth; + case EM_SETMARGINS: +#ifdef EC_LEFTMARGIN if (wParam & EC_LEFTMARGIN) { - vs.leftMarginWidth = LOWORD(lParam); + vs.leftMarginWidth = Platform::LowShortFromLong(lParam); } if (wParam & EC_RIGHTMARGIN) { - vs.rightMarginWidth = HIWORD(lParam); + vs.rightMarginWidth = Platform::HighShortFromLong(lParam); } if (wParam == EC_USEFONTINFO) { vs.leftMarginWidth = vs.aveCharWidth / 2; vs.rightMarginWidth = vs.aveCharWidth / 2; } InvalidateStyleRedraw(); +#endif break; - + + case SCI_SETMARGINLEFT: + vs.leftMarginWidth = lParam; + InvalidateStyleRedraw(); + break; + + case SCI_SETMARGINRIGHT: + vs.rightMarginWidth = lParam; + InvalidateStyleRedraw(); + break; + // Control specific mesages case SCI_ADDTEXT: { @@ -3210,16 +3500,16 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { ClearAll(); return 0; - case SCI_SETUNDOCOLLECTION: - pdoc->SetUndoCollection(static_cast(wParam)); + case SCI_CLEARDOCUMENTSTYLE: + ClearDocumentStyle(); return 0; -#ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_APPENDUNDOSTARTACTION: - // Not just deprecated - now dead - //pdoc->AppendUndoStartAction(); + case SCI_SETUNDOCOLLECTION: + pdoc->SetUndoCollection(wParam); return 0; -#endif + + case SCI_GETUNDOCOLLECTION: + return pdoc->IsCollectingUndo(); case SCI_BEGINUNDOACTION: pdoc->BeginUndoAction(); @@ -3249,12 +3539,48 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETCHARAT: return pdoc->CharAt(wParam); + case SCI_SETCURRENTPOS: + SetSelection(wParam, anchor); + break; + case SCI_GETCURRENTPOS: return currentPos; + case SCI_SETANCHOR: + SetSelection(currentPos, wParam); + break; + case SCI_GETANCHOR: return anchor; + case SCI_SETSELECTIONSTART: + SetSelection(Platform::Maximum(currentPos, wParam), wParam); + break; + + case SCI_GETSELECTIONSTART: + return Platform::Minimum(anchor, currentPos); + + case SCI_SETSELECTIONEND: + SetSelection(wParam, Platform::Minimum(anchor, wParam)); + break; + + case SCI_GETSELECTIONEND: + return Platform::Maximum(anchor, currentPos); + + case SCI_SETPRINTMAGNIFICATION: + printMagnification = wParam; + break; + + case SCI_GETPRINTMAGNIFICATION: + return printMagnification; + + case SCI_SETPRINTCOLOURMODE: + printColourMode = wParam; + break; + + case SCI_GETPRINTCOLOURMODE: + return printColourMode; + case SCI_GETSTYLEAT: if (static_cast(wParam) >= pdoc->Length()) return 0; @@ -3277,7 +3603,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETSTYLEDTEXT: { if (lParam == 0) return 0; - TEXTRANGE *tr = reinterpret_cast(lParam); + TextRange *tr = reinterpret_cast(lParam); int iPlace = 0; for (int iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { tr->lpstrText[iPlace++] = pdoc->CharAt(iChar); @@ -3302,10 +3628,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return vs.viewWhitespace; case SCI_SETVIEWWS: - vs.viewWhitespace = wParam; + vs.viewWhitespace = static_cast(wParam); Redraw(); break; + case SCI_POSITIONFROMPOINT: + return PositionFromLocation(Point(wParam, lParam)); + case SCI_GOTOLINE: GoToLine(wParam); break; @@ -3316,10 +3645,6 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { Redraw(); break; - case SCI_SETANCHOR: - SetSelection(currentPos, wParam); - break; - case SCI_GETCURLINE: { if (lParam == 0) return 0; @@ -3352,25 +3677,19 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { pdoc->SetStyleFor(wParam, static_cast(lParam)); break; - case SCI_SETSTYLINGEX: // Specify a complete styling buffer + case SCI_SETSTYLINGEX: // Specify a complete styling buffer if (lParam == 0) return 0; pdoc->SetStyles(wParam, reinterpret_cast(lParam)); break; -#ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_SETMARGINWIDTH: - if (wParam < 100) { - vs.ms[1].width = wParam; - } - InvalidateStyleRedraw(); - break; -#endif - case SCI_SETBUFFEREDDRAW: bufferedDraw = wParam; break; + case SCI_GETBUFFEREDDRAW: + return bufferedDraw; + case SCI_SETTABWIDTH: if (wParam > 0) pdoc->tabInChars = wParam; @@ -3379,12 +3698,12 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETTABWIDTH: return pdoc->tabInChars; - + case SCI_SETINDENT: pdoc->indentInChars = wParam; InvalidateStyleRedraw(); break; - + case SCI_GETINDENT: return pdoc->indentInChars; @@ -3395,44 +3714,65 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETUSETABS: return pdoc->useTabs; - + case SCI_SETLINEINDENTATION: pdoc->SetLineIndentation(wParam, lParam); break; - + case SCI_GETLINEINDENTATION: return pdoc->GetLineIndentation(wParam); - + case SCI_GETLINEINDENTPOSITION: return pdoc->GetLineIndentPosition(wParam); - + + case SCI_GETCOLUMN: + return pdoc->GetColumn(wParam); + case SCI_SETHSCROLLBAR : horizontalScrollBarVisible = wParam; SetScrollBars(); ReconfigureScrollBars(); break; - + case SCI_GETHSCROLLBAR: return horizontalScrollBarVisible; - - case SCI_SETCODEPAGE: - pdoc->dbcsCodePage = wParam; + + case SCI_SETINDENTATIONGUIDES: + vs.viewIndentationGuides = wParam; + Redraw(); break; -#ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_SETLINENUMBERWIDTH: - if (wParam < 200) { - vs.ms[0].width = wParam; + case SCI_GETINDENTATIONGUIDES: + return vs.viewIndentationGuides; + + case SCI_SETHIGHLIGHTGUIDE: + if ((highlightGuideColumn != static_cast(wParam)) || (wParam > 0)) { + highlightGuideColumn = wParam; + Redraw(); } - InvalidateStyleRedraw(); break; -#endif + + case SCI_GETHIGHLIGHTGUIDE: + return highlightGuideColumn; + + case SCI_GETLINEENDPOSITION: + return pdoc->LineEnd(wParam); + + case SCI_SETCODEPAGE: + pdoc->dbcsCodePage = wParam; + break; + + case SCI_GETCODEPAGE: + return pdoc->dbcsCodePage; case SCI_SETUSEPALETTE: palette.allowRealization = wParam; InvalidateStyleRedraw(); break; + case SCI_GETUSEPALETTE: + return palette.allowRealization; + // Marker definition and setting case SCI_MARKERDEFINE: if (wParam <= MARKER_MAX) @@ -3491,48 +3831,48 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINTYPEN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].symbol ? SC_MARGIN_SYMBOL : SC_MARGIN_NUMBER; else return 0; - + case SCI_SETMARGINWIDTHN: if (ValidMargin(wParam)) { vs.ms[wParam].width = lParam; InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINWIDTHN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].width; else return 0; - + case SCI_SETMARGINMASKN: if (ValidMargin(wParam)) { vs.ms[wParam].mask = lParam; InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINMASKN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].mask; else return 0; - + case SCI_SETMARGINSENSITIVEN: if (ValidMargin(wParam)) { vs.ms[wParam].sensitive = lParam; InvalidateStyleRedraw(); } break; - + case SCI_GETMARGINSENSITIVEN: - if (ValidMargin(wParam)) + if (ValidMargin(wParam)) return vs.ms[wParam].sensitive ? 1 : 0; else return 0; @@ -3598,7 +3938,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { InvalidateStyleRedraw(); } break; - + case SCI_STYLESETVISIBLE: + if (wParam <= STYLE_MAX) { + vs.styles[wParam].visible = lParam; + InvalidateStyleRedraw(); + } + break; + case SCI_STYLERESETDEFAULT: vs.ResetDefaultStyle(); InvalidateStyleRedraw(); @@ -3606,24 +3952,24 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_SETSTYLEBITS: pdoc->SetStylingBits(wParam); break; - + case SCI_GETSTYLEBITS: return pdoc->stylingBits; - + case SCI_SETLINESTATE: return pdoc->SetLineState(wParam, lParam); - + case SCI_GETLINESTATE: return pdoc->GetLineState(wParam); - + case SCI_GETMAXLINESTATE: return pdoc->GetMaxLineState(); - - // Folding messages - + + // Folding messages + case SCI_VISIBLEFROMDOCLINE: return cs.DisplayFromDoc(wParam); - + case SCI_DOCLINEFROMVISIBLE: return cs.DocFromDisplay(wParam); @@ -3633,40 +3979,40 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { RedrawSelMargin(); return prev; } - + case SCI_GETFOLDLEVEL: return pdoc->GetLevel(wParam); - + case SCI_GETLASTCHILD: return pdoc->GetLastChild(wParam, lParam); - + case SCI_GETFOLDPARENT: return pdoc->GetFoldParent(wParam); - + case SCI_SHOWLINES: cs.SetVisible(wParam, lParam, true); SetScrollBars(); Redraw(); break; - + case SCI_HIDELINES: cs.SetVisible(wParam, lParam, false); SetScrollBars(); Redraw(); break; - + case SCI_GETLINEVISIBLE: return cs.GetVisible(wParam); - + case SCI_SETFOLDEXPANDED: if (cs.SetExpanded(wParam, lParam)) { RedrawSelMargin(); } break; - + case SCI_GETFOLDEXPANDED: return cs.GetExpanded(wParam); - + case SCI_SETFOLDFLAGS: foldFlags = wParam; Redraw(); @@ -3675,11 +4021,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_TOGGLEFOLD: ToggleContraction(wParam); break; - + case SCI_ENSUREVISIBLE: EnsureLineVisible(wParam); break; - + case SCI_SEARCHANCHOR: SearchAnchor(); break; @@ -3700,40 +4046,6 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { displayPopupMenu = wParam; break; - #ifdef INCLUDE_DEPRECATED_FEATURES - case SCI_SETFORE: - vs.styles[STYLE_DEFAULT].fore.desired = Colour(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETBACK: - vs.styles[STYLE_DEFAULT].back.desired = Colour(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETBOLD: - vs.styles[STYLE_DEFAULT].bold = wParam; - InvalidateStyleRedraw(); - break; - - case SCI_SETITALIC: - vs.styles[STYLE_DEFAULT].italic = wParam; - InvalidateStyleRedraw(); - break; - - case SCI_SETSIZE: - vs.styles[STYLE_DEFAULT].size = wParam; - InvalidateStyleRedraw(); - break; - - case SCI_SETFONT: - if (wParam == 0) - return 0; - strcpy(vs.styles[STYLE_DEFAULT].fontName, reinterpret_cast(wParam)); - InvalidateStyleRedraw(); - break; -#endif - case SCI_SETSELFORE: vs.selforeset = wParam; vs.selforeground.desired = Colour(lParam); @@ -3751,12 +4063,17 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { InvalidateStyleRedraw(); break; + case SCI_GETCARETFORE: + return vs.caretcolour.desired.AsLong(); + case SCI_ASSIGNCMDKEY: - kmap.AssignCmdKey(LOWORD(wParam), HIWORD(wParam), lParam); + kmap.AssignCmdKey(Platform::LowShortFromLong(wParam), + Platform::HighShortFromLong(wParam), lParam); break; case SCI_CLEARCMDKEY: - kmap.AssignCmdKey(LOWORD(wParam), HIWORD(wParam), WM_NULL); + kmap.AssignCmdKey(Platform::LowShortFromLong(wParam), + Platform::HighShortFromLong(wParam), WM_NULL); break; case SCI_CLEARALLCMDKEYS: @@ -3832,7 +4149,7 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_BRACEHIGHLIGHT: SetBraceHighlight(static_cast(wParam), lParam, STYLE_BRACELIGHT); break; - + case SCI_BRACEBADLIGHT: SetBraceHighlight(static_cast(wParam), -1, STYLE_BRACEBAD); break; @@ -3857,50 +4174,59 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_GETZOOM: return vs.zoomLevel; - + case SCI_GETEDGECOLUMN: return theEdge; - + case SCI_SETEDGECOLUMN: theEdge = wParam; InvalidateStyleRedraw(); break; - + case SCI_GETEDGEMODE: - return edgeState; - + return vs.edgeState; + case SCI_SETEDGEMODE: - edgeState = wParam; + vs.edgeState = wParam; InvalidateStyleRedraw(); break; - + case SCI_GETEDGECOLOUR: return vs.edgecolour.desired.AsLong(); - + case SCI_SETEDGECOLOUR: vs.edgecolour.desired = Colour(wParam); InvalidateStyleRedraw(); break; - + case SCI_GETDOCPOINTER: - return reinterpret_cast(pdoc); + return reinterpret_cast(pdoc); case SCI_SETDOCPOINTER: SetDocPointer(reinterpret_cast(lParam)); return 0; - case SCI_ADDREFDOC: + case SCI_CREATEDOCUMENT: { + Document *doc = new Document(); + doc->AddRef(); + return reinterpret_cast(doc); + } + + case SCI_ADDREFDOCUMENT: (reinterpret_cast(lParam))->AddRef(); break; - - case SCI_RELEASEDOC: + + case SCI_RELEASEDOCUMENT: (reinterpret_cast(lParam))->Release(); break; - + case SCI_SETMODEVENTMASK: modEventMask = wParam; return 0; - + + case SCI_GETMODEVENTMASK: + return modEventMask; + case SCI_CONVERTEOLS: pdoc->ConvertLineEnds(wParam); SetSelection(currentPos, anchor); // Ensure selection inside document @@ -3909,6 +4235,13 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_SELECTIONISRECTANGLE: return (selType == selRectangle) ? 1 : 0; + case SCI_SETOVERTYPE: + inOverstrike = wParam; + break; + + case SCI_GETOVERTYPE: + return inOverstrike ? TRUE : FALSE; + #ifdef MACRO_SUPPORT case SCI_STARTRECORD: recordingMacro = 1; @@ -3917,8 +4250,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_STOPRECORD: recordingMacro = 0; return 0; -#endif - +#endif + default: return DefWndProc(iMessage, wParam, lParam); } diff --git a/src/stc/scintilla/src/Editor.h b/src/stc/scintilla/src/Editor.h index 808a656be1..83967cfd6a 100644 --- a/src/stc/scintilla/src/Editor.h +++ b/src/stc/scintilla/src/Editor.h @@ -31,10 +31,15 @@ public: // Drawing is only performed for maxLineLength characters on each line. enum {maxLineLength = 4000}; int numCharsInLine; - char chars[maxLineLength]; - char styles[maxLineLength]; - char indicators[maxLineLength]; - int positions[maxLineLength]; + int xHighlightGuide; + bool highlightColumn; + int selStart; + int selEnd; + int edgeColumn; + char chars[maxLineLength+1]; + char styles[maxLineLength+1]; + char indicators[maxLineLength+1]; + int positions[maxLineLength+1]; }; class Editor : public DocWatcher { @@ -54,6 +59,8 @@ protected: // ScintillaBase subclass needs access to much of Editor bool stylesValid; ViewStyle vs; Palette palette; + int printMagnification; + int printColourMode; bool hideSelection; bool inOverstrike; @@ -69,6 +76,8 @@ protected: // ScintillaBase subclass needs access to much of Editor Surface pixmapLine; Surface pixmapSelMargin; Surface pixmapSelPattern; + Surface pixmapIndentGuide; + Surface pixmapIndentGuideHighlight; // Intellimouse support - currently only implemented for Windows unsigned int ucWheelScrollLines; int cWheelDelta; //wheel delta from roll @@ -98,8 +107,8 @@ protected: // ScintillaBase subclass needs access to much of Editor bool needUpdateUI; Position braces[2]; int bracesMatchStyle; + int highlightGuideColumn; - int edgeState; int theEdge; enum { notPainting, painting, paintAbandoned } paintState; @@ -114,6 +123,7 @@ protected: // ScintillaBase subclass needs access to much of Editor enum { selStream, selRectangle, selRectangleFixed } selType; int xStartSelect; int xEndSelect; + bool primarySelection; int caretPolicy; int caretSlop; @@ -168,6 +178,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void SetSelection(int currentPos_, int anchor_); void SetSelection(int currentPos_); void SetEmptySelection(int currentPos_); + int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int MovePositionTo(int newPos, bool extend = false); int MovePositionSoVisible(int pos, int moveDir); void SetLastXChosen(); @@ -183,10 +194,10 @@ protected: // ScintillaBase subclass needs access to much of Editor void PaintSelMargin(Surface *surface, PRectangle &rc); void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout &ll); - void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, + void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout &ll); void Paint(Surface *surfaceWindow, PRectangle rcArea); - long FormatRange(bool draw, FORMATRANGE *pfr); + long FormatRange(bool draw, RangeToFormat *pfr); virtual void SetVerticalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0; @@ -199,6 +210,7 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void AddCharUTF(char *s, unsigned int len); void ClearSelection(); void ClearAll(); + void ClearDocumentStyle(); void Cut(); void PasteRectangular(int pos, const char *ptr, int len); virtual void Copy() = 0; @@ -216,6 +228,7 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyStyleToNeeded(int endStyleNeeded); void NotifyChar(char ch); + void NotifyMove(int position); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); virtual void NotifyDoubleClick(Point pt, bool shift); @@ -231,24 +244,25 @@ protected: // ScintillaBase subclass needs access to much of Editor #ifdef MACRO_SUPPORT - void NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam); + void NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam); #endif void PageMove(int direction, bool extend=false); void ChangeCaseOfSelection(bool makeUpperCase); void LineTranspose(); - virtual int KeyCommand(UINT iMessage); + virtual void CancelModes(); + virtual int KeyCommand(unsigned int iMessage); virtual int KeyDefault(int /* key */, int /*modifiers*/); int KeyDown(int key, bool shift, bool ctrl, bool alt); - bool GetWhitespaceVisible(); - void SetWhitespaceVisible(bool view); + int GetWhitespaceVisible(); + void SetWhitespaceVisible(int view); void Indent(bool forwards); - long FindText(UINT iMessage,WPARAM wParam,LPARAM lParam); + long FindText(unsigned int iMessage, unsigned long wParam, long lParam); void SearchAnchor(); - long SearchText(UINT iMessage,WPARAM wParam,LPARAM lParam); + long SearchText(unsigned int iMessage, unsigned long wParam, long lParam); void GoToLine(int lineNo); char *CopyRange(int start, int end); @@ -282,11 +296,11 @@ protected: // ScintillaBase subclass needs access to much of Editor void ToggleContraction(int line); void EnsureLineVisible(int line); - virtual LRESULT DefWndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) = 0; + virtual long DefWndProc(unsigned int iMessage, unsigned long wParam, long lParam) = 0; public: // Public so scintilla_send_message can use it - virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); + virtual long WndProc(unsigned int iMessage, unsigned long wParam, long lParam); // Public so scintilla_set_id can use it int ctrlID; }; diff --git a/src/stc/scintilla/src/KeyMap.cxx b/src/stc/scintilla/src/KeyMap.cxx index 3a6a31f974..d2a6660f3c 100644 --- a/src/stc/scintilla/src/KeyMap.cxx +++ b/src/stc/scintilla/src/KeyMap.cxx @@ -28,7 +28,7 @@ void KeyMap::Clear() { alloc = 0; } -void KeyMap::AssignCmdKey(int key, int modifiers, UINT msg) { +void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { if ((len+1) >= alloc) { KeyToCommand *ktcNew = new KeyToCommand[alloc + 5]; if (!ktcNew) @@ -51,7 +51,7 @@ void KeyMap::AssignCmdKey(int key, int modifiers, UINT msg) { len++; } -UINT KeyMap::Find(int key, int modifiers) { +unsigned int KeyMap::Find(int key, int modifiers) { for (int i=0; i < len; i++) { if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) { return kmap[i].msg; @@ -61,53 +61,55 @@ UINT KeyMap::Find(int key, int modifiers) { } KeyToCommand KeyMap::MapDefault[] = { - {VK_DOWN, SCI_NORM, SCI_LINEDOWN}, - {VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, - {VK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, - {VK_UP, SCI_NORM, SCI_LINEUP}, - {VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, - {VK_UP, SCI_CTRL, SCI_LINESCROLLUP}, - {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_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_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_ESCAPE, SCI_NORM, SCI_CANCEL}, - {VK_BACK, SCI_NORM, SCI_DELETEBACK}, - {VK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, - {'Z', SCI_CTRL, WM_UNDO}, + {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, + {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, + {SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, + {SCK_UP, SCI_NORM, SCI_LINEUP}, + {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, + {SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, + {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, + {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, + {SCK_LEFT, SCI_CTRL, SCI_WORDLEFT}, + {SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND}, + {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, + {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, + {SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT}, + {SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND}, + {SCK_HOME, SCI_NORM, SCI_VCHOME}, + {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, + {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, + {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, + {SCK_END, SCI_NORM, SCI_LINEEND}, + {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, + {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, + {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, + {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, + {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, + {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, + {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, + {SCK_DELETE, SCI_NORM, SCI_CLEAR}, + {SCK_DELETE, SCI_SHIFT, SCI_CUT}, + {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, + {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, + {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, + {SCK_INSERT, SCI_CTRL, SCI_COPY}, + {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, + {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, + {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, + {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, + {SCK_BACK, SCI_ALT, SCI_UNDO}, + {'Z', SCI_CTRL, SCI_UNDO}, {'Y', SCI_CTRL, SCI_REDO}, - {'X', SCI_CTRL, WM_CUT}, - {'C', SCI_CTRL, WM_COPY}, - {'V', SCI_CTRL, WM_PASTE}, + {'X', SCI_CTRL, SCI_CUT}, + {'C', SCI_CTRL, SCI_COPY}, + {'V', SCI_CTRL, SCI_PASTE}, {'A', SCI_CTRL, SCI_SELECTALL}, - {VK_TAB, SCI_NORM, SCI_TAB}, - {VK_TAB, SCI_SHIFT, SCI_BACKTAB}, - {VK_RETURN, SCI_NORM, SCI_NEWLINE}, - {VK_ADD, SCI_CTRL, SCI_ZOOMIN}, - {VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, - {VK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, + {SCK_TAB, SCI_NORM, SCI_TAB}, + {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, + {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, + {SCK_ADD, SCI_CTRL, SCI_ZOOMIN}, + {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, + {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, //'L', SCI_CTRL, SCI_FORMFEED, {'L', SCI_CTRL, SCI_LINECUT}, {'L', SCI_CSHIFT, SCI_LINEDELETE}, diff --git a/src/stc/scintilla/src/KeyMap.h b/src/stc/scintilla/src/KeyMap.h index bc435e1970..c843104174 100644 --- a/src/stc/scintilla/src/KeyMap.h +++ b/src/stc/scintilla/src/KeyMap.h @@ -7,9 +7,9 @@ #define KEYTOCOMMAND_H #define SCI_NORM 0 -#define SCI_SHIFT SHIFT_PRESSED -#define SCI_CTRL LEFT_CTRL_PRESSED -#define SCI_ALT LEFT_ALT_PRESSED +#define SCI_SHIFT SCMOD_SHIFT +#define SCI_CTRL SCMOD_CTRL +#define SCI_ALT SCMOD_ALT #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) #define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) @@ -17,7 +17,7 @@ class KeyToCommand { public: int key; int modifiers; - UINT msg; + unsigned int msg; }; class KeyMap { @@ -29,8 +29,8 @@ public: KeyMap(); ~KeyMap(); void Clear(); - void AssignCmdKey(int key, int modifiers, UINT msg); - UINT Find(int key, int modifiers); // 0 returned on failure + void AssignCmdKey(int key, int modifiers, unsigned int msg); + unsigned int Find(int key, int modifiers); // 0 returned on failure }; #endif diff --git a/src/stc/scintilla/src/LexCPP.cxx b/src/stc/scintilla/src/LexCPP.cxx index 4f042bd61d..b6358ab332 100644 --- a/src/stc/scintilla/src/LexCPP.cxx +++ b/src/stc/scintilla/src/LexCPP.cxx @@ -19,14 +19,13 @@ static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &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'; } + bool wordIsUUID = false; char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) + if (isdigit(s[0]) || (s[0] == '.')) chAttr = SCE_C_NUMBER; else { if (keywords.InList(s)) { @@ -46,6 +45,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo styler.StartAt(startPos); bool fold = styler.GetPropertyInt("fold"); + bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor"); int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; @@ -56,7 +56,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; - int visChars = 0; + int visibleChars = 0; styler.StartSegment(startPos); bool lastWordWasUUID = false; for (unsigned int i = startPos; i < lengthDoc; i++) { @@ -64,6 +64,8 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) + // Avoid triggering two times on Dos/Win // End of line if (state == SCE_C_STRINGEOL) { styler.ColourTo(i, state); @@ -71,18 +73,18 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } if (fold) { int lev = levelPrev; - if (visChars == 0) + if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visChars > 0)) + if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); lineCurrent++; - visChars = 0; levelPrev = levelCurrent; } + visibleChars = 0; } if (!isspace(ch)) - visChars++; + visibleChars++; if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); @@ -92,13 +94,19 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } if (state == SCE_C_DEFAULT) { - if (iswordstart(ch)) { + if (ch == '@' && chNext == '\"') { + styler.ColourTo(i-1, state); + state = SCE_C_VERBATIM; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } else if (iswordstart(ch) || (ch == '@')) { styler.ColourTo(i-1, state); if (lastWordWasUUID) { state = SCE_C_UUID; lastWordWasUUID = false; } else { - state = SCE_C_WORD; + state = SCE_C_IDENTIFIER; } } else if (ch == '/' && chNext == '*') { styler.ColourTo(i-1, state); @@ -115,9 +123,16 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (ch == '\'') { styler.ColourTo(i-1, state); state = SCE_C_CHARACTER; - } else if (ch == '#') { + } else if (ch == '#' && visibleChars == 1) { + // Preprocessor commands are alone on their line styler.ColourTo(i-1, state); state = SCE_C_PREPROCESSOR; + // Skip whitespace between # and preprocessor word + do { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } while (isspace(ch) && (i < lengthDoc)); } else if (isoperator(ch)) { styler.ColourTo(i-1, state); styler.ColourTo(i, SCE_C_OPERATOR); @@ -125,7 +140,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo levelCurrent += (ch == '{') ? 1 : -1; } } - } else if (state == SCE_C_WORD) { + } else if (state == SCE_C_IDENTIFIER) { if (!iswordchar(ch)) { lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_C_DEFAULT; @@ -140,8 +155,6 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo 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 == '}')) { @@ -151,9 +164,16 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } } else { if (state == SCE_C_PREPROCESSOR) { - if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { - styler.ColourTo(i-1, state); - state = SCE_C_DEFAULT; + if (stylingWithinPreprocessor) { + if (isspace(ch)) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else { + if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } } } else if (state == SCE_C_COMMENT) { if (ch == '/' && chPrev == '*') { @@ -188,13 +208,10 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (ch == '\"') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } else if (chNext == '\r' || chNext == '\n') { + } else if (chNext == '\r' || chNext == '\n') { styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; - } + } } else if (state == SCE_C_CHARACTER) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { styler.ColourTo(i-1, SCE_C_STRINGEOL); @@ -208,39 +225,26 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } else if (ch == '\'') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); + } + } else if (state == SCE_C_VERBATIM) { + if (ch == '\"') { + if (chNext == '\"') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } else { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } } } else if (state == SCE_C_UUID) { if (ch == '\r' || ch == '\n' || ch == ')') { styler.ColourTo(i-1, state); + if (ch == ')') + styler.ColourTo(i, SCE_C_OPERATOR); 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; } diff --git a/src/stc/scintilla/src/LexHTML.cxx b/src/stc/scintilla/src/LexHTML.cxx index 653aa4653f..7868b47fc8 100644 --- a/src/stc/scintilla/src/LexHTML.cxx +++ b/src/stc/scintilla/src/LexHTML.cxx @@ -17,15 +17,21 @@ #include "Scintilla.h" #include "SciLexer.h" -enum { eScriptNone, eScriptJS, eScriptVBS, eScriptPython }; +#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START) +#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START) +#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START) + +enum { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML }; +enum { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc }; + static int segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, int prevValue) { - char s[100]; + char s[30 + 1]; s[0] = '\0'; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast(tolower(styler[start + i])); s[i + 1] = '\0'; } -//Platform::DebugPrintf("Scripting indicator [%s]\n", s); + //Platform::DebugPrintf("Scripting indicator [%s]\n", s); if (strstr(s, "vbs")) return eScriptVBS; if (strstr(s, "pyth")) @@ -34,18 +40,93 @@ static int segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigne return eScriptJS; if (strstr(s, "jscr")) return eScriptJS; - + if (strstr(s, "php")) + return eScriptPHP; + if (strstr(s, "xml")) + return eScriptXML; + return prevValue; } -static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || +static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) { + int iResult = 0; + char s[30 + 1]; + s[0] = '\0'; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = static_cast(tolower(styler[start + i])); + s[i + 1] = '\0'; + } + if (0 == strncmp(s, "php", 3)) { + iResult = 3; + } + + return iResult; +} + +//static int ScriptOfState(int state,int defaultScript) +static int ScriptOfState(int state) { + int scriptLanguage; + + if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { + scriptLanguage = eScriptPython; + } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { + scriptLanguage = eScriptVBS; + } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_STRINGEOL)) { + scriptLanguage = eScriptJS; + } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) { + scriptLanguage = eScriptPHP; + } else { + // scriptLanguage = defaultScript; + scriptLanguage = eScriptNone; + } + + return scriptLanguage; +} + +static int statePrintForState(int state, int inScriptType) { + int StateToPrint; + + if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { + StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON); + } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { + StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS); + } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_STRINGEOL)) { + StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS); + } else { + StateToPrint = state; + } + + return StateToPrint; +} + +static int stateForPrintState(int StateToPrint) { + int state; + + if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) { + state = StateToPrint - SCE_HA_PYTHON; + } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) { + state = StateToPrint - SCE_HA_VBS; + } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_STRINGEOL)) { + state = StateToPrint - SCE_HA_JS; + } else { + state = StateToPrint; + } + + return state; +} + +static inline bool IsNumber(unsigned int start, Accessor &styler) { + return isdigit(styler[start]) || (styler[start] == '.') || (styler[start] == '-') || (styler[start] == '#'); +} + +static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { + bool wordIsNumber = IsNumber(start, styler); char chAttr = SCE_H_ATTRIBUTEUNKNOWN; if (wordIsNumber) { chAttr = SCE_H_NUMBER; } else { - char s[100]; + char s[30 + 1]; s[0] = '\0'; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast(tolower(styler[start + i])); @@ -54,15 +135,18 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k if (keywords.InList(s)) chAttr = SCE_H_ATTRIBUTE; } + if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords) + // No keywords -> all are known + chAttr = SCE_H_ATTRIBUTE; styler.ColourTo(end, chAttr); } static int classifyTagHTML(unsigned int start, unsigned int end, - WordList &keywords, Accessor &styler) { - char s[100]; + WordList &keywords, Accessor &styler) { + char s[30 + 1]; // Copy after the '<' unsigned int i = 0; - for (unsigned int cPos=start; cPos <= end && i < 30; cPos++) { + for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) { char ch = styler[cPos]; if (ch != '<') s[i++] = static_cast(tolower(ch)); @@ -71,107 +155,71 @@ static int classifyTagHTML(unsigned int start, unsigned int end, char chAttr = SCE_H_TAGUNKNOWN; if (s[0] == '!' && s[1] == '-' && s[2] == '-') { //Comment chAttr = SCE_H_COMMENT; + } else if (strcmp(s, "![cdata[") == 0) { // In lower case because already converted + chAttr = SCE_H_CDATA; } 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; + } + if (0 == strcmp(s, "script")) { + chAttr = SCE_H_SCRIPT; } } + if ((chAttr == SCE_H_TAGUNKNOWN) && !keywords) + // No keywords -> all are known + chAttr = SCE_H_TAG; styler.ColourTo(end, chAttr); return chAttr; } static void classifyWordHTJS(unsigned int start, unsigned int end, - WordList &keywords, Accessor &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'; - } + WordList &keywords, Accessor &styler, int inScriptType) { char chAttr = SCE_HJ_WORD; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); if (wordIsNumber) chAttr = SCE_HJ_NUMBER; else { + char s[30 + 1]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } if (keywords.InList(s)) chAttr = SCE_HJ_KEYWORD; } - styler.ColourTo(end, chAttr); -} - -static void classifyWordHTJSA(unsigned int start, unsigned int end, - WordList &keywords, Accessor &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); + styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); } -static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &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] = static_cast(tolower(styler[start + i])); - s[i + 1] = '\0'; - } +static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, int inScriptType) { char chAttr = SCE_HB_IDENTIFIER; + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); if (wordIsNumber) chAttr = SCE_HB_NUMBER; else { + char s[30 + 1]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = static_cast(tolower(styler[start + i])); + s[i + 1] = '\0'; + } if (keywords.InList(s)) { chAttr = SCE_HB_WORD; if (strcmp(s, "rem") == 0) chAttr = SCE_HB_COMMENTLINE; } } - styler.ColourTo(end, chAttr); + styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); 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, Accessor &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] = static_cast(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, Accessor &styler, char *prevWord) { - char s[100]; +static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, int inScriptType) { bool wordIsNumber = isdigit(styler[start]); + char s[30 + 1]; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; s[i + 1] = '\0'; @@ -185,28 +233,50 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key chAttr = SCE_HP_NUMBER; else if (keywords.InList(s)) chAttr = SCE_HP_WORD; - styler.ColourTo(end, chAttr); + styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); strcpy(prevWord, s); } -static void classifyWordHTPyA(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) { - char s[100]; +// Update the word colour to default or keyword +// Called when in a PHP word +static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { + char chAttr = SCE_HPHP_DEFAULT; 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'; + if (wordIsNumber) + chAttr = SCE_HPHP_NUMBER; + else { + char s[30 + 1]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = styler[start + i]; + s[i + 1] = '\0'; + } + if (keywords.InList(s)) + chAttr = SCE_HPHP_WORD; } - 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); +} + +// Return the first state to reach when entering a scripting language +static int StateForScript(int scriptLanguage) { + int Result; + switch (scriptLanguage) { + case eScriptVBS: + Result = SCE_HB_START; + break; + case eScriptPython: + Result = SCE_HP_START; + break; + case eScriptPHP: + Result = SCE_HPHP_DEFAULT; + break; + case eScriptXML: + Result = SCE_H_TAGUNKNOWN; + break; + default : + Result = SCE_HJ_START; + break; + } + return Result; } inline bool ishtmlwordchar(char ch) { @@ -215,32 +285,33 @@ inline bool ishtmlwordchar(char 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; + 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[], - Accessor &styler) { - - WordList &keywords=*keywordlists[0]; - WordList &keywords2=*keywordlists[1]; - WordList &keywords3=*keywordlists[2]; - WordList &keywords4=*keywordlists[3]; - +static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + WordList &keywords4 = *keywordlists[3]; + WordList &keywords5 = *keywordlists[4]; + // 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 + int StateToPrint = initStyle; + int state = stateForPrintState(StateToPrint); + + // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen if (InTagState(state)) { while ((startPos > 1) && (InTagState(styler.StyleAt(startPos - 1)))) { startPos--; @@ -253,254 +324,419 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty 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; - + int inScriptType = (lineState >> 0) & 0x03; // 2 bits + int defaultScript = (lineState >> 4) & 0x0F; // 4 bits + int beforePreProc = (lineState >> 8) & 0xFF; // 8 bits + + // int scriptLanguage = ScriptOfState(state,defaultScript); + int scriptLanguage = ScriptOfState(state); + + bool fold = styler.GetPropertyInt("fold"); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + int visibleChars = 0; + char chPrev = ' '; - char chPrev2 = ' '; + char ch = ' '; styler.StartSegment(startPos); int lengthDoc = startPos + length; for (int i = startPos; i < lengthDoc; i++) { - char ch = styler[i]; + char chPrev2 = chPrev; + chPrev = ch; + ch = styler[i]; char chNext = styler.SafeGetCharAt(i + 1); char chNext2 = styler.SafeGetCharAt(i + 2); + // Handle DBCS codepages if (styler.IsLeadByte(ch)) { - chPrev2 = ' '; chPrev = ' '; i += 1; continue; } + if (fold && !isspace(ch)) + visibleChars++; + + // handle script folding + if (fold) { + switch (scriptLanguage) { + case eScriptJS: + case eScriptPHP: + //not currently supported case eScriptVBS: + if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC)) { + if ((ch == '{') || (ch == '}')) { + levelCurrent += (ch == '{') ? 1 : -1; + } + } + break; + case eScriptPython: + if (state != SCE_HP_COMMENTLINE) { + if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) { + levelCurrent++; + } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) { + // check if the number of tabs is lower than the level + int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8; + for (int j = 0;Findlevel > 0;j++) { + char chTmp = styler.SafeGetCharAt(i + j + 1); + if (chTmp == '\t') { + Findlevel -= 8; + } else if (chTmp == ' ') { + Findlevel--; + } else break; + } + + if (Findlevel > 0) { + levelCurrent -= Findlevel / 8; + if (Findlevel % 8) levelCurrent--; + } + } + } + break; + } + } + + // decide what is the current state to print (depending of the script tag) + StateToPrint = statePrintForState(state, inScriptType); + if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { + // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) + // Avoid triggering two times on Dos/Win // New line -> record any line state onto /next/ line + if (fold) { + int lev = levelPrev; + if (visibleChars == 0) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + styler.SetLevel(lineCurrent, lev); + visibleChars = 0; + levelPrev = levelCurrent; + } lineCurrent++; - styler.SetLineState(lineCurrent, - defaultScript | (beforeASP << 8) | (inASP << 16)); + styler.SetLineState(lineCurrent, + ((inScriptType & 0x03) << 0) | + ((defaultScript & 0x0F) << 4) | + ((beforePreProc & 0xFF) << 8)); + } + + // generic end of script processing + else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) { + // Check if it's the end of the script tag (or any other HTML tag) + switch (state) { + // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!) + case SCE_H_DOUBLESTRING: + case SCE_H_SINGLESTRING: + case SCE_HJ_COMMENT: + case SCE_HJ_COMMENTDOC: + case SCE_HJ_COMMENTLINE: + case SCE_HJ_DOUBLESTRING: + case SCE_HJ_SINGLESTRING: + case SCE_HB_STRING: + case SCE_HP_STRING: + case SCE_HP_TRIPLE: + case SCE_HP_TRIPLEDOUBLE: + break; + default : + // maybe we should check here if it's a tag and if it's SCRIPT + + styler.ColourTo(i - 1, StateToPrint); + state = SCE_H_TAGUNKNOWN; + inScriptType = eHtml; + scriptLanguage = eScriptNone; + i += 2; + continue; + } + } + + ///////////////////////////////////// + // handle the start of PHP pre-processor = Non-HTML + else if ((ch == '<') && (chNext == '?')) { + styler.ColourTo(i - 1, StateToPrint); + beforePreProc = state; + scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment() + 2, i + 10, eScriptPHP); + i++; + i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 10); + if (scriptLanguage == eScriptXML) + styler.ColourTo(i, SCE_H_XMLSTART); + else + styler.ColourTo(i, SCE_H_QUESTION); + state = StateForScript(scriptLanguage); + if (inScriptType == eNonHtmlScript) + inScriptType = eNonHtmlScriptPreProc; + else + inScriptType = eNonHtmlPreProc; + continue; } - - // Handle ASP even within other constructs as it is a preprocessor - if ((ch == '<') && (chNext == '%')) { - beforeASP = state; - styler.ColourTo(i - 1, state); + + // handle the start of ASP pre-processor = Non-HTML + else if ((ch == '<') && (chNext == '%')) { + styler.ColourTo(i - 1, StateToPrint); + beforePreProc = state; + if (inScriptType == eNonHtmlScript) + inScriptType = eNonHtmlScriptPreProc; + else + inScriptType = eNonHtmlPreProc; + if (chNext2 == '@') { - styler.ColourTo(i + 2, SCE_H_ASP); + i += 2; // place as if it was the second next char treated 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++; + i += 2; // place as if it was the second next char treated + } + else { + i++; // place as if it was the next char treated } + + + state = StateForScript(defaultScript); } - inASP = 1; + styler.ColourTo(i, SCE_H_ASP); continue; } - if (inASP && (ch == '%') && (chNext == '>')) { - if (state == SCE_H_ASPAT) - defaultScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, defaultScript); + + // handle the end of a pre-processor = Non-HTML + else if (((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && ((ch == '?') || (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); + switch (state) { + case SCE_HJ_WORD: + classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); + break; + case SCE_HB_WORD: + classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); + break; + case SCE_HP_WORD: + classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); + break; + case SCE_HPHP_WORD: + classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); + break; + default : + styler.ColourTo(i - 1, StateToPrint); + break; } - //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; + if (ch == '%') + styler.ColourTo(i, SCE_H_ASP); + else if (scriptLanguage == eScriptXML) + styler.ColourTo(i, SCE_H_XMLEND); + else + styler.ColourTo(i, SCE_H_QUESTION); + state = beforePreProc; + if (inScriptType == eNonHtmlScriptPreProc) + inScriptType = eNonHtmlScript; + else + inScriptType = eHtml; + scriptLanguage = eScriptNone; continue; } - - if (state == SCE_H_DEFAULT) { + ///////////////////////////////////// + + switch (state) { + case 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; - } + styler.ColourTo(i - 1, StateToPrint); + if (chNext == '!' && chNext2 == '-' && styler.SafeGetCharAt(i + 3) == '-') + state = SCE_H_COMMENT; + else + state = SCE_H_TAGUNKNOWN; } 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); + break; + case SCE_H_COMMENT: + if ((ch == '>') && (chPrev == '-') && (chPrev2 == '-')) { + styler.ColourTo(i, StateToPrint); + state = SCE_H_DEFAULT; + } + break; + case SCE_H_CDATA: + if ((ch == '>') && (chPrev == ']') && (chPrev2 == ']')) { + styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; } - } else if (state == SCE_H_ENTITY) { + break; + case SCE_H_ENTITY: if (ch == ';') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; } - } else if (state == SCE_H_TAGUNKNOWN) { - if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { + if (ch != '#' && !isalnum(ch)) { // Should check that '#' follows '&', but it is unlikely anyway... + styler.ColourTo(i, SCE_H_TAGUNKNOWN); + state = SCE_H_DEFAULT; + } + break; + case SCE_H_TAGUNKNOWN: + if (!ishtmlwordchar(ch) && ch != '/' && ch != '-' && ch != '[') { int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler); - lastTagWasScript = eClass == SCE_H_SCRIPT; - if (lastTagWasScript) { - scriptLanguage = eScriptJS; + if (eClass == SCE_H_SCRIPT) { + inScriptType = eNonHtmlScript; + scriptLanguage = defaultScript; 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; + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } } else { - if (eClass == SCE_H_COMMENT) { - state = SCE_H_COMMENT; + if (eClass == SCE_H_CDATA) { + state = SCE_H_CDATA; } else { state = SCE_H_OTHER; } } } - } else if (state == SCE_H_ATTRIBUTE) { + break; + case SCE_H_ATTRIBUTE: if (!ishtmlwordchar(ch) && ch != '/' && ch != '-') { - if (lastTagWasScript) - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i-1, scriptLanguage); + if (inScriptType == eNonHtmlScript) { + 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; + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } + } else if (ch == '=') { + styler.ColourTo(i, SCE_H_OTHER); + state = SCE_H_VALUE; } 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) { + break; + case SCE_H_OTHER: if (ch == '>') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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; + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_H_DOUBLESTRING; } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SINGLESTRING; + } else if (ch == '=') { + styler.ColourTo(i, StateToPrint); + state = SCE_H_VALUE; } else if (ch == '/' && chNext == '>') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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, StateToPrint); styler.ColourTo(i + 1, SCE_H_XMLEND); i++; ch = chNext; state = SCE_H_DEFAULT; } else if (ishtmlwordchar(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_H_ATTRIBUTE; } - } else if (state == SCE_H_DOUBLESTRING) { + break; + case SCE_H_DOUBLESTRING: if (ch == '\"') { - if (lastTagWasScript) + if (inScriptType == eNonHtmlScript) { scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); + } styler.ColourTo(i, SCE_H_DOUBLESTRING); state = SCE_H_OTHER; } - } else if (state == SCE_H_SINGLESTRING) { + break; + case SCE_H_SINGLESTRING: if (ch == '\'') { - if (lastTagWasScript) + if (inScriptType == eNonHtmlScript) { 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) { + break; + case SCE_H_VALUE: + if (!ishtmlwordchar(ch)) { + if (ch == '\"') { + // Should really test for being first character + state = SCE_H_DOUBLESTRING; + } else if (ch == '\'') { + state = SCE_H_SINGLESTRING; + } else { + if (IsNumber(styler.GetStartSegment(), styler)) { + styler.ColourTo(i - 1, SCE_H_NUMBER); + } else { + styler.ColourTo(i - 1, StateToPrint); + } + if (ch == '>') { + styler.ColourTo(i, SCE_H_TAG); + if (inScriptType == eNonHtmlScript) { + state = StateForScript(scriptLanguage); + } else { + state = SCE_H_DEFAULT; + } + } else { + state = SCE_H_OTHER; + } + } + } + break; + case SCE_HJ_DEFAULT: + case SCE_HJ_START: + case SCE_HJ_SYMBOLS: if (iswordstart(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_WORD; } else if (ch == '/' && chNext == '*') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); if (chNext2 == '*') state = SCE_HJ_COMMENTDOC; else state = SCE_HJ_COMMENT; } else if (ch == '/' && chNext == '/') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DOUBLESTRING; } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HJ_SYMBOLS); + styler.ColourTo(i - 1, StateToPrint); + styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); state = SCE_HJ_DEFAULT; } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HJ_START) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DEFAULT; } } - } else if (state == SCE_HJ_WORD) { + break; + case SCE_HJ_WORD: if (!iswordchar(ch)) { - classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler); + classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); //styler.ColourTo(i - 1, eHTJSKeyword); state = SCE_HJ_DEFAULT; if (ch == '/' && chNext == '*') { @@ -514,354 +750,157 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HJ_DOUBLESTRING; } else if (ch == '\'') { state = SCE_HJ_SINGLESTRING; + } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HJ_SYMBOLS); + styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); state = SCE_HJ_DEFAULT; } } - } else if (state == SCE_HJ_COMMENT) { + break; + case SCE_HJ_COMMENT: + case SCE_HJ_COMMENTDOC: if (ch == '/' && chPrev == '*') { + styler.ColourTo(i, StateToPrint); 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) { + break; + case SCE_HJ_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, SCE_HJ_COMMENTLINE); + styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType)); 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) { + break; + case SCE_HJ_DOUBLESTRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; } } else if (ch == '\"') { - styler.ColourTo(i, SCE_HJ_DOUBLESTRING); + styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; i++; ch = chNext; + } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_STRINGEOL; } - } else if (state == SCE_HJ_SINGLESTRING) { + break; + case SCE_HJ_SINGLESTRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; } } else if (ch == '\'') { - styler.ColourTo(i, SCE_HJ_SINGLESTRING); + styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; i++; ch = chNext; + } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HJ_COMMENTLINE; + i += 2; } else if (isLineEnd(ch)) { - styler.ColourTo(i-1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_STRINGEOL; } - } else if (state == SCE_HJ_STRINGEOL) { + break; + case SCE_HJ_STRINGEOL: if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DEFAULT; } else if (!isLineEnd(chNext)) { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HJ_DEFAULT; } - } else if (state == SCE_HJA_DEFAULT || state == SCE_HJA_START) { + break; + case SCE_HB_DEFAULT: + case SCE_HB_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); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_WORD; } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_COMMENTLINE; } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_COMMENTLINE; } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } } - } else if (state == SCE_HB_WORD) { + break; + case SCE_HB_WORD: if (!iswordchar(ch)) { - state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler); + state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); 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); + styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType)); state = SCE_HB_DEFAULT; } } } - } else if (state == SCE_HB_STRING) { + break; + case SCE_HB_STRING: if (ch == '\"') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HB_DEFAULT; i++; ch = chNext; } else if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_STRINGEOL; } - } else if (state == SCE_HB_COMMENTLINE) { + break; + case SCE_HB_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); 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) { + break; + case SCE_HB_STRINGEOL: if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } else if (!isLineEnd(chNext)) { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HB_DEFAULT; } - } else if (state == SCE_HBA_DEFAULT || state == SCE_HBA_START) { + break; + case SCE_HP_DEFAULT: + case SCE_HP_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); + styler.ColourTo(i - 1, StateToPrint); 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); + styler.SafeGetCharAt(i + 3) == '-') { + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_COMMENTLINE; } else if (ch == '#') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_COMMENTLINE; } else if (ch == '\"') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); if (chNext == '\"' && chNext2 == '\"') { i += 2; state = SCE_HP_TRIPLEDOUBLE; @@ -869,10 +908,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty chPrev = ' '; chNext = styler.SafeGetCharAt(i + 1); } else { + // state = statePrintForState(SCE_HP_STRING,inScriptType); state = SCE_HP_STRING; } } else if (ch == '\'') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); if (chNext == '\'' && chNext2 == '\'') { i += 2; state = SCE_HP_TRIPLE; @@ -883,17 +923,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HP_CHARACTER; } } else if (isoperator(ch)) { - styler.ColourTo(i - 1, state); - styler.ColourTo(i, SCE_HP_OPERATOR); + styler.ColourTo(i - 1, StateToPrint); + styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HP_START) { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_DEFAULT; } } - } else if (state == SCE_HP_WORD) { + break; + case SCE_HP_WORD: if (!iswordchar(ch)) { - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord); + classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); state = SCE_HP_DEFAULT; if (ch == '#') { state = SCE_HP_COMMENTLINE; @@ -918,15 +959,17 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HP_CHARACTER; } } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_HP_OPERATOR); + styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); } } - } else if (state == SCE_HP_COMMENTLINE) { + break; + case SCE_HP_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); + styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_STRING) { + break; + case SCE_HP_STRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; @@ -934,10 +977,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\"') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_CHARACTER) { + break; + case SCE_HP_CHARACTER: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; @@ -945,132 +989,111 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\'') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_TRIPLE) { + break; + case SCE_HP_TRIPLE: if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } - } else if (state == SCE_HP_TRIPLEDOUBLE) { + break; + case SCE_HP_TRIPLEDOUBLE: if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, state); + styler.ColourTo(i, StateToPrint); 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; + break; + ///////////// start - PHP state handling + case SCE_HPHP_WORD: + if (!iswordstart(ch)) { + classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); + if (ch == '/' && chNext == '*') { + i++; + state = SCE_HPHP_COMMENT; + } else if (ch == '/' && chNext == '/') { + i++; + state = SCE_HPHP_COMMENTLINE; + } else if (ch == '#') { + state = SCE_HPHP_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; - } + state = SCE_HPHP_HSTRING; } 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); + state = SCE_HPHP_SIMPLESTRING; + } else if (ch == '$') { + state = SCE_HPHP_VARIABLE; + } else { + state = SCE_HPHP_DEFAULT; } } - } else if (state == SCE_HPA_COMMENTLINE) { + break; + case SCE_HPHP_NUMBER: + if (!isdigit(ch)) { + styler.ColourTo(i - 1, SCE_HPHP_NUMBER); + state = SCE_HPHP_DEFAULT; + } + break; + case SCE_HPHP_VARIABLE: + if (!iswordstart(ch)) { + styler.ColourTo(i - 1, SCE_HPHP_VARIABLE); + state = SCE_HPHP_DEFAULT; + } + break; + case SCE_HPHP_COMMENT: + if (ch == '/' && chPrev == '*') { + styler.ColourTo(i, StateToPrint); + state = SCE_HPHP_DEFAULT; + } + break; + case SCE_HPHP_COMMENTLINE: if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, state); - state = SCE_HPA_DEFAULT; + styler.ColourTo(i - 1, StateToPrint); + state = SCE_HPHP_DEFAULT; } - } else if (state == SCE_HPA_STRING) { + break; + case SCE_HPHP_HSTRING: if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + // skip the next char i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } } else if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_HPA_DEFAULT; + styler.ColourTo(i, StateToPrint); + state = SCE_HPHP_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; + break; + case SCE_HPHP_SIMPLESTRING: + if (ch == '\'') { + styler.ColourTo(i, StateToPrint); + state = SCE_HPHP_DEFAULT; } - } else if (state == SCE_HPA_TRIPLEDOUBLE) { - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, state); - state = SCE_HPA_DEFAULT; + break; + case SCE_HPHP_DEFAULT: + styler.ColourTo(i - 1, StateToPrint); + if (isdigit(ch)) { + state = SCE_HPHP_NUMBER; + } else if (iswordstart(ch)) { + state = SCE_HPHP_WORD; + } else if (ch == '/' && chNext == '*') { + i++; + state = SCE_HPHP_COMMENT; + } else if (ch == '/' && chNext == '/') { + i++; + state = SCE_HPHP_COMMENTLINE; + } else if (ch == '#') { + state = SCE_HPHP_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_HPHP_HSTRING; + } else if (ch == '\'') { + state = SCE_HPHP_SIMPLESTRING; + } else if (ch == '$') { + state = SCE_HPHP_VARIABLE; } + break; + ///////////// end - PHP state handling } + + + if (state == SCE_HB_DEFAULT) { // One of the above succeeded if (ch == '\"') { state = SCE_HB_STRING; @@ -1081,8 +1104,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } else if (isoperator(ch)) { styler.ColourTo(i, SCE_HB_DEFAULT); } - } - if (state == SCE_HBA_DEFAULT) { // One of the above succeeded + } else if (state == SCE_HBA_DEFAULT) { // One of the above succeeded if (ch == '\"') { state = SCE_HBA_STRING; } else if (ch == '\'') { @@ -1092,8 +1114,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty } else if (isoperator(ch)) { styler.ColourTo(i, SCE_HBA_DEFAULT); } - } - if (state == SCE_HJ_DEFAULT) { // One of the above succeeded + } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded if (ch == '/' && chNext == '*') { if (styler.SafeGetCharAt(i + 2) == '*') state = SCE_HJ_COMMENTDOC; @@ -1111,29 +1132,20 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty 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); + + StateToPrint = statePrintForState(state, inScriptType); + styler.ColourTo(lengthDoc - 1, StateToPrint); + + // 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 lmHTML(SCLEX_HTML, ColouriseHyperTextDoc); LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc); + diff --git a/src/stc/scintilla/src/LexLua.cxx b/src/stc/scintilla/src/LexLua.cxx new file mode 100644 index 0000000000..e6da7668dd --- /dev/null +++ b/src/stc/scintilla/src/LexLua.cxx @@ -0,0 +1,298 @@ +// LexLua.cxx - lexer for Lua language +// Written by Paul Winwood + +#include +#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 classifyWordLua(unsigned int start, unsigned int end, WordList &keywords, Accessor &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_LUA_IDENTIFIER; + + if (wordIsNumber) + chAttr = SCE_LUA_NUMBER; + else + { + if (keywords.InList(s)) + { + chAttr = SCE_LUA_WORD; + } + } + styler.ColourTo(end, chAttr); +} + +static void ColouriseLuaDoc(unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler) +{ + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + styler.GetLine(startPos); + + int state = initStyle; + char chPrev = ' '; + char chNext = styler[startPos]; + unsigned int lengthDoc = startPos + length; + bool firstChar = true; + int literalString = 0; + + styler.StartSegment(startPos); + for (unsigned int i = startPos; i <= lengthDoc; i++) + { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if (styler.IsLeadByte(ch)) + { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_LUA_STRINGEOL) + { + if (ch != '\r' && ch != '\n') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_DEFAULT; + } + } + + if (state == SCE_LUA_LITERALSTRING && ch == '[' && chNext == '[') + { + literalString++; + } + else + if (state == SCE_LUA_DEFAULT) + { + if (ch == '-' && chNext == '-') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_COMMENTLINE; + } + else + if (ch == '[' && chNext == '[') + { + state = SCE_LUA_LITERALSTRING; + literalString = 1; + } + else + if (iswordstart(ch)) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_WORD; + } + else + if (ch == '\"') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_STRING; + } + else + if (ch == '\'') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_CHARACTER; + } + else + if (ch == '$' && firstChar) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_PREPROCESSOR; + } + else + if (isoperator(ch)) + { + styler.ColourTo(i-1, state); + styler.ColourTo(i, SCE_LUA_OPERATOR); + } + } + else + if (state == SCE_LUA_WORD) + { + if (!iswordchar(ch)) + { + classifyWordLua(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_LUA_DEFAULT; + if (ch == '[' && chNext == '[') + { + literalString = 1; + state = SCE_LUA_LITERALSTRING; + } + else + if (ch == '-' && chNext == '-') + { + state = SCE_LUA_COMMENTLINE; + } + else + if (ch == '\"') + { + state = SCE_LUA_STRING; + } + else + if (ch == '\'') + { + state = SCE_LUA_CHARACTER; + } + else + if (ch == '$' && firstChar) + { + state = SCE_LUA_PREPROCESSOR; + } + else + if (isoperator(ch)) + { + styler.ColourTo(i, SCE_LUA_OPERATOR); + } + } + } + else + { + if (state == SCE_LUA_LITERALSTRING) + { + if (ch == ']' && (chPrev == ']') && (--literalString == 0)) + { + styler.ColourTo(i, state); + state = SCE_LUA_DEFAULT; + } + } + else + if (state == SCE_LUA_PREPROCESSOR) + { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_DEFAULT; + } + } + else + if (state == SCE_LUA_COMMENTLINE) + { + if (ch == '\r' || ch == '\n') + { + styler.ColourTo(i-1, state); + state = SCE_LUA_DEFAULT; + } + } + else + if (state == SCE_LUA_STRING) + { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_STRINGEOL; + } + else + if (ch == '\\') + { + if (chNext == '\"' || chNext == '\\') + { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + else + if (ch == '\"') + { + styler.ColourTo(i, state); + state = SCE_LUA_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + else + if (state == SCE_LUA_CHARACTER) + { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) + { + styler.ColourTo(i-1, state); + state = SCE_LUA_STRINGEOL; + } + else + if (ch == '\\') + { + if (chNext == '\'' || chNext == '\\') + { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + else + if (ch == '\'') + { + styler.ColourTo(i, state); + state = SCE_LUA_DEFAULT; + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } + + if (state == SCE_LUA_DEFAULT) + { + if (ch == '-' && chNext == '-') + { + state = SCE_LUA_COMMENTLINE; + } + else + if (ch == '\"') + { + state = SCE_LUA_STRING; + } + else + if (ch == '\'') + { + state = SCE_LUA_CHARACTER; + } + else + if (ch == '$' && firstChar) + { + state = SCE_LUA_PREPROCESSOR; + } + else + if (iswordstart(ch)) + { + state = SCE_LUA_WORD; + } + else + if (isoperator(ch)) + { + styler.ColourTo(i, SCE_LUA_OPERATOR); + } + } + } + chPrev = ch; + firstChar = (ch == '\r' || ch == '\n'); + } + styler.ColourTo(lengthDoc - 1, state); +} + +LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc); diff --git a/src/stc/scintilla/src/LexOthers.cxx b/src/stc/scintilla/src/LexOthers.cxx index 90f41e3bf3..dd86033687 100644 --- a/src/stc/scintilla/src/LexOthers.cxx +++ b/src/stc/scintilla/src/LexOthers.cxx @@ -49,6 +49,46 @@ static void ColouriseBatchDoc(unsigned int startPos, int length, int, WordList * ColouriseBatchLine(lineBuffer, startPos + length, styler); } +static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) { + // It is needed to remember the current state to recognize starting + // comment lines before the first "diff " or "--- ". If a real + // difference starts then each line starting with ' ' is a whitespace + // otherwise it is considered a comment (Only in..., Binary file...) + if (0 == strncmp(lineBuffer, "diff ", 3)) { + styler.ColourTo(endLine, 2); + } else if (0 == strncmp(lineBuffer, "--- ", 3)) { + styler.ColourTo(endLine, 3); + } else if (0 == strncmp(lineBuffer, "+++ ", 3)) { + styler.ColourTo(endLine, 3); + } else if (lineBuffer[0] == '@') { + styler.ColourTo(endLine, 4); + } else if (lineBuffer[0] == '-') { + styler.ColourTo(endLine, 5); + } else if (lineBuffer[0] == '+') { + styler.ColourTo(endLine, 6); + } else if (lineBuffer[0] != ' ') { + styler.ColourTo(endLine, 1); + } else { + styler.ColourTo(endLine, 0); + } +} + +static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &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)) { + ColouriseDiffLine(lineBuffer, i, styler); + linePos = 0; + } + } + if (linePos > 0) + ColouriseDiffLine(lineBuffer, startPos + length, styler); +} + static void ColourisePropsLine(char *lineBuffer, int lengthLine, int startLine, int endPos, Accessor &styler) { int i = 0; while (isspace(lineBuffer[i]) && (i < lengthLine)) // Skip initial spaces @@ -126,15 +166,21 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, Accessor &styler) { if (lineBuffer[0] == '>') { // Command or return status - styler.ColourTo(endPos, 4); + styler.ColourTo(endPos, SCE_ERR_CMD); } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { - styler.ColourTo(endPos, 1); + styler.ColourTo(endPos, SCE_ERR_PYTHON); } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) { // Borland error message - styler.ColourTo(endPos, 5); + styler.ColourTo(endPos, SCE_ERR_BORLAND); } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) { // Borland warning message - styler.ColourTo(endPos, 5); + styler.ColourTo(endPos, SCE_ERR_BORLAND); + } else if (strstr(lineBuffer, " at " ) && + strstr(lineBuffer, " at " ) < lineBuffer+lengthLine && + strstr(lineBuffer, " line ") && + strstr(lineBuffer, " line ") < lineBuffer+lengthLine) { + // perl error message + styler.ColourTo(endPos, SCE_ERR_PERL); } else { // Look for ::message // Look for (line)message @@ -168,11 +214,11 @@ static void ColouriseErrorListLine(char *lineBuffer, int lengthLine, int endPos, } } if (state == 3) { - styler.ColourTo(endPos, 2); + styler.ColourTo(endPos, SCE_ERR_GCC); } else if ((state == 13) || (state == 14) || (state == 15)) { - styler.ColourTo(endPos, 3); + styler.ColourTo(endPos, SCE_ERR_MS); } else { - styler.ColourTo(endPos, 0); + styler.ColourTo(endPos, SCE_ERR_DEFAULT); } } } @@ -297,8 +343,9 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, styler.ColourTo(lengthDoc, state); } +LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc); +LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc); LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc); -LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc); LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc); -LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc); +LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc); LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc); diff --git a/src/stc/scintilla/src/LexPerl.cxx b/src/stc/scintilla/src/LexPerl.cxx index 3c9972e2d6..a7186fe552 100644 --- a/src/stc/scintilla/src/LexPerl.cxx +++ b/src/stc/scintilla/src/LexPerl.cxx @@ -107,7 +107,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, state = SCE_PL_DEFAULT; } styler.StartAt(startPos); - char chPrev = ' '; + char chPrev = styler.SafeGetCharAt(startPos - 1); char chNext = styler[startPos]; styler.StartSegment(startPos); for (int i = startPos; i < lengthDoc; i++) { @@ -230,7 +230,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, quotes = 0; sookedpos = 0; sooked[sookedpos] = '\0'; - } else if (ch == '=' && isalpha(chNext)) { + } else if (ch == '=' && (chPrev == '\r' || chPrev == '\n') && isalpha(chNext)) { styler.ColourTo(i - 1, state); state = SCE_PL_POD; quotes = 0; @@ -284,7 +284,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, state = SCE_PL_DEFAULT; } } else if (state == SCE_PL_HERE) { - if (isalnum(ch) && quotes < 2) { + if ((isalnum(ch) || ch == '_') && quotes < 2) { sooked[sookedpos++] = ch; sooked[sookedpos] = '\0'; if (quotes == 0) @@ -292,14 +292,17 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, } else { quotes++; } - if (quotes > 1 && isMatch(styler, lengthDoc, i, sooked) && (chPrev == '\n' || chPrev == '\r') ) { - styler.ColourTo(i + sookedpos - 1, SCE_PL_HERE); + if ((quotes > 1) && + (chPrev == '\n' || chPrev == '\r') && + isMatch(styler, lengthDoc, i, sooked)) { i += sookedpos; chNext = styler.SafeGetCharAt(i); if (chNext == '\n' || chNext == '\r') { + styler.ColourTo(i - 1, SCE_PL_HERE); state = SCE_PL_DEFAULT; } - chNext = ' '; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); } } else if (state == SCE_PL_STRING) { if (ch == '\\') { @@ -338,13 +341,13 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, chNext = styler.SafeGetCharAt(i + 1); } } else if (state == SCE_PL_POD) { - if (ch == '=') { + if (ch == '=' && (chPrev == '\r' || chPrev == '\n')) { if (isMatch(styler, lengthDoc, i, "=cut")) { styler.ColourTo(i - 1 + 4, state); i += 4; state = SCE_PL_DEFAULT; - chNext = ' '; - ch = ' '; + ch = styler.SafeGetCharAt(i); + chNext = styler.SafeGetCharAt(i + 1); } } } else if (state == SCE_PL_SCALAR) { @@ -409,7 +412,32 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle, quoteDown = opposite(ch); quotes++; } else { - if (ch == quoteDown && chPrev != '\\') { + if (quotes == 0 && quoteRep == 1) { + /* We matched something like s(...) or tr{...} + * and are looking for the next matcher characters, + * which could be either bracketed ({...}) or non-bracketed + * (/.../). + * + * Number-signs are problematic. If they occur after + * the close of the first part, treat them like + * a quoteUp char, even if they actually start comments. + * + * If we find an alnum, we end the regsubst, and punt. + * + * Eric Promislow ericp@activestate.com Aug 9,2000 + */ + if (isspace(ch)) { + // Keep going + } else if (isalnum(ch)) { + styler.ColourTo(i, state); + state = SCE_PL_DEFAULT; + ch = ' '; + } else { + quoteUp = ch; + quoteDown = opposite(ch); + quotes++; + } + } else if (ch == quoteDown && chPrev != '\\') { quotes--; if (quotes == 0) { quoteRep--; diff --git a/src/stc/scintilla/src/LexPython.cxx b/src/stc/scintilla/src/LexPython.cxx index df8b7085bf..492d21c7d9 100644 --- a/src/stc/scintilla/src/LexPython.cxx +++ b/src/stc/scintilla/src/LexPython.cxx @@ -33,6 +33,13 @@ static void ClassifyWordPy(unsigned int start, unsigned int end, WordList &keywo chAttr = SCE_P_NUMBER; else if (keywords.InList(s)) chAttr = SCE_P_WORD; + // make sure that dot-qualifiers inside the word are lexed correct + else for (unsigned int i = 0; i < end - start + 1; i++) { + if (styler[start + i] == '.') { + styler.ColourTo(start + i - 1, chAttr); + styler.ColourTo(start + i, SCE_P_OPERATOR); + } + } styler.ColourTo(end, chAttr); strcpy(prevWord, s); } diff --git a/src/stc/scintilla/src/LexVB.cxx b/src/stc/scintilla/src/LexVB.cxx index acc3b0d548..67dfa78427 100644 --- a/src/stc/scintilla/src/LexVB.cxx +++ b/src/stc/scintilla/src/LexVB.cxx @@ -20,20 +20,21 @@ static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') || + (styler[start] == '&' && tolower(styler[start+1]) == 'h'); + unsigned int i; + for (i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast(tolower(styler[start + i])); - s[i + 1] = '\0'; } + s[i] = '\0'; char chAttr = SCE_C_DEFAULT; if (wordIsNumber) chAttr = SCE_C_NUMBER; else { - if (keywords.InList(s)) { + if (strcmp(s, "rem") == 0) + chAttr = SCE_C_COMMENTLINE; + 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) @@ -49,6 +50,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, styler.StartAt(startPos); + int visibleChars = 0; int state = initStyle; char chNext = styler[startPos]; styler.StartSegment(startPos); @@ -63,6 +65,17 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, continue; } + if (ch == '\r' || ch == '\n') { + // End of line + if (state == SCE_C_COMMENTLINE || state == SCE_C_PREPROCESSOR) { + styler.ColourTo(i - 1, state); + state = SCE_C_DEFAULT; + } + visibleChars = 0; + } + if (!isspace(ch)) + visibleChars++; + if (state == SCE_C_DEFAULT) { if (iswordstart(ch)) { styler.ColourTo(i - 1, state); @@ -73,6 +86,16 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, } else if (ch == '\"') { styler.ColourTo(i - 1, state); state = SCE_C_STRING; + } else if (ch == '#' && visibleChars == 1) { + // Preprocessor commands are alone on their line + styler.ColourTo(i - 1, state); + state = SCE_C_PREPROCESSOR; + } else if (ch == '&' && tolower(chNext) == 'h') { + styler.ColourTo(i - 1, state); + state = SCE_C_WORD; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_C_OPERATOR); } } else if (state == SCE_C_WORD) { if (!iswordchar(ch)) { @@ -82,16 +105,14 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, state = SCE_C_COMMENTLINE; } else if (ch == '\"') { state = SCE_C_STRING; + } else if (isoperator(ch)) { + styler.ColourTo(i - 1, state); + styler.ColourTo(i, SCE_C_OPERATOR); } } } } 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 (state == SCE_C_STRING) { // VB doubles quotes to preserve them if (ch == '\"') { styler.ColourTo(i, state); diff --git a/src/stc/scintilla/src/PosRegExp.cxx b/src/stc/scintilla/src/PosRegExp.cxx new file mode 100644 index 0000000000..ea719b7c28 --- /dev/null +++ b/src/stc/scintilla/src/PosRegExp.cxx @@ -0,0 +1,1181 @@ +#include +#include +#include +#include + +#include "PosRegExp.h" + +//Up: /[A-Z \x80-\x9f \xf0 ]/x +//Lo: /[a-z \xa0-\xaf \xe0-\xef \xf1 ]/x +//Wd: /[\d _ A-Z a-z \xa0-\xaf \xe0-\xf1 \x80-\x9f]/x +//* // Dos866 +SCharData UCData = {0x0, 0x0, 0x7fffffe, 0x0, 0xffffffff, 0x0, 0x0, 0x10000}, + LCData = {0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0xffff, 0x0, 0x2ffff}, + WdData = {0x0, 0x3ff0000, 0x87fffffe, 0x7fffffe, 0xffffffff, 0xffff, 0x0, 0x3ffff}, + DigData = {0x0, 0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/*/ // cp1251 +SCharData UCData = {0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0xffffffff, 0x0}, + LCData = {0x0, 0x0, 0x0, 0x7fffffe, 0x0, 0x0, 0x0, 0xffffffff}, + WdData = {0x0, 0x3ff0000, 0x87fffffe, 0x7fffffe, 0x0, 0x0, 0xffffffff, 0xffffffff}, + DigData = {0x0, 0x3ff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +//*/ + +/////////////////////////////////////////////// + +int GetNumber(int *str,int s,int e) { + int r = 1, num = 0; + if (e < s) return -1; + for(int i = e-1; i >= s; i--) { + if (str[i] > '9' || str[i] < '0') return -1; + num += (str[i] - 0x30)*r; + r *= 10; + }; + return num; + /* + char tmp[20]; + double Res; + if (e == s) return -1; + for (int i = s;i < e;i++) + tmp[i-s] = (char)Str[i]; + tmp[e-s] = 0; + GetNumber(tmp,&Res); + return (int)Res; + */ +}; + +bool IsDigit(char Symb) { + return DigData.GetBit(Symb); +}; +bool IsWord(char Symb) { + return WdData.GetBit(Symb); +}; +bool IsUpperCase(char Symb) { + return UCData.GetBit(Symb); +}; +bool IsLowerCase(char Symb) { + return LCData.GetBit(Symb); +}; +char LowCase(char Chr) { + if (UCData.GetBit(Chr)) + return Chr+0x20; + return Chr; +}; + +/////////////////////////////////////////////// + +SRegInfo::SRegInfo() { + Next = Parent = 0; + un.Param = 0; + Op = ReEmpty; +}; +SRegInfo::~SRegInfo() { + if (Next) delete Next; + if (un.Param) + switch(Op) { + case ReEnum: + case ReNEnum: + delete un.ChrClass; + break; + default: + if (Op > ReBlockOps && Op < ReSymbolOps || Op == ReBrackets) + delete un.Param; + break; + }; +}; + +/////////////////////////////////////////////// + +void SCharData::SetBit(unsigned char Bit) { + int p = Bit/8; + CArr[p] |= (1 << Bit%8); +}; +void SCharData::ClearBit(unsigned char Bit) { + int p = Bit/8; + CArr[p] &= ~(1 << Bit%8); +}; +bool SCharData::GetBit(unsigned char Bit) { + int p = (unsigned char)Bit/8; + return (CArr[p] & (1 << Bit%8))!=0; +}; + +///////////////////////////////////////////////////////////////// +////////////////////// RegExp Class /////////////////////////// +///////////////////////////////////////////////////////////////// + +PosRegExp::PosRegExp() { + Info = 0; + Exprn = 0; + NoMoves = false; + Error = true; + FirstChar = 0; + CurMatch = 0; +}; +PosRegExp::~PosRegExp() { + if (Info) delete Info; +}; + +bool PosRegExp::SetExpr(const char *Expr) { + if (!this) return false; + Error = true; + CurMatch = 0; + if (SetExprLow(Expr)) Error = false; + return !Error; +}; +bool PosRegExp::isok() { + return !Error; +}; + + +bool PosRegExp::SetExprLow(const char *Expr) { + int Len = strlen(Expr); + bool Ok = false; + int i,j,s = 0,pos,tmp; + int EnterBr = 0,EnterGr = 0,EnterFg = 0; + + if (Info) delete Info; + Info = new SRegInfo; + Exprn = new int[Len]; + + NoCase = false; + Extend = false; + if (Expr[0] == '/') s++; + else return false; + + for (i = Len; i > 0 && !Ok;i--) + if (Expr[i] == '/') { + Len = i-s; + Ok = true; + for (int j = i+1; Expr[j]; j++) { + if (Expr[j] == 'i') NoCase = true; + if (Expr[j] == 'x') Extend = true; + }; + }; + if (!Ok) return false; + + //////////////////////////////// + for (j = 0,pos = 0; j < Len; j++,pos++) { + if (Extend && Expr[j+s] == ' ') { + pos--; + continue; + }; + + Exprn[pos] = (int)(unsigned char)Expr[j+s]; + + if (Expr[j+s] == BackSlash) { + switch (Expr[j+s+1]) { + case 'd': + Exprn[pos] = ReDigit; + break; + case 'D': + Exprn[pos] = ReNDigit; + break; + case 'w': + Exprn[pos] = ReWordSymb; + break; + case 'W': + Exprn[pos] = ReNWordSymb; + break; + case 's': + Exprn[pos] = ReWSpace; + break; + case 'S': + Exprn[pos] = ReNWSpace; + break; + case 'u': + Exprn[pos] = ReUCase; + break; + case 'l': + Exprn[pos] = ReNUCase; + break; + case 't': + Exprn[pos] = '\t'; + break; + case 'n': + Exprn[pos] = '\n'; + break; + case 'r': + Exprn[pos] = '\r'; + break; + case 'b': + Exprn[pos] = ReWBound; + break; + case 'B': + Exprn[pos] = ReNWBound; + break; + case 'c': + Exprn[pos] = RePreNW; + break; + case 'm': + Exprn[pos] = ReStart; + break; + case 'M': + Exprn[pos] = ReEnd; + break; + case 'x': + tmp = toupper(Expr[j+s+2])-0x30; + tmp = (tmp>9?tmp-7:tmp)<<4; + tmp += (toupper(Expr[j+s+3])-0x30)>9?toupper(Expr[j+s+3])-0x37:(toupper(Expr[j+s+3])-0x30); + Exprn[pos] = tmp; + j+=2; + break; + case 'y': + tmp = Expr[j+s+2] - 0x30; + if (tmp >= 0 && tmp <= 9) { + if (tmp == 1) { + tmp = 10 + Expr[j+s+3] - 0x30; + if (tmp >= 10 && tmp <= 19) j++; + else tmp = 1; + }; + Exprn[pos] = ReBkTrace + tmp; + j++; + break; + }; + default: + tmp = Expr[j+s+1] - 0x30; + if (tmp >= 0 && tmp <= 9) { + if (tmp == 1) { + tmp = 10 + Expr[j+s+2] - 0x30; + if (tmp >= 10 && tmp <= 19) j++; + else tmp = 1; + }; + Exprn[pos] = ReBkBrack + tmp; + break; + } else + Exprn[pos] = Expr[j+s+1]; + break; + }; + j++; + continue; + }; + if (Expr[j+s] == ']') { + Exprn[pos] = ReEnumE; + if (EnterFg || !EnterGr) return false; + EnterGr--; + }; + if (Expr[j+s] == '-' && EnterGr) Exprn[pos] = ReFrToEnum; + + if (EnterGr) continue; + + if (Expr[j+s] == '[' && Expr[j+s+1] == '^') { + Exprn[pos] = ReNEnumS; + if (EnterFg) return false; + EnterGr++; + j++; + continue; + }; + if (Expr[j+s] == '*' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGMul; + j++; + continue; + }; + if (Expr[j+s] == '+' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGPlus; + j++; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGQuest; + j++; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '#' && + Expr[j+s+2]>='0' && Expr[j+s+2]<='9') { + Exprn[pos] = ReBehind+Expr[j+s+2]-0x30; + j+=2; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '~' && + Expr[j+s+2]>='0' && Expr[j+s+2]<='9') { + Exprn[pos] = ReNBehind+Expr[j+s+2]-0x30; + j+=2; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '=') { + Exprn[pos] = ReAhead; + j++; + continue; + }; + if (Expr[j+s] == '?' && Expr[j+s+1] == '!') { + Exprn[pos] = ReNAhead; + j++; + continue; + }; + + if (Expr[j+s] == '(') { + Exprn[pos] = ReLBrack; + if (EnterFg) return false; + EnterBr++; + }; + if (Expr[j+s] == ')') { + Exprn[pos] = ReRBrack; + if (!EnterBr || EnterFg) return false; + EnterBr--; + }; + if (Expr[j+s] == '[') { + Exprn[pos] = ReEnumS; + if (EnterFg) return false; + EnterGr++; + }; + if (Expr[j+s] == '{') { + Exprn[pos] = ReRangeS; + if (EnterFg) return false; + EnterFg++; + }; + if (Expr[j+s] == '}' && Expr[j+s+1] == '?') { + Exprn[pos] = ReNGRangeE; + if (!EnterFg) return false; + EnterFg--; + j++; + continue; + }; + if (Expr[j+s] == '}') { + Exprn[pos] = ReRangeE; + if (!EnterFg) return false; + EnterFg--; + }; + + if (Expr[j+s] == '^') Exprn[pos] = ReSoL; + if (Expr[j+s] == '$') Exprn[pos] = ReEoL; + if (Expr[j+s] == '.') Exprn[pos] = ReAnyChr; + if (Expr[j+s] == '*') Exprn[pos] = ReMul; + if (Expr[j+s] == '+') Exprn[pos] = RePlus; + if (Expr[j+s] == '?') Exprn[pos] = ReQuest; + if (Expr[j+s] == '|') Exprn[pos] = ReOr; + }; + if (EnterGr || EnterBr || EnterFg) return false; + + Info->Op = ReBrackets; + Info->un.Param = new SRegInfo; + Info->s = CurMatch++; + + if (!SetStructs(Info->un.Param,0,pos)) return false; + Optimize(); + delete Exprn; + return true; +}; + +void PosRegExp::Optimize() { + PRegInfo Next = Info; + FirstChar = 0; + while(Next) { + if (Next->Op == ReBrackets || Next->Op == RePlus || Next->Op == ReNGPlus) { + Next = Next->un.Param; + continue; + }; + if (Next->Op == ReSymb) { + if (Next->un.Symb & 0xFF00 && Next->un.Symb != ReSoL && Next->un.Symb != ReWBound) + break; + FirstChar = Next->un.Symb; + break; + }; + break; + }; +}; + +bool PosRegExp::SetStructs(PRegInfo &re,int start,int end) { + PRegInfo Next,Prev,Prev2; + int comma,st,en,ng,i, j,k; + int EnterBr; + bool Add; + + if (end - start < 0) return false; + Next = re; + for (i = start; i < end; i++) { + Add = false; + // Ops + if (Exprn[i] > ReBlockOps && Exprn[i] < ReSymbolOps) { + Next->un.Param = 0; + Next->Op = (EOps)Exprn[i]; + Add = true; + }; + // {n,m} + if (Exprn[i] == ReRangeS) { + st = i; + en = -1; + comma = -1; + ng = 0; + for (j = i;j < end;j++) { + if (Exprn[j] == ReNGRangeE) { + en = j; + ng = 1; + break; + }; + if (Exprn[j] == ReRangeE) { + en = j; + break; + }; + if ((char)Exprn[j] == ',') + comma = j; + }; + if (en == -1) return false; + if (comma == -1) comma = en; + Next->s = (char)GetNumber(Exprn,st+1,comma); + if (comma != en) + Next->e = (char)GetNumber(Exprn,comma+1,en); + else + Next->e = Next->s; + Next->un.Param = 0; + Next->Op = ng?ReNGRangeNM:ReRangeNM; + if (en-comma == 1) { + Next->e = -1; + Next->Op = ng?ReNGRangeN:ReRangeN; + }; + i=j; + Add = true; + }; + // [] [^] + if (Exprn[i] == ReEnumS || Exprn[i] == ReNEnumS) { + Next->Op = (Exprn[i] == ReEnumS)?ReEnum:ReNEnum; + for (j = i+1;j < end;j++) { + if (Exprn[j] == ReEnumE) + break; + }; + if (j == end) return false; + Next->un.ChrClass = new SCharData; + memset(Next->un.ChrClass, 0, 32); + for (j = i+1;Exprn[j] != ReEnumE;j++) { + if (Exprn[j+1] == ReFrToEnum) { + for (i = (Exprn[j]&0xFF); i < (Exprn[j+2]&0xFF);i++) + Next->un.ChrClass->SetBit(i&0xFF); + j++; + continue; + }; + switch(Exprn[j]) { + case ReDigit: + for (k = 0x30;k < 0x40;k++) + if (IsDigit((char)k)) + Next->un.ChrClass->SetBit(k); + break; + case ReNDigit: + for (k = 0x30;k < 0x40;k++) + if (!IsDigit((char)k)) + Next->un.ChrClass->SetBit(k); + Next->un.ChrClass->ClearBit(0x0a); + Next->un.ChrClass->ClearBit(0x0d); + break; + case ReWordSymb: + for (k = 0;k < 256;k++) + if (IsWord((char)k)) + Next->un.ChrClass->SetBit(k); + break; + case ReNWordSymb: + for (k = 0;k < 256;k++) + if (!IsWord((char)k)) + Next->un.ChrClass->SetBit(k); + Next->un.ChrClass->ClearBit(0x0a); + Next->un.ChrClass->ClearBit(0x0d); + break; + case ReWSpace: + Next->un.ChrClass->SetBit(0x20); + Next->un.ChrClass->SetBit(0x09); + break; + case ReNWSpace: + memset(Next->un.ChrClass->IArr, 0xFF, 32); + Next->un.ChrClass->ClearBit(0x20); + Next->un.ChrClass->ClearBit(0x09); + Next->un.ChrClass->ClearBit(0x0a); + Next->un.ChrClass->ClearBit(0x0d); + break; + default: + if (!(Exprn[j]&0xFF00)) + Next->un.ChrClass->SetBit(Exprn[j]&0xFF); + break; + }; + }; + Add = true; + i=j; + }; + // ( ... ) + if (Exprn[i] == ReLBrack) { + EnterBr = 1; + for (j = i+1;j < end;j++) { + if (Exprn[j] == ReLBrack) EnterBr++; + if (Exprn[j] == ReRBrack) EnterBr--; + if (!EnterBr) break; + }; + if (EnterBr) return false; + Next->Op = ReBrackets; + Next->un.Param = new SRegInfo; + Next->un.Param->Parent = Next; + Next->s = CurMatch++; + if (CurMatch > MatchesNum) CurMatch = MatchesNum; + if (!SetStructs(Next->un.Param,i+1,j)) return false; + Add = true; + i=j; + }; + if ((Exprn[i]&0xFF00) == ReBkTrace) { + Next->Op = ReBkTrace; + Next->un.Symb = Exprn[i]&0xFF; + Add = true; + }; + if ((Exprn[i]&0xFF00) == ReBkBrack) { + Next->Op = ReBkBrack; + Next->un.Symb = Exprn[i]&0xFF; + Add = true; + }; + if ((Exprn[i]&0xFF00) == ReBehind) { + Next->Op = ReBehind; + Next->s = Exprn[i]&0xFF; + Add = true; + }; + if ((Exprn[i]&0xFF00) == ReNBehind) { + Next->Op = ReNBehind; + Next->s = Exprn[i]&0xFF; + Add = true; + }; + // Chars + if (Exprn[i] >= ReAnyChr && Exprn[i] < ReTemp || Exprn[i] < 0x100) { + Next->Op = ReSymb; + Next->un.Symb = Exprn[i]; + Add = true; + }; + // Next + if (Add && i != end-1) { + Next->Next = new SRegInfo; + Next->Next->Parent = Next->Parent; + Next = Next->Next; + }; + }; + Next = re; + Prev = Prev2 = 0; + while(Next) { + if (Next->Op > ReBlockOps && Next->Op < ReSymbolOps) { + if (!Prev) return false; + if (!Prev2) re = Next; + else Prev2->Next = Next; + //if (Prev->Op > ReBlockOps && Prev->Op < ReSymbolOps) return false; + Prev->Parent = Next; + Prev->Next = 0; + Next->un.Param = Prev; + Prev = Prev2; + }; + Prev2 = Prev; + Prev = Next; + Next = Next->Next; + }; + + return true; +}; + +///////////////////////////////////////////////////////////////// +///////////////////////// Parsing ///////////////////////////// +///////////////////////////////////////////////////////////////// + +bool PosRegExp::CheckSymb(int Symb,bool Inc) { + bool Res; + char ch; + switch(Symb) { + case ReAnyChr: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReSoL: + if (posStart == posParse) + return true; + ch = CharAt(posParse-1,param); + return ch == '\n' || ch == '\r'; + case ReEoL: + if (posEnd == posParse) + return true; + ch = CharAt(posParse,param); + return ch == '\n' || ch == '\r'; + case ReDigit: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = (ch >= 0x30 && ch <= 0x39); + if (Res && Inc) posParse++; + return Res; + case ReNDigit: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = !(ch >= 0x30 && ch <= 0x39) && ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReWordSymb: + if (posParse >= posEnd) return false; + Res = IsWord(CharAt(posParse,param)); + if (Res && Inc) posParse++; + return Res; + case ReNWordSymb: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = !IsWord(ch) && ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReWSpace: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = (ch == 0x20 || ch == '\t'); + if (Res && Inc) posParse++; + return Res; + case ReNWSpace: + if (posParse >= posEnd) return false; + ch = CharAt(posParse,param); + Res = !(ch == 0x20 || ch == '\t') && ch != '\r' && ch != '\n'; + if (Res && Inc) posParse++; + return Res; + case ReUCase: + if (posParse >= posEnd) return false; + Res = IsUpperCase(CharAt(posParse,param)); + if (Res && Inc) posParse++; + return Res; + case ReNUCase: + if (posParse >= posEnd) return false; + Res = IsLowerCase(CharAt(posParse,param)); + if (Res && Inc) posParse++; + return Res; + case ReWBound: + if (posParse >= posEnd) return true; + ch = CharAt(posParse,param); + return IsWord(CharAt(posParse,param)) && (posParse == posStart || !IsWord(CharAt(posParse-1,param))); + case ReNWBound: + if (posParse >= posEnd) return true; + return !IsWord(CharAt(posParse,param)) && IsWord(CharAt(posParse-1,param)); + case RePreNW: + if (posParse >= posEnd) return true; + return (posParse == posStart || !IsWord(CharAt(posParse-1,param))); + case ReStart: + Matches->s[0] = (posParse-posStart); + return true; + case ReEnd: + Matches->e[0] = (posParse-posStart); + return true; + default: + if ((Symb & 0xFF00) || posParse >= posEnd) return false; + if (NoCase) { + if (LowCase(CharAt(posParse,param)) != LowCase((char)Symb&0xFF)) return false; + } else + if (CharAt(posParse,param) != (char)(Symb&0xFF)) return false; + if (Inc) posParse++; + return true; + }; +} + +bool PosRegExp::LowParseRe(PRegInfo &Next) { + PRegInfo OrNext; + int i,match,sv; + int posStr; + + switch(Next->Op) { + case ReSymb: + if (!CheckSymb(Next->un.Symb,true)) return false; + break; + case ReEmpty: + break; + case ReBkTrace: + if (!posBkStr | !BkTrace) return false; + sv = Next->un.Symb; + posStr = posParse; + for (i = BkTrace->s[sv]; i < BkTrace->e[sv]; i++) { + if (CharAt(posStr,param) != CharAt(posBkStr+i,param) || posEnd == posStr) return false; + posStr++; + }; + posParse = posStr; + break; + case ReBkBrack: + sv = Next->un.Symb; + posStr = posParse; + if (Matches->s[sv] == -1 || Matches->e[sv] == -1) return false; + for (i = Matches->s[sv]; i < Matches->e[sv]; i++) { + if (CharAt(posStr,param) != CharAt(posStart+i,param) || posEnd == posStr) return false; + posStr++; + }; + posParse = posStr; + break; + case ReBehind: + sv = Next->s; + posStr = posParse; + posParse -= sv; + if (!LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReNBehind: + sv = Next->s; + posStr = posParse; + posParse -= sv; + if (LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReAhead: + posStr = posParse; + if (!LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReNAhead: + posStr = posParse; + if (LowParse(Next->un.Param)) return false; + posParse = posStr; + break; + case ReEnum: + if (posParse >= posEnd) return false; + if (!Next->un.ChrClass->GetBit(CharAt(posParse,param))) return false; + posParse++; + break; + case ReNEnum: + if (posParse >= posEnd) return false; + if (Next->un.ChrClass->GetBit(CharAt(posParse,param))) return false; + posParse++; + break; + case ReBrackets: + match = Next->s; + sv = posParse-posStart; + posStr = posParse; + if (LowParse(Next->un.Param)) { + if (match || (Matches->s[match] == -1)) + Matches->s[match] = sv; + if (match || (Matches->e[match] == -1)) + Matches->e[match] = posParse-posStart; + return true; + }; + posParse = posStr; + return false; + case ReMul: + posStr = posParse; + while (LowParse(Next->un.Param)); + while(!LowCheckNext(Next) && posStr < posParse) posParse--; + break; + case ReNGMul: + do { + if (LowCheckNext(Next)) break; + } while (LowParse(Next->un.Param)); + break; + case RePlus: + posStr = posParse; + match = false; + while (LowParse(Next->un.Param)) + match = true; + if (!match) return false; + while(!LowCheckNext(Next) && posStr < posParse) posParse--; + break; + case ReNGPlus: + if (!LowParse(Next->un.Param)) return false; + do { + if (LowCheckNext(Next)) break; + } while (LowParse(Next->un.Param)); + break; + case ReQuest: + LowParse(Next->un.Param); + break; + case ReNGQuest: + if (LowCheckNext(Next)) break; + if (!LowParse(Next->un.Param)) return false; + break; + case ReOr: + OrNext = Next; + // posStr = posParse; + if (LowParse(Next->un.Param)) { + while (OrNext && OrNext->Op == ReOr) + OrNext = OrNext->Next; + /*if (!LowCheckNext(OrNext)){ + posParse = posStr; + OrNext = Next; + };*/ + }; + Next = OrNext; + break; + case ReRangeN: + posStr = posParse; + i = 0; + while (LowParse(Next->un.Param)) i++; // ??? + do { + if (i < Next->s) { + posParse = posStr; + return false; + }; + i--; + } while(!LowCheckNext(Next) && posStr < posParse--); + break; + case ReNGRangeN: + posStr = posParse; + i = 0; + while (LowParse(Next->un.Param)) { + i++; + if (i >= Next->s && LowCheckNext(Next)) // ??? + break; + }; + if (i < Next->s) { + posParse = posStr; + return false; + }; + break; + case ReRangeNM: + posStr = posParse; + i = 0; + while (i < Next->s && LowParse(Next->un.Param)) // ??? + i++; + if (i < Next->s) { + posParse = posStr; + return false; + }; + while (i < Next->e && LowParse(Next->un.Param)) // ??? + i++; + + while(!LowCheckNext(Next)) { + i--; + posParse--; + if (i < Next->s) { + posParse = posStr; + return false; + }; + }; + break; + case ReNGRangeNM: + posStr = posParse; + i = 0; + while (i < Next->s && LowParse(Next->un.Param)) // ??? + i++; + if (i < Next->s) { + posParse = posStr; + return false; + }; + while(!LowCheckNext(Next)) { + i++; + if (!LowParse(Next->un.Param) || i > Next->e) { // ??? + posParse = posStr; + return false; + }; + }; + break; + }; + return true; +}; + +bool PosRegExp::LowCheckNext(PRegInfo Re) { + PRegInfo Next; + int tmp = posParse; + Next = Re; + do { + if (Next && Next->Op == ReOr) + while (Next && Next->Op == ReOr) + Next = Next->Next; + if (Next->Next && !LowParse(Next->Next)) { + posParse = tmp; + Ok = false; + return false; + }; + Next = Next->Parent; + } while(Next); + posParse = tmp; + if (Ok != false) Ok = true; + return true; +}; + +bool PosRegExp::LowParse(PRegInfo Re) { + while(Re && posParse <= posEnd) { + if (!LowParseRe(Re)) return false; + if (Re) Re = Re->Next; + }; + return true; +}; + +bool PosRegExp::QuickCheck() { + if (!NoMoves || !FirstChar) + return true; + switch(FirstChar) { + case ReSoL: + if (posParse != posStart) return false; + return true; + case ReWBound: + return IsWord(CharAt(posParse,param)) && (posParse == posStart || !IsWord(CharAt(posParse-1,param))); + default: + if (NoCase && LowCase(CharAt(posParse,param)) != LowCase(FirstChar)) return false; + if (!NoCase && CharAt(posParse,param) != (char)FirstChar) return false; + return true; + }; +}; + +bool PosRegExp::ParseRe(int posStr) { + if (Error) return false; + + posParse = posStr; + if (!QuickCheck()) return false; + + for (int i = 0; i < MatchesNum; i++) + Matches->s[i] = Matches->e[i] = -1; + Matches->CurMatch = CurMatch; + + Ok = -1; + //try{ + do { + if (!LowParse(Info)) { + if (NoMoves) return false; + } else + return true; + posParse = ++posStr; + } while(posParse != posEnd+1); + return false; + //}__except(){ + // return true; + //}; +} +; + +bool PosRegExp::Parse(int posStr,int posSol, int posEol, PMatches Mtch, int Moves) { + if (!this) return false; + + bool s = NoMoves; + if (Moves != -1) NoMoves = Moves!=0; + posStart = posSol; + posEnd = posEol; + Matches = Mtch; + bool r = ParseRe(posStr); + NoMoves = s; + return r; +}; + +bool PosRegExp::Parse(int posStr, int posStop, PMatches Mtch) { + if (!this) return false; + posStart = posStr; + posEnd = posStop; + Matches = Mtch; + return ParseRe(posStr); +}; + +bool PosRegExp::SetNoMoves(bool Moves) { + NoMoves = Moves; + return true; +}; + +bool PosRegExp::SetBkTrace(int posStr,PMatches Trace) { + BkTrace = Trace; + posBkStr = posStr; + return true; +}; + +#define EVAL_MATCHES 16 +#define EVAL_CHUNKSIZE 256 + +#define EVAL_LOWERCASE 1 +#define EVAL_UPPERCASE 2 +#define EVAL_LOWERCASE_NEXT 4 +#define EVAL_UPPERCASE_NEXT 8 + +bool PosRegExp::Evaluate(char *Expr, int posStr, PMatches Mtch, char **Res) { + int length, + newlength, + chunklength, + value, + size, + src, + end; + unsigned flag; + char ch, + *dest, + *pool; + + size = EVAL_CHUNKSIZE; + pool = (char*) malloc (size); + dest = pool; + length = 0; + flag = 0; + while (*Expr) { + switch (ch = *Expr++) { + case '\\': + switch (ch = *Expr++) { + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + ch -= ('A' - '0'); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + value = ch - '0'; + if (Mtch->s[value] != -1 && value < EVAL_MATCHES) { + chunklength = Mtch->e[value] - Mtch->s[value]; + if (chunklength) { + newlength = chunklength + length; + if (newlength > size) { + do + size += EVAL_CHUNKSIZE; + while (size < newlength); + pool = (char*) realloc (pool, size); + dest = pool + length; + } + length = newlength; + src = posStr + Mtch->s[value]; + end = posStr + Mtch->e[value]; + if (flag & EVAL_UPPERCASE) { + if (flag & EVAL_LOWERCASE_NEXT) { + *dest++ = tolower (CharAt(src++,param)); + flag &= ~EVAL_LOWERCASE_NEXT; + } + while (src < end) + *dest++ = toupper (CharAt(src++,param)); + } else if (flag & EVAL_LOWERCASE) { + if (flag & EVAL_UPPERCASE_NEXT) { + *dest++ = toupper (CharAt(src++,param)); + flag &= ~EVAL_UPPERCASE_NEXT; + } + while (src < end) + *dest++ = tolower (CharAt(src++,param)); + } else { + if (flag & EVAL_LOWERCASE_NEXT) { + *dest++ = tolower (CharAt(src++,param)); + flag &= ~EVAL_LOWERCASE_NEXT; + } else if (flag & EVAL_UPPERCASE_NEXT) { + *dest++ = toupper (CharAt(src++,param)); + flag &= ~EVAL_UPPERCASE_NEXT; + } + while (src < end) + *dest++ = CharAt(src++,param); + } + } + } else + goto error; + continue; + case '\0': + goto error; + case 'r': + ch = '\r'; + break; + case 'n': + ch = '\n'; + break; + case 'b': + ch = '\b'; + break; + case 'a': + ch = '\a'; + break; + case 't': + ch = '\t'; + break; + case 'U': + flag |= EVAL_UPPERCASE; + continue; + case 'u': + flag |= EVAL_UPPERCASE_NEXT; + continue; + case 'L': + flag |= EVAL_LOWERCASE; + continue; + case 'l': + flag |= EVAL_LOWERCASE_NEXT; + continue; + case 'Q': + case 'q': + flag &= ~(EVAL_UPPERCASE | EVAL_LOWERCASE); + continue; + case 'x': + { + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + value = value + '0' - 'A' + 10; + if (value > 15) + goto error; + ch = value << 4; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + value = value + '0' - 'A' + 10; + if (value > 15) + goto error; + Expr++; + ch |= value; + break; + } + case 'd': + { + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch = value * 100; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch += value * 10; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch += value; + Expr++; + break; + } + case 'o': + { + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch = value << 6; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch += value << 3; + Expr++; + if (!*Expr) + goto error; + value = toupper (*Expr) - '0'; + if (value > 9) + goto error; + ch |= value; + Expr++; + /* break; */ + } + /* default: + break; */ + } + default: + if (++length > size) { + do + size += EVAL_CHUNKSIZE; + while (size < length); + pool = (char*) realloc (pool, size); + dest = pool + length - 1; + } + if (flag & EVAL_LOWERCASE_NEXT) { + *dest++ = tolower (ch); + flag &= ~EVAL_LOWERCASE_NEXT; + } else if (flag & EVAL_UPPERCASE_NEXT) { + *dest++ = toupper (ch); + flag &= ~EVAL_UPPERCASE_NEXT; + } else if (flag & EVAL_UPPERCASE) + *dest++ = toupper (ch); + else if (flag & EVAL_LOWERCASE) + *dest++ = tolower (ch); + else + *dest++ = ch; + } + } + if (++length > size) { + do + size += EVAL_CHUNKSIZE; + while (size < length); + pool = (char*) realloc (pool, size); + dest = pool + length - 1; + } + *dest = '\0'; + *Res = pool; + return true; +error: + free (pool); + return false; +} diff --git a/src/stc/scintilla/src/PropSet.cxx b/src/stc/scintilla/src/PropSet.cxx index d3dbabaf3b..a58d143164 100644 --- a/src/stc/scintilla/src/PropSet.cxx +++ b/src/stc/scintilla/src/PropSet.cxx @@ -24,6 +24,18 @@ bool EqualCaseInsensitive(const char *a, const char *b) { #endif } +SString::size_type SString::npos = -1; + +inline unsigned int HashString(const char *s) { + unsigned int ret = 0; + while (*s) { + ret <<= 4; + ret ^= *s; + s++; + } + return ret; +} + // 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; @@ -56,47 +68,39 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { PropSet::PropSet() { superPS = 0; - size = 10; - used = 0; - vals = new char * [size]; + for (int root=0; root < hashRoots; root++) + props[root] = 0; } PropSet::~PropSet() { superPS = 0; Clear(); - delete []vals; -} - -void PropSet::EnsureCanAddEntry() { - if (used >= size - 2) { - int newsize = size + 10; - char **newvals = new char * [newsize]; - - for (int i = 0; i < used; i++) { - newvals[i] = vals[i]; - } - delete []vals; - vals = newvals; - size = newsize; - } } void PropSet::Set(const char *key, const char *val) { - EnsureCanAddEntry(); - for (int i = 0; i < used; i += 2) { - if (EqualCaseInsensitive(vals[i], key)) { + unsigned int hash = HashString(key); + for (Property *p=props[hash % hashRoots]; p; p=p->next) { + if ((hash == p->hash) && (0 == strcmp(p->key, key))) { // Replace current value - delete [](vals[i + 1]); - vals[i + 1] = StringDup(val); + delete [](p->val); + p->val = StringDup(val); return; } } // Not found - vals[used++] = StringDup(key); - vals[used++] = StringDup(val); + Property *pNew = new Property; + if (pNew) { + pNew->hash = HashString(key); + pNew->key = StringDup(key); + pNew->val = StringDup(val); + pNew->next = props[hash % hashRoots]; + props[hash % hashRoots] = pNew; + } } void PropSet::Set(char *keyval) { + while (isspace(*keyval)) + keyval++; char *eqat = strchr(keyval, '='); if (eqat) { *eqat = '\0'; @@ -106,11 +110,12 @@ void PropSet::Set(char *keyval) { } SString PropSet::Get(const char *key) { - for (int i = 0; i < used; i += 2) { - if (EqualCaseInsensitive(vals[i], key)) { - return vals[i + 1]; - } - } + unsigned int hash = HashString(key); + for (Property *p=props[hash % hashRoots]; p; p=p->next) { + if ((hash == p->hash) && (0 == strcmp(p->key, key))) { + return p->val; + } + } if (superPS) { // Failed here, so try in base property set return superPS->Get(key); @@ -119,6 +124,36 @@ SString PropSet::Get(const char *key) { } } +SString PropSet::GetExpanded(const char *key) { + SString val = Get(key); + return Expand(val.c_str()); +} + +SString PropSet::Expand(const char *withvars) { + char *base = StringDup(withvars); + char *cpvar = strstr(base, "$("); + while (cpvar) { + char *cpendvar = strchr(cpvar, ')'); + if (cpendvar) { + int lenvar = cpendvar - cpvar - 2; // Subtract the $() + char *var = StringDup(cpvar+2, lenvar); + SString val = GetExpanded(var); + int newlenbase = strlen(base) + val.length() - lenvar; + char *newbase = new char[newlenbase]; + strncpy(newbase, base, cpvar - base); + strcpy(newbase + (cpvar - base), val.c_str()); + strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1); + delete []var; + delete []base; + base = newbase; + } + cpvar = strstr(base, "$("); + } + SString sret = base; + delete []base; + return sret; +} + int PropSet::GetInt(const char *key, int defaultValue) { SString val = Get(key); if (val.length()) @@ -127,9 +162,9 @@ int PropSet::GetInt(const char *key, int defaultValue) { return defaultValue; } -bool isprefix(const char *target, const char *prefix) { +inline bool isprefix(const char *target, const char *prefix) { while (*target && *prefix) { - if (toupper(*target) != toupper(*prefix)) + if (*target != *prefix) return false; target++; prefix++; @@ -146,64 +181,63 @@ bool issuffix(const char *target, const char *suffix) { if (lensuffix > lentarget) return false; for (int i = lensuffix - 1; i >= 0; i--) { - if (toupper(target[i + lentarget - lensuffix]) != toupper(suffix[i])) + if (target[i + lentarget - lensuffix] != suffix[i]) return false; } return true; } SString PropSet::GetWild(const char *keybase, const char *filename) { - for (int i = 0; i < used; i += 2) { - if (isprefix(vals[i], keybase)) { - char *orgkeyfile = vals[i] + strlen(keybase); - char *keyfile = NULL; - - if (strstr(orgkeyfile, "$(") == orgkeyfile) { - char *cpendvar = strchr(orgkeyfile, ')'); - if (cpendvar) { - int lenvar = cpendvar - orgkeyfile - 2; // Subtract the $() - char *var = static_cast(malloc(lenvar + 1)); - strncpy(var, orgkeyfile + 2, lenvar); - var[lenvar] = '\0'; - SString s = Get(var); - free(var); - keyfile = strdup(s.c_str()); - } - } - char *keyptr = keyfile; - - if (keyfile == NULL) - keyfile = orgkeyfile; - - for (; ; ) { - char *del = strchr(keyfile, ';'); - if (del == NULL) - del = keyfile + strlen(keyfile); - char delchr = *del; - *del = '\0'; - if (*keyfile == '*') { - if (issuffix(filename, keyfile + 1)) { - *del = delchr; - free(keyptr); - return vals[i + 1]; - } - } else if (EqualCaseInsensitive(keyfile, filename)) { - *del = delchr; - free(keyptr); - return vals[i + 1]; - } - if (delchr == '\0') - break; - *del = delchr; - keyfile = del + 1; - } - free(keyptr); - - if (EqualCaseInsensitive(vals[i], keybase)) { - return vals[i + 1]; - } - } - } + for (int root=0; root < hashRoots; root++) { + for (Property *p=props[root]; p; p=p->next) { + if (isprefix(p->key, keybase)) { + char *orgkeyfile = p->key + strlen(keybase); + char *keyfile = NULL; + + if (strstr(orgkeyfile, "$(") == orgkeyfile) { + char *cpendvar = strchr(orgkeyfile, ')'); + if (cpendvar) { + *cpendvar = '\0'; + SString s = Get(orgkeyfile + 2); + *cpendvar= ')'; + keyfile = strdup(s.c_str()); + } + } + char *keyptr = keyfile; + + if (keyfile == NULL) + keyfile = orgkeyfile; + + for (; ; ) { + char *del = strchr(keyfile, ';'); + if (del == NULL) + del = keyfile + strlen(keyfile); + char delchr = *del; + *del = '\0'; + if (*keyfile == '*') { + if (issuffix(filename, keyfile + 1)) { + *del = delchr; + free(keyptr); + return p->val; + } + } else if (0 == strcmp(keyfile, filename)) { + *del = delchr; + free(keyptr); + return p->val; + } + if (delchr == '\0') + break; + *del = delchr; + keyfile = del + 1; + } + free(keyptr); + + if (0 == strcmp(p->key, keybase)) { + return p->val; + } + } + } + } if (superPS) { // Failed here, so try in base property set return superPS->GetWild(keybase, filename); @@ -219,9 +253,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() - char *var = new char[lenvar + 1]; - strncpy(var, cpvar + 2, lenvar); - var[lenvar] = '\0'; + char *var = StringDup(cpvar+2, lenvar); SString val = GetWild(var, filename); int newlenbase = strlen(base) + val.length() - lenvar; char *newbase = new char[newlenbase]; @@ -240,36 +272,54 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { } void PropSet::Clear() { - for (int i = 0; i < used; i++) { - delete [](vals[i]); - vals[i] = 0; - } - used = 0; + for (int root=0; root < hashRoots; root++) { + Property *p=props[root]; + while (p) { + Property *pNext=p->next; + p->hash = 0; + delete p->key; + p->key = 0; + delete p->val; + p->val = 0; + delete p; + p = pNext; + } + props[root] = 0; + } } -void PropSet::ReadFromMemory(const char *data, int len) { - if (len > 0) { - const char *pd = data; - char linebuf[60000]; - while (GetFullLine(pd, len, linebuf, sizeof(linebuf))) { - if (isalpha(linebuf[0])) - Set(linebuf); - } - // If there is a final line: - if (isalpha(linebuf[0])) +void PropSet::ReadFromMemory(const char *data, int len, const char *directoryForImports) { + const char *pd = data; + char linebuf[60000]; + bool ifIsTrue = true; + while (len > 0) { + GetFullLine(pd, len, linebuf, sizeof(linebuf)); + if (isalpha(linebuf[0])) // If clause ends with first non-indented line + ifIsTrue = true; + if (isprefix(linebuf, "if ")) { + const char *expr = linebuf + strlen("if") + 1; + ifIsTrue = GetInt(expr); + } else if (isprefix(linebuf, "import ") && directoryForImports) { + char importPath[1024]; + strcpy(importPath, directoryForImports); + strcat(importPath, linebuf + strlen("import") + 1); + strcat(importPath, ".properties"); + Read(importPath,directoryForImports); + } else if (isalpha(linebuf[0])) { Set(linebuf); + } else if (isspace(linebuf[0]) && ifIsTrue) { + Set(linebuf); + } } } -void PropSet::Read(const char *filename) { - //printf("Opening properties <%s>\n", filename); - Clear(); +void PropSet::Read(const char *filename, const char *directoryForImports) { char propsData[60000]; FILE *rcfile = fopen(filename, "rb"); if (rcfile) { int lenFile = fread(propsData, 1, sizeof(propsData), rcfile); fclose(rcfile); - ReadFromMemory(propsData, lenFile); + ReadFromMemory(propsData, lenFile, directoryForImports); } else { //printf("Could not open <%s>\n", filename); } @@ -285,7 +335,8 @@ static bool iswordsep(char ch, bool onlyLineEnds) { // Creates an array that points into each word in the string and puts \0 terminators // after each word. -static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) { +static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) { +#if 1 char prev = '\n'; int words = 0; for (int j = 0; wordlist[j]; j++) { @@ -297,8 +348,8 @@ static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) { if (keywords) { words = 0; prev = '\0'; - int len = strlen(wordlist); - for (int k = 0; k < len; k++) { + int slen = strlen(wordlist); + for (int k = 0; k < slen; k++) { if (!iswordsep(wordlist[k], onlyLineEnds)) { if (!prev) { keywords[words] = &wordlist[k]; @@ -309,25 +360,69 @@ static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) { } prev = wordlist[k]; } - keywords[words] = &wordlist[len]; + keywords[words] = &wordlist[slen]; + *len = words; + } else { + *len = 0; } +#else + int words = 0; // length of the returned buffer of pointers + #undef APICHUNK // how many pointers will be pre-allocated (to avoid buffer reallocation on each new pointer) + #define APICHUNK 256 + int size = APICHUNK; // real size of the returned buffer of pointers + char **keywords; // buffer for the pointers returned + int slen = strlen(wordlist); //length of the buffer with api file + keywords = (char**) malloc((size + 1) * sizeof (*keywords)); + words = 0; + for (int k = 0;;) { + while (iswordsep(wordlist[k], onlyLineEnds)) + wordlist[k++] = '\0'; + if (k >= slen) + break; + if (words >= size) { + do + size += APICHUNK; + while (size <= words); + keywords = (char**) realloc(keywords, (size + 1) * sizeof (*keywords)); + } + keywords[words++] = wordlist + k; + do + if (k < slen) + k++; + else + goto out; + while (!iswordsep(wordlist[k], onlyLineEnds)); + } +out: + keywords[words] = wordlist + slen; + *len = words; +#endif return keywords; } void WordList::Clear() { if (words) { - delete []words; delete []list; +#if 1 + delete []words; +#else + free(words); +#endif + free(wordsNoCase); } words = 0; + wordsNoCase = 0; list = 0; len = 0; + sorted = false; } void WordList::Set(const char *s) { - len = 0; list = StringDup(s); - words = ArrayFromWordList(list, onlyLineEnds); + sorted = false; + words = ArrayFromWordList(list, &len, onlyLineEnds); + wordsNoCase = (char**) malloc ((len + 1) * sizeof (*wordsNoCase)); + memcpy(wordsNoCase, words, (len + 1) * sizeof (*words)); } char *WordList::Allocate(int size) { @@ -337,45 +432,35 @@ char *WordList::Allocate(int size) { } void WordList::SetFromAllocated() { - len = 0; - words = ArrayFromWordList(list, onlyLineEnds); + sorted = false; + words = ArrayFromWordList(list, &len, onlyLineEnds); + wordsNoCase = (char**) malloc ((len + 1) * sizeof (*wordsNoCase)); + memcpy(wordsNoCase, words, (len + 1) * sizeof (*words)); } -// Shell sort based upon public domain C implementation by Raymond Gardner 1991 -// Used here because of problems with mingw qsort. -static void SortWordList(char **words, unsigned int len) { - unsigned int gap = len / 2; - - while (gap > 0) { - unsigned int i = gap; - while (i < len) { - unsigned int j = i; - char **a = words + j; - do { - j -= gap; - char **b = a; - a -= gap; - if (strcmp(*a, *b) > 0) { - char *tmp = *a; - *a = *b; - *b = tmp; - } else { - break; - } - } while (j >= gap); - i++; - } - gap = gap / 2; - } +int cmpString(const void *a1, const void *a2) { + // Can't work out the correct incantation to use modern casts here + return strcmp(*(char**)(a1), *(char**)(a2)); +} + +int cmpStringNoCase(const void *a1, const void *a2) { + // Can't work out the correct incantation to use modern casts here + return strcasecmp(*(char**)(a1), *(char**)(a2)); } +static void SortWordList(char **words, char **wordsNoCase, unsigned int len) { + qsort(reinterpret_cast(words), len, sizeof(*words), + cmpString); + qsort(reinterpret_cast(wordsNoCase), len, sizeof(*wordsNoCase), + cmpStringNoCase); +} + bool WordList::InList(const char *s) { if (0 == words) return false; - if (len == 0) { - for (int i = 0; words[i][0]; i++) - len++; - SortWordList(words, len); + if (!sorted) { + sorted = true; + SortWordList(words, wordsNoCase, len); for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) starts[k] = -1; for (int l = len - 1; l >= 0; l--) { @@ -402,3 +487,256 @@ bool WordList::InList(const char *s) { } return false; } + +/** + * Returns an element (complete) of the wordlist array which has the beginning + * the same as the passed string. The length of the word to compare is passed + * too. Letter case can be ignored or preserved (default). + */ +const char *WordList::GetNearestWord(const char *wordStart, int searchLen /*= -1*/, bool ignoreCase /*= false*/) { + int start = 0; // lower bound of the api array block to search + int end = len - 1; // upper bound of the api array block to search + int pivot; // index of api array element just being compared + int cond; // comparison result (in the sense of strcmp() result) + const char *word; // api array element just being compared + + if (0 == words) + return NULL; + if (!sorted) { + sorted = true; + SortWordList(words, wordsNoCase, len); + } + if (ignoreCase) + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = wordsNoCase[pivot]; + cond = strncasecmp(wordStart, word, searchLen); + if (!cond && nonFuncChar(word[searchLen])) // maybe there should be a "non-word character" test here? + return word; // result must not be freed with free() + else if (cond < 0) + end = pivot - 1; + else if (cond > 0) + start = pivot + 1; + } + else // preserve the letter case + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = words[pivot]; + cond = strncmp(wordStart, word, searchLen); + if (!cond && nonFuncChar(word[searchLen])) // maybe there should be a "non-word character" test here? + return word; // result must not be freed with free() + else if (cond >= 0) + start = pivot + 1; + else if (cond < 0) + end = pivot - 1; + } + return NULL; +} + +/** + * Returns elements (first words of them) of the wordlist array which have + * the beginning the same as the passed string. The length of the word to + * compare is passed too. Letter case can be ignored or preserved (default). + * If there are more words meeting the condition they are returned all of + * them in the ascending order separated with spaces. + * + * NOTE: returned buffer has to be freed with a free() call. + */ +char *WordList::GetNearestWords(const char *wordStart, int searchLen /*= -1*/, bool ignoreCase /*= false*/) { + int wordlen; // length of the word part (before the '(' brace) of the api array element + int length = 0; // length of the returned buffer of words (string) + int newlength; // length of the new buffer before the reallocating itself + #undef WORDCHUNK // how many characters will be pre-allocated (to avoid buffer reallocation on each new word) + #define WORDCHUNK 100 + int size = WORDCHUNK; // real size of the returned buffer of words + char *buffer; // buffer for the words returned + int start = 0; // lower bound of the api array block to search + int end = len - 1; // upper bound of the api array block to search + int pivot; // index of api array element just being compared + int cond; // comparison result (in the sense of strcmp() result) + int oldpivot; // pivot storage to be able to browse the api array upwards and then downwards + const char *word; // api array element just being compared + const char *brace; // position of the opening brace in the api array element just being compared + + if (0 == words) + return NULL; + if (!sorted) { + sorted = true; + SortWordList(words, wordsNoCase, len); + } + buffer = (char*) malloc(size); + *buffer = '\0'; + if (ignoreCase) + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = wordsNoCase[pivot]; + cond = strncasecmp(wordStart, word, searchLen); + if (!cond) { + oldpivot = pivot; + do { // browse sequentially the rest after the hit + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + if (++pivot > end) + break; + word = wordsNoCase[pivot]; + } while (!strncasecmp(wordStart, word, searchLen)); + + pivot = oldpivot; + for (;;) { // browse sequentially the rest before the hit + if (--pivot < start) + break; + word = wordsNoCase[pivot]; + if (strncasecmp(wordStart, word, searchLen)) + break; + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) + { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + } + return buffer; // result has to be freed with free() + } + else if (cond < 0) + end = pivot - 1; + else if (cond > 0) + start = pivot + 1; + } + else // preserve the letter case + while (start <= end) { // binary searching loop + pivot = (start + end) >> 1; + word = words[pivot]; + cond = strncmp(wordStart, word, searchLen); + if (!cond) { + oldpivot = pivot; + do { // browse sequentially the rest after the hit + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) + { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + if (++pivot > end) + break; + word = words[pivot]; + } while (!strncmp(wordStart, word, searchLen)); + + pivot = oldpivot; + for (;;) { // browse sequentially the rest before the hit + if (--pivot < start) + break; + word = words[pivot]; + if (strncmp(wordStart, word, searchLen)) + break; + brace = strchr(word, '('); + if (brace) + do + if (--brace < word) + break; + while (isspace(*brace)); + else { + brace = word + strlen(word); + do + if (--brace < word) + break; + while (isspace(*brace)); + } + wordlen = brace - word + 1; + newlength = length + wordlen; // stretch the buffer + if (length) + newlength++; + if (newlength >= size) + { + do + size += WORDCHUNK; + while (size <= newlength); + buffer = (char*) realloc(buffer, size); + } + if (length) // append a new entry + buffer[length++] = ' '; + memcpy(buffer + length, word, wordlen); + length = newlength; + buffer[length] = '\0'; + } + return buffer; // result has to be freed with free() + } + else if (cond < 0) + end = pivot - 1; + else if (cond > 0) + start = pivot + 1; + } + free(buffer); + return NULL; +} diff --git a/src/stc/scintilla/src/SVector.h b/src/stc/scintilla/src/SVector.h index 550dd87ebd..d4d49c717d 100644 --- a/src/stc/scintilla/src/SVector.h +++ b/src/stc/scintilla/src/SVector.h @@ -6,13 +6,12 @@ #ifndef SVECTOR_H #define SVECTOR_H -// A simple expandable vector. -// T must support assignment. +// A simple expandable integer vector. // Storage not allocated for elements until an element is used. // This makes it very lightweight unless used so is a good match for optional features. -template + class SVector { - T *v; + int *v; unsigned int size; // Number of elements allocated unsigned int len; // Number of elements in vector bool allocFailure; // A memory allocation call has failed @@ -20,19 +19,23 @@ class SVector { // Internally allocate more elements than the user wants to avoid // thrashng the memory allocator void SizeTo(int newSize) { - if (newSize < sizeIncrement) - newSize += sizeIncrement; + if (newSize < 4000) + newSize += 4000; else newSize = (newSize * 3) / 2; - T* newv = new T[newSize]; + int* newv = new int[newSize]; if (!newv) { allocFailure = true; return; } size = newSize; - for (unsigned int i=0; i= len) { if (i >= size) { SizeTo(i); diff --git a/src/stc/scintilla/src/ScintillaBase.cxx b/src/stc/scintilla/src/ScintillaBase.cxx index 87b84f7064..4f182850ad 100644 --- a/src/stc/scintilla/src/ScintillaBase.cxx +++ b/src/stc/scintilla/src/ScintillaBase.cxx @@ -11,9 +11,9 @@ #include "Platform.h" #include "Scintilla.h" +#include "PropSet.h" #ifdef SCI_LEXER #include "SciLexer.h" -#include "PropSet.h" #include "Accessor.h" #include "WindowAccessor.h" #include "DocumentAccessor.h" @@ -41,9 +41,15 @@ ScintillaBase::ScintillaBase() { #endif } -ScintillaBase::~ScintillaBase() {} +ScintillaBase::~ScintillaBase() { +#ifdef SCI_LEXER + for (int wl=0;wlDeleteChars(currentPos, lenEntered); + SetEmptySelection(currentPos); + pdoc->InsertString(currentPos, list); + SetEmptySelection(currentPos + strlen(list)); + } else { + SetEmptySelection(currentPos); + pdoc->InsertString(currentPos, list + lenEntered); + SetEmptySelection(currentPos + strlen(list + lenEntered)); + } + return; + } + } ac.Start(wDraw, idAutoComplete, currentPos, lenEntered); PRectangle rcClient = GetClientRectangle(); Point pt = LocationFromPosition(currentPos-lenEntered); - //Platform::DebugPrintf("Auto complete %x\n", lbAutoComplete); int heightLB = 100; int widthLB = 100; if (pt.x >= rcClient.right - widthLB) { @@ -188,16 +213,18 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { rcac.right = rcac.left + widthLB; rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom); ac.lb.SetPositionRelative(rcac, wMain); - ac.lb.SetFont(vs.styles[0].font); + ac.lb.SetFont(vs.styles[STYLE_DEFAULT].font); + ac.lb.SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth); - int maxStrLen = ac.SetList(list); + ac.SetList(list); // Fiddle the position of the list so it is right next to the target and wide enough for all its strings - PRectangle rcList = ac.lb.GetPosition(); + PRectangle rcList = ac.lb.GetDesiredRect(); int heightAlloced = rcList.bottom - rcList.top; + widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left); // Make an allowance for large strings in list rcList.left = pt.x - 5; - rcList.right = rcList.left + Platform::Maximum(widthLB, maxStrLen * 8 + 16); + rcList.right = rcList.left + widthLB; if (pt.y >= rcClient.bottom - heightLB && // Wont fit below. pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above. rcList.top = pt.y - heightAlloced; @@ -206,8 +233,10 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { } rcList.bottom = rcList.top + heightAlloced; ac.lb.SetPositionRelative(rcList, wMain); - //lbAutoComplete.SetPosition(rcList); ac.Show(); + if (lenEntered != 0) { + AutoCompleteMoveToCurrentWord(); + } } void ScintillaBase::AutoCompleteCancel() { @@ -218,36 +247,63 @@ void ScintillaBase::AutoCompleteMove(int delta) { ac.Move(delta); } +void ScintillaBase::AutoCompleteMoveToCurrentWord() { + char wordCurrent[1000]; + int i; + int startWord = ac.posStart - ac.startLen; + for (i = startWord; i < currentPos; i++) + wordCurrent[i - startWord] = pdoc->CharAt(i); + wordCurrent[i - startWord] = '\0'; + ac.Select(wordCurrent); +} + void ScintillaBase::AutoCompleteChanged(char ch) { - if (currentPos <= ac.posStart) { + if (ac.IsFillUpChar(ch)) { + AutoCompleteCompleted(ch); + } else if (currentPos <= ac.posStart - ac.startLen) { + ac.Cancel(); + } else if (ac.cancelAtStartPos && currentPos <= ac.posStart) { ac.Cancel(); } else if (ac.IsStopChar(ch)) { ac.Cancel(); } else { - char wordCurrent[1000]; - int i; - int startWord = ac.posStart - ac.startLen; - for (i = startWord; i < currentPos; i++) - wordCurrent[i - startWord] = pdoc->CharAt(i); - wordCurrent[i - startWord] = '\0'; - ac.Select(wordCurrent); + AutoCompleteMoveToCurrentWord(); } } -void ScintillaBase::AutoCompleteCompleted() { +void ScintillaBase::AutoCompleteCompleted(char fillUp/*='\0'*/) { int item = ac.lb.GetSelection(); - char selected[200]; + char selected[1000]; if (item != -1) { ac.lb.GetValue(item, selected, sizeof(selected)); } ac.Cancel(); - if (currentPos != ac.posStart) { - pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart); - } - SetEmptySelection(ac.posStart); - if (item != -1) { - pdoc->InsertString(currentPos, selected + ac.startLen); - SetEmptySelection(currentPos + strlen(selected + ac.startLen)); + + if (ac.ignoreCase) { + if (currentPos != ac.posStart) { + pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart); + } + SetEmptySelection(ac.posStart - ac.startLen); + pdoc->DeleteChars(ac.posStart - ac.startLen, ac.startLen); + if (item != -1) { + SString piece = selected; + if (fillUp) + piece += fillUp; + pdoc->InsertString(currentPos, piece.c_str()); + SetEmptySelection(currentPos + piece.length()); + } + } else { + if (currentPos != ac.posStart) { + pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart); + } + SetEmptySelection(ac.posStart); + if (item != -1) { + SString piece = selected + ac.startLen; + if (fillUp) + piece += fillUp; + pdoc->InsertString(currentPos, piece.c_str()); + SetEmptySelection(currentPos + piece.length()); + } } } @@ -258,16 +314,21 @@ void ScintillaBase::ContextMenu(Point pt) { AddToPopUp(""); AddToPopUp("Cut", idcmdCut, currentPos != anchor); AddToPopUp("Copy", idcmdCopy, currentPos != anchor); - AddToPopUp("Paste", idcmdPaste, WndProc(EM_CANPASTE, 0, 0)); + AddToPopUp("Paste", idcmdPaste, WndProc(SCI_CANPASTE, 0, 0)); AddToPopUp("Delete", idcmdDelete, currentPos != anchor); AddToPopUp(""); AddToPopUp("Select All", idcmdSelectAll); popup.Show(pt, wMain); } -void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { +void ScintillaBase::CancelModes() { AutoCompleteCancel(); ct.CallTipCancel(); + Editor::CancelModes(); +} + +void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { + CancelModes(); Editor::ButtonDown(pt, curTime, shift, ctrl, alt); } @@ -295,8 +356,8 @@ void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { #ifdef SCI_LEXER if (lexLanguage != SCLEX_CONTAINER) { int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0); - int lineEndStyled = Platform::SendScintilla(wMain.GetID(), EM_LINEFROMCHAR, endStyled, 0); - endStyled = Platform::SendScintilla(wMain.GetID(), EM_LINEINDEX, lineEndStyled, 0); + int lineEndStyled = Platform::SendScintilla(wMain.GetID(), SCI_LINEFROMPOSITION, endStyled, 0); + endStyled = Platform::SendScintilla(wMain.GetID(), SCI_POSITIONFROMLINE, lineEndStyled, 0); Colourise(endStyled, endStyleNeeded); return; } @@ -304,7 +365,7 @@ void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { Editor::NotifyStyleToNeeded(endStyleNeeded); } -LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { +long ScintillaBase::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { switch (iMessage) { case SCI_AUTOCSHOW: AutoCompleteStart(wParam, reinterpret_cast(lParam)); @@ -325,7 +386,7 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { break; case SCI_AUTOCSETSEPARATOR: - ac.SetSeparator(wParam); + ac.SetSeparator(static_cast(wParam)); break; case SCI_AUTOCGETSEPARATOR: @@ -338,13 +399,38 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_AUTOCSELECT: ac.Select(reinterpret_cast(lParam)); break; + + case SCI_AUTOCSETCANCELATSTART: + ac.cancelAtStartPos = wParam; + break; + + case SCI_AUTOCGETCANCELATSTART: + return ac.cancelAtStartPos; + + case SCI_AUTOCSETFILLUPS: + ac.SetFillUpChars(reinterpret_cast(lParam)); + break; + + case SCI_AUTOCSETCHOOSESINGLE: + ac.chooseSingle = wParam; + break; + case SCI_AUTOCGETCHOOSESINGLE: + return ac.chooseSingle; + + case SCI_AUTOCSETIGNORECASE: + ac.ignoreCase = wParam; + break; + + case SCI_AUTOCGETIGNORECASE: + return ac.ignoreCase; + case SCI_CALLTIPSHOW: { AutoCompleteCancel(); if (!ct.wCallTip.Created()) { PRectangle rc = ct.CallTipStart(currentPos, LocationFromPosition(wParam), reinterpret_cast(lParam), - vs.styles[0].fontName, vs.styles[0].size); + vs.styles[STYLE_DEFAULT].fontName, vs.styles[STYLE_DEFAULT].size); // If the call-tip window would be out of the client // space, adjust so it displays above the text. PRectangle rcClient = GetClientRectangle(); diff --git a/src/stc/scintilla/src/ScintillaBase.h b/src/stc/scintilla/src/ScintillaBase.h index 6344b17a34..e630ba1aac 100644 --- a/src/stc/scintilla/src/ScintillaBase.h +++ b/src/stc/scintilla/src/ScintillaBase.h @@ -47,13 +47,15 @@ protected: virtual void AddCharUTF(char *s, unsigned int len); void Command(int cmdId); - virtual int KeyCommand(UINT iMessage); + virtual void CancelModes(); + virtual int KeyCommand(unsigned int iMessage); void AutoCompleteStart(int lenEntered, const char *list); void AutoCompleteCancel(); void AutoCompleteMove(int delta); void AutoCompleteChanged(char ch=0); - void AutoCompleteCompleted(); + void AutoCompleteCompleted(char fillUp='\0'); + void AutoCompleteMoveToCurrentWord(); virtual void CreateCallTipWindow(PRectangle rc) = 0; @@ -65,7 +67,7 @@ protected: virtual void NotifyStyleToNeeded(int endStyleNeeded); public: // Public so scintilla_send_message can use it - virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam); + virtual long WndProc(unsigned int iMessage, unsigned long wParam, long lParam); }; #endif diff --git a/src/stc/scintilla/src/Style.cxx b/src/stc/scintilla/src/Style.cxx index 7aa44c0eb9..0a52ed41a3 100644 --- a/src/stc/scintilla/src/Style.cxx +++ b/src/stc/scintilla/src/Style.cxx @@ -14,13 +14,13 @@ Style::Style() { aliasOfDefaultFont = true; Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, - false, false, false, false); + false, false, false, false, true); } Style::Style(const Style &source) { Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), 0, 0, 0, - false, false, false, false); + false, false, false, false, true); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -29,6 +29,7 @@ Style::Style(const Style &source) { size = source.size; eolFilled = source.eolFilled; underline = source.underline; + visible = source.visible; } Style::~Style() { @@ -44,7 +45,7 @@ Style &Style::operator=(const Style &source) { return *this; Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), 0, 0, SC_CHARSET_DEFAULT, - false, false, false, false); + false, false, false, false, true); fore.desired = source.fore.desired; back.desired = source.back.desired; characterSet = source.characterSet; @@ -53,12 +54,13 @@ Style &Style::operator=(const Style &source) { size = source.size; eolFilled = source.eolFilled; underline = source.underline; + visible = source.visible; return *this; } void Style::Clear(Colour fore_, Colour back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, bool underline_) { + bool bold_, bool italic_, bool eolFilled_, bool underline_, bool visible_) { fore.desired = fore_; back.desired = back_; characterSet = characterSet_; @@ -68,6 +70,7 @@ void Style::Clear(Colour fore_, Colour back_, int size_, fontName = fontName_; eolFilled = eolFilled_; underline = underline_; + visible = visible_; if (aliasOfDefaultFont) font.SetID(0); else diff --git a/src/stc/scintilla/src/Style.h b/src/stc/scintilla/src/Style.h index dc643d08d2..9a2b4586a3 100644 --- a/src/stc/scintilla/src/Style.h +++ b/src/stc/scintilla/src/Style.h @@ -18,6 +18,7 @@ public: int characterSet; bool eolFilled; bool underline; + bool visible; Font font; unsigned int lineHeight; @@ -34,7 +35,7 @@ public: void Clear(Colour fore_, Colour back_, int size_, const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, bool underline_); + bool bold_, bool italic_, bool eolFilled_, bool underline_, bool visible_); bool EquivalentFontTo(const Style *other) const; void Realise(Surface &surface, int zoomLevel, Style *defaultStyle=0); }; diff --git a/src/stc/scintilla/src/ViewStyle.cxx b/src/stc/scintilla/src/ViewStyle.cxx index 580ecc71ff..9b7a8535e9 100644 --- a/src/stc/scintilla/src/ViewStyle.cxx +++ b/src/stc/scintilla/src/ViewStyle.cxx @@ -69,10 +69,12 @@ ViewStyle::ViewStyle(const ViewStyle &source) { selforeground.desired = source.selforeground.desired; selbackset = source.selbackset; selbackground.desired = source.selbackground.desired; + selbackground2.desired = source.selbackground2.desired; selbar.desired = source.selbar.desired; selbarlight.desired = source.selbarlight.desired; caretcolour.desired = source.caretcolour.desired; edgecolour.desired = source.edgecolour.desired; + edgeState = source.edgeState; leftMarginWidth = source.leftMarginWidth; rightMarginWidth = source.rightMarginWidth; for (int i=0;i < margins; i++) { @@ -83,6 +85,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) { fixedColumnWidth = source.fixedColumnWidth; zoomLevel = source.zoomLevel; viewWhitespace = source.viewWhitespace; + viewIndentationGuides = source.viewIndentationGuides; viewEOL = source.viewEOL; showMarkedLines = source.showMarkedLines; } @@ -111,6 +114,7 @@ void ViewStyle::Init() { selforeground.desired = Colour(0xff, 0, 0); selbackset = true; selbackground.desired = Colour(0xc0, 0xc0, 0xc0); + selbackground2.desired = Colour(0xb0, 0xb0, 0xb0); selbar.desired = Platform::Chrome(); selbarlight.desired = Platform::ChromeHighlight(); styles[STYLE_LINENUMBER].fore.desired = Colour(0, 0, 0); @@ -118,6 +122,7 @@ void ViewStyle::Init() { //caretcolour.desired = Colour(0xff, 0, 0); caretcolour.desired = Colour(0, 0, 0); edgecolour.desired = Colour(0xc0, 0xc0, 0xc0); + edgeState = EDGE_NONE; leftMarginWidth = 1; rightMarginWidth = 1; @@ -142,7 +147,8 @@ void ViewStyle::Init() { maskInLine &= ~ms[margin].mask; } zoomLevel = 0; - viewWhitespace = false; + viewWhitespace = wsInvisible; + viewIndentationGuides = false; viewEOL = false; showMarkedLines = true; } @@ -162,6 +168,7 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { } pal.WantFind(selforeground, want); pal.WantFind(selbackground, want); + pal.WantFind(selbackground2, want); pal.WantFind(selbar, want); pal.WantFind(selbarlight, want); pal.WantFind(caretcolour, want); @@ -203,7 +210,7 @@ void ViewStyle::ResetDefaultStyle() { styles[STYLE_DEFAULT].Clear(Colour(0,0,0), Colour(0xff,0xff,0xff), Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), SC_CHARSET_DEFAULT, - false, false, false, false); + false, false, false, false, true); } void ViewStyle::ClearStyles() { @@ -219,7 +226,8 @@ void ViewStyle::ClearStyles() { styles[STYLE_DEFAULT].bold, styles[STYLE_DEFAULT].italic, styles[STYLE_DEFAULT].eolFilled, - styles[STYLE_DEFAULT].underline); + styles[STYLE_DEFAULT].underline, + styles[STYLE_DEFAULT].visible); } } styles[STYLE_LINENUMBER].back.desired = Platform::Chrome(); diff --git a/src/stc/scintilla/src/ViewStyle.h b/src/stc/scintilla/src/ViewStyle.h index 4436e83ff4..5b0ab1925f 100644 --- a/src/stc/scintilla/src/ViewStyle.h +++ b/src/stc/scintilla/src/ViewStyle.h @@ -26,6 +26,7 @@ public: const char *Save(const char *name); }; +enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; class ViewStyle { public: FontNames fontNames; @@ -41,6 +42,7 @@ public: ColourPair selforeground; bool selbackset; ColourPair selbackground; + ColourPair selbackground2; ColourPair selbar; ColourPair selbarlight; // Margins are ordered: Line Numbers, Selection Margin, Spacing Margin @@ -52,11 +54,13 @@ public: MarginStyle ms[margins]; int fixedColumnWidth; int zoomLevel; - bool viewWhitespace; + WhiteSpaceVisibility viewWhitespace; + bool viewIndentationGuides; bool viewEOL; bool showMarkedLines; ColourPair caretcolour; ColourPair edgecolour; + int edgeState; ViewStyle(); ViewStyle(const ViewStyle &source); diff --git a/src/stc/scintilla/src/WindowAccessor.cxx b/src/stc/scintilla/src/WindowAccessor.cxx index 059c877bda..5f3deac7db 100644 --- a/src/stc/scintilla/src/WindowAccessor.cxx +++ b/src/stc/scintilla/src/WindowAccessor.cxx @@ -4,6 +4,7 @@ // The License.txt file describes the conditions under which this software may be distributed. #include +#include #include #include @@ -17,25 +18,26 @@ WindowAccessor::~WindowAccessor() { } +#if PLAT_WIN bool WindowAccessor::InternalIsLeadByte(char ch) { -#if PLAT_GTK - // TODO: support DBCS under GTK+ - return false; -#elif PLAT_WIN if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the // same so none is considered a lead byte. return false; else return IsDBCSLeadByteEx(codePage, ch); -#elif PLAT_WX +} +#else +// PLAT_GTK or PLAT_WX +// TODO: support DBCS under GTK+ and WX +bool WindowAccessor::InternalIsLeadByte(char) { return false; -#endif } +#endif void WindowAccessor::Fill(int position) { if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); + lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0); startPos = position - slopSize; if (startPos + bufferSize > lenDoc) startPos = lenDoc - bufferSize; @@ -45,8 +47,8 @@ void WindowAccessor::Fill(int position) { if (endPos > lenDoc) endPos = lenDoc; - TEXTRANGE tr = {{startPos, endPos}, buf}; - Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast(&tr)); + TextRange tr = {{startPos, endPos}, buf}; + Platform::SendScintilla(id, SCI_GETTEXTRANGE, 0, reinterpret_cast(&tr)); } char WindowAccessor::StyleAt(int position) { @@ -55,11 +57,11 @@ char WindowAccessor::StyleAt(int position) { } int WindowAccessor::GetLine(int position) { - return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0); + return Platform::SendScintilla(id, SCI_LINEFROMPOSITION, position, 0); } int WindowAccessor::LineStart(int line) { - return Platform::SendScintilla(id, EM_LINEINDEX, line, 0); + return Platform::SendScintilla(id, SCI_POSITIONFROMLINE, line, 0); } int WindowAccessor::LevelAt(int line) { @@ -68,7 +70,7 @@ int WindowAccessor::LevelAt(int line) { int WindowAccessor::Length() { if (lenDoc == -1) - lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0); + lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0); return lenDoc; } @@ -121,7 +123,7 @@ void WindowAccessor::Flush() { lenDoc = -1; if (validLen > 0) { Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen, - reinterpret_cast(styleBuf)); + reinterpret_cast(styleBuf)); validLen = 0; } } diff --git a/src/stc/stc.cpp b/src/stc/stc.cpp index aa7bf8dd98..3fde7ae05d 100644 --- a/src/stc/stc.cpp +++ b/src/stc/stc.cpp @@ -26,7 +26,7 @@ // If we don't do something like this, then the linker tends to "optimize" // them away. (eric@sourcegear.com) -int wxForceScintillaLexers(void) +static int wxForceScintillaLexers(void) { extern LexerModule lmCPP; extern LexerModule lmHTML; @@ -39,6 +39,7 @@ int wxForceScintillaLexers(void) extern LexerModule lmPython; extern LexerModule lmSQL; extern LexerModule lmVB; + extern LexerModule lmLua; if ( &lmCPP @@ -52,14 +53,11 @@ int wxForceScintillaLexers(void) && &lmPython && &lmSQL && &lmVB + && &lmLua ) { return 1; } - else - { - return 0; - } } //---------------------------------------------------------------------- @@ -131,7 +129,7 @@ wxString wxStyledTextCtrl::GetText() { int len = GetTextLength(); char* buff = text.GetWriteBuf(len+1); - SendMsg(WM_GETTEXT, len, (long)buff); + SendMsg(SCI_GETTEXT, len, (long)buff); buff[len] = 0; text.UngetWriteBuf(); return text; @@ -139,7 +137,7 @@ wxString wxStyledTextCtrl::GetText() { bool wxStyledTextCtrl::SetText(const wxString& text) { - return SendMsg(WM_SETTEXT, 0, (long)text.c_str()) != 0; + return SendMsg(SCI_SETTEXT, 0, (long)text.c_str()) != 0; } @@ -148,8 +146,7 @@ wxString wxStyledTextCtrl::GetLine(int line) { int len = GetLineLength(line); char* buff = text.GetWriteBuf(len+1); - *((WORD*)buff) = len; - SendMsg(EM_GETLINE, line, (long)buff); + SendMsg(SCI_GETLINE, line, (long)buff); buff[len] = 0; text.UngetWriteBuf(); return text; @@ -157,12 +154,12 @@ wxString wxStyledTextCtrl::GetLine(int line) { void wxStyledTextCtrl::ReplaceSelection(const wxString& text) { - SendMsg(EM_REPLACESEL, 0, (long)text.c_str()); + SendMsg(SCI_REPLACESEL, 0, (long)text.c_str()); } void wxStyledTextCtrl::SetReadOnly(bool readOnly) { - SendMsg(EM_SETREADONLY, (long)readOnly); + SendMsg(SCI_SETREADONLY, (long)readOnly); m_readOnly = readOnly; } @@ -175,18 +172,18 @@ bool wxStyledTextCtrl::GetReadOnly() { void wxStyledTextCtrl::GetTextRange(int startPos, int endPos, char* buff) { - TEXTRANGE tr; + TextRange tr; tr.lpstrText = buff; tr.chrg.cpMin = startPos; tr.chrg.cpMax = endPos; - SendMsg(EM_GETTEXTRANGE, 0, (long)&tr); + SendMsg(SCI_GETTEXTRANGE, 0, (long)&tr); } wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) { wxString text; int len = endPos - startPos; - char* buff = text.GetWriteBuf(len); + char* buff = text.GetWriteBuf(len+1); GetTextRange(startPos, endPos, buff); text.UngetWriteBuf(); return text; @@ -194,7 +191,7 @@ wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) { void wxStyledTextCtrl::GetStyledTextRange(int startPos, int endPos, char* buff) { - TEXTRANGE tr; + TextRange tr; tr.lpstrText = buff; tr.chrg.cpMin = startPos; tr.chrg.cpMax = endPos; @@ -205,7 +202,7 @@ void wxStyledTextCtrl::GetStyledTextRange(int startPos, int endPos, char* buff) wxString wxStyledTextCtrl::GetStyledTextRange(int startPos, int endPos) { wxString text; int len = endPos - startPos; - char* buff = text.GetWriteBuf(len*2); + char* buff = text.GetWriteBuf(len*2+1); GetStyledTextRange(startPos, endPos, buff); text.UngetWriteBuf(len*2); return text; @@ -257,27 +254,27 @@ int wxStyledTextCtrl::GetStyleBits() { void wxStyledTextCtrl::Cut() { - SendMsg(WM_CUT); + SendMsg(SCI_CUT); } void wxStyledTextCtrl::Copy() { - SendMsg(WM_COPY); + SendMsg(SCI_COPY); } void wxStyledTextCtrl::Paste() { - SendMsg(WM_PASTE); + SendMsg(SCI_PASTE); } bool wxStyledTextCtrl::CanPaste() { - return SendMsg(EM_CANPASTE) != 0; + return SendMsg(SCI_CANPASTE) != 0; } void wxStyledTextCtrl::ClearClipbrd() { - SendMsg(WM_CLEAR); + SendMsg(SCI_CLEAR); } @@ -286,17 +283,17 @@ void wxStyledTextCtrl::ClearClipbrd() { // Undo and Redo void wxStyledTextCtrl::Undo() { - SendMsg(WM_UNDO); + SendMsg(SCI_UNDO); } bool wxStyledTextCtrl::CanUndo() { - return SendMsg(EM_CANUNDO) != 0; + return SendMsg(SCI_CANUNDO) != 0; } void wxStyledTextCtrl::EmptyUndoBuffer() { - SendMsg(EM_EMPTYUNDOBUFFER); + SendMsg(SCI_EMPTYUNDOBUFFER); } @@ -340,12 +337,14 @@ void wxStyledTextCtrl::EndUndoAction() { void wxStyledTextCtrl::GetSelection(int* startPos, int* endPos) { - SendMsg(EM_GETSEL, (long)startPos, (long)endPos); +// SendMsg(EM_GETSEL, (long)startPos, (long)endPos); + *startPos = SendMsg(SCI_GETSELECTIONSTART); + *endPos = SendMsg(SCI_GETSELECTIONEND); } void wxStyledTextCtrl::SetSelection(int startPos, int endPos) { - SendMsg(EM_SETSEL, startPos, endPos); + SendMsg(SCI_SETSEL, startPos, endPos); } @@ -356,16 +355,16 @@ wxString wxStyledTextCtrl::GetSelectedText() { GetSelection(&start, &end); int len = end - start; - char* buff = text.GetWriteBuf(len); + char* buff = text.GetWriteBuf(len+1); - SendMsg(EM_GETSELTEXT, 0, (long)buff); + SendMsg(SCI_GETSELTEXT, 0, (long)buff); text.UngetWriteBuf(); return text; } void wxStyledTextCtrl::HideSelection(bool hide) { - SendMsg(EM_HIDESELECTION, hide); + SendMsg(SCI_HIDESELECTION, hide); } @@ -375,46 +374,32 @@ bool wxStyledTextCtrl::GetHideSelection() { int wxStyledTextCtrl::GetTextLength() { - return SendMsg(WM_GETTEXTLENGTH); + return SendMsg(SCI_GETTEXTLENGTH); } int wxStyledTextCtrl::GetFirstVisibleLine() { - return SendMsg(EM_GETFIRSTVISIBLELINE); + return SendMsg(SCI_GETFIRSTVISIBLELINE); } int wxStyledTextCtrl::GetLineCount() { - return SendMsg(EM_GETLINECOUNT); + return SendMsg(SCI_GETLINECOUNT); } bool wxStyledTextCtrl::GetModified() { - return SendMsg(EM_GETMODIFY) != 0; -} - - -wxRect wxStyledTextCtrl::GetRect() { - PRectangle pr; - SendMsg(EM_GETRECT, 0, (long)&pr); - - wxRect rect = wxRectFromPRectangle(pr); - return rect; + return SendMsg(SCI_GETMODIFY) != 0; } int wxStyledTextCtrl::GetLineFromPos(int pos) { - return SendMsg(EM_LINEFROMCHAR, pos); + return SendMsg(SCI_LINEFROMPOSITION, pos); } int wxStyledTextCtrl::GetLineStartPos(int line) { - return SendMsg(EM_LINEINDEX, line); -} - - -int wxStyledTextCtrl::GetLineLengthAtPos(int pos) { - return SendMsg(EM_LINELENGTH, pos); + return SendMsg(SCI_POSITIONFROMLINE, line); } @@ -445,23 +430,14 @@ wxString wxStyledTextCtrl::GetCurrentLineText(int* linePos) { int wxStyledTextCtrl::PositionFromPoint(wxPoint pt) { - Point spt(pt.x, pt.y); - long rv = SendMsg(EM_CHARFROMPOS, 0, (long)&spt); - return LOWORD(rv); -} - - -int wxStyledTextCtrl::LineFromPoint(wxPoint pt) { - Point spt(pt.x, pt.y); - long rv = SendMsg(EM_CHARFROMPOS, 0, (long)&spt); - return HIWORD(rv); + return SendMsg(SCI_POSITIONFROMPOINT, pt.x, pt.y); } wxPoint wxStyledTextCtrl::PointFromPosition(int pos) { - Point pt; - SendMsg(EM_POSFROMCHAR, (long)&pt, pos); - return wxPoint(pt.x, pt.y); + int x = SendMsg(SCI_POINTXFROMPOSITION, 0, pos); + int y = SendMsg(SCI_POINTYFROMPOSITION, 0, pos); + return wxPoint(x, y); } @@ -513,7 +489,7 @@ void wxStyledTextCtrl::PageMove(int cmdKey, bool extendSelection) { void wxStyledTextCtrl::ScrollBy(int columnDelta, int lineDelta) { - SendMsg(EM_LINESCROLL, columnDelta, lineDelta); + SendMsg(SCI_LINESCROLL, columnDelta, lineDelta); } void wxStyledTextCtrl::ScrollToLine(int line) { @@ -527,7 +503,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) { void wxStyledTextCtrl::EnsureCaretVisible() { - SendMsg(EM_SCROLLCARET); + SendMsg(SCI_SCROLLCARET); } @@ -536,11 +512,6 @@ void wxStyledTextCtrl::SetCaretPolicy(int policy, int slop) { } -int wxStyledTextCtrl::GetSelectionType() { - return SendMsg(EM_SELECTIONTYPE); -} - - int wxStyledTextCtrl::GetLinesOnScreen() { return SendMsg(SCI_LINESONSCREEN); } @@ -568,18 +539,18 @@ bool wxStyledTextCtrl::GetUseHorizontalScrollBar() { // Searching int wxStyledTextCtrl::FindText(int minPos, int maxPos, - const wxString& text, - bool caseSensitive, bool wholeWord) { - FINDTEXTEX ft; + const wxString& text, + bool caseSensitive, bool wholeWord) { + TextToFind ft; int flags = 0; - flags |= caseSensitive ? FR_MATCHCASE : 0; - flags |= wholeWord ? FR_WHOLEWORD : 0; + flags |= caseSensitive ? SCFIND_MATCHCASE : 0; + flags |= wholeWord ? SCFIND_WHOLEWORD : 0; ft.chrg.cpMin = minPos; ft.chrg.cpMax = maxPos; ft.lpstrText = (char*)text.c_str(); - return SendMsg(EM_FINDTEXT, flags, (long)&ft); + return SendMsg(SCI_FINDTEXT, flags, (long)&ft); } @@ -590,8 +561,8 @@ void wxStyledTextCtrl::SearchAnchor() { int wxStyledTextCtrl::SearchNext(const wxString& text, bool caseSensitive, bool wholeWord) { int flags = 0; - flags |= caseSensitive ? FR_MATCHCASE : 0; - flags |= wholeWord ? FR_WHOLEWORD : 0; + flags |= caseSensitive ? SCFIND_MATCHCASE : 0; + flags |= wholeWord ? SCFIND_WHOLEWORD : 0; return SendMsg(SCI_SEARCHNEXT, flags, (long)text.c_str()); } @@ -599,8 +570,8 @@ int wxStyledTextCtrl::SearchNext(const wxString& text, bool caseSensitive, bool int wxStyledTextCtrl::SearchPrev(const wxString& text, bool caseSensitive, bool wholeWord) { int flags = 0; - flags |= caseSensitive ? FR_MATCHCASE : 0; - flags |= wholeWord ? FR_WHOLEWORD : 0; + flags |= caseSensitive ? SCFIND_MATCHCASE : 0; + flags |= wholeWord ? SCFIND_WHOLEWORD : 0; return SendMsg(SCI_SEARCHPREV, flags, (long)text.c_str()); } @@ -836,29 +807,24 @@ void wxStyledTextCtrl::StyleSetUnderline(int styleNum, bool underline) { // Margins in the edit area int wxStyledTextCtrl::GetLeftMargin() { - return LOWORD(SendMsg(EM_GETMARGINS)); + return SendMsg(SCI_GETMARGINLEFT); } int wxStyledTextCtrl::GetRightMargin() { - return HIWORD(SendMsg(EM_GETMARGINS)); + return SendMsg(SCI_GETMARGINRIGHT); } void wxStyledTextCtrl::SetMargins(int left, int right) { int flag = 0; - int val = 0; if (right != -1) { - flag |= EC_RIGHTMARGIN; - val = right << 16; + SendMsg(SCI_SETMARGINRIGHT, 0, right); } if (left != -1) { - flag |= EC_LEFTMARGIN; - val |= (left & 0xffff); + SendMsg(SCI_SETMARGINLEFT, 0, left); } - - SendMsg(EM_SETMARGINS, flag, val); } @@ -1180,6 +1146,8 @@ void wxStyledTextCtrl::CallTipSetBackground(const wxColour& colour) { //---------------------------------------------------------------------- // Key bindings +#define MAKELONG(a, b) ((a) | ((b) << 16)) + void wxStyledTextCtrl::CmdKeyAssign(int key, int modifiers, int cmd) { SendMsg(SCI_ASSIGNCMDKEY, MAKELONG(key, modifiers), cmd); } @@ -1212,7 +1180,7 @@ wxStyledTextCtrl::FormatRange(bool doDraw, wxDC* target, // Why does it use two? Can they be the same? wxRect renderRect, wxRect pageRect) { - FORMATRANGE fr; + RangeToFormat fr; fr.hdc = draw; fr.hdcTarget = target; @@ -1227,7 +1195,7 @@ wxStyledTextCtrl::FormatRange(bool doDraw, fr.chrg.cpMin = startPos; fr.chrg.cpMax = endPos; - return SendMsg(EM_FORMATRANGE, doDraw, (long)&fr); + return SendMsg(SCI_FORMATRANGE, doDraw, (long)&fr); } -- 2.45.2