]> git.saurik.com Git - wxWidgets.git/commitdiff
Updated Scintilla to 1.52 (on the trunk this time too)
authorRobin Dunn <robin@alldunn.com>
Sat, 19 Apr 2003 20:00:02 +0000 (20:00 +0000)
committerRobin Dunn <robin@alldunn.com>
Sat, 19 Apr 2003 20:00:02 +0000 (20:00 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20296 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

160 files changed:
contrib/include/wx/stc/stc.h
contrib/samples/stc/stctest.cpp
contrib/src/stc/Makefile.in
contrib/src/stc/PlatWX.cpp
contrib/src/stc/ScintillaWX.cpp
contrib/src/stc/ScintillaWX.h
contrib/src/stc/StcVC.dsp
contrib/src/stc/gen_iface.py
contrib/src/stc/makefile.b32
contrib/src/stc/makefile.g95
contrib/src/stc/makefile.vc
contrib/src/stc/makefile.wat
contrib/src/stc/scintilla/License.txt [new file with mode: 0644]
contrib/src/stc/scintilla/README.txt
contrib/src/stc/scintilla/include/Accessor.h
contrib/src/stc/scintilla/include/KeyWords.h
contrib/src/stc/scintilla/include/Platform.h
contrib/src/stc/scintilla/include/PropSet.h
contrib/src/stc/scintilla/include/SString.h
contrib/src/stc/scintilla/include/SciLexer.h
contrib/src/stc/scintilla/include/Scintilla.h
contrib/src/stc/scintilla/include/Scintilla.iface
contrib/src/stc/scintilla/include/ScintillaWidget.h
contrib/src/stc/scintilla/include/WindowAccessor.h
contrib/src/stc/scintilla/src/AutoComplete.cxx
contrib/src/stc/scintilla/src/AutoComplete.h
contrib/src/stc/scintilla/src/CallTip.cxx
contrib/src/stc/scintilla/src/CallTip.h
contrib/src/stc/scintilla/src/CellBuffer.cxx
contrib/src/stc/scintilla/src/CellBuffer.h
contrib/src/stc/scintilla/src/Document.cxx
contrib/src/stc/scintilla/src/Document.h
contrib/src/stc/scintilla/src/DocumentAccessor.cxx
contrib/src/stc/scintilla/src/DocumentAccessor.h
contrib/src/stc/scintilla/src/Editor.cxx
contrib/src/stc/scintilla/src/Editor.h
contrib/src/stc/scintilla/src/KeyMap.cxx
contrib/src/stc/scintilla/src/KeyWords.cxx
contrib/src/stc/scintilla/src/LexAVE.cxx
contrib/src/stc/scintilla/src/LexAda.cxx
contrib/src/stc/scintilla/src/LexAsm.cxx [new file with mode: 0644]
contrib/src/stc/scintilla/src/LexBullant.cxx
contrib/src/stc/scintilla/src/LexCPP.cxx
contrib/src/stc/scintilla/src/LexCSS.cxx [new file with mode: 0644]
contrib/src/stc/scintilla/src/LexConf.cxx
contrib/src/stc/scintilla/src/LexCrontab.cxx
contrib/src/stc/scintilla/src/LexEiffel.cxx
contrib/src/stc/scintilla/src/LexFortran.cxx [new file with mode: 0644]
contrib/src/stc/scintilla/src/LexHTML.cxx
contrib/src/stc/scintilla/src/LexLisp.cxx
contrib/src/stc/scintilla/src/LexLua.cxx
contrib/src/stc/scintilla/src/LexMatlab.cxx
contrib/src/stc/scintilla/src/LexOthers.cxx
contrib/src/stc/scintilla/src/LexPOV.cxx [new file with mode: 0644]
contrib/src/stc/scintilla/src/LexPascal.cxx
contrib/src/stc/scintilla/src/LexPerl.cxx
contrib/src/stc/scintilla/src/LexPython.cxx
contrib/src/stc/scintilla/src/LexRuby.cxx
contrib/src/stc/scintilla/src/LexSQL.cxx
contrib/src/stc/scintilla/src/LexVB.cxx
contrib/src/stc/scintilla/src/LineMarker.cxx
contrib/src/stc/scintilla/src/LineMarker.h
contrib/src/stc/scintilla/src/PropSet.cxx
contrib/src/stc/scintilla/src/RESearch.cxx
contrib/src/stc/scintilla/src/RESearch.h
contrib/src/stc/scintilla/src/SVector.h
contrib/src/stc/scintilla/src/ScintillaBase.cxx
contrib/src/stc/scintilla/src/ScintillaBase.h
contrib/src/stc/scintilla/src/Style.cxx
contrib/src/stc/scintilla/src/Style.h
contrib/src/stc/scintilla/src/StyleContext.cxx
contrib/src/stc/scintilla/src/StyleContext.h
contrib/src/stc/scintilla/src/ViewStyle.cxx
contrib/src/stc/scintilla/src/ViewStyle.h
contrib/src/stc/scintilla/src/WindowAccessor.cxx
contrib/src/stc/scintilla/src/XPM.cxx [new file with mode: 0644]
contrib/src/stc/scintilla/src/XPM.h [new file with mode: 0644]
contrib/src/stc/stc.cpp
contrib/src/stc/stc.cpp.in
contrib/src/stc/stc.h.in
include/wx/stc/stc.h
samples/stc/stctest.cpp
src/stc/Makefile.in
src/stc/PlatWX.cpp
src/stc/ScintillaWX.cpp
src/stc/ScintillaWX.h
src/stc/StcVC.dsp
src/stc/gen_iface.py
src/stc/makefile.b32
src/stc/makefile.g95
src/stc/makefile.vc
src/stc/makefile.wat
src/stc/scintilla/License.txt [new file with mode: 0644]
src/stc/scintilla/README.txt
src/stc/scintilla/include/Accessor.h
src/stc/scintilla/include/KeyWords.h
src/stc/scintilla/include/Platform.h
src/stc/scintilla/include/PropSet.h
src/stc/scintilla/include/SString.h
src/stc/scintilla/include/SciLexer.h
src/stc/scintilla/include/Scintilla.h
src/stc/scintilla/include/Scintilla.iface
src/stc/scintilla/include/ScintillaWidget.h
src/stc/scintilla/include/WindowAccessor.h
src/stc/scintilla/src/AutoComplete.cxx
src/stc/scintilla/src/AutoComplete.h
src/stc/scintilla/src/CallTip.cxx
src/stc/scintilla/src/CallTip.h
src/stc/scintilla/src/CellBuffer.cxx
src/stc/scintilla/src/CellBuffer.h
src/stc/scintilla/src/Document.cxx
src/stc/scintilla/src/Document.h
src/stc/scintilla/src/DocumentAccessor.cxx
src/stc/scintilla/src/DocumentAccessor.h
src/stc/scintilla/src/Editor.cxx
src/stc/scintilla/src/Editor.h
src/stc/scintilla/src/KeyMap.cxx
src/stc/scintilla/src/KeyWords.cxx
src/stc/scintilla/src/LexAVE.cxx
src/stc/scintilla/src/LexAda.cxx
src/stc/scintilla/src/LexAsm.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexBullant.cxx
src/stc/scintilla/src/LexCPP.cxx
src/stc/scintilla/src/LexCSS.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexConf.cxx
src/stc/scintilla/src/LexCrontab.cxx
src/stc/scintilla/src/LexEiffel.cxx
src/stc/scintilla/src/LexFortran.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexHTML.cxx
src/stc/scintilla/src/LexLisp.cxx
src/stc/scintilla/src/LexLua.cxx
src/stc/scintilla/src/LexMatlab.cxx
src/stc/scintilla/src/LexOthers.cxx
src/stc/scintilla/src/LexPOV.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexPascal.cxx
src/stc/scintilla/src/LexPerl.cxx
src/stc/scintilla/src/LexPython.cxx
src/stc/scintilla/src/LexRuby.cxx
src/stc/scintilla/src/LexSQL.cxx
src/stc/scintilla/src/LexVB.cxx
src/stc/scintilla/src/LineMarker.cxx
src/stc/scintilla/src/LineMarker.h
src/stc/scintilla/src/PropSet.cxx
src/stc/scintilla/src/RESearch.cxx
src/stc/scintilla/src/RESearch.h
src/stc/scintilla/src/SVector.h
src/stc/scintilla/src/ScintillaBase.cxx
src/stc/scintilla/src/ScintillaBase.h
src/stc/scintilla/src/Style.cxx
src/stc/scintilla/src/Style.h
src/stc/scintilla/src/StyleContext.cxx
src/stc/scintilla/src/StyleContext.h
src/stc/scintilla/src/ViewStyle.cxx
src/stc/scintilla/src/ViewStyle.h
src/stc/scintilla/src/WindowAccessor.cxx
src/stc/scintilla/src/XPM.cxx [new file with mode: 0644]
src/stc/scintilla/src/XPM.h [new file with mode: 0644]
src/stc/stc.cpp
src/stc/stc.cpp.in
src/stc/stc.h.in

index 096949085a8d66a873fb1eaddee11d5fad045afa..41e36f3e8b3dacb4147c06589acb6ccb8c73c96e 100644 (file)
@@ -77,6 +77,9 @@
 // The SC_CP_UTF8 value can be used to enter Unicode mode.
 // This is the same value as CP_UTF8 in Windows
 #define wxSTC_CP_UTF8 65001
+
+// The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+#define wxSTC_CP_DBCS 1
 #define wxSTC_MARKER_MAX 31
 #define wxSTC_MARK_CIRCLE 0
 #define wxSTC_MARK_ROUNDRECT 1
 #define wxSTC_MARK_BACKGROUND 22
 #define wxSTC_MARK_DOTDOTDOT 23
 #define wxSTC_MARK_ARROWS 24
+#define wxSTC_MARK_PIXMAP 25
 #define wxSTC_MARK_CHARACTER 10000
 
 // Markers used for outlining column.
 #define wxSTC_FIND_MATCHCASE 4
 #define wxSTC_FIND_WORDSTART 0x00100000
 #define wxSTC_FIND_REGEXP 0x00200000
+#define wxSTC_FIND_POSIX 0x00400000
 #define wxSTC_FOLDLEVELBASE 0x400
 #define wxSTC_FOLDLEVELWHITEFLAG 0x1000
 #define wxSTC_FOLDLEVELHEADERFLAG 0x2000
+#define wxSTC_FOLDLEVELBOXHEADERFLAG 0x4000
+#define wxSTC_FOLDLEVELBOXFOOTERFLAG 0x8000
+#define wxSTC_FOLDLEVELCONTRACTED 0x10000
+#define wxSTC_FOLDLEVELUNINDENT 0x20000
 #define wxSTC_FOLDLEVELNUMBERMASK 0x0FFF
+#define wxSTC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002
+#define wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004
+#define wxSTC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
+#define wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
+#define wxSTC_FOLDFLAG_LEVELNUMBERS 0x0040
+#define wxSTC_FOLDFLAG_BOX 0x0001
 #define wxSTC_TIME_FOREVER 10000000
 #define wxSTC_WRAP_NONE 0
 #define wxSTC_WRAP_WORD 1
 #define wxSTC_EDGE_LINE 1
 #define wxSTC_EDGE_BACKGROUND 2
 #define wxSTC_CURSORNORMAL -1
-#define wxSTC_CURSORWAIT 3
+#define wxSTC_CURSORWAIT 4
 
 // Constants for use with SetVisiblePolicy, similar to SetCaretPolicy.
 #define wxSTC_VISIBLE_SLOP 0x01
 #define wxSTC_LEX_BAAN 31
 #define wxSTC_LEX_MATLAB 32
 #define wxSTC_LEX_SCRIPTOL 33
+#define wxSTC_LEX_ASM 34
+#define wxSTC_LEX_CPPNOCASE 35
+#define wxSTC_LEX_FORTRAN 36
+#define wxSTC_LEX_F77 37
+#define wxSTC_LEX_CSS 38
+#define wxSTC_LEX_POV 39
 
 // When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 // value assigned in sequence from SCLEX_AUTOMATIC+1.
 #define wxSTC_ERR_DIFF_ADDITION 11
 #define wxSTC_ERR_DIFF_DELETION 12
 #define wxSTC_ERR_DIFF_MESSAGE 13
+#define wxSTC_ERR_PHP 14
+#define wxSTC_ERR_ELF 15
+#define wxSTC_ERR_IFC 16
 
 // Lexical states for SCLEX_BATCH
 #define wxSTC_BAT_DEFAULT 0
 #define wxSTC_AVE_COMMENT 1
 #define wxSTC_AVE_NUMBER 2
 #define wxSTC_AVE_WORD 3
-#define wxSTC_AVE_KEYWORD 4
-#define wxSTC_AVE_STATEMENT 5
 #define wxSTC_AVE_STRING 6
 #define wxSTC_AVE_ENUM 7
 #define wxSTC_AVE_STRINGEOL 8
 #define wxSTC_AVE_IDENTIFIER 9
 #define wxSTC_AVE_OPERATOR 10
+#define wxSTC_AVE_WORD1 11
+#define wxSTC_AVE_WORD2 12
+#define wxSTC_AVE_WORD3 13
+#define wxSTC_AVE_WORD4 14
+#define wxSTC_AVE_WORD5 15
+#define wxSTC_AVE_WORD6 16
 
 // Lexical states for SCLEX_ADA
 #define wxSTC_ADA_DEFAULT 0
-#define wxSTC_ADA_COMMENT 1
-#define wxSTC_ADA_NUMBER 2
-#define wxSTC_ADA_WORD 3
-#define wxSTC_ADA_STRING 4
+#define wxSTC_ADA_WORD 1
+#define wxSTC_ADA_IDENTIFIER 2
+#define wxSTC_ADA_NUMBER 3
+#define wxSTC_ADA_DELIMITER 4
 #define wxSTC_ADA_CHARACTER 5
-#define wxSTC_ADA_OPERATOR 6
-#define wxSTC_ADA_IDENTIFIER 7
+#define wxSTC_ADA_CHARACTEREOL 6
+#define wxSTC_ADA_STRING 7
 #define wxSTC_ADA_STRINGEOL 8
+#define wxSTC_ADA_LABEL 9
+#define wxSTC_ADA_COMMENTLINE 10
+#define wxSTC_ADA_ILLEGAL 11
 
 // Lexical states for SCLEX_BAAN
 #define wxSTC_BAAN_DEFAULT 0
 #define wxSTC_SCRIPTOL_COMMENTDOCKEYWORDERROR 18
 #define wxSTC_SCRIPTOL_COMMENTBASIC 19
 
+// Lexical states for SCLEX_ASM
+#define wxSTC_ASM_DEFAULT 0
+#define wxSTC_ASM_COMMENT 1
+#define wxSTC_ASM_NUMBER 2
+#define wxSTC_ASM_STRING 3
+#define wxSTC_ASM_OPERATOR 4
+#define wxSTC_ASM_IDENTIFIER 5
+#define wxSTC_ASM_CPUINSTRUCTION 6
+#define wxSTC_ASM_MATHINSTRUCTION 7
+#define wxSTC_ASM_REGISTER 8
+#define wxSTC_ASM_DIRECTIVE 9
+#define wxSTC_ASM_DIRECTIVEOPERAND 10
+
+// Lexical states for SCLEX_FORTRAN
+#define wxSTC_F_DEFAULT 0
+#define wxSTC_F_COMMENT 1
+#define wxSTC_F_NUMBER 2
+#define wxSTC_F_STRING1 3
+#define wxSTC_F_STRING2 4
+#define wxSTC_F_STRINGEOL 5
+#define wxSTC_F_OPERATOR 6
+#define wxSTC_F_IDENTIFIER 7
+#define wxSTC_F_WORD 8
+#define wxSTC_F_WORD2 9
+#define wxSTC_F_WORD3 10
+#define wxSTC_F_PREPROCESSOR 11
+#define wxSTC_F_OPERATOR2 12
+#define wxSTC_F_LABEL 13
+#define wxSTC_F_CONTINUATION 14
+
+// Lexical states for SCLEX_CSS
+#define wxSTC_CSS_DEFAULT 0
+#define wxSTC_CSS_TAG 1
+#define wxSTC_CSS_CLASS 2
+#define wxSTC_CSS_PSEUDOCLASS 3
+#define wxSTC_CSS_UNKNOWN_PSEUDOCLASS 4
+#define wxSTC_CSS_OPERATOR 5
+#define wxSTC_CSS_IDENTIFIER 6
+#define wxSTC_CSS_UNKNOWN_IDENTIFIER 7
+#define wxSTC_CSS_VALUE 8
+#define wxSTC_CSS_COMMENT 9
+#define wxSTC_CSS_ID 10
+#define wxSTC_CSS_IMPORTANT 11
+#define wxSTC_CSS_DIRECTIVE 12
+#define wxSTC_CSS_DOUBLESTRING 13
+#define wxSTC_CSS_SINGLESTRING 14
+
+// Lexical states for SCLEX_POV
+#define wxSTC_POV_DEFAULT 0
+#define wxSTC_POV_COMMENT 1
+#define wxSTC_POV_COMMENTLINE 2
+#define wxSTC_POV_COMMENTDOC 3
+#define wxSTC_POV_NUMBER 4
+#define wxSTC_POV_WORD 5
+#define wxSTC_POV_STRING 6
+#define wxSTC_POV_OPERATOR 7
+#define wxSTC_POV_IDENTIFIER 8
+#define wxSTC_POV_BRACE 9
+#define wxSTC_POV_WORD2 10
+
 
 //-----------------------------------------
 // Commands that can be bound to keystrokes
 // Switch the current line with the previous.
 #define wxSTC_CMD_LINETRANSPOSE 2339
 
+// Duplicate the current line.
+#define wxSTC_CMD_LINEDUPLICATE 2404
+
 // Transform the selection to lower case.
 #define wxSTC_CMD_LOWERCASE 2340
 
 // caret position.
 #define wxSTC_CMD_LINEENDDISPLAYEXTEND 2348
 
+// These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)?
+// except they behave differently when word-wrap is enabled:
+// They go first to the start / end of the display line, like (Home|LineEnd)Display
+// The difference is that, the cursor is already at the point, it goes on to the start
+// or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend.
+#define wxSTC_CMD_HOMEWRAP 2349
+#define wxSTC_CMD_HOMEWRAPEXTEND 2450
+#define wxSTC_CMD_LINEENDWRAP 2451
+#define wxSTC_CMD_LINEENDWRAPEXTEND 2452
+#define wxSTC_CMD_VCHOMEWRAP 2453
+#define wxSTC_CMD_VCHOMEWRAPEXTEND 2454
+
 // Move to the previous change in capitalisation.
 #define wxSTC_CMD_WORDPARTLEFT 2390
 
 // Delete forwards from the current position to the end of the line.
 #define wxSTC_CMD_DELLINERIGHT 2396
 
+// Move caret between paragraphs (delimited by empty lines)
+#define wxSTC_CMD_PARADOWN 2413
+#define wxSTC_CMD_PARADOWNEXTEND 2414
+#define wxSTC_CMD_PARAUP 2415
+#define wxSTC_CMD_PARAUPEXTEND 2416
+
 
 // END of generated section
 //----------------------------------------------------------------------
@@ -1091,8 +1203,8 @@ public:
     // Set the symbol used for a particular marker number,
     // and optionally the fore and background colours.
     void MarkerDefine(int markerNumber, int markerSymbol,
-                         const wxColour& foreground = wxNullColour,
-                         const wxColour& background = wxNullColour);
+                const wxColour& foreground = wxNullColour,
+                const wxColour& background = wxNullColour);
 
     // Set the foreground colour used for a particular marker number.
     void MarkerSetForeground(int markerNumber, const wxColour& fore);
@@ -1118,6 +1230,9 @@ public:
     // Find the previous line before lineStart that includes a marker in mask.
     int MarkerPrevious(int lineStart, int markerMask);
 
+    // Define a marker from a bitmap
+    void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp);
+
     // Set a margin to be either numeric or symbolic.
     void SetMarginType(int margin, int marginType);
 
@@ -1178,6 +1293,9 @@ public:
     // Set the character set of the font in a style.
     void StyleSetCharacterSet(int style, int characterSet);
 
+    // Set a style to be a hotspot or not.
+    void StyleSetHotSpot(int style, bool hotspot);
+
     // Set the foreground colour of the selection and whether to use this setting.
     void SetSelForeground(bool useSetting, const wxColour& fore);
 
@@ -1339,6 +1457,19 @@ public:
     // after the inserted text upon completion.
     bool AutoCompGetDropRestOfWord();
 
+    // Register an image for use in autocompletion lists.
+    void RegisterImage(int type, const wxBitmap& bmp);
+
+    // Clear all the registered images.
+    void ClearRegisteredImages();
+
+    // Retrieve the auto-completion list type-separator character.
+    int AutoCompGetTypeSeparator();
+
+    // Change the type-separator character in the string setting up an auto-completion list.
+    // Default is '?' but can be changed if items contain '?'.
+    void AutoCompSetTypeSeparator(int separatorCharacter);
+
     // Set the number of spaces used for one level of indentation.
     void SetIndent(int indentSize);
 
@@ -1427,14 +1558,14 @@ public:
 
     // On Windows, will draw the document into a display context such as a printer.
     int FormatRange(bool   doDraw,
-                               int    startPos,
-                               int    endPos,
-                               wxDC*  draw,
-                               wxDC*  target,  // Why does it use two? Can they be the same?
-                               wxRect renderRect,
-                               wxRect pageRect);
-
-    // Retrieve the line at the top of the display.
+               int    startPos,
+               int    endPos,
+               wxDC*  draw,
+               wxDC*  target,  // Why does it use two? Can they be the same?
+               wxRect renderRect,
+               wxRect pageRect);
+
+    // Retrieve the display line at the top of the display.
     int GetFirstVisibleLine();
 
     // Retrieve the contents of a line.
@@ -1589,6 +1720,12 @@ public:
     // Set the background colour for the call tip.
     void CallTipSetBackground(const wxColour& back);
 
+    // Set the foreground colour for the call tip.
+    void CallTipSetForeground(const wxColour& fore);
+
+    // Set the foreground colour for the highlighted part of the call tip.
+    void CallTipSetForegroundHighlight(const wxColour& fore);
+
     // Find the display line of a document line taking hidden lines into account.
     int VisibleFromDocLine(int line);
 
@@ -1630,7 +1767,7 @@ public:
     // Ensure a particular line is visible by expanding any header line hiding it.
     void EnsureVisible(int line);
 
-    // Set some debugging options for folding.
+    // Set some style options for folding.
     void SetFoldFlags(int flags);
 
     // Ensure a particular line is visible by expanding any header line hiding it.
@@ -1696,6 +1833,39 @@ public:
     // Retrieve the height of a particular line of text in pixels.
     int TextHeight(int line);
 
+    // Show or hide the vertical scroll bar.
+    void SetUseVerticalScrollBar(bool show);
+
+    // Is the vertical scroll bar visible?
+    bool GetUseVerticalScrollBar();
+
+    // Append a string to the end of the document without changing the selection.
+    void AppendText(int length, const wxString& text);
+
+    // Is drawing done in two phases with backgrounds drawn before foregrounds?
+    bool GetTwoPhaseDraw();
+
+    // In twoPhaseDraw mode, drawing is performed in two phases, first the background
+    // and then the foreground. This avoids chopping off characters that overlap the next run.
+    void SetTwoPhaseDraw(bool twoPhase);
+
+    // Make the target range start and end be the same as the selection range start and end.
+    void TargetFromSelection();
+
+    // Join the lines in the target.
+    void LinesJoin();
+
+    // Split the lines in the target into lines that are less wide than pixelWidth
+    // where possible.
+    void LinesSplit(int pixelWidth);
+
+    // Set the colours used as a chequerboard pattern in the fold margin
+    void SetFoldMarginColour(bool useSetting, const wxColour& back);
+    void SetFoldMarginHiColour(bool useSetting, const wxColour& fore);
+
+    // Duplicate the current line.
+    void LineDuplicate();
+
     // Move caret to first position on display line.
     void HomeDisplay();
 
@@ -1860,6 +2030,9 @@ public:
     void SetXOffset(int newOffset);
     int GetXOffset();
 
+    // Set the last x chosen value to be the caret x position
+    void ChooseCaretX();
+
     // Set the way the caret is kept visible when going sideway.
     // The exclusion zone is given in pixels.
     void SetXCaretPolicy(int caretPolicy, int caretSlop);
@@ -1868,6 +2041,21 @@ public:
     // The exclusion zone is given in lines.
     void SetYCaretPolicy(int caretPolicy, int caretSlop);
 
+    // Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).
+    void SetPrintWrapMode(int mode);
+
+    // Is printing line wrapped.
+    int GetPrintWrapMode();
+
+    // Set a fore colour for active hotspots.
+    void SetHotspotActiveForeground(bool useSetting, const wxColour& fore);
+
+    // Set a back colour for active hotspots.
+    void SetHotspotActiveBackground(bool useSetting, const wxColour& back);
+
+    // Enable / Disable underlining active hotspots.
+    void SetHotspotActiveUnderline(bool underline);
+
     // Start notifying the container of all key presses and commands.
     void StartRecord();
 
@@ -2005,11 +2193,11 @@ private:
     void NotifyChange();
     void NotifyParent(SCNotification* scn);
 
-
-private:
     DECLARE_EVENT_TABLE()
     DECLARE_CLASS(wxStyledTextCtrl)
 
+protected:
+
     ScintillaWX*        m_swx;
     wxStopWatch         m_stopWatch;
     wxScrollBar*        m_vScrollBar;
@@ -2128,6 +2316,8 @@ private:
 #endif
 };
 
+
+
 #ifndef SWIG
 BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE,                  1650)
@@ -2153,6 +2343,9 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER,               1670)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP,                 1671)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM,                    1672)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK,           1673)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK,          1674)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK,           1675)
 END_DECLARE_EVENT_TYPES()
 #else
     enum {
@@ -2179,6 +2372,9 @@ END_DECLARE_EVENT_TYPES()
         wxEVT_STC_DRAG_OVER,
         wxEVT_STC_DO_DROP,
         wxEVT_STC_ZOOM,
+        wxEVT_STC_HOTSPOT_CLICK,
+        wxEVT_STC_HOTSPOT_DCLICK,
+        wxEVT_STC_CALLTIP_CLICK
     };
 #endif
 
@@ -2210,6 +2406,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&);
 #define EVT_STC_DRAG_OVER(id, fn)               DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER,             id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_DO_DROP(id, fn)                 DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP,               id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_ZOOM(id, fn)                    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM,                  id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_CLICK(id, fn)           DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK,         id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_DCLICK(id, fn)          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK,        id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_CALLTIP_CLICK(id, fn))          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK          id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+
 #endif
 
 //----------------------------------------------------------------------
index 578044d546c8b6d6dc88965ef2cd93c723faac2d..538d00ef98aa4f05126fb8554833d3bbea89bdfb 100644 (file)
@@ -40,7 +40,26 @@ public:
 };
 
 //----------------------------------------------------------------------
+//  Make an editor class
 
+class MySTC : public wxStyledTextCtrl
+{
+public:
+    MySTC(wxWindow *parent, wxWindowID id,
+          const wxPoint& pos = wxDefaultPosition,
+          const wxSize& size = wxDefaultSize, long style = 0);
+
+    void OnKeyPressed(wxKeyEvent& evt);
+
+private:
+    DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(MySTC, wxStyledTextCtrl)
+    EVT_KEY_DOWN(MySTC::OnKeyPressed)
+END_EVENT_TABLE()
+
+//----------------------------------------------------------------------
 // Define a new frame type: this is going to be our main frame
 class MyFrame : public wxFrame
 {
@@ -51,7 +70,7 @@ public:
     void OnAbout(wxCommandEvent& event);
 
 private:
-    wxStyledTextCtrl* ed;
+    MySTC* ed;
 
     DECLARE_EVENT_TABLE()
 };
@@ -79,7 +98,7 @@ IMPLEMENT_APP(MyApp)
 bool MyApp::OnInit()
 {
     MyFrame *frame = new MyFrame(_T("Testing wxStyledTextCtrl"),
-                                 wxPoint(5, 5), wxSize(400, 600));
+                                 wxPoint(5, 5), wxSize(600, 600));
 
     frame->Show(TRUE);
     return TRUE;
@@ -123,32 +142,71 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
 
     //----------------------------------------
     // Setup the editor
-    ed = new wxStyledTextCtrl(this, ID_ED);
+    ed = new MySTC(this, ID_ED);
+}
+
+
+// event handlers
+
+void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+    // TRUE is to force the frame to close
+    Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+    wxString msg;
+    msg.Printf( _T("Testing wxStyledTextCtrl...\n"));
 
+    wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this);
+}
+
+
+//----------------------------------------------------------------------
+
+wxChar* keywords =
+_T("asm auto bool break case catch char class const \
+const_cast continue default delete do double \
+dynamic_cast else enum explicit export extern \
+false float for friend goto if inline int long \
+mutable namespace new operator private protected \
+public register reinterpret_cast return short signed \
+sizeof static static_cast struct switch template this \
+throw true try typedef typeid typename union unsigned \
+using virtual void volatile wchar_t while");
+
+
+
+MySTC::MySTC(wxWindow *parent, wxWindowID id,
+             const wxPoint& pos, const wxSize& size,
+             long style)
+    : wxStyledTextCtrl(parent, id, pos, size, style)
+{
     // Default font
     wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL);
-    ed->StyleSetFont(wxSTC_STYLE_DEFAULT, font);
-    ed->StyleClearAll();
-
-    ed->StyleSetForeground(0,  wxColour(0x80, 0x80, 0x80));
-    ed->StyleSetForeground(1,  wxColour(0x00, 0x7f, 0x00));
-    //ed->StyleSetForeground(2,  wxColour(0x00, 0x7f, 0x00));
-    ed->StyleSetForeground(3,  wxColour(0x7f, 0x7f, 0x7f));
-    ed->StyleSetForeground(4,  wxColour(0x00, 0x7f, 0x7f));
-    ed->StyleSetForeground(5,  wxColour(0x00, 0x00, 0x7f));
-    ed->StyleSetForeground(6,  wxColour(0x7f, 0x00, 0x7f));
-    ed->StyleSetForeground(7,  wxColour(0x7f, 0x00, 0x7f));
-    ed->StyleSetForeground(8,  wxColour(0x00, 0x7f, 0x7f));
-    ed->StyleSetForeground(9,  wxColour(0x7f, 0x7f, 0x7f));
-    ed->StyleSetForeground(10, wxColour(0x00, 0x00, 0x00));
-    ed->StyleSetForeground(11, wxColour(0x00, 0x00, 0x00));
-    ed->StyleSetBold(5,  TRUE);
-    ed->StyleSetBold(10, TRUE);
+    StyleSetFont(wxSTC_STYLE_DEFAULT, font);
+    StyleClearAll();
+
+    StyleSetForeground(0,  wxColour(0x80, 0x80, 0x80));
+    StyleSetForeground(1,  wxColour(0x00, 0x7f, 0x00));
+    //StyleSetForeground(2,  wxColour(0x00, 0x7f, 0x00));
+    StyleSetForeground(3,  wxColour(0x7f, 0x7f, 0x7f));
+    StyleSetForeground(4,  wxColour(0x00, 0x7f, 0x7f));
+    StyleSetForeground(5,  wxColour(0x00, 0x00, 0x7f));
+    StyleSetForeground(6,  wxColour(0x7f, 0x00, 0x7f));
+    StyleSetForeground(7,  wxColour(0x7f, 0x00, 0x7f));
+    StyleSetForeground(8,  wxColour(0x00, 0x7f, 0x7f));
+    StyleSetForeground(9,  wxColour(0x7f, 0x7f, 0x7f));
+    StyleSetForeground(10, wxColour(0x00, 0x00, 0x00));
+    StyleSetForeground(11, wxColour(0x00, 0x00, 0x00));
+    StyleSetBold(5,  TRUE);
+    StyleSetBold(10, TRUE);
 
 #ifdef __WXMSW__
-    ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9"));
+    StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9"));
 #else
-    ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9"));
+    StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9"));
 #endif
 
     // give it some text to play with
@@ -161,36 +219,36 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
     st = wxString::FromAscii(buf);
     delete[] buf;
 
-    ed->InsertText(0, st);
-    ed->EmptyUndoBuffer();
+    InsertText(0, st);
+    EmptyUndoBuffer();
 
-    ed->SetLexer(wxSTC_LEX_CPP);
-    ed->SetKeyWords(0,
-_T("asm auto bool break case catch char class const \
-const_cast continue default delete do double \
-dynamic_cast else enum explicit export extern \
-false float for friend goto if inline int long \
-mutable namespace new operator private protected \
-public register reinterpret_cast return short signed \
-sizeof static static_cast struct switch template this \
-throw true try typedef typeid typename union unsigned \
-using virtual void volatile wchar_t while"));
-
-}
-
-
-// event handlers
-
-void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
-{
-    // TRUE is to force the frame to close
-    Close(TRUE);
+    SetLexer(wxSTC_LEX_CPP);
+    SetKeyWords(0, keywords);
 }
 
-void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+void MySTC::OnKeyPressed(wxKeyEvent& evt)
 {
-    wxString msg;
-    msg.Printf( _T("Testing wxStyledTextCtrl...\n"));
-
-    wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this);
+    if (CallTipActive())
+        CallTipCancel();
+
+    int key = evt.GetKeyCode();
+    if ( key == WXK_SPACE && evt.ControlDown()) {
+        int pos = GetCurrentPos();
+
+        if (evt.ShiftDown()) {
+            // show how to do CallTips
+            CallTipSetBackground(wxColour(_T("YELLOW")));
+            CallTipShow(pos, _T("lots of of text: blah, blah, blah\n\n"
+                                "show some suff, maybe parameters..\n\n"
+                                "fubar(param1, param2)"));
+        }
+        else {
+            // show how to do AutoComplete
+            AutoCompSetIgnoreCase(false);
+            AutoCompShow(0, keywords);   // reuse the keyword list here
+            // normally you would build a string of completion texts...
+        }
+    }
+    else
+        evt.Skip();
 }
index 042da17f87d235ddad1f1daef70465841f540b11..9df25a3db22d00b80ef3e735339d44554e906a0a 100644 (file)
@@ -34,18 +34,22 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
         KeyMap.o               \
         KeyWords.o             \
        LexAVE.o                \
+       LexAda.o                \
+       LexAsm.o                \
        LexBaan.o               \
        LexBullant.o            \
        LexMatlab.o             \
-       LexAda.o                \
        LexCPP.o                \
        LexConf.o               \
        LexCrontab.o            \
+       LexCSS.o                \
        LexEiffel.o             \
+       LexFortran.o            \
        LexHTML.o               \
        LexLisp.o               \
        LexLua.o                \
        LexOthers.o             \
+       LexPOV.o                \
        LexPascal.o             \
        LexPerl.o               \
        LexPython.o             \
@@ -61,6 +65,8 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
        UniConversion.o         \
         ViewStyle.o            \
        WindowAccessor.o        \
+       XPM.o                   \
+
 
 DEPFILES=$(OBJECTS:.o=.d)
 
index fbf1faf2a370d9db55d4eb62d7bfadcdd8298f63..80f8f795ce95279d8ebf75ffaca32a66a3546f8d 100644 (file)
@@ -8,7 +8,10 @@
 
 #include <wx/wx.h>
 #include <wx/encconv.h>
-
+#include <wx/listctrl.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
+#include <wx/imaglist.h>
 
 #include "Platform.h"
 #include "PlatWX.h"
@@ -189,9 +192,6 @@ void Font::Create(const char *faceName, int characterSet, int size, bool bold, b
                     false,
                     stc2wx(faceName),
                     encoding);
-#ifdef __WXMAC__
-        ((wxFont*)id)->SetNoAntiAliasing( true ) ;
-#endif
 }
 
 
@@ -216,42 +216,44 @@ public:
     SurfaceImpl();
     ~SurfaceImpl();
 
-    void Init();
-    void Init(SurfaceID sid);
-    void InitPixMap(int width, int height, Surface *surface_);
-
-    void Release();
-    bool Initialised();
-    void PenColour(ColourAllocated fore);
-    int LogPixelsY();
-    int DeviceHeightFont(int points);
-    void MoveTo(int x_, int y_);
-    void LineTo(int x_, int y_);
-    void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
-    void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
-    void FillRectangle(PRectangle rc, ColourAllocated back);
-    void FillRectangle(PRectangle rc, Surface &surfacePattern);
-    void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
-    void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
-    void Copy(PRectangle rc, Point from, Surface &surfaceSource);
-
-    void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
-    void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
-    void MeasureWidths(Font &font_, const char *s, int len, int *positions);
-    int WidthText(Font &font_, const char *s, int len);
-    int WidthChar(Font &font_, char ch);
-    int Ascent(Font &font_);
-    int Descent(Font &font_);
-    int InternalLeading(Font &font_);
-    int ExternalLeading(Font &font_);
-    int Height(Font &font_);
-    int AverageCharWidth(Font &font_);
-
-    int SetPalette(Palette *pal, bool inBackGround);
-    void SetClip(PRectangle rc);
-    void FlushCachedState();
-
-    void SetUnicodeMode(bool unicodeMode_);
+    virtual void Init(WindowID wid);
+    virtual void Init(SurfaceID sid, WindowID wid);
+    virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid);
+
+    virtual void Release();
+    virtual bool Initialised();
+    virtual void PenColour(ColourAllocated fore);
+    virtual int LogPixelsY();
+    virtual int DeviceHeightFont(int points);
+    virtual void MoveTo(int x_, int y_);
+    virtual void LineTo(int x_, int y_);
+    virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
+    virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+    virtual void FillRectangle(PRectangle rc, ColourAllocated back);
+    virtual void FillRectangle(PRectangle rc, Surface &surfacePattern);
+    virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+    virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+    virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource);
+
+    virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
+    virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
+    virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore);
+    virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions);
+    virtual int WidthText(Font &font_, const char *s, int len);
+    virtual int WidthChar(Font &font_, char ch);
+    virtual int Ascent(Font &font_);
+    virtual int Descent(Font &font_);
+    virtual int InternalLeading(Font &font_);
+    virtual int ExternalLeading(Font &font_);
+    virtual int Height(Font &font_);
+    virtual int AverageCharWidth(Font &font_);
+
+    virtual int SetPalette(Palette *pal, bool inBackGround);
+    virtual void SetClip(PRectangle rc);
+    virtual void FlushCachedState();
+
+    virtual void SetUnicodeMode(bool unicodeMode_);
+    virtual void SetDBCSMode(int codePage);
 
     void BrushColour(ColourAllocated back);
     void SetFont(Font &font_);
@@ -268,25 +270,7 @@ SurfaceImpl::~SurfaceImpl() {
     Release();
 }
 
-void SurfaceImpl::Release() {
-    if (bitmap) {
-        ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
-        delete bitmap;
-        bitmap = 0;
-    }
-    if (hdcOwned) {
-        delete hdc;
-        hdc = 0;
-        hdcOwned = false;
-    }
-}
-
-
-bool SurfaceImpl::Initialised() {
-    return hdc != 0;
-}
-
-void SurfaceImpl::Init() {
+void SurfaceImpl::Init(WindowID wid) {
 #if 0
     Release();
     hdc = new wxMemoryDC();
@@ -295,16 +279,16 @@ void SurfaceImpl::Init() {
     // On Mac and GTK the DC is not really valid until it has a bitmap
     // selected into it.  So instead of just creating the DC with no bitmap,
     // go ahead and give it one.
-    InitPixMap(1,1,NULL);
+    InitPixMap(1,1,NULL,wid);
 #endif
 }
 
-void SurfaceImpl::Init(SurfaceID hdc_) {
+void SurfaceImpl::Init(SurfaceID hdc_, WindowID) {
     Release();
     hdc = (wxDC*)hdc_;
 }
 
-void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
+void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID) {
     Release();
     hdc = new wxMemoryDC();
     hdcOwned = true;
@@ -314,6 +298,26 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
     ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
 }
 
+
+void SurfaceImpl::Release() {
+    if (bitmap) {
+        ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
+        delete bitmap;
+        bitmap = 0;
+    }
+    if (hdcOwned) {
+        delete hdc;
+        hdc = 0;
+        hdcOwned = false;
+    }
+}
+
+
+bool SurfaceImpl::Initialised() {
+    return hdc != 0;
+}
+
+
 void SurfaceImpl::PenColour(ColourAllocated fore) {
     hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
 }
@@ -401,7 +405,7 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
     SetFont(font);
     hdc->SetTextForeground(wxColourFromCA(fore));
     hdc->SetTextBackground(wxColourFromCA(back));
-    FillRectangle(rc, back);
+    //FillRectangle(rc, back);
 
     // ybase is where the baseline should be, but wxWin uses the upper left
     // corner, so I need to calculate the real position for the text...
@@ -414,28 +418,36 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
     SetFont(font);
     hdc->SetTextForeground(wxColourFromCA(fore));
     hdc->SetTextBackground(wxColourFromCA(back));
-    FillRectangle(rc, back);
+    //FillRectangle(rc, back);
     hdc->SetClippingRegion(wxRectFromPRectangle(rc));
 
     // see comments above
     hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
-    hdc->DestroyClippingRegion();
 }
 
-int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
+
+void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase,
+                                      const char *s, int len,
+                                      ColourAllocated fore) {
+
     SetFont(font);
-    int w;
-    int h;
+    hdc->SetTextForeground(wxColourFromCA(fore));
+    hdc->SetBackgroundMode(wxTRANSPARENT);
 
-    hdc->GetTextExtent(stc2wx(s, len), &w, &h);
-    return w;
+    // ybase is where the baseline should be, but wxWin uses the upper left
+    // corner, so I need to calculate the real position for the text...
+    hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
+
+    hdc->SetBackgroundMode(wxSOLID);
 }
 
 
 void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
+
     wxString str = stc2wx(s, len);
     SetFont(font);
 
+#ifndef __WXMAC__
     // Calculate the position of each character based on the widths of
     // the previous characters
     int* tpos = new int[len];
@@ -447,9 +459,26 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio
         totalWidth += w;
         tpos[i] = totalWidth;
     }
+#else
+    // Instead of a running total, remeasure from the begining of the
+    // text for each character's position.  This is because with AA fonts
+    // on OS X widths can be fractions of pixels wide when more than one
+    // are drawn together, so the sum of all character widths is not necessarily
+    // (and probably not) the same as the whole string width.
+    int* tpos = new int[len];
+    size_t i;
+    for (i=0; i<str.Length(); i++) {
+        int w, h;
+        hdc->GetTextExtent(str.Left(i+1), &w, &h);
+        tpos[i] = w;
+    }
+#endif
+
 
 #if wxUSE_UNICODE
     // Map the widths for UCS-2 characters back to the UTF-8 input string
+    // NOTE:  I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2
+    // so figure it out and fix it!
     i = 0;
     size_t ui = 0;
     while (i < len) {
@@ -475,6 +504,16 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio
 }
 
 
+int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
+    SetFont(font);
+    int w;
+    int h;
+
+    hdc->GetTextExtent(stc2wx(s, len), &w, &h);
+    return w;
+}
+
+
 int SurfaceImpl::WidthChar(Font &font, char ch) {
     SetFont(font);
     int w;
@@ -545,6 +584,11 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
 #endif
 }
 
+void SurfaceImpl::SetDBCSMode(int codePage) {
+    // dbcsMode = codePage == SC_CP_DBCS;
+}
+
+
 Surface *Surface::Allocate() {
     return new SurfaceImpl;
 }
@@ -559,8 +603,10 @@ Window::~Window() {
 }
 
 void Window::Destroy() {
-    if (id)
+    if (id) {
+        Show(FALSE);
         GETWIN(id)->Destroy();
+    }
     id = 0;
 }
 
@@ -569,6 +615,7 @@ bool Window::HasFocus() {
 }
 
 PRectangle Window::GetPosition() {
+    if (! id) return PRectangle();
     wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
     return PRectangleFromwxRect(rc);
 }
@@ -583,6 +630,7 @@ void Window::SetPositionRelative(PRectangle rc, Window) {
 }
 
 PRectangle Window::GetClientPosition() {
+    if (! id) return PRectangle();
     wxSize sz = GETWIN(id)->GetClientSize();
     return  PRectangle(0, 0, sz.x, sz.y);
 }
@@ -631,6 +679,8 @@ void Window::SetCursor(Cursor curs) {
     case cursorReverseArrow:
         cursorId = wxCURSOR_RIGHT_ARROW;
         break;
+    case cursorHand:
+        cursorId = wxCURSOR_HAND;
     default:
         cursorId = wxCURSOR_ARROW;
         break;
@@ -653,199 +703,347 @@ void Window::SetTitle(const char *s) {
 // Helper classes for ListBox
 
 
-#if 1 // defined(__WXMAC__)
-class wxSTCListBoxWin : public wxListBox {
+// This is a simple subclass of wxLIstView that just resets focus to the
+// parent when it gets it.
+class wxSTCListBox : public wxListView {
 public:
-    wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
-        : wxListBox(parent, id, wxDefaultPosition, wxSize(0,0),
-                    0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER) {
-        SetCursor(wxCursor(wxCURSOR_ARROW));
-        Hide();
-    }
+    wxSTCListBox(wxWindow* parent, wxWindowID id,
+                 const wxPoint& pos, const wxSize& size,
+                 long style)
+        : wxListView(parent, id, pos, size, style)
+    {}
 
     void OnFocus(wxFocusEvent& event) {
         GetParent()->SetFocus();
         event.Skip();
     }
 
-    wxListBox* GetLB() { return this; }
-
 private:
     DECLARE_EVENT_TABLE()
 };
 
-
-BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxListBox)
-    EVT_SET_FOCUS(wxSTCListBoxWin::OnFocus)
+BEGIN_EVENT_TABLE(wxSTCListBox, wxListView)
+    EVT_SET_FOCUS( wxSTCListBox::OnFocus)
 END_EVENT_TABLE()
 
 
 
-#else
-
 
-class wxSTCListBox : public wxListBox {
+// A window to place the wxSTCListBox upon
+class wxSTCListBoxWin : public wxWindow {
+private:
+    wxListView*         lv;
+    CallBackAction      doubleClickAction;
+    void*               doubleClickActionData;
 public:
-    wxSTCListBox(wxWindow* parent, wxWindowID id)
-        : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize,
-                    0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER | wxWANTS_CHARS)
-        {}
-
-    void OnKeyDown(wxKeyEvent& event) {
-        // Give the key events to the STC.  It will then update
-        // the listbox as needed.
-        GetGrandParent()->GetEventHandler()->ProcessEvent(event);
+    wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
+        wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxNO_BORDER )
+    {
+
+        SetBackgroundColour(*wxBLACK);
+        lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
+                              wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER);
+        lv->SetCursor(wxCursor(wxCURSOR_ARROW));
+        lv->InsertColumn(0, wxEmptyString);
+        lv->InsertColumn(1, wxEmptyString);
+        Hide();
     }
 
-private:
-    DECLARE_EVENT_TABLE()
-};
-
-BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox)
-    EVT_KEY_DOWN(wxSTCListBox::OnKeyDown)
-    EVT_CHAR(wxSTCListBox::OnKeyDown)
-END_EVENT_TABLE()
-
+    int IconWidth() {
+        wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
+        if (il != NULL) {
+            int w, h;
+            il->GetSize(0, w, h);
+            return w;
+        }
+        return 0;
+    }
 
 
-#undef  wxSTC_USE_POPUP
-#define wxSTC_USE_POPUP 0  // wxPopupWindow just doesn't work well in this case...
+    void SetDoubleClickAction(CallBackAction action, void *data) {
+        doubleClickAction = action;
+        doubleClickActionData = data;
+    }
 
-// A window to place the listbox upon.  If wxPopupWindow is supported then
-// that will be used so the listbox can extend beyond the client area of the
-// wxSTC if needed.
-#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
-#include <wx/popupwin.h>
-#define wxSTCListBoxWinBase wxPopupWindow
-#define param2  wxBORDER_NONE  // popup's 2nd param is flags
-#else
-#define wxSTCListBoxWinBase wxWindow
-#define param2 -1 // wxWindow's 2nd param is ID
-#endif
 
-class wxSTCListBoxWin : public wxSTCListBoxWinBase {
-public:
-    wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
-        : wxSTCListBoxWinBase(parent, param2) {
-        lb = new wxSTCListBox(this, id);
-        lb->SetCursor(wxCursor(wxCURSOR_ARROW));
-        lb->SetFocus();
-   }
+    void OnFocus(wxFocusEvent& event) {
+        GetParent()->SetFocus();
+        event.Skip();
+    }
 
     void OnSize(wxSizeEvent& event) {
-        lb->SetSize(GetSize());
+        // resize the child, leaving a 1 pixel border
+        wxSize sz = GetClientSize();
+        lv->SetSize(1, 1, sz.x-2, sz.y-2);
+        // reset the column widths
+        lv->SetColumnWidth(0, IconWidth()+4);
+        lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
+                           wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
+        event.Skip();
     }
 
-    wxListBox* GetLB() { return lb; }
-
-#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
-    virtual void DoSetSize(int x, int y,
-                           int width, int height,
-                           int sizeFlags = wxSIZE_AUTO) {
-        if (x != -1)
-            GetParent()->ClientToScreen(&x, NULL);
-        if (y != -1)
-            GetParent()->ClientToScreen(NULL, &y);
-        wxSTCListBoxWinBase::DoSetSize(x, y, width, height, sizeFlags);
+    void OnActivate(wxListEvent& event) {
+        doubleClickAction(doubleClickActionData);
     }
-#endif
+
+    wxListView* GetLB() { return lv; }
 
 private:
-    wxSTCListBox* lb;
     DECLARE_EVENT_TABLE()
 };
 
-BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase)
-    EVT_SIZE(wxSTCListBoxWin::OnSize)
+
+BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow)
+    EVT_SET_FOCUS          (    wxSTCListBoxWin::OnFocus)
+    EVT_SIZE               (    wxSTCListBoxWin::OnSize)
+    EVT_LIST_ITEM_ACTIVATED(-1, wxSTCListBoxWin::OnActivate)
 END_EVENT_TABLE()
-#endif
 
-inline wxListBox* GETLB(WindowID win) {
-    return (((wxSTCListBoxWin*)win)->GetLB());
+
+
+inline wxSTCListBoxWin* GETLBW(WindowID win) {
+    return ((wxSTCListBoxWin*)win);
+}
+
+inline wxListView* GETLB(WindowID win) {
+    return GETLBW(win)->GetLB();
 }
 
 //----------------------------------------------------------------------
 
-ListBox::ListBox() {
+class ListBoxImpl : public ListBox {
+private:
+    int                 lineHeight;
+    bool                unicodeMode;
+    int                 desiredVisibleRows;
+    int                 aveCharWidth;
+    int                 maxStrWidth;
+    wxImageList*        imgList;
+    wxArrayInt*         imgTypeMap;
+
+public:
+    ListBoxImpl();
+    ~ListBoxImpl();
+
+    virtual void SetFont(Font &font);
+    virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_);
+    virtual void SetAverageCharWidth(int width);
+    virtual void SetVisibleRows(int rows);
+    virtual PRectangle GetDesiredRect();
+    virtual int CaretFromEdge();
+    virtual void Clear();
+    virtual void Append(char *s, int type = -1);
+    virtual int Length();
+    virtual void Select(int n);
+    virtual int GetSelection();
+    virtual int Find(const char *prefix);
+    virtual void GetValue(int n, char *value, int len);
+    virtual void Sort();
+    virtual void RegisterImage(int type, const char *xpm_data);
+    virtual void ClearRegisteredImages();
+    virtual void SetDoubleClickAction(CallBackAction, void *);
+
+};
+
+
+ListBoxImpl::ListBoxImpl()
+    : lineHeight(10), unicodeMode(false),
+      desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
+      imgList(NULL), imgTypeMap(NULL)
+{
 }
 
-ListBox::~ListBox() {
+ListBoxImpl::~ListBoxImpl() {
+    if (imgList) {
+        delete imgList;
+        imgList = NULL;
+    }
+    if (imgTypeMap) {
+        delete imgTypeMap;
+        imgTypeMap = NULL;
+    }
 }
 
-void ListBox::Create(Window &parent, int ctrlID) {
+
+void ListBoxImpl::SetFont(Font &font) {
+    GETLB(id)->SetFont(*((wxFont*)font.GetID()));
+}
+
+
+void ListBoxImpl::Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_) {
+    lineHeight =  lineHeight_;
+    unicodeMode = unicodeMode_;
+    maxStrWidth = 0;
     id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
+    if (imgList != NULL)
+        GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
 }
 
-void ListBox::SetVisibleRows(int rows) {
+
+void ListBoxImpl::SetAverageCharWidth(int width) {
+    aveCharWidth = width;
+}
+
+
+void ListBoxImpl::SetVisibleRows(int rows) {
     desiredVisibleRows = rows;
 }
 
-PRectangle ListBox::GetDesiredRect() {
-    wxSize sz = GETLB(id)->GetBestSize();
+
+PRectangle ListBoxImpl::GetDesiredRect() {
+    // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
+    // the max size in Append and calculate it here...
+    int maxw = maxStrWidth;
+    int maxh = 0;
+
+    // give it a default if there are no lines, and/or add a bit more
+    if (maxw == 0) maxw = 100;
+    maxw += aveCharWidth * 3 +
+            GETLBW(id)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
+    if (maxw > 350)
+        maxw = 350;
+
+    // estimate a desired height
+    int count = GETLB(id)->GetItemCount();
+    if (count) {
+        wxRect rect;
+        GETLB(id)->GetItemRect(0, rect);
+        maxh = count * rect.GetHeight();
+        if (maxh > 140)  // TODO:  Use desiredVisibleRows??
+            maxh = 140;
+
+        // Try to make the size an exact multiple of some number of lines
+        int lines = maxh / rect.GetHeight();
+        maxh = (lines + 1) * rect.GetHeight() + 2;
+    }
+    else
+        maxh = 100;
+
     PRectangle rc;
     rc.top = 0;
     rc.left = 0;
-    if (sz.x > 400)
-        sz.x = 400;
-    if (sz.y > 140)  // TODO:  Use desiredVisibleRows??
-        sz.y = 140;
-    rc.right = sz.x;
-    rc.bottom = sz.y;
+    rc.right = maxw;
+    rc.bottom = maxh;
     return rc;
 }
 
-void ListBox::SetAverageCharWidth(int width) {
-    aveCharWidth = width;
-}
 
-void ListBox::SetFont(Font &font) {
-    GETLB(id)->SetFont(*((wxFont*)font.GetID()));
+int ListBoxImpl::CaretFromEdge() {
+    return 4 + GETLBW(id)->IconWidth();
 }
 
-void ListBox::Clear() {
-    GETLB(id)->Clear();
+
+void ListBoxImpl::Clear() {
+    GETLB(id)->DeleteAllItems();
 }
 
-void ListBox::Append(char *s) {
-    GETLB(id)->Append(stc2wx(s));
+
+void ListBoxImpl::Append(char *s, int type) {
+    wxString text = stc2wx(s);
+    long count  = GETLB(id)->GetItemCount();
+    long itemID  = GETLB(id)->InsertItem(count, wxEmptyString);
+    GETLB(id)->SetItem(itemID, 1, text);
+    int itemWidth = 0;
+    GETLB(id)->GetTextExtent(text, &itemWidth, NULL);
+    maxStrWidth = wxMax(maxStrWidth, itemWidth);
+    if (type != -1) {
+        wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
+        long idx = imgTypeMap->Item(type);
+        GETLB(id)->SetItemImage(itemID, idx, idx);
+    }
 }
 
-int ListBox::Length() {
-    return GETLB(id)->GetCount();
+
+int ListBoxImpl::Length() {
+    return GETLB(id)->GetItemCount();
 }
 
-void ListBox::Select(int n) {
+
+void ListBoxImpl::Select(int n) {
     bool select = TRUE;
     if (n == -1) {
         n = 0;
         select = FALSE;
     }
-    GETLB(id)->SetSelection(n, select);
-#ifdef __WXGTK__
-    if (n > 4)
-        n = n - 4;
-    else
-        n = 0;
-    GETLB(id)->SetFirstItem(n);
-#endif
+    GETLB(id)->Focus(n);
+    GETLB(id)->Select(n, select);
 }
 
-int ListBox::GetSelection() {
-    return GETLB(id)->GetSelection();
+
+int ListBoxImpl::GetSelection() {
+    return GETLB(id)->GetFirstSelected();
 }
 
-int ListBox::Find(const char *prefix) {
+
+int ListBoxImpl::Find(const char *prefix) {
     // No longer used
     return -1;
 }
 
-void ListBox::GetValue(int n, char *value, int len) {
-    wxString text = GETLB(id)->GetString(n);
-    strncpy(value, wx2stc(text), len);
+
+void ListBoxImpl::GetValue(int n, char *value, int len) {
+    wxListItem item;
+    item.SetId(n);
+    item.SetColumn(1);
+    item.SetMask(wxLIST_MASK_TEXT);
+    GETLB(id)->GetItem(item);
+    strncpy(value, wx2stc(item.GetText()), len);
     value[len-1] = '\0';
 }
 
-void ListBox::Sort() {
+void ListBoxImpl::Sort() {
+}
+
+
+void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
+    wxMemoryInputStream stream(xpm_data, strlen(xpm_data)+1);
+    wxBitmap bmp(wxImage(stream, wxBITMAP_TYPE_XPM));
+
+    if (! imgList) {
+        // assumes all images are the same size
+        imgList = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), TRUE);
+        imgTypeMap = new wxArrayInt;
+    }
+
+    int idx = imgList->Add(bmp);
+
+    // do we need to extend the mapping array?
+    wxArrayInt& itm = *imgTypeMap;
+    if ( itm.GetCount() < type+1)
+        itm.Add(-1, type - itm.GetCount() + 1);
+
+    // Add an item that maps type to the image index
+    itm[type] = idx;
+}
+
+void ListBoxImpl::ClearRegisteredImages() {
+    if (imgList) {
+        delete imgList;
+        imgList = NULL;
+    }
+    if (imgTypeMap) {
+        delete imgTypeMap;
+        imgTypeMap = NULL;
+    }
+    if (id)
+        GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
+}
+
+
+void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
+    GETLBW(id)->SetDoubleClickAction(action, data);
+}
+
+
+
+ListBox::ListBox() {
+}
+
+ListBox::~ListBox() {
+}
+
+ListBox *ListBox::Allocate() {
+    return new ListBoxImpl();
 }
 
 //----------------------------------------------------------------------
@@ -890,13 +1088,16 @@ const char *Platform::DefaultFont() {
 }
 
 int Platform::DefaultFontSize() {
-    return 8;
+    return wxNORMAL_FONT->GetPointSize();
 }
 
 unsigned int Platform::DoubleClickTime() {
     return 500;   // **** ::GetDoubleClickTime();
 }
 
+bool Platform::MouseButtonBounce() {
+       return FALSE;
+}
 void Platform::DebugDisplay(const char *s) {
     wxLogDebug(stc2wx(s));
 }
@@ -998,6 +1199,13 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) {
     return false;
 }
 
+int Platform::DBCSCharLength(int codePage, const char *s) {
+    return 0;
+}
+
+int Platform::DBCSCharMaxLength() {
+    return 0;
+}
 
 
 //----------------------------------------------------------------------
index 12ad21dafe4403a3aeab97d9023096c8c87ba02b..9aeda729c7301fea568d4bb2df53453ad273090a 100644 (file)
@@ -67,26 +67,28 @@ void  wxSTCDropTarget::OnLeave() {
 #define param2  wxBORDER_NONE  // popup's 2nd param is flags
 #else
 #define wxSTCCallTipBase wxWindow
-#define param2 -1 // wxWindows 2nd param is ID
+#define param2 -1 // wxWindow's 2nd param is ID
 #endif
 
 class wxSTCCallTip : public wxSTCCallTipBase {
 public:
-    wxSTCCallTip(wxWindow* parent, CallTip* ct)
-        : wxSTCCallTipBase(parent, param2)
+    wxSTCCallTip(wxWindow* parent, CallTip* ct, ScintillaWX* swx)
+        : wxSTCCallTipBase(parent, param2),
+          m_ct(ct), m_swx(swx)
         {
-            m_ct = ct;
         }
 
     ~wxSTCCallTip() {
-        if (HasCapture()) ReleaseMouse();
     }
 
+    bool AcceptsFocus() const { return FALSE; }
+
     void OnPaint(wxPaintEvent& evt) {
         wxPaintDC dc(this);
         Surface* surfaceWindow = Surface::Allocate();
-        surfaceWindow->Init(&dc);
+        surfaceWindow->Init(&dc, m_ct->wDraw.GetID());
         m_ct->PaintCT(surfaceWindow);
+        surfaceWindow->Release();
         delete surfaceWindow;
     }
 
@@ -95,6 +97,13 @@ public:
         event.Skip();
     }
 
+    void OnLeftDown(wxMouseEvent& event) {
+        wxPoint pt = event.GetPosition();
+        Point p(pt.x, pt.y);
+        m_ct->MouseClick(p);
+        m_swx->CallTipClick();
+    }
+
 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP
     virtual void DoSetSize(int x, int y,
                            int width, int height,
@@ -105,32 +114,18 @@ public:
             GetParent()->ClientToScreen(NULL, &y);
         wxSTCCallTipBase::DoSetSize(x, y, width, height, sizeFlags);
     }
-
-    virtual bool Show( bool show = TRUE ) {
-        bool retval = wxSTCCallTipBase::Show(show);
-        if (show)
-            CaptureMouse();
-        else
-            if (HasCapture()) ReleaseMouse();
-        return retval;
-    }
-
-    void OnLeftDown(wxMouseEvent& ) {
-        Show(FALSE);
-    }
 #endif
 
 private:
-    CallTip*    m_ct;
+    CallTip*      m_ct;
+    ScintillaWX*  m_swx;
     DECLARE_EVENT_TABLE()
 };
 
 BEGIN_EVENT_TABLE(wxSTCCallTip, wxSTCCallTipBase)
     EVT_PAINT(wxSTCCallTip::OnPaint)
     EVT_SET_FOCUS(wxSTCCallTip::OnFocus)
-#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
     EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown)
-#endif
 END_EVENT_TABLE()
 
 
@@ -139,6 +134,7 @@ END_EVENT_TABLE()
 
 
 ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
+    capturedMouse = false;
     wMain = win;
     stc   = win;
     wheelRotation = 0;
@@ -220,15 +216,16 @@ void ScintillaWX::SetTicking(bool on) {
 
 
 void ScintillaWX::SetMouseCapture(bool on) {
-    if (on && !stc->HasCapture())
+    if (on && !capturedMouse)
         stc->CaptureMouse();
-    else if (!on && stc->HasCapture())
+    else if (!on && capturedMouse && stc->HasCapture())
         stc->ReleaseMouse();
+    capturedMouse = on;
 }
 
 
 bool ScintillaWX::HaveMouseCapture() {
-    return stc->HasCapture();
+    return capturedMouse;
 }
 
 
@@ -387,8 +384,10 @@ bool ScintillaWX::CanPaste() {
 }
 
 void ScintillaWX::CreateCallTipWindow(PRectangle) {
-    ct.wCallTip = new wxSTCCallTip(stc, &ct);
-    ct.wDraw = ct.wCallTip;
+    if (! ct.wCallTip.Created() ) {
+        ct.wCallTip = new wxSTCCallTip(stc, &ct, this);
+        ct.wDraw = ct.wCallTip;
+    }
 }
 
 
@@ -436,37 +435,37 @@ long ScintillaWX::WndProc(unsigned int iMessage, unsigned long wParam, long lPar
       switch (iMessage) {
       case SCI_CALLTIPSHOW: {
           // NOTE: This is copied here from scintilla/src/ScintillaBase.cxx
-          // because of the little tweak that needs done below.  When updating
-          // new versions double check that this is still needed, and that any
-          // new code there is copied here too.
+          // because of the little tweak that needs done below for wxGTK.
+          // When updating new versions double check that this is still
+          // needed, and that any new code there is copied here too.
+          Point pt = LocationFromPosition(wParam);
+          char* defn = reinterpret_cast<char *>(lParam);
           AutoCompleteCancel();
-          if (!ct.wCallTip.Created()) {
-              Point pt = LocationFromPosition(wParam);
-              pt.y += vs.lineHeight;
-              PRectangle rc = ct.CallTipStart(currentPos, pt,
-                                              reinterpret_cast<char *>(lParam),
-                                              vs.styles[STYLE_DEFAULT].fontName,
-                                              vs.styles[STYLE_DEFAULT].sizeZoomed,
-                                              IsUnicodeMode());
-              // If the call-tip window would be out of the client
-              // space, adjust so it displays above the text.
-              PRectangle rcClient = GetClientRectangle();
-              if (rc.bottom > rcClient.bottom) {
+          pt.y += vs.lineHeight;
+          PRectangle rc = ct.CallTipStart(currentPos, pt,
+                                          defn,
+                                          vs.styles[STYLE_DEFAULT].fontName,
+                                          vs.styles[STYLE_DEFAULT].sizeZoomed,
+                                          IsUnicodeMode(),
+                                          wMain);
+          // If the call-tip window would be out of the client
+          // space, adjust so it displays above the text.
+          PRectangle rcClient = GetClientRectangle();
+          if (rc.bottom > rcClient.bottom) {
 #ifdef __WXGTK__
-                  int offset = int(vs.lineHeight * 1.25)  + rc.Height();
+              int offset = int(vs.lineHeight * 1.25)  + rc.Height();
 #else
-                  int offset = vs.lineHeight + rc.Height();
+              int offset = vs.lineHeight + rc.Height();
 #endif
-                  rc.top -= offset;
-                  rc.bottom -= offset;
-              }
-              // Now display the window.
-              CreateCallTipWindow(rc);
-              ct.wCallTip.SetPositionRelative(rc, wMain);
-              ct.wCallTip.Show();
+              rc.top -= offset;
+              rc.bottom -= offset;
           }
-      }
+          // Now display the window.
+          CreateCallTipWindow(rc);
+          ct.wCallTip.SetPositionRelative(rc, wMain);
+          ct.wCallTip.Show();
           break;
+      }
 
       default:
           return ScintillaBase::WndProc(iMessage, wParam, lParam);
@@ -483,22 +482,22 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
 
     paintState = painting;
     Surface* surfaceWindow = Surface::Allocate();
-    surfaceWindow->Init(dc);
-    PRectangle rcPaint = PRectangleFromwxRect(rect);
+    surfaceWindow->Init(dc, wMain.GetID());
+    rcPaint = PRectangleFromwxRect(rect);
+    PRectangle rcClient = GetClientRectangle();
+    paintingAllText = rcPaint.Contains(rcClient);
+
     dc->BeginDrawing();
+    ClipChildren(*dc, rcPaint);
     Paint(surfaceWindow, rcPaint);
     dc->EndDrawing();
+
     delete surfaceWindow;
     if (paintState == paintAbandoned) {
         // Painting area was insufficient to cover new styling or brace highlight positions
         FullPaint();
     }
     paintState = notPainting;
-#ifdef __WXGTK__
-    // On wxGTK the editor window paints can overwrite the listbox...
-    if (ac.Active())
-        ((wxWindow*)ac.lb.GetID())->Refresh(TRUE);
-#endif
 }
 
 
@@ -775,16 +774,18 @@ void ScintillaWX::DoDragLeave() {
 // Redraw all of text area. This paint will not be abandoned.
 void ScintillaWX::FullPaint() {
     paintState = painting;
-    rcPaint = GetTextRectangle();
+    rcPaint = GetClientRectangle();
     paintingAllText = true;
     wxClientDC dc(stc);
     Surface* surfaceWindow = Surface::Allocate();
-    surfaceWindow->Init(&dc);
-    Paint(surfaceWindow, rcPaint);
-    delete surfaceWindow;
+    surfaceWindow->Init(&dc, wMain.GetID());
 
-//     stc->Refresh(FALSE);
+    dc.BeginDrawing();
+    ClipChildren(dc, rcPaint);
+    Paint(surfaceWindow, rcPaint);
+    dc.EndDrawing();
 
+    delete surfaceWindow;
     paintState = notPainting;
 }
 
@@ -798,6 +799,21 @@ void ScintillaWX::DoScrollToColumn(int column) {
     HorizontalScrollTo(column * vs.spaceWidth);
 }
 
+void ScintillaWX::ClipChildren(wxDC& dc, PRectangle rect) {
+#ifdef __WXGTK__
+    wxRegion rgn(wxRectFromPRectangle(rect));
+    if (ac.Active()) {
+        wxRect childRect = ((wxWindow*)ac.lb->GetID())->GetRect();
+        rgn.Subtract(childRect);
+    }
+    if (ct.inCallTipMode) {
+        wxRect childRect = ((wxWindow*)ct.wCallTip.GetID())->GetRect();
+        rgn.Subtract(childRect);
+    }
+
+    dc.SetClippingRegion(rgn);
+#endif
+}
 
 
 //----------------------------------------------------------------------
index 04b2ac03334234128380d6be32010656e2b09033..4c6b35c6e3276e05ca65aa4743b1284a840829bb 100644 (file)
@@ -27,6 +27,7 @@
 #include "Platform.h"
 
 #include "Scintilla.h"
+#include "XPM.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
 #include "PropSet.h"
@@ -149,8 +150,10 @@ public:
     bool GetHideSelection() { return hideSelection; }
     void DoScrollToLine(int line);
     void DoScrollToColumn(int column);
+    void ClipChildren(wxDC& dc, PRectangle rect);
 
 private:
+    bool                capturedMouse;
     wxStyledTextCtrl*   stc;
 
 #if wxUSE_DRAG_AND_DROP
@@ -158,6 +161,9 @@ private:
     wxDragResult        dragResult;
 #endif
     int                 wheelRotation;
+
+
+    friend class wxSTCCallTip;
 };
 
 //----------------------------------------------------------------------
index a6c2c4ce95dad7c2ab2e0b5d1925a8596c2b7399..7007794571f48ddf4980591b93af0125df90a566 100644 (file)
@@ -282,6 +282,10 @@ SOURCE=.\scintilla\src\LexAda.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexAsm.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexAVE.cxx
 # End Source File
 # Begin Source File
@@ -306,10 +310,18 @@ SOURCE=.\scintilla\src\LexCrontab.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexCSS.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexEiffel.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexFortran.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexHTML.cxx
 # End Source File
 # Begin Source File
@@ -330,6 +342,10 @@ SOURCE=.\scintilla\src\LexOthers.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexPOV.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexPascal.cxx
 # End Source File
 # Begin Source File
@@ -446,6 +462,10 @@ SOURCE=.\scintilla\src\WindowAccessor.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\XPM.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\include\WindowAccessor.h
 # End Source File
 # End Group
index 668938046684a360c1626c342c873d4696c4d617..885357f398abddf8e4799deb61bcb78d0916ec2b 100644 (file)
@@ -42,6 +42,9 @@ cmdValues = [ (2300, 2349),
               (2176, 2180),
               (2390, 2393),
               (2395, 2396),
+              2404,
+              (2413, 2416),
+              (2450, 2454),
             ]
 
 
@@ -88,90 +91,114 @@ methodOverrideMap = {
     'GetViewWS' : ( 'GetViewWhiteSpace', 0, 0, 0),
     'SetViewWS' : ( 'SetViewWhiteSpace', 0, 0, 0),
 
-    'GetCharAt' : ( 0, 0,
-                    '''int %s(int pos) {
-                       return (unsigned char)SendMsg(%s, pos, 0);''',
-                    0),
-
-    'GetStyleAt' : ( 0, 0,
-                    '''int %s(int pos) {
-                       return (unsigned char)SendMsg(%s, pos, 0);''',
-                    0),
-
-    'GetStyledText' : (0,
-                       'wxMemoryBuffer %s(int startPos, int endPos);',
-
-                       '''wxMemoryBuffer %s(int startPos, int endPos) {
-                          wxMemoryBuffer buf;
-                          if (endPos < startPos) {
-                              int temp = startPos;
-                              startPos = endPos;
-                              endPos = temp;
-                          }
-                          int len = endPos - startPos;
-                          if (!len) return buf;
-                          TextRange tr;
-                          tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
-                          tr.chrg.cpMin = startPos;
-                          tr.chrg.cpMax = endPos;
-                          len = SendMsg(%s, 0, (long)&tr);
-                          buf.UngetWriteBuf(len);
-                          return buf;''',
-
-                       ('Retrieve a buffer of cells.',)),
-
-
-    'PositionFromPoint' : (0,
-                           'int %s(wxPoint pt);',
-
-                           '''int %s(wxPoint pt) {
-                              return SendMsg(%s, pt.x, pt.y);''',
-
-                           0),
-
-    'GetCurLine' : (0,
-                    '#ifdef SWIG\n    wxString %s(int* OUTPUT);\n#else\n    wxString GetCurLine(int* linePos=NULL);\n#endif',
-
-                    '''wxString %s(int* linePos) {
-                       int len = LineLength(GetCurrentLine());
-                       if (!len) {
-                           if (linePos)  *linePos = 0;
-                           return wxEmptyString;
-                       }
-
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
-
-                       int pos = SendMsg(%s, len+1, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       if (linePos)  *linePos = pos;
-                       return stc2wx(buf);''',
-
-                    0),
+    'GetCharAt' :
+    ( 0, 0,
+      '''int %s(int pos) {
+         return (unsigned char)SendMsg(%s, pos, 0);''',
+      0),
+
+    'GetStyleAt' :
+    ( 0, 0,
+      '''int %s(int pos) {
+         return (unsigned char)SendMsg(%s, pos, 0);''',
+      0),
+
+    'GetStyledText' :
+    (0,
+     'wxMemoryBuffer %s(int startPos, int endPos);',
+
+     '''wxMemoryBuffer %s(int startPos, int endPos) {
+        wxMemoryBuffer buf;
+        if (endPos < startPos) {
+            int temp = startPos;
+            startPos = endPos;
+            endPos = temp;
+        }
+        int len = endPos - startPos;
+        if (!len) return buf;
+        TextRange tr;
+        tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
+        tr.chrg.cpMin = startPos;
+        tr.chrg.cpMax = endPos;
+        len = SendMsg(%s, 0, (long)&tr);
+        buf.UngetWriteBuf(len);
+        return buf;''',
+
+     ('Retrieve a buffer of cells.',)),
+
+
+    'PositionFromPoint' :
+    (0,
+     'int %s(wxPoint pt);',
+
+     '''int %s(wxPoint pt) {
+        return SendMsg(%s, pt.x, pt.y);''',
+     0),
+
+    'GetCurLine' :
+    (0,
+     '#ifdef SWIG\n    wxString %s(int* OUTPUT);\n#else\n    wxString GetCurLine(int* linePos=NULL);\n#endif',
+
+        '''wxString %s(int* linePos) {
+        int len = LineLength(GetCurrentLine());
+        if (!len) {
+            if (linePos)  *linePos = 0;
+            return wxEmptyString;
+        }
+
+        wxMemoryBuffer mbuf(len+1);
+        char* buf = (char*)mbuf.GetWriteBuf(len+1);
+
+        int pos = SendMsg(%s, len+1, (long)buf);
+        mbuf.UngetWriteBuf(len);
+        mbuf.AppendByte(0);
+        if (linePos)  *linePos = pos;
+        return stc2wx(buf);''',
+
+     0),
 
     'SetUsePalette' : (None, 0,0,0),
 
     'MarkerSetFore' : ('MarkerSetForeground', 0, 0, 0),
     'MarkerSetBack' : ('MarkerSetBackground', 0, 0, 0),
 
-    'MarkerDefine' : (0,
-                      '''void %s(int markerNumber, int markerSymbol,
-                         const wxColour& foreground = wxNullColour,
-                         const wxColour& background = wxNullColour);''',
-
-                      '''void %s(int markerNumber, int markerSymbol,
-                            const wxColour& foreground,
-                            const wxColour& background) {
-
-                            SendMsg(%s, markerNumber, markerSymbol);
-                            if (foreground.Ok())
-                                MarkerSetForeground(markerNumber, foreground);
-                            if (background.Ok())
-                                MarkerSetBackground(markerNumber, background);''',
+    'MarkerDefine' :
+    (0,
+     '''void %s(int markerNumber, int markerSymbol,
+                const wxColour& foreground = wxNullColour,
+                const wxColour& background = wxNullColour);''',
+
+     '''void %s(int markerNumber, int markerSymbol,
+                const wxColour& foreground,
+                const wxColour& background) {
+
+                SendMsg(%s, markerNumber, markerSymbol);
+                if (foreground.Ok())
+                    MarkerSetForeground(markerNumber, foreground);
+                if (background.Ok())
+                    MarkerSetBackground(markerNumber, background);''',
+
+     ('Set the symbol used for a particular marker number,',
+      'and optionally the fore and background colours.')),
+
+
+    'MarkerDefinePixmap' :
+    ('MarkerDefineBitmap',
+     '''void %s(int markerNumber, const wxBitmap& bmp);''',
+     '''void %s(int markerNumber, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(%s, markerNumber, (long)buff);
+        delete [] buff;
+        ''',
+     ('Define a marker from a bitmap',)),
 
-                      ('Set the symbol used for a particular marker number,',
-                       'and optionally the fore and background colours.')),
 
     'SetMarginTypeN' : ('SetMarginType', 0, 0, 0),
     'GetMarginTypeN' : ('GetMarginType', 0, 0, 0),
@@ -189,32 +216,33 @@ methodOverrideMap = {
     'SetCaretFore' : ('SetCaretForeground', 0, 0, 0),
     'StyleSetFont' : ('StyleSetFaceName', 0, 0, 0),
 
-    'AssignCmdKey' : ('CmdKeyAssign',
-                      'void %s(int key, int modifiers, int cmd);',
+    'AssignCmdKey' :
+    ('CmdKeyAssign',
+     'void %s(int key, int modifiers, int cmd);',
 
-                      '''void %s(int key, int modifiers, int cmd) {
-                          SendMsg(%s, MAKELONG(key, modifiers), cmd);''',
+     '''void %s(int key, int modifiers, int cmd) {
+         SendMsg(%s, MAKELONG(key, modifiers), cmd);''',
+     0),
 
-                      0),
 
-    'ClearCmdKey' : ('CmdKeyClear',
-                      'void %s(int key, int modifiers);',
+    'ClearCmdKey' :
+    ('CmdKeyClear',
+     'void %s(int key, int modifiers);',
 
-                      '''void %s(int key, int modifiers) {
-                          SendMsg(%s, MAKELONG(key, modifiers));''',
-
-                      0),
+     '''void %s(int key, int modifiers) {
+         SendMsg(%s, MAKELONG(key, modifiers));''',
+     0),
 
     'ClearAllCmdKeys' : ('CmdKeyClearAll', 0, 0, 0),
 
 
-    'SetStylingEx' : ('SetStyleBytes',
-                      'void %s(int length, char* styleBytes);',
-
-                      '''void %s(int length, char* styleBytes) {
-                          SendMsg(%s, length, (long)styleBytes);''',
+    'SetStylingEx' :
+    ('SetStyleBytes',
+     'void %s(int length, char* styleBytes);',
 
-                      0),
+     '''void %s(int length, char* styleBytes) {
+        SendMsg(%s, length, (long)styleBytes);''',
+     0),
 
 
     'IndicSetStyle' : ('IndicatorSetStyle', 0, 0, 0),
@@ -245,129 +273,162 @@ methodOverrideMap = {
     'AutoCGetAutoHide' : ('AutoCompGetAutoHide', 0, 0, 0),
     'AutoCSetDropRestOfWord' : ('AutoCompSetDropRestOfWord', 0,0,0),
     'AutoCGetDropRestOfWord' : ('AutoCompGetDropRestOfWord', 0,0,0),
+    'AutoCGetTypeSeparator' : ('AutoCompGetTypeSeparator', 0, 0, 0),
+    'AutoCSetTypeSeparator' : ('AutoCompSetTypeSeparator', 0, 0, 0),
+
+    'RegisterImage' :
+    (0,
+     '''void %s(int type, const wxBitmap& bmp);''',
+     '''void %s(int type, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(%s, type, (long)buff);
+        delete [] buff;
+     ''',
+     ('Register an image for use in autocompletion lists.',)),
+
+
+    'ClearRegisteredImages' : (0, 0, 0,
+                               ('Clear all the registered images.',)),
 
 
     'SetHScrollBar' : ('SetUseHorizontalScrollBar', 0, 0, 0),
     'GetHScrollBar' : ('GetUseHorizontalScrollBar', 0, 0, 0),
 
+    'SetVScrollBar' : ('SetUseVerticalScrollBar', 0, 0, 0),
+    'GetVScrollBar' : ('GetUseVerticalScrollBar', 0, 0, 0),
+
     'GetCaretFore' : ('GetCaretForeground', 0, 0, 0),
 
     'GetUsePalette' : (None, 0, 0, 0),
 
-    'FindText' : (0,
-                  '''int %s(int minPos, int maxPos, const wxString& text, int flags=0);''',
-
-                  '''int %s(int minPos, int maxPos,
-                            const wxString& text,
-                            int flags) {
-                     TextToFind  ft;
-                     ft.chrg.cpMin = minPos;
-                     ft.chrg.cpMax = maxPos;
-                     wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                     ft.lpstrText = (char*)(const char*)buf;
-
-                     return SendMsg(%s, flags, (long)&ft);''',
-                  0),
-
-    'FormatRange' : (0,
-                     '''int %s(bool   doDraw,
-                               int    startPos,
-                               int    endPos,
-                               wxDC*  draw,
-                               wxDC*  target,  // Why does it use two? Can they be the same?
-                               wxRect renderRect,
-                               wxRect pageRect);''',
-                     ''' int %s(bool   doDraw,
-                                int    startPos,
-                                int    endPos,
-                                wxDC*  draw,
-                                wxDC*  target,  // Why does it use two? Can they be the same?
-                                wxRect renderRect,
-                                wxRect pageRect) {
-                            RangeToFormat fr;
-
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            fr.hdc = draw;
-                            fr.hdcTarget = target;
-                            fr.rc.top = renderRect.GetTop();
-                            fr.rc.left = renderRect.GetLeft();
-                            fr.rc.right = renderRect.GetRight();
-                            fr.rc.bottom = renderRect.GetBottom();
-                            fr.rcPage.top = pageRect.GetTop();
-                            fr.rcPage.left = pageRect.GetLeft();
-                            fr.rcPage.right = pageRect.GetRight();
-                            fr.rcPage.bottom = pageRect.GetBottom();
-                            fr.chrg.cpMin = startPos;
-                            fr.chrg.cpMax = endPos;
-
-                            return SendMsg(%s, doDraw, (long)&fr);''',
-                     0),
-
-
-    'GetLine' : (0,
-                    'wxString %s(int line);',
-
-                    '''wxString %s(int line) {
-                       int len = LineLength(line);
-                       if (!len) return wxEmptyString;
-
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                       SendMsg(%s, line, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       return stc2wx(buf);''',
-
-                    ('Retrieve the contents of a line.',)),
+    'FindText' :
+    (0,
+     '''int %s(int minPos, int maxPos, const wxString& text, int flags=0);''',
+
+     '''int %s(int minPos, int maxPos,
+               const wxString& text,
+               int flags) {
+            TextToFind  ft;
+            ft.chrg.cpMin = minPos;
+            ft.chrg.cpMax = maxPos;
+            wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+            ft.lpstrText = (char*)(const char*)buf;
+
+            return SendMsg(%s, flags, (long)&ft);''',
+     0),
+
+    'FormatRange' :
+    (0,
+     '''int %s(bool   doDraw,
+               int    startPos,
+               int    endPos,
+               wxDC*  draw,
+               wxDC*  target,  // Why does it use two? Can they be the same?
+               wxRect renderRect,
+               wxRect pageRect);''',
+     ''' int %s(bool   doDraw,
+                int    startPos,
+                int    endPos,
+                wxDC*  draw,
+                wxDC*  target,  // Why does it use two? Can they be the same?
+                wxRect renderRect,
+                wxRect pageRect) {
+             RangeToFormat fr;
+
+             if (endPos < startPos) {
+                 int temp = startPos;
+                 startPos = endPos;
+                 endPos = temp;
+             }
+             fr.hdc = draw;
+             fr.hdcTarget = target;
+             fr.rc.top = renderRect.GetTop();
+             fr.rc.left = renderRect.GetLeft();
+             fr.rc.right = renderRect.GetRight();
+             fr.rc.bottom = renderRect.GetBottom();
+             fr.rcPage.top = pageRect.GetTop();
+             fr.rcPage.left = pageRect.GetLeft();
+             fr.rcPage.right = pageRect.GetRight();
+             fr.rcPage.bottom = pageRect.GetBottom();
+             fr.chrg.cpMin = startPos;
+             fr.chrg.cpMax = endPos;
+
+             return SendMsg(%s, doDraw, (long)&fr);''',
+     0),
+
+
+    'GetLine' :
+    (0,
+     'wxString %s(int line);',
+
+     '''wxString %s(int line) {
+         int len = LineLength(line);
+         if (!len) return wxEmptyString;
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(%s, line, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+
+     ('Retrieve the contents of a line.',)),
 
     'SetSel' : ('SetSelection', 0, 0, 0),
-    'GetSelText' : ('GetSelectedText',
-                    'wxString %s();',
-
-                    '''wxString %s() {
-                            int   start;
-                            int   end;
-
-                            GetSelection(&start, &end);
-                            int   len  = end - start;
-                            if (!len) return wxEmptyString;
-
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                            SendMsg(%s, 0, (long)buf);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);''',
-
-                    ('Retrieve the selected text.',)),
-
-    'GetTextRange' : (0,
-                      'wxString %s(int startPos, int endPos);',
-
-                      '''wxString %s(int startPos, int endPos) {
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            int   len  = endPos - startPos;
-                            if (!len) return wxEmptyString;
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len);
-                            TextRange tr;
-                            tr.lpstrText = buf;
-                            tr.chrg.cpMin = startPos;
-                            tr.chrg.cpMax = endPos;
-                            SendMsg(%s, 0, (long)&tr);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);''',
-
-                       ('Retrieve a range of text.',)),
+
+    'GetSelText' :
+    ('GetSelectedText',
+     'wxString %s();',
+
+     '''wxString %s() {
+         int   start;
+         int   end;
+
+         GetSelection(&start, &end);
+         int   len  = end - start;
+         if (!len) return wxEmptyString;
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(%s, 0, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+
+     ('Retrieve the selected text.',)),
+
+
+    'GetTextRange' :
+    (0,
+     'wxString %s(int startPos, int endPos);',
+
+     '''wxString %s(int startPos, int endPos) {
+         if (endPos < startPos) {
+             int temp = startPos;
+             startPos = endPos;
+             endPos = temp;
+         }
+         int   len  = endPos - startPos;
+         if (!len) return wxEmptyString;
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len);
+         TextRange tr;
+         tr.lpstrText = buf;
+         tr.chrg.cpMin = startPos;
+         tr.chrg.cpMax = endPos;
+         SendMsg(%s, 0, (long)&tr);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+
+     ('Retrieve a range of text.',)),
 
     'PointXFromPosition' : (None, 0, 0, 0),
     'PointYFromPosition' : (None, 0, 0, 0),
@@ -376,88 +437,104 @@ methodOverrideMap = {
     'ReplaceSel' : ('ReplaceSelection', 0, 0, 0),
     'Null' : (None, 0, 0, 0),
 
-    'GetText' : (0,
-                 'wxString %s();',
+    'GetText' :
+    (0,
+     'wxString %s();',
 
-                 '''wxString %s() {
-                        int len  = GetTextLength();
-                        wxMemoryBuffer mbuf(len+1);   // leave room for the null...
-                        char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                        SendMsg(%s, len+1, (long)buf);
-                        mbuf.UngetWriteBuf(len);
-                        mbuf.AppendByte(0);
-                        return stc2wx(buf);''',
+     '''wxString %s() {
+         int len  = GetTextLength();
+         wxMemoryBuffer mbuf(len+1);   // leave room for the null...
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(%s, len+1, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
 
-                 ('Retrieve all the text in the document.', )),
+     ('Retrieve all the text in the document.', )),
 
     'GetDirectFunction' : (None, 0, 0, 0),
     'GetDirectPointer' : (None, 0, 0, 0),
 
-    'CallTipPosStart' : ('CallTipPosAtStart', 0, 0, 0),
-    'CallTipSetHlt' : ('CallTipSetHighlight', 0, 0, 0),
-    'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0),
-
-
-    'ReplaceTarget' : (0,
-                       'int %s(const wxString& text);',
-
-                       '''
-                       int %s(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
-                       0),
-
-    'ReplaceTargetRE' : (0,
-                       'int %s(const wxString& text);',
-
-                       '''
-                       int %s(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
-                       0),
-
-    'SearchInTarget' : (0,
-                       'int %s(const wxString& text);',
-
-                       '''
-                       int %s(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
-                       0),
-
-
-    'GetDocPointer' : (0,
-                       'void* %s();',
-                       '''void* %s() {
-                           return (void*)SendMsg(%s);''',
-                       0),
-
-    'SetDocPointer' : (0,
-                       'void %s(void* docPointer);',
-                       '''void %s(void* docPointer) {
-                           SendMsg(%s, 0, (long)docPointer);''',
-                       0),
-
-    'CreateDocument' : (0,
-                       'void* %s();',
-                       '''void* %s() {
-                           return (void*)SendMsg(%s);''',
-                        0),
-
-    'AddRefDocument' : (0,
-                       'void %s(void* docPointer);',
-                       '''void %s(void* docPointer) {
-                           SendMsg(%s, 0, (long)docPointer);''',
-                        0),
-
-    'ReleaseDocument' : (0,
-                       'void %s(void* docPointer);',
-                       '''void %s(void* docPointer) {
-                           SendMsg(%s, 0, (long)docPointer);''',
-                         0),
-    'SetCodePage' : (0,
-                     0,
-                     '''void %s(int codePage) {
+    'CallTipPosStart'   : ('CallTipPosAtStart', 0, 0, 0),
+    'CallTipSetHlt'     : ('CallTipSetHighlight', 0, 0, 0),
+    'CallTipSetBack'    : ('CallTipSetBackground', 0, 0, 0),
+    'CallTipSetFore'    : ('CallTipSetForeground', 0, 0, 0),
+    'CallTipSetForeHlt' : ('CallTipSetForegroundHighlight', 0, 0, 0),
+
+    'SetHotspotActiveFore' : ('SetHotspotActiveForeground', 0, 0, 0),
+    'SetHotspotActiveBack' : ('SetHotspotActiveBackground', 0, 0, 0),
+
+
+    'ReplaceTarget' :
+    (0,
+     'int %s(const wxString& text);',
+
+     '''
+     int %s(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
+     0),
+
+    'ReplaceTargetRE' :
+    (0,
+     'int %s(const wxString& text);',
+
+     '''
+     int %s(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
+     0),
+
+    'SearchInTarget' :
+    (0,
+     'int %s(const wxString& text);',
+
+     '''
+     int %s(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
+     0),
+
+
+    'GetDocPointer' :
+    (0,
+     'void* %s();',
+     '''void* %s() {
+         return (void*)SendMsg(%s);''',
+     0),
+
+    'SetDocPointer' :
+    (0,
+     'void %s(void* docPointer);',
+     '''void %s(void* docPointer) {
+         SendMsg(%s, 0, (long)docPointer);''',
+     0),
+
+    'CreateDocument' :
+    (0,
+     'void* %s();',
+     '''void* %s() {
+         return (void*)SendMsg(%s);''',
+     0),
+
+    'AddRefDocument' :
+    (0,
+     'void %s(void* docPointer);',
+     '''void %s(void* docPointer) {
+         SendMsg(%s, 0, (long)docPointer);''',
+     0),
+
+    'ReleaseDocument' :
+    (0,
+     'void %s(void* docPointer);',
+     '''void %s(void* docPointer) {
+         SendMsg(%s, 0, (long)docPointer);''',
+     0),
+
+    'SetCodePage' :
+    (0,
+     0,
+     '''void %s(int codePage) {
 #if wxUSE_UNICODE
     wxASSERT_MSG(codePage == wxSTC_CP_UTF8,
                  wxT("Only wxSTC_CP_UTF8 may be used when wxUSE_UNICODE is on."));
@@ -465,8 +542,8 @@ methodOverrideMap = {
     wxASSERT_MSG(codePage != wxSTC_CP_UTF8,
                  wxT("wxSTC_CP_UTF8 may not be used when wxUSE_UNICODE is off."));
 #endif
-                 SendMsg(%s, codePage);''',
-                         ("Set the code page used to interpret the bytes of the document as characters.",) ),
+    SendMsg(%s, codePage);''',
+     ("Set the code page used to interpret the bytes of the document as characters.",) ),
 
 
     'GrabFocus' : (None, 0, 0, 0),
@@ -474,6 +551,9 @@ methodOverrideMap = {
     'GetFocus'  : ('GetSTCFocus', 0, 0, 0),
 
 
+    'LoadLexerLibrary' : (None, 0,0,0),
+
+
 
     # Remove all methods that are key commands since they can be
     # executed with CmdKeyExecute
@@ -522,7 +602,16 @@ methodOverrideMap = {
     'LineScrollDown' : (None, 0, 0, 0),
     'LineScrollUp' : (None, 0, 0, 0),
     'DeleteBackNotLine' : (None, 0, 0, 0),
-
+    'HomeWrap' : (None, 0, 0, 0),
+    'HomeWrapExtend' : (None, 0, 0, 0),
+    'LineEndWrap' : (None, 0, 0, 0),
+    'LineEndWrapExtend' : (None, 0, 0, 0),
+    'VCHomeWrap' : (None, 0, 0, 0),
+    'VCHomeWrapExtend' : (None, 0, 0, 0),
+    'ParaDown' : (None, 0, 0, 0),
+    'ParaDownExtend' : (None, 0, 0, 0),
+    'ParaUp' : (None, 0, 0, 0),
+    'ParaUpExtend' : (None, 0, 0, 0),
 
 
 
index 5a9843f863077cb96a351b3658af499d9e606638..345d6590004c8d32f8a07b62bf2a9946fef0f816 100644 (file)
@@ -34,17 +34,21 @@ OBJECTS = \
         KeyWords.obj           \
        LexAVE.obj              \
        LexAda.obj              \
+       LexAsm.obj              \
        LexBaan.obj             \
        LexBullant.obj          \
        LexMatlab.obj           \
        LexCPP.obj              \
        LexConf.obj             \
        LexCrontab.obj          \
+       LexCSS.obj              \
        LexEiffel.obj           \
+       LexFortran.obj          \
        LexHTML.obj             \
        LexLisp.obj             \
        LexLua.obj              \
        LexOthers.obj           \
+       LexPOV.obj              \
        LexPascal.obj           \
        LexPerl.obj             \
        LexPython.obj           \
@@ -60,17 +64,19 @@ OBJECTS = \
        UniConversion.obj       \
         ViewStyle.obj          \
        WindowAccessor.obj      \
+       XPM.obj                 \
                                \
        PlatWX.obj              \
        ScintillaWX.obj         \
        stc.obj                 \
 
+
 STCCFG = stc.cfg
 STCCPPFLAGS=$(DLL_FLAGS) $(EXTRACPPFLAGS) @$(STCCFG)
 
 default: $(STCCFG) $(LIBTARGET)
 
-cleancfg: 
+cleancfg:
        del $(STCCFG)
 
 {$(S)}.cxx.obj:
index 4ae99521f58955ba58d28045ce8ac48b47da85f0..25dd4ad0cdb77a12739326d256be1cd933563e8c 100644 (file)
@@ -22,17 +22,21 @@ OBJECTS = \
         $(S)/KeyWords.$(OBJSUFF)       \
        $(S)/LexAVE.$(OBJSUFF)          \
        $(S)/LexAda.$(OBJSUFF)          \
+       $(S)/LexAsm.$(OBJSUFF)          \
        $(S)/LexBaan.$(OBJSUFF)         \
        $(S)/LexBullant.$(OBJSUFF)      \
        $(S)/LexMatlab.$(OBJSUFF)       \
        $(S)/LexCPP.$(OBJSUFF)          \
        $(S)/LexConf.$(OBJSUFF)         \
        $(S)/LexCrontab.$(OBJSUFF)      \
+       $(S)/LexCSS.$(OBJSUFF)          \
        $(S)/LexEiffel.$(OBJSUFF)       \
+       $(S)/LexFortran.$(OBJSUFF)      \
        $(S)/LexHTML.$(OBJSUFF)         \
        $(S)/LexLisp.$(OBJSUFF)         \
        $(S)/LexLua.$(OBJSUFF)          \
        $(S)/LexOthers.$(OBJSUFF)       \
+       $(S)/LexPOV.$(OBJSUFF)          \
        $(S)/LexPascal.$(OBJSUFF)       \
        $(S)/LexPerl.$(OBJSUFF)         \
        $(S)/LexPython.$(OBJSUFF)       \
@@ -48,11 +52,13 @@ OBJECTS = \
        $(S)/UniConversion.$(OBJSUFF)   \
         $(S)/ViewStyle.$(OBJSUFF)      \
        $(S)/WindowAccessor.$(OBJSUFF)  \
+       $(S)/XPM.$(OBJSUFF)             \
        \
        PlatWX.$(OBJSUFF) \
        ScintillaWX.$(OBJSUFF) \
        stc.$(OBJSUFF)
 
+
 LIBTARGET = $(WXDIR)/lib/libstc.a
 
 include $(WXDIR)/src/makelib.g95
\ No newline at end of file
index 9a3fdc08e79132fe0ee0d16377ed819a0edca812..4aa0e2c352f7b6b05c1a136e7de17098ad5d0409 100644 (file)
@@ -27,17 +27,21 @@ OBJECTS = \
         $(D)\KeyWords.obj              \
        $(D)\LexAVE.obj                 \
        $(D)\LexAda.obj                 \
+       $(D)\LexAsm.obj                 \
        $(D)\LexBaan.obj                \
        $(D)\LexBullant.obj             \
        $(D)\LexMatlab.obj              \
        $(D)\LexCPP.obj                 \
        $(D)\LexConf.obj                \
        $(D)\LexCrontab.obj             \
+       $(D)\LexCSS.obj                 \
        $(D)\LexEiffel.obj              \
+       $(D)\LexFortran.obj             \
        $(D)\LexHTML.obj                \
        $(D)\LexLisp.obj                \
        $(D)\LexLua.obj                 \
        $(D)\LexOthers.obj              \
+       $(D)\LexPOV.obj                 \
        $(D)\LexPascal.obj              \
        $(D)\LexPerl.obj                \
        $(D)\LexPython.obj              \
@@ -53,6 +57,7 @@ OBJECTS = \
        $(D)\UniConversion.obj          \
         $(D)\ViewStyle.obj             \
        $(D)\WindowAccessor.obj         \
+       $(D)\XPM.obj                    \
                                \
        $(D)\PlatWX.obj         \
        $(D)\ScintillaWX.obj    \
index 3a4201775649698be1eb5b1cf444e09277d928d0..76a2985a3bcd5afbfddfc0b312568b8d688bc57a 100644 (file)
@@ -31,17 +31,21 @@ OBJECTS = &
     KeyWords.obj               &
        LexAVE.obj                      &
        LexAda.obj                      &
+       LexAsm.obj                      &
        LexBaan.obj                     &
        LexBullant.obj              &
        LexMatlab.obj           &
        LexCPP.obj                      &
        LexConf.obj                     &
        LexCrontab.obj              &
+       LexCSS.obj                  &
        LexEiffel.obj               &
+       LexFortran.obj              &
        LexHTML.obj                     &
        LexLisp.obj                     &
        LexLua.obj                      &
        LexOthers.obj               &
+       LexPOV.obj                  &
        LexPascal.obj               &
        LexPerl.obj                     &
        LexPython.obj               &
@@ -57,9 +61,10 @@ OBJECTS = &
        UniConversion.obj           &
     ViewStyle.obj                  &
        WindowAccessor.obj          &
+       XPM.obj                     &
        PlatWX.obj              &
        ScintillaWX.obj         &
-       stc.obj     
+       stc.obj
 
 all: $(STCLIB) .SYMBOLIC
 
@@ -67,17 +72,17 @@ $(STCLIB): $(OBJECTS)
        *wlib /b /c /n /P=256 $(STCLIB) $(OBJECTS)
 
 clean:   .SYMBOLIC
-    -erase *.obj 
-    -erase *.bak 
-    -erase *.err 
-    -erase *.pch 
-    -erase $(STCLIB) 
+    -erase *.obj
+    -erase *.bak
+    -erase *.err
+    -erase *.pch
+    -erase $(STCLIB)
     -erase *.lbc
 
 .EXTENSIONS: .cxx
 .cxx: $(S)
 
 .cxx.obj:
-    $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS) 
+    $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS)
 
 
diff --git a/contrib/src/stc/scintilla/License.txt b/contrib/src/stc/scintilla/License.txt
new file mode 100644 (file)
index 0000000..cbe25b2
--- /dev/null
@@ -0,0 +1,20 @@
+License for Scintilla and SciTE
+
+Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+
+All Rights Reserved 
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that 
+both that copyright notice and this permission notice appear in 
+supporting documentation. 
+
+NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY 
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 
+OR PERFORMANCE OF THIS SOFTWARE. 
\ No newline at end of file
index 8538707cdeb85e8ae6419a6d4e24074022a4619a..4f5b08f1cb81993e00bd72d2e1ddc16512ae23c2 100644 (file)
@@ -3,5 +3,4 @@ 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.48
-
+The current version of the Scintilla code is 1.52
index 0b2c4baee25cb8a8bc1768adf22a05c9a5fe2358..3f59c07939bad89bbb469d31eb992912022e6b92 100644 (file)
@@ -25,7 +25,7 @@ protected:
        char buf[bufferSize+1];
        int startPos;
        int endPos;
-       int codePage;   
+       int codePage;
 
        virtual bool InternalIsLeadByte(char ch)=0;
        virtual void Fill(int position)=0;
@@ -44,7 +44,7 @@ public:
                if (position < startPos || position >= endPos) {
                        Fill(position);
                        if (position < startPos || position >= endPos) {
-                               // Position is outside range of document 
+                               // Position is outside range of document
                                return chDefault;
                        }
                }
index df4e870c580f507203f57f61f2cc58a7af04a2fe..c51c88ef594b090d6323ac316f73d04651170b1c 100644 (file)
@@ -7,7 +7,7 @@
 
 typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
                   WordList *keywordlists[], Accessor &styler);
-                  
+
 /**
  * A LexerModule is responsible for lexing and folding a particular language.
  * The class maintains a list of LexerModules which can be searched to find a
@@ -26,7 +26,7 @@ protected:
 
 public:
        const char *languageName;
-       LexerModule(int language_, LexerFunction fnLexer_, 
+       LexerModule(int language_, LexerFunction fnLexer_,
                const char *languageName_=0, LexerFunction fnFolder_=0,
                const char * const wordListDescriptions_[] = NULL);
        int GetLanguage() const { return language; }
index 1a8dfaa96e0cad7e1e2e6d66fb1cf81684b1ece7..7f5985c7657bd39d2fec7197cd487aa1be985bd6 100644 (file)
@@ -3,7 +3,7 @@
  ** Interface to platform facilities. Also includes some basic utilities.
  ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef PLATFORM_H
@@ -109,6 +109,12 @@ public:
                return (right > other.left) && (left < other.right) &&
                        (bottom > other.top) && (top < other.bottom);
        }
+       void Move(int xDelta, int yDelta) {
+               left += xDelta;
+               top += yDelta;
+               right += xDelta;
+               bottom += yDelta;
+       }
        int Width() { return right - left; }
        int Height() { return bottom - top; }
 };
@@ -136,7 +142,7 @@ public:
        }
 
        ColourDesired(unsigned int red, unsigned int green, unsigned int blue) {
-               co = red | (green << 8) | (blue << 16);
+               Set(red, green, blue);
        }
 
        bool operator==(const ColourDesired &other) const {
@@ -147,6 +153,31 @@ public:
                co = lcol;
        }
 
+       void Set(unsigned int red, unsigned int green, unsigned int blue) {
+               co = red | (green << 8) | (blue << 16);
+       }
+
+       static inline unsigned int ValueOfHex(const char ch) {
+               if (ch >= '0' && ch <= '9')
+                       return ch - '0';
+               else if (ch >= 'A' && ch <= 'F')
+                       return ch - 'A' + 10;
+               else if (ch >= 'a' && ch <= 'f')
+                       return ch - 'a' + 10;
+               else
+                       return 0;
+       }
+
+       void Set(const char *val) {
+               if (*val == '#') {
+                       val++;
+               }
+               unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]);
+               unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]);
+               unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]);
+               Set(r, g, b);
+       }
+
        long AsLong() const {
                return co;
        }
@@ -196,6 +227,9 @@ struct ColourPair {
                desired = desired_;
                allocated.Set(desired.AsLong());
        }
+       void Copy() {
+               allocated.Set(desired.AsLong());
+       }
 };
 
 class Window;  // Forward declaration for Palette
@@ -271,9 +305,9 @@ public:
        virtual ~Surface() {};
        static Surface *Allocate();
 
-       virtual void Init()=0;
-       virtual void Init(SurfaceID sid)=0;
-       virtual void InitPixMap(int width, int height, Surface *surface_)=0;
+       virtual void Init(WindowID wid)=0;
+       virtual void Init(SurfaceID sid, WindowID wid)=0;
+       virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0;
 
        virtual void Release()=0;
        virtual bool Initialised()=0;
@@ -292,6 +326,7 @@ public:
 
        virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
        virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
+       virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0;
        virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0;
        virtual int WidthText(Font &font_, const char *s, int len)=0;
        virtual int WidthChar(Font &font_, char ch)=0;
@@ -307,6 +342,7 @@ public:
        virtual void FlushCachedState()=0;
 
        virtual void SetUnicodeMode(bool unicodeMode_)=0;
+       virtual void SetDBCSMode(int codePage)=0;
 };
 
 /**
@@ -329,8 +365,8 @@ public:
                id = id_;
                return *this;
        }
-       WindowID GetID() { return id; }
-       bool Created() { return id != 0; }
+       WindowID GetID() const { return id; }
+       bool Created() const { return id != 0; }
        void Destroy();
        bool HasFocus();
        PRectangle GetPosition();
@@ -341,7 +377,7 @@ public:
        void InvalidateAll();
        void InvalidateRectangle(PRectangle rc);
        virtual void SetFont(Font &font);
-       enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow };
+       enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
        void SetCursor(Cursor curs);
        void SetTitle(const char *s);
 private:
@@ -353,38 +389,28 @@ private:
  */
 
 class ListBox : public Window {
-private:
-#if PLAT_GTK
-       WindowID list;
-       WindowID scroller;
-       int current;
-#endif
-       int desiredVisibleRows;
-       unsigned int maxItemCharacters;
-       unsigned int aveCharWidth;
-public:
-       CallBackAction doubleClickAction;
-       void *doubleClickActionData;
 public:
        ListBox();
        virtual ~ListBox();
-       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();
-       void Select(int n);
-       int GetSelection();
-       int Find(const char *prefix);
-       void GetValue(int n, char *value, int len);
-       void Sort();
-       void SetDoubleClickAction(CallBackAction action, void *data) {
-               doubleClickAction = action;
-               doubleClickActionData = data;
-       }
+       static ListBox *Allocate();
+
+       virtual void SetFont(Font &font)=0;
+       virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_)=0;
+       virtual void SetAverageCharWidth(int width)=0;
+       virtual void SetVisibleRows(int rows)=0;
+       virtual PRectangle GetDesiredRect()=0;
+       virtual int CaretFromEdge()=0;
+       virtual void Clear()=0;
+       virtual void Append(char *s, int type = -1)=0;
+       virtual int Length()=0;
+       virtual void Select(int n)=0;
+       virtual int GetSelection()=0;
+       virtual int Find(const char *prefix)=0;
+       virtual void GetValue(int n, char *value, int len)=0;
+       virtual void Sort()=0;
+       virtual void RegisterImage(int type, const char *xpm_data)=0;
+       virtual void ClearRegisteredImages()=0;
+       virtual void SetDoubleClickAction(CallBackAction, void *)=0;
 };
 
 /**
@@ -426,6 +452,7 @@ public:
        static const char *DefaultFont();
        static int DefaultFontSize();
        static unsigned int DoubleClickTime();
+       static bool MouseButtonBounce();
        static void DebugDisplay(const char *s);
        static bool IsKeyDown(int key);
        static long SendScintilla(
@@ -433,6 +460,8 @@ public:
        static long SendScintillaPointer(
                WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0);
        static bool IsDBCSLeadByte(int codePage, char ch);
+       static int DBCSCharLength(int codePage, const char *s);
+       static int DBCSCharMaxLength();
 
        // These are utility functions not really tied to a platform
        static int Minimum(int a, int b);
index 59588c62edc08fca5cfa351765eff3c5a1c258da..3f1b64f77fc89ea026e39a9730cfc157e441c6e2 100644 (file)
@@ -60,7 +60,7 @@ public:
        bool onlyLineEnds;      ///< Delimited by any white space or only line ends
        bool sorted;
        int starts[256];
-       WordList(bool onlyLineEnds_ = false) : 
+       WordList(bool onlyLineEnds_ = false) :
                words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), sorted(false) {}
        ~WordList() { Clear(); }
        operator bool() { return len ? true : false; }
@@ -70,9 +70,9 @@ public:
        char *Allocate(int size);
        void SetFromAllocated();
        bool InList(const char *s);
-       const char *GetNearestWord(const char *wordStart, int searchLen = -1, 
+       const char *GetNearestWord(const char *wordStart, int searchLen = -1,
                bool ignoreCase = false, SString wordCharacters="");
-       char *GetNearestWords(const char *wordStart, int searchLen=-1, 
+       char *GetNearestWords(const char *wordStart, int searchLen=-1,
                bool ignoreCase=false, char otherSeparator='\0');
 };
 
index 3c7ccc33a51622610aef1b261992b201fc655602..01602df7816fbc65d28c4fd4f7af1e4b6423fd09 100644 (file)
@@ -238,7 +238,7 @@ public:
                return append(sOther, static_cast<lenpos_t>(measure_length));
        }
        SString &operator+=(const SString &sOther) {
-               return append(sOther.s, sOther.sSize);
+               return append(sOther.s, sOther.sLen);
        }
        SString &operator+=(char ch) {
                return append(&ch, 1);
@@ -369,11 +369,7 @@ public:
  */
 inline char *StringDup(
        const char *s,                  ///< The string to duplicate
-        /* gcc 2.96 doesn't seem to like this syntax: gives
-           'non-local function uses anonymous type'
-           SString::lenpos_t len=SString::measure_length)      ///< The length of memory to allocate. Optional.
-        */
-        SString::lenpos_t len=0xffffffffU)     ///< The length of memory to allocate. Optional.
+       SString::lenpos_t len=SString::measure_length)  ///< The length of memory to allocate. Optional.
 {
        return SString::StringAllocate(s, len);
 }
index a6066cd58519563197cee2a2054a67baa3e38d0e..e1da492b279f122423d359d340eff396e953e7fb 100644 (file)
 #define SCLEX_BAAN 31
 #define SCLEX_MATLAB 32
 #define SCLEX_SCRIPTOL 33
+#define SCLEX_ASM 34
+#define SCLEX_CPPNOCASE 35
+#define SCLEX_FORTRAN 36
+#define SCLEX_F77 37
+#define SCLEX_CSS 38
+#define SCLEX_POV 39
 #define SCLEX_AUTOMATIC 1000
 #define SCE_P_DEFAULT 0
 #define SCE_P_COMMENTLINE 1
 #define SCE_ERR_DIFF_ADDITION 11
 #define SCE_ERR_DIFF_DELETION 12
 #define SCE_ERR_DIFF_MESSAGE 13
+#define SCE_ERR_PHP 14
+#define SCE_ERR_ELF 15
+#define SCE_ERR_IFC 16
 #define SCE_BAT_DEFAULT 0
 #define SCE_BAT_COMMENT 1
 #define SCE_BAT_WORD 2
 #define SCE_AVE_COMMENT 1
 #define SCE_AVE_NUMBER 2
 #define SCE_AVE_WORD 3
-#define SCE_AVE_KEYWORD 4
-#define SCE_AVE_STATEMENT 5
 #define SCE_AVE_STRING 6
 #define SCE_AVE_ENUM 7
 #define SCE_AVE_STRINGEOL 8
 #define SCE_AVE_IDENTIFIER 9
 #define SCE_AVE_OPERATOR 10
+#define SCE_AVE_WORD1 11
+#define SCE_AVE_WORD2 12
+#define SCE_AVE_WORD3 13
+#define SCE_AVE_WORD4 14
+#define SCE_AVE_WORD5 15
+#define SCE_AVE_WORD6 16
 #define SCE_ADA_DEFAULT 0
-#define SCE_ADA_COMMENT 1
-#define SCE_ADA_NUMBER 2
-#define SCE_ADA_WORD 3
-#define SCE_ADA_STRING 4
+#define SCE_ADA_WORD 1
+#define SCE_ADA_IDENTIFIER 2
+#define SCE_ADA_NUMBER 3
+#define SCE_ADA_DELIMITER 4
 #define SCE_ADA_CHARACTER 5
-#define SCE_ADA_OPERATOR 6
-#define SCE_ADA_IDENTIFIER 7
+#define SCE_ADA_CHARACTEREOL 6
+#define SCE_ADA_STRING 7
 #define SCE_ADA_STRINGEOL 8
+#define SCE_ADA_LABEL 9
+#define SCE_ADA_COMMENTLINE 10
+#define SCE_ADA_ILLEGAL 11
 #define SCE_BAAN_DEFAULT 0
 #define SCE_BAAN_COMMENT 1
 #define SCE_BAAN_COMMENTDOC 2
 #define SCE_SCRIPTOL_COMMENTDOCKEYWORD 17
 #define SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR 18
 #define SCE_SCRIPTOL_COMMENTBASIC 19
+#define SCE_ASM_DEFAULT 0
+#define SCE_ASM_COMMENT 1
+#define SCE_ASM_NUMBER 2
+#define SCE_ASM_STRING 3
+#define SCE_ASM_OPERATOR 4
+#define SCE_ASM_IDENTIFIER 5
+#define SCE_ASM_CPUINSTRUCTION 6
+#define SCE_ASM_MATHINSTRUCTION 7
+#define SCE_ASM_REGISTER 8
+#define SCE_ASM_DIRECTIVE 9
+#define SCE_ASM_DIRECTIVEOPERAND 10
+#define SCE_F_DEFAULT 0
+#define SCE_F_COMMENT 1
+#define SCE_F_NUMBER 2
+#define SCE_F_STRING1 3
+#define SCE_F_STRING2 4
+#define SCE_F_STRINGEOL 5
+#define SCE_F_OPERATOR 6
+#define SCE_F_IDENTIFIER 7
+#define SCE_F_WORD 8
+#define SCE_F_WORD2 9
+#define SCE_F_WORD3 10
+#define SCE_F_PREPROCESSOR 11
+#define SCE_F_OPERATOR2 12
+#define SCE_F_LABEL 13
+#define SCE_F_CONTINUATION 14
+#define SCE_CSS_DEFAULT 0
+#define SCE_CSS_TAG 1
+#define SCE_CSS_CLASS 2
+#define SCE_CSS_PSEUDOCLASS 3
+#define SCE_CSS_UNKNOWN_PSEUDOCLASS 4
+#define SCE_CSS_OPERATOR 5
+#define SCE_CSS_IDENTIFIER 6
+#define SCE_CSS_UNKNOWN_IDENTIFIER 7
+#define SCE_CSS_VALUE 8
+#define SCE_CSS_COMMENT 9
+#define SCE_CSS_ID 10
+#define SCE_CSS_IMPORTANT 11
+#define SCE_CSS_DIRECTIVE 12
+#define SCE_CSS_DOUBLESTRING 13
+#define SCE_CSS_SINGLESTRING 14
+#define SCE_POV_DEFAULT 0
+#define SCE_POV_COMMENT 1
+#define SCE_POV_COMMENTLINE 2
+#define SCE_POV_COMMENTDOC 3
+#define SCE_POV_NUMBER 4
+#define SCE_POV_WORD 5
+#define SCE_POV_STRING 6
+#define SCE_POV_OPERATOR 7
+#define SCE_POV_IDENTIFIER 8
+#define SCE_POV_BRACE 9
+#define SCE_POV_WORD2 10
 //--Autogenerated -- end of section automatically generated from Scintilla.iface
 
 #endif
index 30fcf50fc400e9ab082e3dabde2c36fec57980c1..c377d07cc20a90b6957832351f25b69d4b4dda77 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Scintilla.h
  ** Interface to the edit control.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 // Most of this file is automatically generated from the Scintilla.iface interface definition
@@ -83,6 +83,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETTABWIDTH 2036
 #define SCI_GETTABWIDTH 2121
 #define SC_CP_UTF8 65001
+#define SC_CP_DBCS 1
 #define SCI_SETCODEPAGE 2037
 #define SCI_SETUSEPALETTE 2039
 #define MARKER_MAX 31
@@ -111,6 +112,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MARK_BACKGROUND 22
 #define SC_MARK_DOTDOTDOT 23
 #define SC_MARK_ARROWS 24
+#define SC_MARK_PIXMAP 25
 #define SC_MARK_CHARACTER 10000
 #define SC_MARKNUM_FOLDEREND 25
 #define SC_MARKNUM_FOLDEROPENMID 26
@@ -129,6 +131,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_MARKERGET 2046
 #define SCI_MARKERNEXT 2047
 #define SCI_MARKERPREVIOUS 2048
+#define SCI_MARKERDEFINEPIXMAP 2049
 #define SC_MARGIN_SYMBOL 0
 #define SC_MARGIN_NUMBER 1
 #define SCI_SETMARGINTYPEN 2240
@@ -181,6 +184,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_CASE_LOWER 2
 #define SCI_STYLESETCASE 2060
 #define SCI_STYLESETCHARACTERSET 2066
+#define SCI_STYLESETHOTSPOT 2409
 #define SCI_SETSELFORE 2067
 #define SCI_SETSELBACK 2068
 #define SCI_SETCARETFORE 2069
@@ -241,6 +245,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_AUTOCGETAUTOHIDE 2119
 #define SCI_AUTOCSETDROPRESTOFWORD 2270
 #define SCI_AUTOCGETDROPRESTOFWORD 2271
+#define SCI_REGISTERIMAGE 2405
+#define SCI_CLEARREGISTEREDIMAGES 2408
+#define SCI_AUTOCGETTYPESEPARATOR 2285
+#define SCI_AUTOCSETTYPESEPARATOR 2286
 #define SCI_SETINDENT 2122
 #define SCI_GETINDENT 2123
 #define SCI_SETUSETABS 2124
@@ -278,6 +286,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCFIND_MATCHCASE 4
 #define SCFIND_WORDSTART 0x00100000
 #define SCFIND_REGEXP 0x00200000
+#define SCFIND_POSIX 0x00400000
 #define SCI_FINDTEXT 2150
 #define SCI_FORMATRANGE 2151
 #define SCI_GETFIRSTVISIBLELINE 2152
@@ -333,11 +342,17 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_CALLTIPPOSSTART 2203
 #define SCI_CALLTIPSETHLT 2204
 #define SCI_CALLTIPSETBACK 2205
+#define SCI_CALLTIPSETFORE 2206
+#define SCI_CALLTIPSETFOREHLT 2207
 #define SCI_VISIBLEFROMDOCLINE 2220
 #define SCI_DOCLINEFROMVISIBLE 2221
 #define SC_FOLDLEVELBASE 0x400
 #define SC_FOLDLEVELWHITEFLAG 0x1000
 #define SC_FOLDLEVELHEADERFLAG 0x2000
+#define SC_FOLDLEVELBOXHEADERFLAG 0x4000
+#define SC_FOLDLEVELBOXFOOTERFLAG 0x8000
+#define SC_FOLDLEVELCONTRACTED 0x10000
+#define SC_FOLDLEVELUNINDENT 0x20000
 #define SC_FOLDLEVELNUMBERMASK 0x0FFF
 #define SCI_SETFOLDLEVEL 2222
 #define SCI_GETFOLDLEVEL 2223
@@ -350,6 +365,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETFOLDEXPANDED 2230
 #define SCI_TOGGLEFOLD 2231
 #define SCI_ENSUREVISIBLE 2232
+#define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002
+#define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004
+#define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
+#define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
+#define SC_FOLDFLAG_LEVELNUMBERS 0x0040
+#define SC_FOLDFLAG_BOX 0x0001
 #define SCI_SETFOLDFLAGS 2233
 #define SCI_ENSUREVISIBLEENFORCEPOLICY 2234
 #define SCI_SETTABINDENTS 2260
@@ -377,6 +398,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETENDATLASTLINE 2277
 #define SCI_GETENDATLASTLINE 2278
 #define SCI_TEXTHEIGHT 2279
+#define SCI_SETVSCROLLBAR 2280
+#define SCI_GETVSCROLLBAR 2281
+#define SCI_APPENDTEXT 2282
+#define SCI_GETTWOPHASEDRAW 2283
+#define SCI_SETTWOPHASEDRAW 2284
+#define SCI_TARGETFROMSELECTION 2287
+#define SCI_LINESJOIN 2288
+#define SCI_LINESSPLIT 2289
+#define SCI_SETFOLDMARGINCOLOUR 2290
+#define SCI_SETFOLDMARGINHICOLOUR 2291
 #define SCI_LINEDOWN 2300
 #define SCI_LINEDOWNEXTEND 2301
 #define SCI_LINEUP 2302
@@ -417,6 +448,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_LINECUT 2337
 #define SCI_LINEDELETE 2338
 #define SCI_LINETRANSPOSE 2339
+#define SCI_LINEDUPLICATE 2404
 #define SCI_LOWERCASE 2340
 #define SCI_UPPERCASE 2341
 #define SCI_LINESCROLLDOWN 2342
@@ -426,6 +458,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_HOMEDISPLAYEXTEND 2346
 #define SCI_LINEENDDISPLAY 2347
 #define SCI_LINEENDDISPLAYEXTEND 2348
+#define SCI_HOMEWRAP 2349
+#define SCI_HOMEWRAPEXTEND 2450
+#define SCI_LINEENDWRAP 2451
+#define SCI_LINEENDWRAPEXTEND 2452
+#define SCI_VCHOMEWRAP 2453
+#define SCI_VCHOMEWRAPEXTEND 2454
 #define SCI_MOVECARETINSIDEVIEW 2401
 #define SCI_LINELENGTH 2350
 #define SCI_BRACEHIGHLIGHT 2351
@@ -464,7 +502,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETMOUSEDOWNCAPTURES 2384
 #define SCI_GETMOUSEDOWNCAPTURES 2385
 #define SC_CURSORNORMAL -1
-#define SC_CURSORWAIT 3
+#define SC_CURSORWAIT 4
 #define SCI_SETCURSOR 2386
 #define SCI_GETCURSOR 2387
 #define SCI_SETCONTROLCHARSYMBOL 2388
@@ -480,6 +518,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_DELLINERIGHT 2396
 #define SCI_SETXOFFSET 2397
 #define SCI_GETXOFFSET 2398
+#define SCI_CHOOSECARETX 2399
 #define SCI_GRABFOCUS 2400
 #define CARET_SLOP 0x01
 #define CARET_STRICT 0x04
@@ -487,6 +526,15 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define CARET_EVEN 0x08
 #define SCI_SETXCARETPOLICY 2402
 #define SCI_SETYCARETPOLICY 2403
+#define SCI_SETPRINTWRAPMODE 2406
+#define SCI_GETPRINTWRAPMODE 2407
+#define SCI_SETHOTSPOTACTIVEFORE 2410
+#define SCI_SETHOTSPOTACTIVEBACK 2411
+#define SCI_SETHOTSPOTACTIVEUNDERLINE 2412
+#define SCI_PARADOWN 2413
+#define SCI_PARADOWNEXTEND 2414
+#define SCI_PARAUP 2415
+#define SCI_PARAUPEXTEND 2416
 #define SCI_STARTRECORD 3001
 #define SCI_STOPRECORD 3002
 #define SCI_SETLEXER 4001
@@ -495,6 +543,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETPROPERTY 4004
 #define SCI_SETKEYWORDS 4005
 #define SCI_SETLEXERLANGUAGE 4006
+#define SCI_LOADLEXERLIBRARY 4007
 #define SC_MOD_INSERTTEXT 0x1
 #define SC_MOD_DELETETEXT 0x2
 #define SC_MOD_CHANGESTYLE 0x4
@@ -548,6 +597,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCN_DWELLSTART 2016
 #define SCN_DWELLEND 2017
 #define SCN_ZOOM 2018
+#define SCN_HOTSPOTCLICK 2019
+#define SCN_HOTSPOTDOUBLECLICK 2020
+#define SCN_CALLTIPCLICK 2021
 //--Autogenerated -- end of section automatically generated from Scintilla.iface
 
 // These structures are defined to be exactly the same shape as the Win32
index d6383b103bb9300ce08ed383b18630b8cfb2295e..c5dacbdf048033cd972491020e66635bb7f88c05 100644 (file)
@@ -221,6 +221,9 @@ get int GetTabWidth=2121(,)
 # This is the same value as CP_UTF8 in Windows
 val SC_CP_UTF8=65001
 
+# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+val SC_CP_DBCS=1
+
 # Set the code page used to interpret the bytes of the document as characters.
 # The SC_CP_UTF8 value can be used to enter Unicode mode.
 set void SetCodePage=2037(int codePage,)
@@ -260,6 +263,7 @@ val SC_MARK_CIRCLEMINUSCONNECTED=21
 val SC_MARK_BACKGROUND=22
 val SC_MARK_DOTDOTDOT=23
 val SC_MARK_ARROWS=24
+val SC_MARK_PIXMAP=25
 
 val SC_MARK_CHARACTER=10000
 
@@ -302,6 +306,9 @@ fun int MarkerNext=2047(int lineStart, int markerMask)
 # Find the previous line before lineStart that includes a marker in mask.
 fun int MarkerPrevious=2048(int lineStart, int markerMask)
 
+# Define a marker from a pixmap.
+fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
+
 enu MarginType=SC_MARGIN_
 val SC_MARGIN_SYMBOL=0
 val SC_MARGIN_NUMBER=1
@@ -405,6 +412,9 @@ set void StyleSetCase=2060(int style, int caseForce)
 # Set the character set of the font in a style.
 set void StyleSetCharacterSet=2066(int style, int characterSet)
 
+# Set a style to be a hotspot or not.
+set void StyleSetHotSpot=2409(int style, bool hotspot)
+
 # Set the foreground colour of the selection and whether to use this setting.
 fun void SetSelFore=2067(bool useSetting, colour fore)
 
@@ -578,6 +588,19 @@ set void AutoCSetDropRestOfWord=2270(bool dropRestOfWord,)
 # after the inserted text upon completion.
 get bool AutoCGetDropRestOfWord=2271(,)
 
+# Register an XPM image for use in autocompletion lists.
+fun void RegisterImage=2405(int type, string xpmData)
+
+# Clear all the registered XPM images.
+fun void ClearRegisteredImages=2408(,)
+
+# Retrieve the auto-completion list type-separator character.
+get int AutoCGetTypeSeparator=2285(,)
+
+# Change the type-separator character in the string setting up an auto-completion list.
+# Default is '?' but can be changed if items contain '?'.
+set void AutoCSetTypeSeparator=2286(int separatorCharacter,)
+
 # Set the number of spaces used for one level of indentation.
 set void SetIndent=2122(int indentSize,)
 
@@ -681,6 +704,7 @@ val SCFIND_WHOLEWORD=2
 val SCFIND_MATCHCASE=4
 val SCFIND_WORDSTART=0x00100000
 val SCFIND_REGEXP=0x00200000
+val SCFIND_POSIX=0x00400000
 
 # Find some text in the document.
 fun position FindText=2150(int flags, findtext ft)
@@ -688,7 +712,7 @@ fun position FindText=2150(int flags, findtext ft)
 # On Windows, will draw the document into a display context such as a printer.
 fun void FormatRange=2151(bool draw, formatrange fr)
 
-# Retrieve the line at the top of the display.
+# Retrieve the display line at the top of the display.
 get int GetFirstVisibleLine=2152(,)
 
 # Retrieve the contents of a line.
@@ -863,6 +887,12 @@ fun void CallTipSetHlt=2204(int start, int end)
 # Set the background colour for the call tip.
 set void CallTipSetBack=2205(colour back,)
 
+# Set the foreground colour for the call tip.
+set void CallTipSetFore=2206(colour fore,)
+
+# Set the foreground colour for the highlighted part of the call tip.
+set void CallTipSetForeHlt=2207(colour fore,)
+
 # Find the display line of a document line taking hidden lines into account.
 fun int VisibleFromDocLine=2220(int line,)
 
@@ -873,6 +903,10 @@ enu FoldLevel=SC_FOLDLEVEL
 val SC_FOLDLEVELBASE=0x400
 val SC_FOLDLEVELWHITEFLAG=0x1000
 val SC_FOLDLEVELHEADERFLAG=0x2000
+val SC_FOLDLEVELBOXHEADERFLAG=0x4000
+val SC_FOLDLEVELBOXFOOTERFLAG=0x8000
+val SC_FOLDLEVELCONTRACTED=0x10000
+val SC_FOLDLEVELUNINDENT=0x20000
 val SC_FOLDLEVELNUMBERMASK=0x0FFF
 
 # Set the fold level of a line.
@@ -910,7 +944,15 @@ fun void ToggleFold=2231(int line,)
 # Ensure a particular line is visible by expanding any header line hiding it.
 fun void EnsureVisible=2232(int line,)
 
-# Set some debugging options for folding.
+enu FoldFlag=SC_FOLDFLAG_
+val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002
+val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004
+val SC_FOLDFLAG_LINEAFTER_EXPANDED=0x0008
+val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010
+val SC_FOLDFLAG_LEVELNUMBERS=0x0040
+val SC_FOLDFLAG_BOX=0x0001
+
+# Set some style options for folding.
 fun void SetFoldFlags=2233(int flags,)
 
 # Ensure a particular line is visible by expanding any header line hiding it.
@@ -988,6 +1030,38 @@ get int GetEndAtLastLine=2278(,)
 # Retrieve the height of a particular line of text in pixels.
 fun int TextHeight=2279(int line,)
 
+# Show or hide the vertical scroll bar.
+set void SetVScrollBar=2280(bool show,)
+
+# Is the vertical scroll bar visible?
+get bool GetVScrollBar=2281(,)
+
+# Append a string to the end of the document without changing the selection.
+fun void AppendText=2282(int length, string text)
+
+# Is drawing done in two phases with backgrounds drawn before foregrounds?
+get bool GetTwoPhaseDraw=2283(,)
+
+# In twoPhaseDraw mode, drawing is performed in two phases, first the background
+# and then the foreground. This avoids chopping off characters that overlap the next run.
+set void SetTwoPhaseDraw=2284(bool twoPhase,)
+
+# Make the target range start and end be the same as the selection range start and end.
+fun void TargetFromSelection=2287(,)
+
+# Join the lines in the target.
+fun void LinesJoin=2288(,)
+
+# Split the lines in the target into lines that are less wide than pixelWidth
+# where possible.
+fun void LinesSplit=2289(int pixelWidth,)
+
+# Set the colours used as a chequerboard pattern in the fold margin
+fun void SetFoldMarginColour=2290(bool useSetting, colour back)
+fun void SetFoldMarginHiColour=2291(bool useSetting, colour fore)
+
+## New messages go here
+
 ## Start of key messages
 # Move caret down one line.
 fun void LineDown=2300(,)
@@ -1111,6 +1185,9 @@ fun void LineDelete=2338(,)
 # Switch the current line with the previous.
 fun void LineTranspose=2339(,)
 
+# Duplicate the current line.
+fun void LineDuplicate=2404(,)
+
 # Transform the selection to lower case.
 fun void LowerCase=2340(,)
 
@@ -1141,6 +1218,19 @@ fun void LineEndDisplay=2347(,)
 # caret position.
 fun void LineEndDisplayExtend=2348(,)
 
+# These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)?
+# except they behave differently when word-wrap is enabled:
+# They go first to the start / end of the display line, like (Home|LineEnd)Display
+# The difference is that, the cursor is already at the point, it goes on to the start
+# or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend.
+
+fun void HomeWrap=2349(,)
+fun void HomeWrapExtend=2450(,)
+fun void LineEndWrap=2451(,)
+fun void LineEndWrapExtend=2452(,)
+fun void VCHomeWrap=2453(,)
+fun void VCHomeWrapExtend=2454(,)
+
 # Move the caret inside current view if it's not there already.
 fun void MoveCaretInsideView=2401(,)
 
@@ -1251,7 +1341,7 @@ get bool GetMouseDownCaptures=2385(,)
 
 enu CursorShape=SC_CURSOR
 val SC_CURSORNORMAL=-1
-val SC_CURSORWAIT=3
+val SC_CURSORWAIT=4
 # Sets the cursor to one of the SC_CURSOR* values.
 set void SetCursor=2386(int cursorType,)
 # Get cursor type.
@@ -1291,6 +1381,9 @@ fun void DelLineRight=2396(,)
 set void SetXOffset=2397(int newOffset,)
 get int GetXOffset=2398(,)
 
+# Set the last x chosen value to be the caret x position
+fun void ChooseCaretX=2399(,)
+
 # Set the focus to this Scintilla widget.
 # GTK+ Specific.
 fun void GrabFocus=2400(,)
@@ -1327,6 +1420,27 @@ fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop)
 # The exclusion zone is given in lines.
 fun void SetYCaretPolicy=2403(int caretPolicy, int caretSlop)
 
+# Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).
+set void SetPrintWrapMode=2406(int mode,)
+
+# Is printing line wrapped.
+get int GetPrintWrapMode=2407(,)
+
+# Set a fore colour for active hotspots.
+set void SetHotspotActiveFore=2410(bool useSetting, colour fore)
+
+# Set a back colour for active hotspots.
+set void SetHotspotActiveBack=2411(bool useSetting, colour back)
+
+# Enable / Disable underlining active hotspots.
+set void SetHotspotActiveUnderline=2412(bool underline,)
+
+# Move caret between paragraphs (delimited by empty lines)
+fun void ParaDown=2413(,)
+fun void ParaDownExtend=2414(,)
+fun void ParaUp=2415(,)
+fun void ParaUpExtend=2416(,)
+
 # Start notifying the container of all key presses and commands.
 fun void StartRecord=3001(,)
 
@@ -1351,6 +1465,10 @@ set void SetKeyWords=4005(int keywordSet, string keyWords)
 # Set the lexing language of the document based on string name.
 set void SetLexerLanguage=4006(, string language)
 
+# Load a lexer library (dll / so)
+# NOT YET IMPLEMENTED
+fun void LoadLexerLibrary=4007(, string path)
+
 # Notifications
 # Type of modification and the action which caused the modification.
 # These are defined as a bit mask to make it easy to specify which notifications are wanted.
@@ -1442,6 +1560,12 @@ val SCLEX_PHP=30
 val SCLEX_BAAN=31
 val SCLEX_MATLAB=32
 val SCLEX_SCRIPTOL=33
+val SCLEX_ASM=34
+val SCLEX_CPPNOCASE=35
+val SCLEX_FORTRAN=36
+val SCLEX_F77=37
+val SCLEX_CSS=38
+val SCLEX_POV=39
 
 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 # value assigned in sequence from SCLEX_AUTOMATIC+1.
@@ -1708,6 +1832,9 @@ val SCE_ERR_DIFF_CHANGED=10
 val SCE_ERR_DIFF_ADDITION=11
 val SCE_ERR_DIFF_DELETION=12
 val SCE_ERR_DIFF_MESSAGE=13
+val SCE_ERR_PHP=14
+val SCE_ERR_ELF=15
+val SCE_ERR_IFC=16
 # Lexical states for SCLEX_BATCH
 lex Batch=SCLEX_BATCH SCE_BAT_
 val SCE_BAT_DEFAULT=0
@@ -1754,24 +1881,31 @@ val SCE_AVE_DEFAULT=0
 val SCE_AVE_COMMENT=1
 val SCE_AVE_NUMBER=2
 val SCE_AVE_WORD=3
-val SCE_AVE_KEYWORD=4
-val SCE_AVE_STATEMENT=5
 val SCE_AVE_STRING=6
 val SCE_AVE_ENUM=7
 val SCE_AVE_STRINGEOL=8
 val SCE_AVE_IDENTIFIER=9
 val SCE_AVE_OPERATOR=10
+val SCE_AVE_WORD1=11
+val SCE_AVE_WORD2=12
+val SCE_AVE_WORD3=13
+val SCE_AVE_WORD4=14
+val SCE_AVE_WORD5=15
+val SCE_AVE_WORD6=16
 # Lexical states for SCLEX_ADA
 lex Ada=SCLEX_ADA SCE_ADA_
 val SCE_ADA_DEFAULT=0
-val SCE_ADA_COMMENT=1
-val SCE_ADA_NUMBER=2
-val SCE_ADA_WORD=3
-val SCE_ADA_STRING=4
+val SCE_ADA_WORD=1
+val SCE_ADA_IDENTIFIER=2
+val SCE_ADA_NUMBER=3
+val SCE_ADA_DELIMITER=4
 val SCE_ADA_CHARACTER=5
-val SCE_ADA_OPERATOR=6
-val SCE_ADA_IDENTIFIER=7
+val SCE_ADA_CHARACTEREOL=6
+val SCE_ADA_STRING=7
 val SCE_ADA_STRINGEOL=8
+val SCE_ADA_LABEL=9
+val SCE_ADA_COMMENTLINE=10
+val SCE_ADA_ILLEGAL=11
 # Lexical states for SCLEX_BAAN
 lex Baan=SCLEX_BAAN SCE_BAAN_
 val SCE_BAAN_DEFAULT=0
@@ -1852,7 +1986,67 @@ val SCE_SCRIPTOL_WORD2=16
 val SCE_SCRIPTOL_COMMENTDOCKEYWORD=17
 val SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR=18
 val SCE_SCRIPTOL_COMMENTBASIC=19
-
+# Lexical states for SCLEX_ASM
+lex Asm=SCLEX_ASM SCE_ASM_
+val SCE_ASM_DEFAULT=0
+val SCE_ASM_COMMENT=1
+val SCE_ASM_NUMBER=2
+val SCE_ASM_STRING=3
+val SCE_ASM_OPERATOR=4
+val SCE_ASM_IDENTIFIER=5
+val SCE_ASM_CPUINSTRUCTION=6
+val SCE_ASM_MATHINSTRUCTION=7
+val SCE_ASM_REGISTER=8
+val SCE_ASM_DIRECTIVE=9
+val SCE_ASM_DIRECTIVEOPERAND=10
+# Lexical states for SCLEX_FORTRAN
+lex Fortran=SCLEX_FORTRAN SCE_F_
+lex F77=SCLEX_F77 SCE_F_
+val SCE_F_DEFAULT=0
+val SCE_F_COMMENT=1
+val SCE_F_NUMBER=2
+val SCE_F_STRING1=3
+val SCE_F_STRING2=4
+val SCE_F_STRINGEOL=5
+val SCE_F_OPERATOR=6
+val SCE_F_IDENTIFIER=7
+val SCE_F_WORD=8
+val SCE_F_WORD2=9
+val SCE_F_WORD3=10
+val SCE_F_PREPROCESSOR=11
+val SCE_F_OPERATOR2=12
+val SCE_F_LABEL=13
+val SCE_F_CONTINUATION=14
+# Lexical states for SCLEX_CSS
+lex CSS=SCLEX_CSS SCE_CSS_
+val SCE_CSS_DEFAULT=0
+val SCE_CSS_TAG=1
+val SCE_CSS_CLASS=2
+val SCE_CSS_PSEUDOCLASS=3
+val SCE_CSS_UNKNOWN_PSEUDOCLASS=4
+val SCE_CSS_OPERATOR=5
+val SCE_CSS_IDENTIFIER=6
+val SCE_CSS_UNKNOWN_IDENTIFIER=7
+val SCE_CSS_VALUE=8
+val SCE_CSS_COMMENT=9
+val SCE_CSS_ID=10
+val SCE_CSS_IMPORTANT=11
+val SCE_CSS_DIRECTIVE=12
+val SCE_CSS_DOUBLESTRING=13
+val SCE_CSS_SINGLESTRING=14
+# Lexical states for SCLEX_POV
+lex POV=SCLEX_POV SCE_POV_
+val SCE_POV_DEFAULT=0
+val SCE_POV_COMMENT=1
+val SCE_POV_COMMENTLINE=2
+val SCE_POV_COMMENTDOC=3
+val SCE_POV_NUMBER=4
+val SCE_POV_WORD=5
+val SCE_POV_STRING=6
+val SCE_POV_OPERATOR=7
+val SCE_POV_IDENTIFIER=8
+val SCE_POV_BRACE=9
+val SCE_POV_WORD2=10
 # Events
 
 evt void StyleNeeded=2000(int position)
@@ -1874,6 +2068,9 @@ evt void URIDropped=2015(string text)
 evt void DwellStart=2016(int position)
 evt void DwellEnd=2017(int position)
 evt void Zoom=2018(void)
+evt void HotSpotClick=2019(int modifiers, int position)
+evt void HotSpotDoubleClick=2020(int modifiers, int position)
+evt void CallTipClick=2021(int position)
 
 cat Deprecated
 
index 203f35733923a00babbf6d846cb1c1e5b4a67b63..765fd8594d159e6420d32fdcc3cc420711400b00 100644 (file)
@@ -37,7 +37,8 @@ struct _ScintillaClass {
 guint          scintilla_get_type      (void);
 GtkWidget*     scintilla_new           (void);
 void           scintilla_set_id        (ScintillaObject *sci,int id);
-sptr_t scintilla_send_message  (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+sptr_t         scintilla_send_message  (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+void           scintilla_release_resources(void);
 
 #if GTK_MAJOR_VERSION < 2
 #define SCINTILLA_NOTIFY "notify"
index 6c16b150f267751c1cc38f2e2213b9d934a64da8..43246050170cf5efd355f9e5a38648d772e3ddeb 100644 (file)
@@ -26,8 +26,8 @@ protected:
        bool InternalIsLeadByte(char ch);
        void Fill(int position);
 public:
-       WindowAccessor(WindowID id_, PropSet &props_) : 
-               Accessor(), id(id_), props(props_), 
+       WindowAccessor(WindowID id_, PropSet &props_) :
+               Accessor(), id(id_), props(props_),
                lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
        }
        ~WindowAccessor();
@@ -40,8 +40,8 @@ public:
        void Flush();
        int GetLineState(int line);
        int SetLineState(int line, int state);
-       int GetPropertyInt(const char *key, int defaultValue=0) { 
-               return props.GetInt(key, defaultValue); 
+       int GetPropertyInt(const char *key, int defaultValue=0) {
+               return props.GetInt(key, defaultValue);
        }
        char *GetProperties() {
                return props.ToString();
index d971fa12a09da6b943ee2ac0735a9a0a43427a55..adbd24d038fa5cdc6def23578b7c1ced63ad868e 100644 (file)
@@ -2,7 +2,7 @@
 /** @file AutoComplete.cxx
  ** Defines the auto completion list box.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 #include "PropSet.h"
 #include "AutoComplete.h"
 
-AutoComplete::AutoComplete() : 
+AutoComplete::AutoComplete() :
        active(false),
        separator(' '),
+       typesep('?'),
        ignoreCase(false),
        chooseSingle(false),
+       lb(0),
        posStart(0),
        startLen(0),
        cancelAtStartPos(true),
        autoHide(true),
        dropRestOfWord(false)   {
+       lb = ListBox::Allocate();
        stopChars[0] = '\0';
        fillUpChars[0] = '\0';
 }
 
 AutoComplete::~AutoComplete() {
-       lb.Destroy();
+       if (lb) {
+               lb->Destroy();
+               delete lb;
+               lb = 0;
+       }
 }
 
 bool AutoComplete::Active() {
        return active;
 }
 
-void AutoComplete::Start(Window &parent, int ctrlID, int position, int startLen_) {
-       if (!lb.Created()) {
-               lb.Create(parent, ctrlID);
+void AutoComplete::Start(Window &parent, int ctrlID, int position,
+       int startLen_, int lineHeight, bool unicodeMode) {
+       if (active) {
+               Cancel();
        }
-       lb.Clear();
+       lb->Create(parent, ctrlID, lineHeight, unicodeMode);
+       lb->Clear();
        active = true;
        startLen = startLen_;
        posStart = position;
@@ -63,7 +72,7 @@ void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
 bool AutoComplete::IsFillUpChar(char ch) {
        return ch && strchr(fillUpChars, ch);
 }
+
 void AutoComplete::SetSeparator(char separator_) {
        separator = separator_;
 }
@@ -72,49 +81,65 @@ char AutoComplete::GetSeparator() {
        return separator;
 }
 
+void AutoComplete::SetTypesep(char separator_) {
+       typesep = separator_;
+}
+
+char AutoComplete::GetTypesep() {
+       return typesep;
+}
+
 void AutoComplete::SetList(const char *list) {
-       lb.Clear();
+       lb->Clear();
        char *words = new char[strlen(list) + 1];
        if (words) {
                strcpy(words, list);
                char *startword = words;
+               char *numword = NULL;
                int i = 0;
                for (; words && words[i]; i++) {
                        if (words[i] == separator) {
                                words[i] = '\0';
-                               lb.Append(startword);
+                               if (numword)
+                                       *numword = '\0';
+                               lb->Append(startword, numword?atoi(numword + 1):-1);
                                startword = words + i + 1;
+                               numword = NULL;
+                       } else if (words[i] == typesep) {
+                               numword = words + i;
                        }
                }
                if (startword) {
-                       lb.Append(startword);
+                       if (numword)
+                               *numword = '\0';
+                       lb->Append(startword, numword?atoi(numword + 1):-1);
                }
                delete []words;
        }
 }
 
 void AutoComplete::Show() {
-       lb.Show();
-       lb.Select(0);
+       lb->Show();
+       lb->Select(0);
 }
 
 void AutoComplete::Cancel() {
-       if (lb.Created()) {
-               lb.Destroy();
+       if (lb->Created()) {
+               lb->Destroy();
                active = false;
        }
 }
 
 
 void AutoComplete::Move(int delta) {
-       int count = lb.Length();
-       int current = lb.GetSelection();
+       int count = lb->Length();
+       int current = lb->GetSelection();
        current += delta;
        if (current >= count)
                current = count - 1;
        if (current < 0)
                current = 0;
-       lb.Select(current);
+       lb->Select(current);
 }
 
 void AutoComplete::Select(const char *word) {
@@ -123,10 +148,10 @@ void AutoComplete::Select(const char *word) {
        const int maxItemLen=1000;
        char item[maxItemLen];
        int start = 0; // lower bound of the api array block to search
-       int end = lb.Length() - 1; // upper bound of the api array block to search
+       int end = lb->Length() - 1; // upper bound of the api array block to search
        while ((start <= end) && (location == -1)) { // Binary searching loop
                int pivot = (start + end) / 2;
-               lb.GetValue(pivot, item, maxItemLen);
+               lb->GetValue(pivot, item, maxItemLen);
                int cond;
                if (ignoreCase)
                        cond = CompareNCaseInsensitive(word, item, lenWord);
@@ -135,7 +160,7 @@ void AutoComplete::Select(const char *word) {
                if (!cond) {
                        // Find first match
                        while (pivot > start) {
-                               lb.GetValue(pivot-1, item, maxItemLen);
+                               lb->GetValue(pivot-1, item, maxItemLen);
                                if (ignoreCase)
                                        cond = CompareNCaseInsensitive(word, item, lenWord);
                                else
@@ -154,6 +179,6 @@ void AutoComplete::Select(const char *word) {
        if (location == -1 && autoHide)
                Cancel();
        else
-               lb.Select(location);
+               lb->Select(location);
 }
 
index 622a5666ec5ffdf56357ed4760e4d00b3daea92c..981fb44c061b3110fe747214aaab8d2d1767c9bb 100644 (file)
@@ -2,7 +2,7 @@
 /** @file AutoComplete.h
  ** Defines the auto completion list box.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef AUTOCOMPLETE_H
@@ -15,11 +15,12 @@ class AutoComplete {
        char stopChars[256];
        char fillUpChars[256];
        char separator;
+       char typesep; // Type seperator
 
 public:
        bool ignoreCase;
        bool chooseSingle;
-       ListBox lb;
+       ListBox *lb;
        int posStart;
        int startLen;
        /// Should autocompletion be canceled if editor's currentPos <= startPos?
@@ -34,7 +35,8 @@ public:
        bool Active();
 
        /// Display the auto completion list positioned to be near a character position
-       void Start(Window &parent, int ctrlID, int position, int startLen_);
+       void Start(Window &parent, int ctrlID, int position,
+               int startLen_, int lineHeight, bool unicodeMode);
 
        /// The stop chars are characters which, when typed, cause the auto completion list to disappear
        void SetStopChars(const char *stopChars_);
@@ -48,6 +50,10 @@ public:
        void SetSeparator(char separator_);
        char GetSeparator();
 
+       /// The typesep character is used for seperating the word from the type
+       void SetTypesep(char separator_);
+       char GetTypesep();
+
        /// The list string contains a sequence of words separated by the separator character
        void SetList(const char *list);
 
index d67173b084a5c52ed3116d26c0a7e4585b8c1d25..314f9bfa716df518edc06ab52628633ffdcfbc1a 100644 (file)
@@ -18,6 +18,9 @@ CallTip::CallTip() {
        inCallTipMode = false;
        posStartCallTip = 0;
        val = 0;
+       xUp = -100;
+       xDown = -100;
+       lineHeight = 1;
        startHighlight = 0;
        endHighlight = 0;
 
@@ -35,6 +38,8 @@ CallTip::~CallTip() {
        val = 0;
 }
 
+const int widthArrow = 14;
+
 void CallTip::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(colourBG, want);
        pal.WantFind(colourUnSel, want);
@@ -43,24 +48,98 @@ void CallTip::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(colourLight, want);
 }
 
-void CallTip::PaintCT(Surface *surfaceWindow) {
-       if (!val)
-               return ;
+void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
+       int posStart, int posEnd, int ytext, PRectangle rcClient,
+       bool highlight, bool draw) {
+       s += posStart;
+       int len = posEnd - posStart;
+       int maxEnd = 0;
+       int ends[10];
+       for (int i=0;i<len;i++) {
+               if (s[i] <= '\002') {
+                       if (i > 0)
+                               ends[maxEnd++] = i;
+                       ends[maxEnd++] = i+1;
+               }
+       }
+       ends[maxEnd++] = len;
+       int startSeg = 0;
+       int xEnd;
+       for (int seg = 0; seg<maxEnd; seg++) {
+               int endSeg = ends[seg];
+               if (endSeg > startSeg) {
+                       if (s[startSeg] <= '\002') {
+                               xEnd = x + widthArrow;
+                               offsetMain = xEnd;
+                               if (draw) {
+                                       const int halfWidth = widthArrow / 2 - 3;
+                                       const int centreX = x + widthArrow / 2 - 1;
+                                       const int centreY = (rcClient.top + rcClient.bottom) / 2;
+                                       rcClient.left = x;
+                                       rcClient.right = xEnd;
+                                       surface->FillRectangle(rcClient, colourBG.allocated);
+                                       PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
+                                       surface->FillRectangle(rcClientInner, colourUnSel.allocated);
+
+                                       if (s[startSeg] == '\001') {
+                                               // Up arrow
+                                               Point pts[] = {
+                                               Point(centreX - halfWidth, centreY + halfWidth / 2),
+                                               Point(centreX + halfWidth, centreY + halfWidth / 2),
+                                               Point(centreX, centreY - halfWidth + halfWidth / 2),
+                                               };
+                                               surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
+                                                               colourBG.allocated, colourBG.allocated);
+                                       } else {
+                                               // Down arrow
+                                               Point pts[] = {
+                                               Point(centreX - halfWidth, centreY - halfWidth / 2),
+                                               Point(centreX + halfWidth, centreY - halfWidth / 2),
+                                               Point(centreX, centreY + halfWidth - halfWidth / 2),
+                                               };
+                                               surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
+                                                               colourBG.allocated, colourBG.allocated);
+                                       }
+                               } else {
+                                       if (s[startSeg] == '\001') {
+                                               xUp = x+1;
+                                       } else {
+                                               xDown = x+1;
+                                       }
+                               }
+                       } else {
+                               xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
+                               if (draw) {
+                                       rcClient.left = x;
+                                       rcClient.right = xEnd;
+                                       surface->DrawTextNoClip(rcClient, font, ytext,
+                                                                               s+startSeg, endSeg - startSeg,
+                                                                               highlight ? colourSel.allocated : colourUnSel.allocated,
+                                                                               colourBG.allocated);
+                               }
+                       }
+                       x = xEnd;
+                       startSeg = endSeg;
+               }
+       }
+}
+
+int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
        PRectangle rcClientPos = wCallTip.GetClientPosition();
        PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
                                rcClientPos.bottom - rcClientPos.top);
        PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
 
-       surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
        // To make a nice small call tip window, it is only sized to fit most normal characters without accents
-       int lineHeight = surfaceWindow->Height(font);
        int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
 
        // For each line...
        // Draw the definition in three parts: before highlight, highlighted, after highlight
        int ytext = rcClient.top + ascent + 1;
+       rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
        char *chunkVal = val;
        bool moreChunks = true;
+       int maxWidth = 0;
        while (moreChunks) {
                char *chunkEnd = strchr(chunkVal, '\n');
                if (chunkEnd == NULL) {
@@ -76,36 +155,38 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
                int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
                thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
                thisEndHighlight -= chunkOffset;
-               int x = 5;
-               int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight);
-               rcClient.left = x;
                rcClient.top = ytext - ascent - 1;
-               rcClient.right = xEnd;
-               surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
-                                       chunkVal, thisStartHighlight,
-                                       colourUnSel.allocated, colourBG.allocated);
-               x = xEnd;
-
-               xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight,
-                                                   thisEndHighlight - thisStartHighlight);
-               rcClient.top = ytext;
-               rcClient.left = x;
-               rcClient.right = xEnd;
-               surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
-                                       chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight,
-                                       colourSel.allocated, colourBG.allocated);
-               x = xEnd;
-
-               xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight,
-                                                   chunkLength - thisEndHighlight);
-               rcClient.left = x;
-               rcClient.right = xEnd;
-               surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
-                                       chunkVal + thisEndHighlight, chunkLength - thisEndHighlight,
-                                       colourUnSel.allocated, colourBG.allocated);
+
+               int x = 5;
+
+               DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
+                       ytext, rcClient, false, draw);
+               DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
+                       ytext, rcClient, true, draw);
+               DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
+                       ytext, rcClient, false, draw);
+
                chunkVal = chunkEnd + 1;
                ytext += lineHeight;
+               rcClient.bottom += lineHeight;
+               maxWidth = Platform::Maximum(maxWidth, x);
        }
+       return maxWidth;
+}
+
+void CallTip::PaintCT(Surface *surfaceWindow) {
+       if (!val)
+               return;
+       PRectangle rcClientPos = wCallTip.GetClientPosition();
+       PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
+                               rcClientPos.bottom - rcClientPos.top);
+       PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
+
+       surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
+
+       offsetMain = 5;
+       PaintContents(surfaceWindow, true);
+
        // Draw a raised border around the edges of the window
        surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
        surfaceWindow->PenColour(colourShade.allocated);
@@ -116,20 +197,34 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
        surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
 }
 
+void CallTip::MouseClick(Point pt) {
+       clickPlace = 0;
+       if (pt.y < lineHeight) {
+               if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
+                       clickPlace = 1;
+               } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
+                       clickPlace = 2;
+               }
+       }
+}
+
 PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
-                                 const char *faceName, int size, bool unicodeMode_) {
+                                 const char *faceName, int size,
+                                 int codePage_, Window &wParent) {
+       clickPlace = 0;
        if (val)
                delete []val;
        val = new char[strlen(defn) + 1];
        if (!val)
                return PRectangle();
        strcpy(val, defn);
-       unicodeMode = unicodeMode_;
+       codePage = codePage_;
        Surface *surfaceMeasure = Surface::Allocate();
        if (!surfaceMeasure)
                return PRectangle();
-       surfaceMeasure->Init();
-       surfaceMeasure->SetUnicodeMode(unicodeMode);
+       surfaceMeasure->Init(wParent.GetID());
+       surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
+       surfaceMeasure->SetDBCSMode(codePage);
        startHighlight = 0;
        endHighlight = 0;
        inCallTipMode = true;
@@ -138,23 +233,22 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
        font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false);
        // Look for multiple lines in the text
        // Only support \n here - simply means container must avoid \r!
-       int width = 0;
        int numLines = 1;
        const char *newline;
        const char *look = val;
+       xUp = -100;
+       xDown = -100;
+       offsetMain = 5;
+       int width = PaintContents(surfaceMeasure, false) + 5;
        while ((newline = strchr(look, '\n')) != NULL) {
-               int thisWidth = surfaceMeasure->WidthText(font, look, newline - look);
-               width = Platform::Maximum(width, thisWidth);
                look = newline + 1;
                numLines++;
        }
-       int lastWidth = surfaceMeasure->WidthText(font, look, static_cast<int>(strlen(look)));
-       width = Platform::Maximum(width, lastWidth) + 10;
-       int lineHeight = surfaceMeasure->Height(font);
+       lineHeight = surfaceMeasure->Height(font);
        // Extra line for border and an empty line at top and bottom
        int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
        delete surfaceMeasure;
-       return PRectangle(pt.x -5, pt.y + 1, pt.x + width - 5, pt.y + 1 + height);
+       return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
 }
 
 void CallTip::CallTipCancel() {
index 9f5025f63bafbcb41a9c6092f324b66f9a98a017..ffaedb0771b746a40b1f4ac647b6adb26d993607 100644 (file)
@@ -15,9 +15,17 @@ class CallTip {
        int endHighlight;
        char *val;
        Font font;
+       int xUp;
+       int xDown;
+       int lineHeight;
+       int offsetMain;
        // Private so CallTip objects can not be copied
        CallTip(const CallTip &) {}
        CallTip &operator=(const CallTip &) { return *this; }
+       void DrawChunk(Surface *surface, int &x, const char *s,
+               int posStart, int posEnd, int ytext, PRectangle rcClient,
+               bool highlight, bool draw);
+       int PaintContents(Surface *surfaceWindow, bool draw);
 
 public:
        Window wCallTip;
@@ -29,22 +37,25 @@ public:
        ColourPair colourSel;
        ColourPair colourShade;
        ColourPair colourLight;
-       bool unicodeMode;
-       
+       int codePage;
+       int clickPlace;
+
        CallTip();
        ~CallTip();
-       
+
        /// Claim or accept palette entries for the colours required to paint a calltip.
        void RefreshColourPalette(Palette &pal, bool want);
-       
+
        void PaintCT(Surface *surfaceWindow);
-       
+
+       void MouseClick(Point pt);
+
        /// Setup the calltip and return a rectangle of the area required.
-       PRectangle CallTipStart(int pos, Point pt, const char *defn, 
-               const char *faceName, int size, bool unicodeMode_);
-               
+       PRectangle CallTipStart(int pos, Point pt, const char *defn,
+               const char *faceName, int size, int codePage_, Window &wParent);
+
        void CallTipCancel();
-       
+
        /// Set a range of characters to be displayed in a highlight style.
        /// Commonly used to highlight the current parameter.
        void SetHighlight(int start, int end);
index 420dee6ff70ed50386f9e0bc914797201fdae91e..8f292869d743ed28d3bfc7aaf6f9c3c5de2953b6 100644 (file)
@@ -739,6 +739,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) {
 }
 
 bool CellBuffer::SetStyleAt(int position, char style, char mask) {
+       style &= mask;
        char curVal = ByteAt(position * 2 + 1);
        if ((curVal & mask) != style) {
                SetByteAt(position*2 + 1, static_cast<char>((curVal & ~mask) | style));
index 5cfcbfe1f01fcaac2f1601f029401227dc187f4c..2866d548cb808560373c6d7040c495a0ae277020 100644 (file)
@@ -212,7 +212,7 @@ public:
        int GetMark(int line);
        void DeleteAllMarks(int markerNum);
        int LineFromHandle(int markerHandle);
+
        /// Actions without undo
        void BasicInsertString(int position, char *s, int insertLength);
        void BasicDeleteChars(int position, int deleteLength);
index 7458120442ab5afc9c0814dedd02ecd376d2efe4..20900bcf97ab4ea310e0c89d167fa4857ceff822 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Document.cxx
  ** Text document that handles notifications, DBCS, styling, words and end of line.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -23,6 +23,22 @@ static inline bool isspacechar(unsigned char ch) {
        return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
 }
 
+static inline bool IsPunctuation(char ch) {
+       return isascii(ch) && ispunct(ch);
+}
+
+static inline bool IsADigit(char ch) {
+       return isascii(ch) && isdigit(ch);
+}
+
+static inline bool IsLowerCase(char ch) {
+       return isascii(ch) && islower(ch);
+}
+
+static inline bool IsUpperCase(char ch) {
+       return isascii(ch) && isupper(ch);
+}
+
 Document::Document() {
        refCount = 0;
 #ifdef unix
@@ -218,32 +234,12 @@ bool Document::IsCrLf(int pos) {
        return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
 }
 
-bool Document::IsDBCS(int pos) {
-       if (dbcsCodePage) {
-               if (SC_CP_UTF8 == dbcsCodePage) {
-                       unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
-                       return ch >= 0x80;
-               } else {
-                       // Anchor DBCS calculations at start of line because start of line can
-                       // not be a DBCS trail byte.
-                       int startLine = pos;
-                       while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n')
-                               startLine--;
-                       while (startLine <= pos) {
-                               if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine))) {
-                                       startLine++;
-                                       if (startLine >= pos)
-                                               return true;
-                               }
-                               startLine++;
-                       }
-               }
-       }
-       return false;
-}
+static const int maxBytesInDBCSCharacter=5;
 
 int Document::LenChar(int pos) {
-       if (IsCrLf(pos)) {
+       if (pos < 0) {
+               return 1;
+       } else if (IsCrLf(pos)) {
                return 2;
        } else if (SC_CP_UTF8 == dbcsCodePage) {
                unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
@@ -257,8 +253,14 @@ int Document::LenChar(int pos) {
                        return lengthDoc -pos;
                else
                        return len;
-       } else if (IsDBCS(pos)) {
-               return 2;
+       } else if (dbcsCodePage) {
+               char mbstr[maxBytesInDBCSCharacter+1];
+               int i;
+               for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
+                       mbstr[i] = cb.CharAt(pos+i);
+               }
+               mbstr[i] = '\0';
+               return Platform::DBCSCharLength(dbcsCodePage, mbstr);
        } else {
                return 1;
        }
@@ -308,26 +310,28 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
                        // Anchor DBCS calculations at start of line because start of line can
                        // not be a DBCS trail byte.
                        int startLine = pos;
+
                        while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n')
                                startLine--;
-                       bool atLeadByte = false;
                        while (startLine < pos) {
-                               if (atLeadByte)
-                                       atLeadByte = false;
-                               else if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine)))
-                                       atLeadByte = true;
-                               else
-                                       atLeadByte = false;
-                               startLine++;
-                       }
-
-
-                       if (atLeadByte) {
-                               // Position is between a lead byte and a trail byte
-                               if (moveDir > 0)
-                                       return pos + 1;
-                               else
-                                       return pos - 1;
+                               char mbstr[maxBytesInDBCSCharacter+1];
+                               int i;
+                               for(i=0;i<Platform::DBCSCharMaxLength();i++) {
+                                       mbstr[i] = cb.CharAt(startLine+i);
+                               }
+                               mbstr[i] = '\0';
+
+                               int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+                               if (startLine + mbsize == pos) {
+                                       return pos;
+                               } else if (startLine + mbsize > pos) {
+                                       if (moveDir > 0) {
+                                               return startLine + mbsize;
+                                       } else {
+                                               return startLine;
+                                       }
+                               }
+                               startLine += mbsize;
                        }
                }
        }
@@ -524,7 +528,7 @@ bool Document::InsertString(int position, const char *s, size_t insertLength) {
                        sWithStyle[i*2] = s[i];
                        sWithStyle[i*2 + 1] = 0;
                }
-               changed = InsertStyledString(position*2, sWithStyle, 
+               changed = InsertStyledString(position*2, sWithStyle,
                        static_cast<int>(insertLength*2));
                delete []sWithStyle;
        }
@@ -545,11 +549,9 @@ void Document::DelCharBack(int pos) {
                return;
        } else if (IsCrLf(pos - 2)) {
                DeleteChars(pos - 2, 2);
-       } else if (SC_CP_UTF8 == dbcsCodePage) {
+       } else if (dbcsCodePage) {
                int startChar = MovePositionOutsideChar(pos - 1, -1, false);
                DeleteChars(startChar, pos - startChar);
-       } else if (IsDBCS(pos - 1)) {
-               DeleteChars(pos - 2, 2);
        } else {
                DeleteChars(pos - 1, 1);
        }
@@ -718,6 +720,33 @@ void Document::ConvertLineEnds(int eolModeSet) {
        EndUndoAction();
 }
 
+int Document::ParaDown(int pos) {
+       int line = LineFromPosition(pos);
+       while (line < LinesTotal() && LineStart(line) != LineEnd(line)) { // skip non-empty lines
+               line++;
+       }
+       while (line < LinesTotal() && LineStart(line) == LineEnd(line)) { // skip empty lines
+               line++;
+       }
+       if (line < LinesTotal())
+               return LineStart(line);
+       else // end of a document
+               return LineEnd(line-1);
+}
+
+int Document::ParaUp(int pos) {
+       int line = LineFromPosition(pos);
+       line--;
+       while (line >= 0 && LineStart(line) == LineEnd(line)) { // skip empty lines
+               line--;
+       }
+       while (line >= 0 && LineStart(line) != LineEnd(line)) { // skip non-empty lines
+               line--;
+       }
+       line++;
+       return LineStart(line);
+}
+
 Document::charClassification Document::WordCharClass(unsigned char ch) {
        if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))
                return ccWord;
@@ -745,7 +774,7 @@ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {
 }
 
 /**
- * Find the start of the next word in either a forward (delta >= 0) or backwards direction 
+ * Find the start of the next word in either a forward (delta >= 0) or backwards direction
  * (delta < 0).
  * This is looking for a transition between character classes although there is also some
  * additional movement to transit white space.
@@ -798,7 +827,7 @@ bool Document::IsWordEndAt(int pos) {
 }
 
 /**
- * Check that the given range is has transitions between character classes at both 
+ * Check that the given range is has transitions between character classes at both
  * ends and where the characters on the inside are word or punctuation characters.
  */
 bool Document::IsWordAt(int start, int end) {
@@ -845,7 +874,7 @@ public:
  * Has not been tested with backwards DBCS searches yet.
  */
 long Document::FindText(int minPos, int maxPos, const char *s,
-                        bool caseSensitive, bool word, bool wordStart, bool regExp,
+                        bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix,
                         int *length) {
        if (regExp) {
                if (!pre)
@@ -853,22 +882,16 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                if (!pre)
                        return -1;
 
-               int startPos;
-               int endPos;
+               int increment = (minPos <= maxPos) ? 1 : -1;
 
-               if (minPos <= maxPos) {
-                       startPos = minPos;
-                       endPos = maxPos;
-               } else {
-                       startPos = maxPos;
-                       endPos = minPos;
-               }
+               int startPos = minPos;
+               int endPos = maxPos;
 
                // Range endpoints should not be inside DBCS characters, but just in case, move them.
                startPos = MovePositionOutsideChar(startPos, 1, false);
                endPos = MovePositionOutsideChar(endPos, 1, false);
 
-               const char *errmsg = pre->Compile(s, *length, caseSensitive);
+               const char *errmsg = pre->Compile(s, *length, caseSensitive, posix);
                if (errmsg) {
                        return -1;
                }
@@ -878,7 +901,9 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                //     Replace: $(\1-\2)
                int lineRangeStart = LineFromPosition(startPos);
                int lineRangeEnd = LineFromPosition(endPos);
-               if ((startPos >= LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) {
+               if ((increment == 1) &&
+                       (startPos >= LineEnd(lineRangeStart)) &&
+                       (lineRangeStart < lineRangeEnd)) {
                        // the start position is at end of line or between line end characters.
                        lineRangeStart++;
                        startPos = LineStart(lineRangeStart);
@@ -886,36 +911,54 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                int pos = -1;
                int lenRet = 0;
                char searchEnd = s[*length - 1];
-               if (*length == 1) {
-                       // These produce empty selections so nudge them on if needed
-                       if (s[0] == '^') {
-                               if (startPos == LineStart(lineRangeStart))
-                                       startPos++;
-                       } else if (s[0] == '$') {
-                               if ((startPos == LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd))
-                                       startPos = LineStart(lineRangeStart + 1);
-                       }
-                       lineRangeStart = LineFromPosition(startPos);
-                       lineRangeEnd = LineFromPosition(endPos);
-               }
-               for (int line = lineRangeStart; line <= lineRangeEnd; line++) {
+               int lineRangeBreak = lineRangeEnd + increment;
+               for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
                        int startOfLine = LineStart(line);
                        int endOfLine = LineEnd(line);
-                       if (line == lineRangeStart) {
-                               if ((startPos != startOfLine) && (s[0] == '^'))
-                                       continue;       // Can't match start of line if start position after start of line
-                               startOfLine = startPos;
-                       }
-                       if (line == lineRangeEnd) {
-                               if ((endPos != endOfLine) && (searchEnd == '$'))
-                                       continue;       // Can't match end of line if end position before end of line
-                               endOfLine = endPos;
+                       if (increment == 1) {
+                               if (line == lineRangeStart) {
+                                       if ((startPos != startOfLine) && (s[0] == '^'))
+                                               continue;       // Can't match start of line if start position after start of line
+                                       startOfLine = startPos;
+                               }
+                               if (line == lineRangeEnd) {
+                                       if ((endPos != endOfLine) && (searchEnd == '$'))
+                                               continue;       // Can't match end of line if end position before end of line
+                                       endOfLine = endPos;
+                               }
+                       } else {
+                               if (line == lineRangeEnd) {
+                                       if ((endPos != startOfLine) && (s[0] == '^'))
+                                               continue;       // Can't match start of line if end position after start of line
+                                       startOfLine = endPos;
+                               }
+                               if (line == lineRangeStart) {
+                                       if ((startPos != endOfLine) && (searchEnd == '$'))
+                                               continue;       // Can't match end of line if start position before end of line
+                                       endOfLine = startPos;
+                               }
                        }
+
                        DocumentIndexer di(this, endOfLine);
                        int success = pre->Execute(di, startOfLine, endOfLine);
                        if (success) {
                                pos = pre->bopat[0];
                                lenRet = pre->eopat[0] - pre->bopat[0];
+                               if (increment == -1) {
+                                       // Check for the last match on this line.
+                                       int repetitions = 1000; // Break out of infinite loop
+                                       while (success && (pre->eopat[0] < endOfLine) && (repetitions--)) {
+                                               success = pre->Execute(di, pre->eopat[0], endOfLine);
+                                               if (success) {
+                                                       if (pre->eopat[0] <= minPos) {
+                                                               pos = pre->bopat[0];
+                                                               lenRet = pre->eopat[0] - pre->bopat[0];
+                                                       } else {
+                                                               success = 0;
+                                                       }
+                                               }
+                                       }
+                               }
                                break;
                        }
                }
@@ -1033,16 +1076,17 @@ int Document::LinesTotal() {
 
 void Document::ChangeCase(Range r, bool makeUpperCase) {
        for (int pos = r.start; pos < r.end; pos++) {
-               char ch = CharAt(pos);
-               if (dbcsCodePage && IsDBCS(pos)) {
-                       pos += LenChar(pos);
+               int len = LenChar(pos);
+               if (dbcsCodePage && (len > 1)) {
+                       pos += len;
                } else {
+                       char ch = CharAt(pos);
                        if (makeUpperCase) {
-                               if (islower(ch)) {
+                               if (IsLowerCase(ch)) {
                                        ChangeChar(pos, static_cast<char>(MakeUpperCase(ch)));
                                }
                        } else {
-                               if (isupper(ch)) {
+                               if (IsUpperCase(ch)) {
                                        ChangeChar(pos, static_cast<char>(MakeLowerCase(ch)));
                                }
                        }
@@ -1067,7 +1111,7 @@ void Document::SetWordChars(unsigned char *chars) {
                }
        } else {
                for (ch = 0; ch < 256; ch++) {
-                       if (ch >= 0x80 || isalnum(ch) || ch == '_') 
+                       if (ch >= 0x80 || isalnum(ch) || ch == '_')
                                charClass[ch] = ccWord;
                }
        }
@@ -1092,6 +1136,7 @@ bool Document::SetStyleFor(int length, char style) {
                return false;
        } else {
                enteredCount++;
+               style &= stylingMask;
                int prevEndStyled = endStyled;
                if (cb.SetStyleFor(endStyled, length, style, stylingMask)) {
                        DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
@@ -1206,7 +1251,7 @@ void Document::NotifyModified(DocModification mh) {
 }
 
 bool Document::IsWordPartSeparator(char ch) {
-       return ispunct(ch) && (WordCharClass(ch) == ccWord);
+       return (WordCharClass(ch) == ccWord) && IsPunctuation(ch);
 }
 
 int Document::WordPartLeft(int pos) {
@@ -1221,31 +1266,38 @@ int Document::WordPartLeft(int pos) {
                if (pos > 0) {
                        startChar = cb.CharAt(pos);
                        --pos;
-                       if (islower(startChar)) {
-                               while (pos > 0 && islower(cb.CharAt(pos)))
+                       if (IsLowerCase(startChar)) {
+                               while (pos > 0 && IsLowerCase(cb.CharAt(pos)))
                                        --pos;
-                               if (!isupper(cb.CharAt(pos)) && !islower(cb.CharAt(pos)))
+                               if (!IsUpperCase(cb.CharAt(pos)) && !IsLowerCase(cb.CharAt(pos)))
                                        ++pos;
-                       } else if (isupper(startChar)) {
-                               while (pos > 0 && isupper(cb.CharAt(pos)))
+                       } else if (IsUpperCase(startChar)) {
+                               while (pos > 0 && IsUpperCase(cb.CharAt(pos)))
                                        --pos;
-                               if (!isupper(cb.CharAt(pos)))
+                               if (!IsUpperCase(cb.CharAt(pos)))
                                        ++pos;
-                       } else if (isdigit(startChar)) {
-                               while (pos > 0 && isdigit(cb.CharAt(pos)))
+                       } else if (IsADigit(startChar)) {
+                               while (pos > 0 && IsADigit(cb.CharAt(pos)))
                                        --pos;
-                               if (!isdigit(cb.CharAt(pos)))
+                               if (!IsADigit(cb.CharAt(pos)))
                                        ++pos;
-                       } else if (ispunct(startChar)) {
-                               while (pos > 0 && ispunct(cb.CharAt(pos)))
+                       } else if (IsPunctuation(startChar)) {
+                               while (pos > 0 && IsPunctuation(cb.CharAt(pos)))
                                        --pos;
-                               if (!ispunct(cb.CharAt(pos)))
+                               if (!IsPunctuation(cb.CharAt(pos)))
                                        ++pos;
                        } else if (isspacechar(startChar)) {
                                while (pos > 0 && isspacechar(cb.CharAt(pos)))
                                        --pos;
                                if (!isspacechar(cb.CharAt(pos)))
                                        ++pos;
+                       } else if (!isascii(startChar)) {
+                               while (pos > 0 && !isascii(cb.CharAt(pos)))
+                                       --pos;
+                               if (isascii(cb.CharAt(pos)))
+                                       ++pos;
+                       } else {
+                               ++pos;
                        }
                }
        }
@@ -1260,29 +1312,47 @@ int Document::WordPartRight(int pos) {
                        ++pos;
                startChar = cb.CharAt(pos);
        }
-       if (islower(startChar)) {
-               while (pos < length && islower(cb.CharAt(pos)))
+       if (!isascii(startChar)) {
+               while (pos < length && !isascii(cb.CharAt(pos)))
                        ++pos;
-       } else if (isupper(startChar)) {
-               if (islower(cb.CharAt(pos + 1))) {
+       } else if (IsLowerCase(startChar)) {
+               while (pos < length && IsLowerCase(cb.CharAt(pos)))
                        ++pos;
-                       while (pos < length && islower(cb.CharAt(pos)))
+       } else if (IsUpperCase(startChar)) {
+               if (IsLowerCase(cb.CharAt(pos + 1))) {
+                       ++pos;
+                       while (pos < length && IsLowerCase(cb.CharAt(pos)))
                                ++pos;
                } else {
-                       while (pos < length && isupper(cb.CharAt(pos)))
+                       while (pos < length && IsUpperCase(cb.CharAt(pos)))
                                ++pos;
                }
-               if (islower(cb.CharAt(pos)) && isupper(cb.CharAt(pos - 1)))
+               if (IsLowerCase(cb.CharAt(pos)) && IsUpperCase(cb.CharAt(pos - 1)))
                        --pos;
-       } else if (isdigit(startChar)) {
-               while (pos < length && isdigit(cb.CharAt(pos)))
+       } else if (IsADigit(startChar)) {
+               while (pos < length && IsADigit(cb.CharAt(pos)))
                        ++pos;
-       } else if (ispunct(startChar)) {
-               while (pos < length && ispunct(cb.CharAt(pos)))
+       } else if (IsPunctuation(startChar)) {
+               while (pos < length && IsPunctuation(cb.CharAt(pos)))
                        ++pos;
        } else if (isspacechar(startChar)) {
                while (pos < length && isspacechar(cb.CharAt(pos)))
                        ++pos;
+       } else {
+               ++pos;
+       }
+       return pos;
+}
+
+int Document::ExtendStyleRange(int pos, int delta) {
+       int sStart = cb.StyleAt(pos);
+       if (delta < 0) {
+               while (pos > 0 && (cb.StyleAt(pos) == sStart))
+                       pos--;
+               pos++;
+       } else {
+               while (pos < (Length()) && (cb.StyleAt(pos) == sStart))
+                       pos++;
        }
        return pos;
 }
index 82931207cfcbe8cb7662f9ea07cb1e72a079936e..bcdbe00ca5c888da8a9ba37982beab7f3f448285 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Document.h
  ** Text document that handles notifications, DBCS, styling, words and end of line.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef DOCUMENT_H
@@ -26,10 +26,10 @@ public:
        Position start;
        Position end;
 
-       Range(Position pos=0) : 
+       Range(Position pos=0) :
                start(pos), end(pos) {
        };
-       Range(Position start_, Position end_) : 
+       Range(Position start_, Position end_) :
                start(start_), end(end_) {
        };
 
@@ -60,7 +60,7 @@ public:
        }
 
        bool Overlaps(Range other) const {
-               return 
+               return
                Contains(other.start) ||
                Contains(other.end) ||
                other.Contains(start) ||
@@ -88,7 +88,7 @@ public:
                }
        };
 
-private:       
+private:
        int refCount;
        CellBuffer cb;
        enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
@@ -191,8 +191,8 @@ public:
        int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
        int NextWordStart(int pos, int delta);
        int Length() { return cb.Length(); }
-       long FindText(int minPos, int maxPos, const char *s, 
-               bool caseSensitive, bool word, bool wordStart, bool regExp, int *length);
+       long FindText(int minPos, int maxPos, const char *s,
+               bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length);
        long FindText(int iMessage, unsigned long wParam, long lParam);
        const char *SubstituteByPosition(const char *text, int *length);
        int LinesTotal();
@@ -220,9 +220,11 @@ public:
        bool IsWordPartSeparator(char ch);
        int WordPartLeft(int pos);
        int WordPartRight(int pos);
+       int ExtendStyleRange(int pos, int delta);
+       int ParaUp(int pos);
+       int ParaDown(int pos);
 
 private:
-       bool IsDBCS(int pos);
        charClassification WordCharClass(unsigned char ch);
        bool IsWordStartAt(int pos);
        bool IsWordEndAt(int pos);
@@ -252,7 +254,7 @@ public:
        int foldLevelNow;
        int foldLevelPrev;
 
-       DocModification(int modificationType_, int position_=0, int length_=0, 
+       DocModification(int modificationType_, int position_=0, int length_=0,
                int linesAdded_=0, const char *text_=0) :
                modificationType(modificationType_),
                position(position_),
index 595edf8ba21a276b98a7bd4d8276c8e5b53c730d..b7902df35a1bfc02e764275f2709879440507f3c 100644 (file)
@@ -174,7 +174,7 @@ int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnI
        *flags = spaceFlags;
        indent += SC_FOLDLEVELBASE;
        // if completely empty line or the start of a comment...
-       if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || 
+       if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
                (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
                return indent | SC_FOLDLEVELWHITEFLAG;
        else
index dc591d13ec3142c08216f5451b18e752db0fb6e1..f6523c94f995c1ce37a20ec1b65917b420aefc93 100644 (file)
@@ -32,9 +32,9 @@ protected:
        void Fill(int position);
 
 public:
-       DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : 
+       DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) :
                Accessor(), pdoc(pdoc_), props(props_), id(id_),
-               lenDoc(-1), validLen(0), chFlags(0), chWhile(0), 
+               lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
                startSeg(0), startPosStyling(0) {
        }
        ~DocumentAccessor();
@@ -47,8 +47,8 @@ public:
        void Flush();
        int GetLineState(int line);
        int SetLineState(int line, int state);
-       int GetPropertyInt(const char *key, int defaultValue=0) { 
-               return props.GetInt(key, defaultValue); 
+       int GetPropertyInt(const char *key, int defaultValue=0) {
+               return props.GetInt(key, defaultValue);
        }
        char *GetProperties() {
                return props.ToString();
index f2ba9f088b5e70d193cafd5780c504674dc1eb38..44399a5fb0dc21aa57cae56a337f82e487323971 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Editor.cxx
  ** Main code for the edit control.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -12,7 +12,9 @@
 
 #include "Platform.h"
 
+#ifndef PLAT_QT
 #define INCLUDE_DEPRECATED_FEATURES
+#endif
 #include "Scintilla.h"
 
 #include "ContractionState.h"
@@ -20,6 +22,7 @@
 #include "CellBuffer.h"
 #include "KeyMap.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
 #include "ViewStyle.h"
@@ -52,7 +55,7 @@ LineLayout::LineLayout(int maxLineLength_) :
        positions(0),
        widthLine(wrapWidthInfinite),
        lines(1) {
-               Resize(maxLineLength_);
+       Resize(maxLineLength_);
 }
 
 LineLayout::~LineLayout() {
@@ -96,7 +99,7 @@ void LineLayout::SetLineStart(int line, int start) {
                int *newLineStarts = new int[newMaxLines];
                if (!newLineStarts)
                        return;
-               for (int i=0; i<newMaxLines; i++) {
+               for (int i = 0; i < newMaxLines; i++) {
                        if (i < lenLineStarts)
                                newLineStarts[i] = lineStarts[i];
                        else
@@ -110,7 +113,7 @@ void LineLayout::SetLineStart(int line, int start) {
 }
 
 void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
-       char bracesMatchStyle, int xHighlight) {
+                                    char bracesMatchStyle, int xHighlight) {
        if (rangeLine.ContainsCharacter(braces[0])) {
                int braceOffset = braces[0] - rangeLine.start;
                if (braceOffset < numCharsInLine) {
@@ -126,7 +129,7 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
                }
        }
        if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) ||
-               (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
+               (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
                xHighlightGuide = xHighlight;
        }
 }
@@ -165,9 +168,9 @@ void LineLayoutCache::Allocate(int length_) {
                size = (size / 16 + 1) * 16;
        }
        if (size > 0) {
-               cache = new LineLayout *[size];
+               cache = new LineLayout * [size];
        }
-       for (int i=0; i<size; i++)
+       for (int i = 0; i < size; i++)
                cache[i] = 0;
 }
 
@@ -183,7 +186,7 @@ void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
        if (lengthForLevel > size) {
                Deallocate();
        } else if (lengthForLevel < length) {
-               for (int i=lengthForLevel; i<length; i++) {
+               for (int i = lengthForLevel; i < length; i++) {
                        delete cache[i];
                        cache[i] = 0;
                }
@@ -194,7 +197,7 @@ void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
 }
 
 void LineLayoutCache::Deallocate() {
-       for (int i=0; i<length; i++)
+       for (int i = 0; i < length; i++)
                delete cache[i];
        delete []cache;
        cache = 0;
@@ -203,7 +206,7 @@ void LineLayoutCache::Deallocate() {
 
 void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
        if (cache && !allInvalidated) {
-               for (int i=0; i<length; i++) {
+               for (int i = 0; i < length; i++) {
                        if (cache[i]) {
                                cache[i]->Invalidate(validity_);
                        }
@@ -223,7 +226,7 @@ void LineLayoutCache::SetLevel(int level_) {
 }
 
 LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_,
-       int linesOnScreen, int linesInDoc) {
+                                      int linesOnScreen, int linesInDoc) {
        AllocateForLevel(linesOnScreen, linesInDoc);
        if (styleClock != styleClock_) {
                Invalidate(LineLayout::llCheckTextAndStyle);
@@ -243,7 +246,7 @@ LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChar
                if (cache && (pos < length)) {
                        if (cache[pos]) {
                                if ((cache[pos]->lineNumber != lineNumber) ||
-                                       (cache[pos]->maxLineLength < maxChars)) {
+                                       (cache[pos]->maxLineLength < maxChars)) {
                                        delete cache[pos];
                                        cache[pos] = 0;
                                }
@@ -283,6 +286,7 @@ Editor::Editor() {
 
        printMagnification = 0;
        printColourMode = SC_PRINT_NORMAL;
+       printWrapState = eWrapWord;
        cursorMode = SC_CURSORNORMAL;
        controlCharSymbol = 0;  /* Draw the control characters */
 
@@ -293,6 +297,7 @@ Editor::Editor() {
        mouseDownCaptures = true;
 
        bufferedDraw = true;
+       twoPhaseDraw = true;
 
        lastClickTime = 0;
        dwellDelay = SC_TIME_FOREVER;
@@ -327,6 +332,7 @@ Editor::Editor() {
        xCaretMargin = 50;
        horizontalScrollBarVisible = true;
        scrollWidth = 2000;
+       verticalScrollBarVisible = true;
        endAtLastLine = true;
 
        pixmapLine = Surface::Allocate();
@@ -358,7 +364,7 @@ Editor::Editor() {
        modEventMask = SC_MODEVENTMASKALL;
 
        pdoc = new Document();
-       pdoc ->AddRef();
+       pdoc->AddRef();
        pdoc->AddWatcher(this, 0);
 
        recordingMacro = false;
@@ -368,7 +374,10 @@ Editor::Editor() {
        wrapWidth = LineLayout::wrapWidthInfinite;
        docLineLastWrapped = -1;
 
-       llc.SetLevel(LineLayoutCache::llcDocument);
+       hsStart = -1;
+       hsEnd = -1;
+
+       llc.SetLevel(LineLayoutCache::llcCaret);
 }
 
 Editor::~Editor() {
@@ -414,7 +423,7 @@ void Editor::RefreshColourPalette(Palette &pal, bool want) {
 void Editor::RefreshStyleData() {
        if (!stylesValid) {
                stylesValid = true;
-               AutoSurface surface(IsUnicodeMode());
+               AutoSurface surface(this);
                if (surface) {
                        vs.Refresh(*surface);
                        RefreshColourPalette(palette, true);
@@ -474,10 +483,10 @@ static inline bool IsControlCharacter(char ch) {
 
 const char *ControlCharacterString(unsigned char ch) {
        const char *reps[] = {
-           "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
-           "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
-           "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
-           "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
+               "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
+               "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
+               "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
+               "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
        };
        if (ch < (sizeof(reps) / sizeof(reps[0]))) {
                return reps[ch];
@@ -486,6 +495,29 @@ const char *ControlCharacterString(unsigned char ch) {
        }
 }
 
+// Convenience class to ensure LineLayout objects are always disposed.
+class AutoLineLayout {
+       LineLayoutCache &llc;
+       LineLayout *ll;
+       AutoLineLayout &operator=(const AutoLineLayout &) { return * this; }
+public:
+       AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {}
+       ~AutoLineLayout() {
+               llc.Dispose(ll);
+               ll = 0;
+       }
+       LineLayout *operator->() const {
+               return ll;
+       }
+       operator LineLayout *() const {
+               return ll;
+       }
+       void Set(LineLayout *ll_) {
+               llc.Dispose(ll);
+               ll = ll_;
+       }
+};
+
 Point Editor::LocationFromPosition(int pos) {
        Point pt;
        RefreshStyleData();
@@ -494,8 +526,8 @@ Point Editor::LocationFromPosition(int pos) {
        int line = pdoc->LineFromPosition(pos);
        int lineVisible = cs.DisplayFromDoc(line);
        //Platform::DebugPrintf("line=%d\n", line);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(line);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(line));
        if (surface && ll) {
                // -1 because of adding in for visible lines in following loop.
                pt.y = (lineVisible - topLine - 1) * vs.lineHeight;
@@ -507,8 +539,8 @@ Point Editor::LocationFromPosition(int pos) {
                if (posInLine > ll->maxLineLength) {
                        pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
                }
-               for (int subLine=0; subLine<ll->lines; subLine++) {
-                       if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) {
+               for (int subLine = 0; subLine < ll->lines; subLine++) {
+                       if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) {
                                pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)];
                        }
                        if (posInLine >= ll->LineStart(subLine)) {
@@ -517,7 +549,6 @@ Point Editor::LocationFromPosition(int pos) {
                }
                pt.x += vs.fixedColumnWidth - xOffset;
        }
-       llc.Dispose(ll);
        return pt;
 }
 
@@ -535,6 +566,10 @@ void Editor::SetTopLine(int topLineNew) {
        posTopLine = pdoc->LineStart(topLine);
 }
 
+static inline bool IsEOLChar(char ch) {
+       return (ch == '\r') || (ch == '\n');
+}
+
 int Editor::PositionFromLocation(Point pt) {
        RefreshStyleData();
        pt.x = pt.x - vs.fixedColumnWidth + xOffset;
@@ -547,31 +582,28 @@ int Editor::PositionFromLocation(Point pt) {
        int lineDoc = cs.DocFromDisplay(visibleLine);
        if (lineDoc >= pdoc->LinesTotal())
                return pdoc->Length();
-       AutoSurface surface(IsUnicodeMode());
-       int retVal = 0;
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       unsigned int posLineStart = pdoc->LineStart(lineDoc);
+       int retVal = posLineStart;
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
-               unsigned int posLineStart = pdoc->LineStart(lineDoc);
                int lineStartSet = cs.DisplayFromDoc(lineDoc);
                int subLine = visibleLine - lineStartSet;
                if (subLine < ll->lines) {
                        int lineStart = ll->LineStart(subLine);
-                       int lineEnd = ll->LineStart(subLine+1);
+                       int lineEnd = ll->LineStart(subLine + 1);
                        int subLineStart = ll->positions[lineStart];
                        for (int i = lineStart; i < lineEnd; i++) {
                                if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) ||
-                                       ll->chars[i] == '\r' || ll->chars[i] == '\n') {
-                                       llc.Dispose(ll);
+                                       IsEOLChar(ll->chars[i])) {
                                        return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
                                }
                        }
-                       llc.Dispose(ll);
                        return lineEnd + posLineStart;
                }
                retVal = ll->numCharsInLine + posLineStart;
        }
-       llc.Dispose(ll);
        return retVal;
 }
 
@@ -595,8 +627,8 @@ int Editor::PositionFromLocationClose(Point pt) {
                return INVALID_POSITION;
        if (lineDoc >= pdoc->LinesTotal())
                return INVALID_POSITION;
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
@@ -604,18 +636,16 @@ int Editor::PositionFromLocationClose(Point pt) {
                int subLine = visibleLine - lineStartSet;
                if (subLine < ll->lines) {
                        int lineStart = ll->LineStart(subLine);
-                       int lineEnd = ll->LineStart(subLine+1);
+                       int lineEnd = ll->LineStart(subLine + 1);
                        int subLineStart = ll->positions[lineStart];
                        for (int i = lineStart; i < lineEnd; i++) {
                                if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) ||
-                                       ll->chars[i] == '\r' || ll->chars[i] == '\n') {
-                                       llc.Dispose(ll);
+                                       IsEOLChar(ll->chars[i])) {
                                        return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
                                }
                        }
                }
        }
-       llc.Dispose(ll);
 
        return INVALID_POSITION;
 }
@@ -629,8 +659,8 @@ int Editor::PositionFromLineX(int lineDoc, int x) {
        if (lineDoc >= pdoc->LinesTotal())
                return pdoc->Length();
        //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        int retVal = 0;
        if (surface && ll) {
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
@@ -638,17 +668,16 @@ int Editor::PositionFromLineX(int lineDoc, int x) {
                retVal = ll->numCharsInLine + posLineStart;
                int subLine = 0;
                int lineStart = ll->LineStart(subLine);
-               int lineEnd = ll->LineStart(subLine+1);
+               int lineEnd = ll->LineStart(subLine + 1);
                int subLineStart = ll->positions[lineStart];
                for (int i = lineStart; i < lineEnd; i++) {
                        if (x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) ||
-                               ll->chars[i] == '\r' || ll->chars[i] == '\n') {
+                               IsEOLChar(ll->chars[i])) {
                                retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
                                break;
                        }
                }
        }
-       llc.Dispose(ll);
        return retVal;
 }
 
@@ -820,18 +849,45 @@ void Editor::SetEmptySelection(int currentPos_) {
        SetSelection(currentPos_, currentPos_);
 }
 
+bool Editor::RangeContainsProtected(int start, int end) const {
+       if (vs.ProtectionActive()) {
+               if (start > end) {
+                       int t = start;
+                       start = end;
+                       end = t;
+               }
+               int mask = pdoc->stylingBitsMask;
+               for (int pos = start; pos < end; pos++) {
+                       if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected())
+                               return true;
+               }
+       }
+       return false;
+}
+
+bool Editor::SelectionContainsProtected() const {
+       // TODO: make support rectangular selection
+       return RangeContainsProtected(anchor, 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].IsProtected()))
-                       pos++;
-       } else {
-               while ((pos > 0) &&
-                       (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
-                       pos--;
+       if (vs.ProtectionActive()) {
+               int mask = pdoc->stylingBitsMask;
+               if (moveDir > 0) {
+                       if ((pos > 0) && vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()) {
+                               while ((pos < pdoc->Length()) &&
+                                       (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()))
+                                       pos++;
+                       }
+               } else if (moveDir < 0) {
+                       if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) {
+                               while ((pos > 0) &&
+                                       (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
+                                       pos--;
+                       }
+               }
        }
        return pos;
 }
@@ -845,9 +901,9 @@ int Editor::MovePositionTo(int newPos, bool extend, bool ensureVisible) {
        } else {
                SetEmptySelection(newPos);
        }
+       ShowCaretAtCurrentPosition();
        if (ensureVisible)
                EnsureCaretVisible();
-       ShowCaretAtCurrentPosition();
        NotifyMove(newPos);
        return 0;
 }
@@ -877,7 +933,7 @@ void Editor::SetLastXChosen() {
        lastXChosen = pt.x;
 }
 
-void Editor::ScrollTo(int line) {
+void Editor::ScrollTo(int line, bool moveThumb) {
        int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());
        if (topLineNew != topLine) {
                // Try to optimise small scrolls
@@ -890,7 +946,9 @@ void Editor::ScrollTo(int line) {
                } else {
                        Redraw();
                }
-               SetVerticalScrollPos();
+               if (moveThumb) {
+                       SetVerticalScrollPos();
+               }
        }
 }
 
@@ -916,32 +974,31 @@ void Editor::MoveCaretInsideView(bool ensureVisible) {
        if (pt.y < rcClient.top) {
                MovePositionTo(PositionFromLocation(
                                   Point(lastXChosen, rcClient.top)),
-                                                  false, ensureVisible);
+                              false, ensureVisible);
        } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
                int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
                MovePositionTo(PositionFromLocation(
                                   Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
-                                                  false, ensureVisible);
+                              false, ensureVisible);
        }
 }
 
 int Editor::DisplayFromPosition(int pos) {
        int lineDoc = pdoc->LineFromPosition(pos);
        int lineDisplay = cs.DisplayFromDoc(lineDoc);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
                int posInLine = pos - posLineStart;
                lineDisplay--; // To make up for first increment ahead.
-               for (int subLine=0; subLine<ll->lines; subLine++) {
-                       if (posInLine >= ll->LineStart(subLine)) {
+               for (int subLine = 0; subLine < ll->lines; subLine++) {
+                       if (posInLine >= ll->LineStart(subLine)) {
                                lineDisplay++;
                        }
                }
        }
-       llc.Dispose(ll);
        return lineDisplay;
 }
 
@@ -1092,9 +1149,9 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
                }
                newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
                if (newTopLine != topLine) {
+                       Redraw();
                        SetTopLine(newTopLine);
                        SetVerticalScrollPos();
-                       Redraw();
                }
        }
 
@@ -1166,7 +1223,7 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
                        }
                } else {        // No slop
                        if (bStrict ||
-                               (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) {
+                               (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) {
                                // Strict or going out of display
                                if (bEven) {
                                        // Center caret
@@ -1201,6 +1258,14 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
                }
                if (xOffset != xOffsetNew) {
                        xOffset = xOffsetNew;
+                       if (xOffsetNew > 0) {
+                               PRectangle rcText = GetTextRectangle();
+                               if (horizontalScrollBarVisible == true &&
+                                       rcText.Width() + xOffset > scrollWidth) {
+                                       scrollWidth = xOffset + rcText.Width();
+                                       SetScrollBars();
+                               }
+                       }
                        SetHorizontalScrollPos();
                        Redraw();
                }
@@ -1249,7 +1314,7 @@ bool Editor::WrapLines() {
                if (wrapState == eWrapNone) {
                        if (wrapWidth != LineLayout::wrapWidthInfinite) {
                                wrapWidth = LineLayout::wrapWidthInfinite;
-                               for (int lineDoc=0; lineDoc<pdoc->LinesTotal(); lineDoc++) {
+                               for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
                                        cs.SetHeight(lineDoc, 1);
                                }
                                wrapOccurred = true;
@@ -1265,18 +1330,17 @@ bool Editor::WrapLines() {
                        wrapWidth = rcTextArea.Width();
                        // Ensure all of the document is styled.
                        pdoc->EnsureStyledTo(pdoc->Length());
-                       AutoSurface surface(IsUnicodeMode());
+                       AutoSurface surface(this);
                        if (surface) {
                                int lastLineToWrap = pdoc->LinesTotal();
                                while (docLineLastWrapped <= lastLineToWrap) {
                                        docLineLastWrapped++;
-                                       LineLayout *ll = RetrieveLineLayout(docLineLastWrapped);
+                                       AutoLineLayout ll(llc, RetrieveLineLayout(docLineLastWrapped));
                                        int linesWrapped = 1;
                                        if (ll) {
                                                LayoutLine(docLineLastWrapped, surface, vs, ll, wrapWidth);
                                                linesWrapped = ll->lines;
                                        }
-                                       llc.Dispose(ll);
                                        if (cs.SetHeight(docLineLastWrapped, linesWrapped)) {
                                                wrapOccurred = true;
                                        }
@@ -1299,6 +1363,63 @@ bool Editor::WrapLines() {
        return wrapOccurred;
 }
 
+void Editor::LinesJoin() {
+       if (!RangeContainsProtected(targetStart, targetEnd)) {
+               pdoc->BeginUndoAction();
+               bool prevNonWS = true;
+               for (int pos = targetStart; pos < targetEnd; pos++) {
+                       if (IsEOLChar(pdoc->CharAt(pos))) {
+                               targetEnd -= pdoc->LenChar(pos);
+                               pdoc->DelChar(pos);
+                               if (prevNonWS) {
+                                       // Ensure at least one space separating previous lines
+                                       pdoc->InsertChar(pos, ' ');
+                               }
+                       } else {
+                               prevNonWS = pdoc->CharAt(pos) != ' ';
+                       }
+               }
+               pdoc->EndUndoAction();
+       }
+}
+
+const char *StringFromEOLMode(int eolMode) {
+       if (eolMode == SC_EOL_CRLF) {
+               return "\r\n";
+       } else if (eolMode == SC_EOL_CR) {
+               return "\r";
+       } else {
+               return "\n";
+       }
+}
+
+void Editor::LinesSplit(int pixelWidth) {
+       if (!RangeContainsProtected(targetStart, targetEnd)) {
+               if (pixelWidth == 0) {
+                       PRectangle rcText = GetTextRectangle();
+                       pixelWidth = rcText.Width();
+               }
+               int lineStart = pdoc->LineFromPosition(targetStart);
+               int lineEnd = pdoc->LineFromPosition(targetEnd);
+               const char *eol = StringFromEOLMode(pdoc->eolMode);
+               pdoc->BeginUndoAction();
+               for (int line = lineStart; line <= lineEnd; line++) {
+                       AutoSurface surface(this);
+                       AutoLineLayout ll(llc, RetrieveLineLayout(line));
+                       if (surface && ll) {
+                               unsigned int posLineStart = pdoc->LineStart(line);
+                               LayoutLine(line, surface, vs, ll, pixelWidth);
+                               for (int subLine = 1; subLine < ll->lines; subLine++) {
+                                       pdoc->InsertString(posLineStart + (subLine - 1) * strlen(eol) +
+                                               ll->LineStart(subLine), eol);
+                                       targetEnd += strlen(eol);
+                               }
+                       }
+               }
+               pdoc->EndUndoAction();
+       }
+}
+
 int Editor::SubstituteMarkerIfEmpty(int markerCheck, int markerDefault) {
        if (vs.markers[markerCheck].markType == SC_MARK_EMPTY)
                return markerDefault;
@@ -1371,9 +1492,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 
                        // Old code does not know about new markers needed to distinguish all cases
                        int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID,
-                               SC_MARKNUM_FOLDEROPEN);
+                                           SC_MARKNUM_FOLDEROPEN);
                        int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND,
-                               SC_MARKNUM_FOLDER);
+                                                               SC_MARKNUM_FOLDER);
 
                        while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
 
@@ -1385,7 +1506,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 
                                // Decide which fold indicator should be displayed
                                level = pdoc->GetLevel(lineDoc);
-                               int levelNext = pdoc->GetLevel(lineDoc+1);
+                               int levelNext = pdoc->GetLevel(lineDoc + 1);
                                int marks = pdoc->GetMark(lineDoc);
                                if (!firstSubLine)
                                        marks = 0;
@@ -1455,7 +1576,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
                                        number[0] = '\0';
                                        if (firstSubLine)
                                                sprintf(number, "%d", lineDoc + 1);
-                                       if (foldFlags & 64)
+                                       if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS)
                                                sprintf(number, "%X", pdoc->GetLevel(lineDoc));
                                        PRectangle rcNumber = rcMarker;
                                        // Right justify
@@ -1463,9 +1584,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
                                        int xpos = rcNumber.right - width - 3;
                                        rcNumber.left = xpos;
                                        surface->DrawTextNoClip(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);
+                                                               rcNumber.top + vs.maxAscent, number, strlen(number),
+                                                               vs.styles[STYLE_LINENUMBER].fore.allocated,
+                                                               vs.styles[STYLE_LINENUMBER].back.allocated);
                                }
 
                                if (marks) {
@@ -1518,8 +1639,8 @@ LineLayout *Editor::RetrieveLineLayout(int lineNumber) {
        int posLineEnd = pdoc->LineStart(lineNumber + 1);
        int lineCaret = pdoc->LineFromPosition(currentPos);
        return llc.Retrieve(lineNumber, lineCaret,
-               posLineEnd - posLineStart, pdoc->GetStyleClock(),
-               LinesOnScreen() + 1, pdoc->LinesTotal());
+                           posLineEnd - posLineStart, pdoc->GetStyleClock(),
+                           LinesOnScreen() + 1, pdoc->LinesTotal());
 }
 
 /**
@@ -1540,7 +1661,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                int lineLength = 0;
                for (int cid = posLineStart; cid < posLineEnd; cid++) {
                        char chDoc = pdoc->CharAt(cid);
-                       if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
+                       if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
                                lineLength++;
                        }
                }
@@ -1554,20 +1675,20 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) {
                                char chDoc = pdoc->CharAt(charInDoc);
                                styleByte = pdoc->StyleAt(charInDoc);
-                               if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
-                                       allSame = allSame && 
-                                               (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
-                                       allSame = allSame && 
-                                               (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+                               if (vstyle.viewEOL || (!IsEOLChar(chDoc != '\r'))) {
+                                       allSame = allSame &&
+                                                 (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
+                                       allSame = allSame &&
+                                                 (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
                                        if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
-                                               allSame = allSame && 
-                                                       (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+                                               allSame = allSame &&
+                                                         (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
                                        else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
-                                               allSame = allSame && 
-                                                       (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+                                               allSame = allSame &&
+                                                         (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
                                        else
                                                allSame = allSame &&
-                                                       (ll->chars[numCharsInLine] == chDoc);
+                                                         (ll->chars[numCharsInLine] == chDoc);
                                        numCharsInLine++;
                                }
                        }
@@ -1599,7 +1720,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
                        char chDoc = pdoc->CharAt(charInDoc);
                        styleByte = pdoc->StyleAt(charInDoc);
-                       if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
+                       if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
                                ll->chars[numCharsInLine] = chDoc;
                                ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
                                ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
@@ -1630,13 +1751,13 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        bool isControl = isControlNext;
                        isControlNext = IsControlCharacter(ll->chars[charInLine + 1]);
                        if ((ll->styles[charInLine] != ll->styles[charInLine + 1]) ||
-                               isControl || isControlNext) {
+                               isControl || isControlNext) {
                                ll->positions[startseg] = 0;
                                if (vstyle.styles[ll->styles[charInLine]].visible) {
                                        if (isControl) {
                                                if (ll->chars[charInLine] == '\t') {
                                                        ll->positions[charInLine + 1] = ((((startsegx + 2) /
-                                                                                         tabWidth) + 1) * tabWidth) - startsegx;
+                                                                                          tabWidth) + 1) * tabWidth) - startsegx;
                                                } else if (controlCharSymbol < 32) {
                                                        const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
                                                        // +3 For a blank on front and rounded edge each side:
@@ -1644,7 +1765,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                                } else {
                                                        char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
                                                        surface->MeasureWidths(ctrlCharsFont, cc, 1,
-                                                                                                  ll->positions + startseg + 1);
+                                                                              ll->positions + startseg + 1);
                                                }
                                                lastSegItalics = false;
                                        } else {        // Regular character
@@ -1656,7 +1777,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                                } else {
                                                        lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
                                                        surface->MeasureWidths(vstyle.styles[ll->styles[charInLine]].font, ll->chars + startseg,
-                                                                              lenSeg, ll->positions + startseg + 1);
+                                                                              lenSeg, ll->positions + startseg + 1);
                                                }
                                        }
                                } else {    // invisible
@@ -1697,19 +1818,19 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        int lastGoodBreak = 0;
                        int lastLineStart = 0;
                        int startOffset = 0;
-                       int p=0;
+                       int p = 0;
                        while (p < ll->numCharsInLine) {
-                               if ((ll->positions[p+1] - startOffset) >= width) {
+                               if ((ll->positions[p + 1] - startOffset) >= width) {
                                        if (lastGoodBreak == lastLineStart) {
                                                // Try moving to start of last character
                                                if (p > 0) {
                                                        lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1)
-                                                               - posLineStart;
+                                                                       - posLineStart;
                                                }
                                                if (lastGoodBreak == lastLineStart) {
                                                        // Ensure at least one character on line.
-                                                       lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart +1, 1)
-                                                               - posLineStart;
+                                                       lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1)
+                                                                       - posLineStart;
                                                }
                                        }
                                        lastLineStart = lastGoodBreak;
@@ -1720,9 +1841,9 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                        continue;
                                }
                                if (p > 0) {
-                                       if (ll->styles[p] != ll->styles[p-1]) {
+                                       if (ll->styles[p] != ll->styles[p - 1]) {
                                                lastGoodBreak = p;
-                                       } else if (IsSpaceOrTab(ll->chars[p-1]) && !IsSpaceOrTab(ll->chars[p])) {
+                                       } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) {
                                                lastGoodBreak = p;
                                        }
                                }
@@ -1734,6 +1855,71 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
        }
 }
 
+ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
+                                       ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+       if (inSelection) {
+               if (vsDraw.selbackset) {
+                       if (primarySelection)
+                               return vsDraw.selbackground.allocated;
+                       else
+                               return vsDraw.selbackground2.allocated;
+               }
+       } else {
+               if ((vsDraw.edgeState == EDGE_BACKGROUND) &&
+                       (i >= ll->edgeColumn) &&
+                       !IsEOLChar(ll->chars[i]))
+                       return vsDraw.edgecolour.allocated;
+               if (inHotspot)
+                       return vsDraw.hotspotBackground.allocated;
+               if (overrideBackground)
+                       return background;
+       }
+       return vsDraw.styles[styleMain].back.allocated;
+}
+
+void Editor::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight) {
+       Point from(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0);
+       PRectangle rcCopyArea(start + 1, rcSegment.top, start + 2, rcSegment.bottom);
+       surface->Copy(rcCopyArea, from,
+                     highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide);
+}
+
+void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
+                     int line, int lineEnd, int xStart, int subLine, int subLineStart,
+                     bool overrideBackground, ColourAllocated background) {
+
+       int styleMask = pdoc->stylingBitsMask;
+       PRectangle rcSegment = rcLine;
+
+       // Fill in a PRectangle representing the end of line characters
+       int xEol = ll->positions[lineEnd] - subLineStart;
+       rcSegment.left = xEol + xStart;
+       rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
+       int posLineEnd = pdoc->LineStart(line + 1);
+       bool eolInSelection = (subLine == (ll->lines - 1)) &&
+                             (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 (overrideBackground) {
+               surface->FillRectangle(rcSegment, background);
+       } else {
+               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+       }
+
+       rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
+       rcSegment.right = rcLine.right;
+       if (overrideBackground) {
+               surface->FillRectangle(rcSegment, background);
+       } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
+               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+       } else {
+               surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
+       }
+}
+
 void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
                       PRectangle rcLine, LineLayout *ll, int subLine) {
 
@@ -1780,29 +1966,93 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                }
        }
 
+       bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) &&
+                                       (!overrideBackground) && (vsDraw.whitespaceBackgroundSet);
+
        bool inIndentation = subLine == 0;      // Do not handle indentation except on first subline.
        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 styleMask = pdoc->stylingBitsMask;
        int startseg = ll->LineStart(subLine);
        int subLineStart = ll->positions[startseg];
        int lineStart = 0;
        int lineEnd = 0;
        if (subLine < ll->lines) {
                lineStart = ll->LineStart(subLine);
-               lineEnd = ll->LineStart(subLine+1);
+               lineEnd = ll->LineStart(subLine + 1);
+       }
+       int i;
+
+       // Background drawing loop
+       for (i = lineStart; twoPhaseDraw && (i < lineEnd); i++) {
+
+               int iDoc = i + posLineStart;
+               // If there is the end of a style run for any reason
+               if ((ll->styles[i] != ll->styles[i + 1]) ||
+                       i == (lineEnd - 1) ||
+                       IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) ||
+                       ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) ||
+                       (i == (ll->edgeColumn - 1))) {
+                       rcSegment.left = ll->positions[startseg] + xStart - subLineStart;
+                       rcSegment.right = ll->positions[i + 1] + xStart - subLineStart;
+                       // 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) && (rcSegment.right >= rcLine.left)) {
+                               int styleMain = ll->styles[i];
+                               bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+                               bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
+                               ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
+                               if (ll->chars[i] == '\t') {
+                                       // Tab display
+                                       if (drawWhitespaceBackground &&
+                                               (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
+                                               textBack = vsDraw.whitespaceBackground.allocated;
+                                       surface->FillRectangle(rcSegment, textBack);
+                               } else if (IsControlCharacter(ll->chars[i])) {
+                                       // Control character display
+                                       inIndentation = false;
+                                       surface->FillRectangle(rcSegment, textBack);
+                               } else {
+                                       // Normal text display
+                                       surface->FillRectangle(rcSegment, textBack);
+                                       if (vsDraw.viewWhitespace != wsInvisible ||
+                                               (inIndentation && vsDraw.viewIndentationGuides)) {
+                                               for (int cpos = 0; cpos <= i - startseg; cpos++) {
+                                                       if (ll->chars[cpos + startseg] == ' ') {
+                                                               if (drawWhitespaceBackground &&
+                                                                       (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) {
+                                                                       PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top,
+                                                                                          ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom);
+                                                                       surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated);
+                                                               }
+                                                       } else {
+                                                               inIndentation = false;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       startseg = i + 1;
+               }
        }
-       for (int i = lineStart; i < lineEnd; i++) {
+
+       if (twoPhaseDraw) {
+               DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd,
+                       xStart, subLine, subLineStart, overrideBackground, background);
+       }
+
+       inIndentation = subLine == 0;   // Do not handle indentation except on first subline.
+       startseg = ll->LineStart(subLine);
+       // Foreground drawing loop
+       for (i = lineStart; i < lineEnd; i++) {
 
                int iDoc = i + posLineStart;
                // If there is the end of a style run for any reason
                if ((ll->styles[i] != ll->styles[i + 1]) ||
-                               i == (lineEnd-1) ||
+                       i == (lineEnd - 1) ||
                        IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) ||
                        ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) ||
                        (i == (ll->edgeColumn - 1))) {
@@ -1812,30 +2062,27 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                        // draw strings that are completely past the right side of the window.
                        if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) {
                                int styleMain = ll->styles[i];
-                               ColourAllocated textBack = vsDraw.styles[styleMain].back.allocated;
                                ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
                                Font &textFont = vsDraw.styles[styleMain].font;
+                               //hotspot foreground
+                               if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) {
+                                       if (vsDraw.hotspotForegroundSet)
+                                               textFore = vsDraw.hotspotForeground.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 (overrideBackground)
-                                               textBack = background;
-                                       if ((vsDraw.edgeState == EDGE_BACKGROUND) && (i >= ll->edgeColumn) && (ll->chars[i] != '\n') && (ll->chars[i] != '\r'))
-                                               textBack = vsDraw.edgecolour.allocated;
+                               if (inSelection && (vsDraw.selforeset)) {
+                                       textFore = vsDraw.selforeground.allocated;
                                }
+                               bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
+                               ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
                                if (ll->chars[i] == '\t') {
-                                       // Manage tab display
-                                       if (!overrideBackground && vsDraw.whitespaceBackgroundSet && (vsDraw.viewWhitespace != wsInvisible) && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
-                                               textBack = vsDraw.whitespaceBackground.allocated;
-                                       surface->FillRectangle(rcSegment, textBack);
+                                       // Tab display
+                                       if (!twoPhaseDraw) {
+                                               if (drawWhitespaceBackground &&
+                                                       (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
+                                                       textBack = vsDraw.whitespaceBackground.allocated;
+                                               surface->FillRectangle(rcSegment, textBack);
+                                       }
                                        if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) {
                                                if (vsDraw.whitespaceForegroundSet)
                                                        textFore = vsDraw.whitespaceForeground.allocated;
@@ -1844,29 +2091,29 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                        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);
+                                                               DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIG + xStart, rcSegment,
+                                                                               (ll->xHighlightGuide == xIG));
                                                        }
                                                }
                                        }
                                        if (vsDraw.viewWhitespace != wsInvisible) {
                                                if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
                                                        PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4,
-                                                                        rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
+                                                                        rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
                                                        DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2);
                                                }
                                        }
                                } else if (IsControlCharacter(ll->chars[i])) {
-                                       // Manage control character display
+                                       // Control character display
                                        inIndentation = false;
                                        if (controlCharSymbol < 32) {
                                                // Draw the character
                                                const char *ctrlChar = ControlCharacterString(ll->chars[i]);
-                                               surface->FillRectangle(rcSegment, textBack);
+                                               if (!twoPhaseDraw) {
+                                                       surface->FillRectangle(rcSegment, textBack);
+                                               }
                                                int normalCharHeight = surface->Ascent(ctrlCharsFont) -
-                                                                          surface->InternalLeading(ctrlCharsFont);
+                                                                      surface->InternalLeading(ctrlCharsFont);
                                                PRectangle rcCChar = rcSegment;
                                                rcCChar.left = rcCChar.left + 1;
                                                rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight;
@@ -1879,19 +2126,27 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                rcChar.left++;
                                                rcChar.right--;
                                                surface->DrawTextClipped(rcChar, ctrlCharsFont,
-                                                                        rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar),
-                                                                        textBack, textFore);
+                                                                        rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar),
+                                                                        textBack, textFore);
                                        } else {
                                                char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
                                                surface->DrawTextNoClip(rcSegment, ctrlCharsFont,
-                                                                                 rcSegment.top + vsDraw.maxAscent,
-                                                                                 cc, 1, textBack, textFore);
+                                                                       rcSegment.top + vsDraw.maxAscent,
+                                                                       cc, 1, textBack, textFore);
                                        }
                                } else {
-                                       // Manage normal display
-                                       surface->DrawTextNoClip(rcSegment, textFont,
-                                                         rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
-                                                         i - startseg + 1, textFore, textBack);
+                                       // Normal text display
+                                       if (vsDraw.styles[styleMain].visible) {
+                                               if (twoPhaseDraw) {
+                                                       surface->DrawTextTransparent(rcSegment, textFont,
+                                                                                    rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
+                                                                                    i - startseg + 1, textFore);
+                                               } else {
+                                                       surface->DrawTextNoClip(rcSegment, textFont,
+                                                                               rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
+                                                                               i - startseg + 1, textFore, textBack);
+                                               }
+                                       }
                                        if (vsDraw.viewWhitespace != wsInvisible ||
                                                (inIndentation && vsDraw.viewIndentationGuides)) {
                                                for (int cpos = 0; cpos <= i - startseg; cpos++) {
@@ -1901,12 +2156,13 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                                                textFore = vsDraw.whitespaceForeground.allocated;
                                                                        if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
                                                                                int xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2;
-                                                                               if (!overrideBackground && vsDraw.whitespaceBackgroundSet) {
+                                                                               if (!twoPhaseDraw && drawWhitespaceBackground &&
+                                                                                       (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) {
                                                                                        textBack = vsDraw.whitespaceBackground.allocated;
                                                                                        PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom);
                                                                                        surface->FillRectangle(rcSpace, textBack);
                                                                                }
-                                                                               PRectangle rcDot(xmid + xStart  - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
+                                                                               PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
                                                                                rcDot.right = rcDot.left + 1;
                                                                                rcDot.bottom = rcDot.top + 1;
                                                                                surface->FillRectangle(rcDot, textFore);
@@ -1915,10 +2171,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                                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);
+                                                                               DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, startSpace + xStart, rcSegment,
+                                                                                               (ll->xHighlightGuide == ll->positions[cpos + startseg]));
                                                                        }
                                                                }
                                                        } else {
@@ -1927,7 +2181,15 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                }
                                        }
                                }
-                               if (vsDraw.styles[styleMain].underline) {
+                               if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) {
+                                       PRectangle rcUL = rcSegment;
+                                       rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
+                                       rcUL.bottom = rcUL.top + 1;
+                                       if (vsDraw.hotspotForegroundSet)
+                                               surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated);
+                                       else
+                                               surface->FillRectangle(rcUL, textFore);
+                               } else if (vsDraw.styles[styleMain].underline) {
                                        PRectangle rcUL = rcSegment;
                                        rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
                                        rcUL.bottom = rcUL.top + 1;
@@ -1964,31 +2226,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        }
        // End of the drawing of the current line
 
-       // Fill in a PRectangle representing the end of line characters
-       int xEol = ll->positions[lineEnd] - subLineStart;
-       rcSegment.left = xEol + xStart;
-       rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
-       bool eolInSelection = (subLine == (ll->lines-1)) &&
-               (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 (overrideBackground) {
-               surface->FillRectangle(rcSegment, background);
-       } else {
-               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
-       }
-
-       rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
-       rcSegment.right = rcLine.right;
-       if (overrideBackground) {
-               surface->FillRectangle(rcSegment, background);
-       } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
-               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
-       } else {
-               surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
+       if (!twoPhaseDraw) {
+               DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd,
+                       xStart, subLine, subLineStart, overrideBackground, background);
        }
 
        if (vsDraw.edgeState == EDGE_LINE) {
@@ -1999,47 +2239,48 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        }
 }
 
-void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
-       //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
-       //      paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
-
-       RefreshStyleData();
-
-       PRectangle rcClient = GetClientRectangle();
-       //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d)   %d\n",
-       //      rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
-
-       if (WrapLines()) {
-               // The wrapping process has changed the height of some lines so abandon this
-               // paint for a complete repaint.
-               if (AbandonPaint()) {
-                       return;
-               }
-       }
-
+void Editor::RefreshPixMaps(Surface *surfaceWindow) {
        if (!pixmapSelPattern->Initialised()) {
-               pixmapSelPattern->InitPixMap(8, 8, surfaceWindow);
-               // This complex procedure is to reproduce the checker board dithered pattern used by windows
+               const int patternSize = 8;
+               pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow, wMain.GetID());
+               // This complex procedure is to reproduce the checkerboard dithered pattern used by windows
                // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half
                // way between the chrome colour and the chrome highlight colour making a nice transition
                // between the window chrome and the content area. And it works in low colour depths.
-               PRectangle rcPattern(0, 0, 8, 8);
-               if (vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff)) {
-                       pixmapSelPattern->FillRectangle(rcPattern, vs.selbar.allocated);
-                       pixmapSelPattern->PenColour(vs.selbarlight.allocated);
-                       for (int stripe = 0; stripe < 8; stripe++) {
-                               pixmapSelPattern->MoveTo(0, stripe * 2);
-                               pixmapSelPattern->LineTo(8, stripe * 2 - 8);
-                       }
-               } else {
+               PRectangle rcPattern(0, 0, patternSize, patternSize);
+
+               // Initialize default colours based on the chrome colour scheme.  Typically the highlight is white.
+               ColourAllocated colourFMFill = vs.selbar.allocated;
+               ColourAllocated colourFMStripes = vs.selbarlight.allocated;
+
+               if (!(vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff))) {
                        // User has chosen an unusual chrome colour scheme so just use the highlight edge colour.
-                       pixmapSelPattern->FillRectangle(rcPattern, vs.selbarlight.allocated);
+                       // (Typically, the highlight colour is white.)
+                       colourFMFill = vs.selbarlight.allocated;
+               }
+
+               if (vs.foldmarginColourSet) {
+                       // override default fold margin colour
+                       colourFMFill = vs.foldmarginColour.allocated;
+               }
+               if (vs.foldmarginHighlightColourSet) {
+                       // override default fold margin highlight colour
+                       colourFMStripes = vs.foldmarginHighlightColour.allocated;
+               }
+
+               pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
+               pixmapSelPattern->PenColour(colourFMStripes);
+               for (int stripe = 0; stripe < patternSize; stripe++) {
+                       // Alternating 1 pixel stripes is same as checkerboard.
+                       pixmapSelPattern->MoveTo(0, stripe * 2);
+                       pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
                }
        }
+
        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);
+               pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID());
+               pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID());
                PRectangle rcIG(0, 0, 1, vs.lineHeight);
                pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated);
                pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated);
@@ -2055,12 +2296,26 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 
        if (bufferedDraw) {
                if (!pixmapLine->Initialised()) {
+                       PRectangle rcClient = GetClientRectangle();
                        pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(),
-                                             surfaceWindow);
+                                              surfaceWindow, wMain.GetID());
                        pixmapSelMargin->InitPixMap(vs.fixedColumnWidth,
-                                                  rcClient.Height(), surfaceWindow);
+                                                   rcClient.Height(), surfaceWindow, wMain.GetID());
                }
        }
+}
+
+void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
+       //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
+       //      paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
+
+       RefreshStyleData();
+
+       RefreshPixMaps(surfaceWindow);
+
+       PRectangle rcClient = GetClientRectangle();
+       //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d)   %d\n",
+       //      rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
 
        surfaceWindow->SetPalette(&palette, true);
        pixmapLine->SetPalette(&palette, !hasFocus);
@@ -2090,6 +2345,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 
        PaintSelMargin(surfaceWindow, rcArea);
 
+       if (WrapLines()) {
+               // The wrapping process has changed the height of some lines so abandon this
+               // paint for a complete repaint.
+               if (AbandonPaint()) {
+                       return;
+               }
+       }
+
        PRectangle rcRightMargin = rcClient;
        rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
        if (rcArea.Intersects(rcRightMargin)) {
@@ -2119,6 +2382,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        surface = pixmapLine;
                }
                surface->SetUnicodeMode(IsUnicodeMode());
+               surface->SetDBCSMode(CodePage());
 
                int visibleLine = topLine + screenLinePaintFirst;
 
@@ -2140,7 +2404,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                //double durCopy = 0.0;
                //ElapsedTime etWhole;
                int lineDocPrevious = -1;       // Used to avoid laying out one document line multiple times
-               LineLayout *ll = 0;
+               AutoLineLayout ll(llc, 0);
                while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) {
 
                        int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -2153,8 +2417,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        // and determine the x position at which each character starts.
                        //ElapsedTime et;
                        if (lineDoc != lineDocPrevious) {
-                               llc.Dispose(ll);
-                               ll = RetrieveLineLayout(lineDoc);
+                               ll.Set(RetrieveLineLayout(lineDoc));
                                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                                lineDocPrevious = lineDoc;
                        }
@@ -2170,6 +2433,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                        ll->containsCaret = false;
                                }
 
+                               GetHotSpotRange(ll->hsStart, ll->hsEnd);
+
                                PRectangle rcLine = rcClient;
                                rcLine.top = ypos;
                                rcLine.bottom = ypos + vs.lineHeight;
@@ -2177,7 +2442,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
                                // Highlight the current braces if any
                                ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
-                                       highlightGuideColumn * vs.spaceWidth);
+                                                      highlightGuideColumn * vs.spaceWidth);
 
                                // Draw the line
                                DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
@@ -2187,26 +2452,68 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                ll->RestoreBracesHighlight(rangeLine, braces);
 
                                bool expanded = cs.GetExpanded(lineDoc);
-                               if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) {
-                                       if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+                               if ((foldFlags & SC_FOLDFLAG_BOX) == 0) {
+                                       // Paint the line above the fold
+                                       if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
+                                               ||
+                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
+                                               if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+                                                       PRectangle rcFoldLine = rcLine;
+                                                       rcFoldLine.bottom = rcFoldLine.top + 1;
+                                                       surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+                                               }
+                                       }
+                                       // Paint the line below the fold
+                                       if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
+                                               ||
+                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
+                                               if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+                                                       PRectangle rcFoldLine = rcLine;
+                                                       rcFoldLine.top = rcFoldLine.bottom - 1;
+                                                       surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+                                               }
+                                       }
+                               } else {
+                                       int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
+                                       int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
+                                       int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK);
+                                       int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars);
+                                       // Draw line above fold
+                                       if ((FoldLevelPrev < FoldLevelCurr)
+                                               ||
+                                               (FoldLevelFlags & SC_FOLDLEVELBOXHEADERFLAG
+                                                &&
+                                                (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELBOXFOOTERFLAG) == 0)) {
                                                PRectangle rcFoldLine = rcLine;
                                                rcFoldLine.bottom = rcFoldLine.top + 1;
+                                               rcFoldLine.left += xStart + FoldLevelCurr * vs.spaceWidth * indentationStep - 1;
                                                surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
                                        }
-                               }
-                               if ( (expanded && (foldFlags & 8)) || (!expanded && (foldFlags & 16)) ) {
-                                       if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+
+                                       // Line below the fold (or below a contracted fold)
+                                       if (FoldLevelFlags & SC_FOLDLEVELBOXFOOTERFLAG
+                                               ||
+                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
                                                PRectangle rcFoldLine = rcLine;
                                                rcFoldLine.top = rcFoldLine.bottom - 1;
+                                               rcFoldLine.left += xStart + (FoldLevelCurr) * vs.spaceWidth * indentationStep - 1;
                                                surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
                                        }
+
+                                       PRectangle rcBoxLine = rcLine;
+                                       // Draw vertical line for every fold level
+                                       for (int i = 0; i <= FoldLevelCurr; i++) {
+                                               rcBoxLine.left = xStart + i * vs.spaceWidth * indentationStep - 1;
+                                               rcBoxLine.right = rcBoxLine.left + 1;
+                                               surface->FillRectangle(rcBoxLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+                                       }
                                }
 
                                // Draw the Caret
                                if (lineDoc == lineCaret) {
                                        int offset = Platform::Minimum(posCaret - rangeLine.start, ll->maxLineLength);
                                        if ((offset >= ll->LineStart(subLine)) &&
-                                               ((offset < ll->LineStart(subLine+1)) || offset == ll->numCharsInLine)) {
+                                               ((offset < ll->LineStart(subLine + 1)) || offset == ll->numCharsInLine)) {
                                                int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;
                                                int widthOverstrikeCaret;
                                                if (posCaret == pdoc->Length()) {   // At end of document
@@ -2244,7 +2551,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                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);
                                }
                                //durCopy += et.Duration(true);
@@ -2258,7 +2565,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        visibleLine++;
                        //gdk_flush();
                }
-               llc.Dispose(ll);
                //if (durPaint < 0.00000001)
                //      durPaint = 0.00000001;
 
@@ -2307,10 +2613,10 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
        if (!pfr)
                return 0;
 
-       AutoSurface surface(pfr->hdc, IsUnicodeMode());
+       AutoSurface surface(pfr->hdc, this);
        if (!surface)
                return 0;
-       AutoSurface surfaceMeasure(pfr->hdcTarget, IsUnicodeMode());
+       AutoSurface surfaceMeasure(pfr->hdcTarget, this);
        if (!surfaceMeasure) {
                return 0;
        }
@@ -2364,8 +2670,8 @@ long Editor::FormatRange(bool draw, RangeToFormat *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,
-                                                    "99999" lineNumberPrintSpace, 5 + strlen(lineNumberPrintSpace));
+               lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font,
+                                 "99999" lineNumberPrintSpace, 5 + strlen(lineNumberPrintSpace));
                vsPrint.ms[lineNumberIndex].width = lineNumberWidth;
        }
 
@@ -2373,12 +2679,12 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
        int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1;
        if (linePrintLast < linePrintStart)
                linePrintLast = linePrintStart;
-       int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax - 1);
+       int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax);
        if (linePrintLast > linePrintMax)
                linePrintLast = linePrintMax;
        //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n",
-       //      linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight,
-       //      surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font));
+       //      linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight,
+       //      surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font));
        int endPosPrint = pdoc->Length();
        if (linePrintLast < pdoc->LinesTotal())
                endPosPrint = pdoc->LineStart(linePrintLast + 1);
@@ -2388,61 +2694,101 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
 
        int xStart = vsPrint.fixedColumnWidth + pfr->rc.left + lineNumberWidth;
        int ypos = pfr->rc.top;
-       int line = linePrintStart;
-
-       if (draw) {     // Otherwise just measuring
 
-               while (line <= linePrintLast && ypos < pfr->rc.bottom) {
-
-                       // When printing, the hdc and hdcTarget may be the same, so
-                       // changing the state of surfaceMeasure may change the underlying
-                       // state of surface. Therefore, any cached state is discarded before
-                       // using each surface.
-                       surfaceMeasure->FlushCachedState();
+       int lineDoc = linePrintStart;
+
+       int nPrintPos = pfr->chrg.cpMin;
+       int visibleLine = 0;
+       int widthPrint = pfr->rc.Width() - lineNumberWidth;
+       if (printWrapState == eWrapNone)
+               widthPrint = LineLayout::wrapWidthInfinite;
+
+       while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) {
+
+               // When printing, the hdc and hdcTarget may be the same, so
+               // changing the state of surfaceMeasure may change the underlying
+               // state of surface. Therefore, any cached state is discarded before
+               // using each surface.
+               surfaceMeasure->FlushCachedState();
+
+               // Copy this line and its styles from the document into local arrays
+               // and determine the x position at which each character starts.
+               LineLayout ll(8000);
+               LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
+
+               ll.selStart = -1;
+               ll.selEnd = -1;
+               ll.containsCaret = false;
+
+               PRectangle rcLine;
+               rcLine.left = pfr->rc.left + lineNumberWidth;
+               rcLine.top = ypos;
+               rcLine.right = pfr->rc.right - 1;
+               rcLine.bottom = ypos + vsPrint.lineHeight;
+
+               // When document line is wrapped over multiple display lines, find where
+               // to start printing from to ensure a particular position is on the first
+               // line of the page.
+               if (visibleLine == 0) {
+                       int startWithinLine = nPrintPos - pdoc->LineStart(lineDoc);
+                       for (int iwl = 0; iwl < ll.lines - 1; iwl++) {
+                               if (ll.LineStart(iwl) <= startWithinLine && ll.LineStart(iwl + 1) >= startWithinLine) {
+                                       visibleLine = -iwl;
+                               }
+                       }
 
-                       // Copy this line and its styles from the document into local arrays
-                       // and determine the x position at which each character starts.
-                       LineLayout ll(8000);
-                       LayoutLine(line, surfaceMeasure, vsPrint, &ll);
-                       ll.selStart = -1;
-                       ll.selEnd = -1;
-                       ll.containsCaret = false;
-
-                       PRectangle rcLine;
-                       rcLine.left = pfr->rc.left + lineNumberWidth;
-                       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));
-                               surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
-                                                 ypos + vsPrint.maxAscent, number, strlen(number),
-                                                 vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
-                                                 vsPrint.styles[STYLE_LINENUMBER].back.allocated);
+                       if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) {
+                               visibleLine = -(ll.lines - 1);
                        }
+               }
 
-                       // Draw the line
+               if (draw && lineNumberWidth &&
+                       (ypos + vsPrint.lineHeight <= pfr->rc.bottom) &&
+                       (visibleLine >= 0)) {
+                       char number[100];
+                       sprintf(number, "%d" lineNumberPrintSpace, lineDoc + 1);
+                       PRectangle rcNumber = rcLine;
+                       rcNumber.right = rcNumber.left + lineNumberWidth;
+                       // Right justify
+                       rcNumber.left -= surfaceMeasure->WidthText(
+                                            vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number));
                        surface->FlushCachedState();
-                       DrawLine(surface, vsPrint, line, line, xStart, rcLine, &ll);
-
-                       ypos += vsPrint.lineHeight;
-                       line++;
+                       surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
+                                               ypos + vsPrint.maxAscent, number, strlen(number),
+                                               vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
+                                               vsPrint.styles[STYLE_LINENUMBER].back.allocated);
+               }
+
+               // Draw the line
+               surface->FlushCachedState();
+
+               for (int iwl = 0; iwl < ll.lines; iwl++) {
+                       if (ypos + vsPrint.lineHeight <= pfr->rc.bottom) {
+                               if (visibleLine >= 0) {
+                                       if (draw) {
+                                               rcLine.top = ypos;
+                                               rcLine.bottom = ypos + vsPrint.lineHeight;
+                                               DrawLine(surface, vsPrint, lineDoc, visibleLine, xStart, rcLine, &ll, iwl);
+                                       }
+                                       ypos += vsPrint.lineHeight;
+                               }
+                               visibleLine++;
+                               if (iwl == ll.lines - 1)
+                                       nPrintPos = pdoc->LineStart(lineDoc + 1);
+                               else
+                                       nPrintPos += ll.LineStart(iwl + 1) - ll.LineStart(iwl);
+                       }
                }
+
+               ++lineDoc;
        }
 
-       return endPosPrint;
+       return nPrintPos;
 }
 
 int Editor::TextWidth(int style, const char *text) {
        RefreshStyleData();
-       AutoSurface surface(IsUnicodeMode());
+       AutoSurface surface(this);
        if (surface) {
                return surface->WidthText(vs.styles[style].font, text, strlen(text));
        } else {
@@ -2451,8 +2797,7 @@ int Editor::TextWidth(int style, const char *text) {
 }
 
 // Empty method is overridden on GTK+ to show / hide scrollbars
-void Editor::ReconfigureScrollBars() {
-}
+void Editor::ReconfigureScrollBars() {}
 
 void Editor::SetScrollBars() {
        RefreshStyleData();
@@ -2499,9 +2844,9 @@ void Editor::AddChar(char ch) {
 void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
        bool wasSelection = currentPos != anchor;
        ClearSelection();
-       if (inOverstrike && !wasSelection) {
-               if (currentPos < (pdoc->Length() - 1)) {
-                       if ((pdoc->CharAt(currentPos) != '\r') && (pdoc->CharAt(currentPos) != '\n')) {
+       if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
+               if (currentPos < (pdoc->Length())) {
+                       if (!IsEOLChar(pdoc->CharAt(currentPos))) {
                                pdoc->DelChar(currentPos);
                        }
                }
@@ -2516,7 +2861,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 
        if (treatAsDBCS) {
                NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
-                       static_cast<unsigned char>(s[1]));
+                          static_cast<unsigned char>(s[1]));
        } else {
                int byte = static_cast<unsigned char>(s[0]);
                if ((byte < 0xC0) || (1 == len)) {
@@ -2542,7 +2887,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
                                if (((byte2 & 0xC0) == 0x80) && ((byte3 & 0xC0) == 0x80)) {
                                        // Three-byte-character lead byte followed by two trail bytes.
                                        byte = (((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) |
-                                               (byte3 & 0x3F));
+                                               (byte3 & 0x3F));
                                }
                                // A three-byte-character lead-byte not followed by two trail-bytes
                                // represents itself.
@@ -2553,30 +2898,32 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 }
 
 void Editor::ClearSelection() {
-       if (selType == selRectangle) {
-               pdoc->BeginUndoAction();
-               int lineStart = pdoc->LineFromPosition(SelectionStart());
-               int lineEnd = pdoc->LineFromPosition(SelectionEnd());
-               int startPos = SelectionStart();
-               for (int line = lineEnd; line >= lineStart; line--) {
-                       startPos = SelectionStart(line);
-                       unsigned int chars = SelectionEnd(line) - startPos;
+       if (!SelectionContainsProtected()) {
+               if (selType == selRectangle) {
+                       pdoc->BeginUndoAction();
+                       int lineStart = pdoc->LineFromPosition(SelectionStart());
+                       int lineEnd = pdoc->LineFromPosition(SelectionEnd());
+                       int startPos = SelectionStart();
+                       for (int line = lineEnd; line >= lineStart; line--) {
+                               startPos = SelectionStart(line);
+                               unsigned int chars = SelectionEnd(line) - startPos;
+                               if (0 != chars) {
+                                       pdoc->DeleteChars(startPos, chars);
+                               }
+                       }
+                       SetEmptySelection(startPos);
+                       pdoc->EndUndoAction();
+                       selType = selStream;
+               } else {
+                       int startPos = SelectionStart();
+                       unsigned int chars = SelectionEnd() - startPos;
+                       SetEmptySelection(startPos);
                        if (0 != chars) {
+                               pdoc->BeginUndoAction();
                                pdoc->DeleteChars(startPos, chars);
+                               pdoc->EndUndoAction();
                        }
                }
-               SetEmptySelection(startPos);
-               pdoc->EndUndoAction();
-               selType = selStream;
-       } else {
-               int startPos = SelectionStart();
-               unsigned int chars = SelectionEnd() - startPos;
-               SetEmptySelection(startPos);
-               if (0 != chars) {
-                       pdoc->BeginUndoAction();
-                       pdoc->DeleteChars(startPos, chars);
-                       pdoc->EndUndoAction();
-               }
        }
 }
 
@@ -2603,14 +2950,14 @@ void Editor::ClearDocumentStyle() {
 }
 
 void Editor::Cut() {
-       if (!pdoc->IsReadOnly()) {
+       if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) {
                Copy();
                ClearSelection();
        }
 }
 
 void Editor::PasteRectangular(int pos, const char *ptr, int len) {
-       if (pdoc->IsReadOnly()) {
+       if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
                return;
        }
        currentPos = pos;
@@ -2619,7 +2966,7 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) {
        bool prevCr = false;
        pdoc->BeginUndoAction();
        for (int i = 0; i < len; i++) {
-               if ((ptr[i] == '\r') || (ptr[i] == '\n')) {
+               if (IsEOLChar(ptr[i])) {
                        if ((ptr[i] == '\r') || (!prevCr))
                                line++;
                        if (line >= pdoc->LinesTotal()) {
@@ -2648,12 +2995,14 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) {
 }
 
 bool Editor::CanPaste() {
-       return !pdoc->IsReadOnly();
+       return !pdoc->IsReadOnly() && !SelectionContainsProtected();
 }
 
 void Editor::Clear() {
        if (currentPos == anchor) {
-               DelChar();
+               if (!RangeContainsProtected(currentPos, currentPos + 1)) {
+                       DelChar();
+               }
        } else {
                ClearSelection();
        }
@@ -2683,29 +3032,33 @@ void Editor::Redo() {
 }
 
 void Editor::DelChar() {
-       pdoc->DelChar(currentPos);
+       if (!RangeContainsProtected(currentPos, currentPos + 1)) {
+               pdoc->DelChar(currentPos);
+       }
        // Avoid blinking during rapid typing:
        ShowCaretAtCurrentPosition();
 }
 
 void Editor::DelCharBack(bool allowLineStartDeletion) {
        if (currentPos == anchor) {
-               int lineCurrentPos = pdoc->LineFromPosition(currentPos);
-               if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
-                       if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
-                               pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) {
-                               pdoc->BeginUndoAction();
-                               int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-                               int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars);
-                               if (indentation % indentationStep == 0) {
-                                       pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+               if (!RangeContainsProtected(currentPos - 1, currentPos)) {
+                       int lineCurrentPos = pdoc->LineFromPosition(currentPos);
+                       if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
+                               if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+                                       pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) {
+                                       pdoc->BeginUndoAction();
+                                       int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+                                       int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars);
+                                       if (indentation % indentationStep == 0) {
+                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+                                       } else {
+                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+                                       }
+                                       SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+                                       pdoc->EndUndoAction();
                                } else {
-                                       pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+                                       pdoc->DelCharBack(currentPos);
                                }
-                               SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-                               pdoc->EndUndoAction();
-                       } else {
-                               pdoc->DelCharBack(currentPos);
                        }
                }
        } else {
@@ -2764,6 +3117,24 @@ void Editor::NotifyDoubleClick(Point, bool) {
        NotifyParent(scn);
 }
 
+void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) {
+       SCNotification scn;
+       scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK;
+       scn.position = position;
+       scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+                       (alt ? SCI_ALT : 0);
+       NotifyParent(scn);
+}
+
+void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) {
+       SCNotification scn;
+       scn.nmhdr.code = SCN_HOTSPOTCLICK;
+       scn.position = position;
+       scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+                       (alt ? SCI_ALT : 0);
+       NotifyParent(scn);
+}
+
 void Editor::NotifyUpdateUI() {
        SCNotification scn;
        scn.nmhdr.code = SCN_UPDATEUI;
@@ -2841,23 +3212,22 @@ void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
 
 void Editor::CheckModificationForWrap(DocModification mh) {
        if ((mh.modificationType & SC_MOD_INSERTTEXT) ||
-               (mh.modificationType & SC_MOD_DELETETEXT)) {
+               (mh.modificationType & SC_MOD_DELETETEXT)) {
                llc.Invalidate(LineLayout::llCheckTextAndStyle);
                if (wrapState != eWrapNone) {
                        int lineDoc = pdoc->LineFromPosition(mh.position);
                        if (mh.linesAdded == 0) {
-                               AutoSurface surface(IsUnicodeMode());
-                               LineLayout *ll = RetrieveLineLayout(lineDoc);
+                               AutoSurface surface(this);
+                               AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
                                if (surface && ll) {
                                        LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                                        if (cs.GetHeight(lineDoc) != ll->lines) {
-                                               NeedWrapping(lineDoc-1);
+                                               NeedWrapping(lineDoc - 1);
                                                Redraw();
                                        }
                                } else {
                                        NeedWrapping(lineDoc);
                                }
-                               llc.Dispose(ll);
                        } else {
                                NeedWrapping(lineDoc);
                        }
@@ -3004,6 +3374,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_REPLACESEL:
        case SCI_ADDTEXT:
        case SCI_INSERTTEXT:
+       case SCI_APPENDTEXT:
        case SCI_CLEARALL:
        case SCI_SELECTALL:
        case SCI_GOTOLINE:
@@ -3013,8 +3384,12 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_SEARCHPREV:
        case SCI_LINEDOWN:
        case SCI_LINEDOWNEXTEND:
+       case SCI_PARADOWN:
+       case SCI_PARADOWNEXTEND:
        case SCI_LINEUP:
        case SCI_LINEUPEXTEND:
+       case SCI_PARAUP:
+       case SCI_PARAUPEXTEND:
        case SCI_CHARLEFT:
        case SCI_CHARLEFTEXTEND:
        case SCI_CHARRIGHT:
@@ -3031,6 +3406,10 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_HOMEEXTEND:
        case SCI_LINEEND:
        case SCI_LINEENDEXTEND:
+       case SCI_HOMEWRAP:
+       case SCI_HOMEWRAPEXTEND:
+       case SCI_LINEENDWRAP:
+       case SCI_LINEENDWRAPEXTEND:
        case SCI_DOCUMENTSTART:
        case SCI_DOCUMENTSTARTEXTEND:
        case SCI_DOCUMENTEND:
@@ -3047,6 +3426,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_FORMFEED:
        case SCI_VCHOME:
        case SCI_VCHOMEEXTEND:
+       case SCI_VCHOMEWRAP:
+       case SCI_VCHOMEWRAPEXTEND:
        case SCI_DELWORDLEFT:
        case SCI_DELWORDRIGHT:
        case SCI_DELLINELEFT:
@@ -3054,6 +3435,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_LINECUT:
        case SCI_LINEDELETE:
        case SCI_LINETRANSPOSE:
+       case SCI_LINEDUPLICATE:
        case SCI_LOWERCASE:
        case SCI_UPPERCASE:
        case SCI_LINESCROLLDOWN:
@@ -3070,7 +3452,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_NEWLINE:
        default:
                //              printf("Filtered out %ld of macro recording\n", iMessage);
-               return;
+               return ;
        }
 
        // Send notification
@@ -3154,6 +3536,17 @@ void Editor::LineTranspose() {
        }
 }
 
+void Editor::LineDuplicate() {
+       int line = pdoc->LineFromPosition(currentPos);
+       int start = pdoc->LineStart(line);
+       int end = pdoc->LineEnd(line);
+       char *thisLine = CopyRange(start, end);
+       const char *eol = StringFromEOLMode(pdoc->eolMode);
+       pdoc->InsertString(end, eol);
+       pdoc->InsertString(end + strlen(eol), thisLine, end - start);
+       delete []thisLine;
+}
+
 void Editor::CancelModes() {}
 
 void Editor::NewLine() {
@@ -3178,7 +3571,7 @@ void Editor::NewLine() {
 void Editor::CursorUpOrDown(int direction, bool extend) {
        Point pt = LocationFromPosition(currentPos);
        int posNew = PositionFromLocation(
-               Point(lastXChosen, pt.y + direction * vs.lineHeight));
+                        Point(lastXChosen, pt.y + direction * vs.lineHeight));
        if (direction < 0) {
                // Line wrapping may lead to a location on the same line, so
                // seek back if that is the case.
@@ -3196,29 +3589,28 @@ void Editor::CursorUpOrDown(int direction, bool extend) {
 int Editor::StartEndDisplayLine(int pos, bool start) {
        RefreshStyleData();
        int line = pdoc->LineFromPosition(pos);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(line);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(line));
        int posRet = INVALID_POSITION;
        if (surface && ll) {
                unsigned int posLineStart = pdoc->LineStart(line);
                LayoutLine(line, surface, vs, ll, wrapWidth);
                int posInLine = pos - posLineStart;
                if (posInLine <= ll->maxLineLength) {
-                       for (int subLine=0; subLine<ll->lines; subLine++) {
-                               if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) {
+                       for (int subLine = 0; subLine < ll->lines; subLine++) {
+                               if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) {
                                        if (start) {
                                                posRet = ll->LineStart(subLine) + posLineStart;
                                        } else {
                                                if (subLine == ll->lines - 1)
-                                                       posRet = ll->LineStart(subLine+1) + posLineStart;
+                                                       posRet = ll->LineStart(subLine + 1) + posLineStart;
                                                else
-                                                       posRet = ll->LineStart(subLine+1) + posLineStart - 1;
+                                                       posRet = ll->LineStart(subLine + 1) + posLineStart - 1;
                                        }
                                }
                        }
                }
        }
-       llc.Dispose(ll);
        if (posRet == INVALID_POSITION) {
                return pos;
        } else {
@@ -3234,6 +3626,12 @@ int Editor::KeyCommand(unsigned int iMessage) {
        case SCI_LINEDOWNEXTEND:
                CursorUpOrDown(1, true);
                break;
+       case SCI_PARADOWN:
+               MovePositionTo(pdoc->ParaDown(currentPos));
+               break;
+       case SCI_PARADOWNEXTEND:
+               MovePositionTo(pdoc->ParaDown(currentPos), true);
+               break;
        case SCI_LINESCROLLDOWN:
                ScrollTo(topLine + 1);
                MoveCaretInsideView(false);
@@ -3244,6 +3642,12 @@ int Editor::KeyCommand(unsigned int iMessage) {
        case SCI_LINEUPEXTEND:
                CursorUpOrDown(-1, true);
                break;
+       case SCI_PARAUP:
+               MovePositionTo(pdoc->ParaUp(currentPos));
+               break;
+       case SCI_PARAUPEXTEND:
+               MovePositionTo(pdoc->ParaUp(currentPos), true);
+               break;
        case SCI_LINESCROLLUP:
                ScrollTo(topLine - 1);
                MoveCaretInsideView(false);
@@ -3304,6 +3708,38 @@ int Editor::KeyCommand(unsigned int iMessage) {
                MovePositionTo(pdoc->LineEndPosition(currentPos), true);
                SetLastXChosen();
                break;
+       case SCI_HOMEWRAP: {
+                       int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if (currentPos <= homePos)
+                               homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+                       MovePositionTo(homePos);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_HOMEWRAPEXTEND: {
+                       int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if (currentPos <= homePos)
+                               homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+                       MovePositionTo(homePos, true);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_LINEENDWRAP: {
+                       int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
+                       if (currentPos >= endPos)
+                               endPos = pdoc->LineEndPosition(currentPos);
+                       MovePositionTo(endPos);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_LINEENDWRAPEXTEND: {
+                       int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
+                       if (currentPos >= endPos)
+                               endPos = pdoc->LineEndPosition(currentPos);
+                       MovePositionTo(endPos, true);
+                       SetLastXChosen();
+               }
+               break;
        case SCI_DOCUMENTSTART:
                MovePositionTo(0);
                SetLastXChosen();
@@ -3321,10 +3757,10 @@ int Editor::KeyCommand(unsigned int iMessage) {
                SetLastXChosen();
                break;
        case SCI_PAGEUP:
-               PageMove( -1);
+               PageMove(-1);
                break;
        case SCI_PAGEUPEXTEND:
-               PageMove( -1, true);
+               PageMove(-1, true);
                break;
        case SCI_PAGEDOWN:
                PageMove(1);
@@ -3338,7 +3774,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
                ShowCaretAtCurrentPosition();
                NotifyUpdateUI();
                break;
-       case SCI_CANCEL:                // Cancel any modes - handled in subclass
+       case SCI_CANCEL:                // Cancel any modes - handled in subclass
                // Also unselect text
                CancelModes();
                break;
@@ -3376,6 +3812,26 @@ int Editor::KeyCommand(unsigned int iMessage) {
                MovePositionTo(pdoc->VCHomePosition(currentPos), true);
                SetLastXChosen();
                break;
+       case SCI_VCHOMEWRAP: {
+                       int homePos = pdoc->VCHomePosition(currentPos);
+                       int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+                               homePos = viewLineStart;
+
+                       MovePositionTo(homePos);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_VCHOMEWRAPEXTEND: {
+                       int homePos = pdoc->VCHomePosition(currentPos);
+                       int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+                               homePos = viewLineStart;
+
+                       MovePositionTo(homePos, true);
+                       SetLastXChosen();
+               }
+               break;
        case SCI_ZOOMIN:
                if (vs.zoomLevel < 20) {
                        vs.zoomLevel++;
@@ -3438,6 +3894,9 @@ int Editor::KeyCommand(unsigned int iMessage) {
        case SCI_LINETRANSPOSE:
                LineTranspose();
                break;
+       case SCI_LINEDUPLICATE:
+               LineDuplicate();
+               break;
        case SCI_LOWERCASE:
                ChangeCaseOfSelection(false);
                break;
@@ -3462,22 +3921,22 @@ int Editor::KeyCommand(unsigned int iMessage) {
                break;
        case SCI_HOMEDISPLAY:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, true), -1));
+                                  StartEndDisplayLine(currentPos, true), -1));
                SetLastXChosen();
                break;
        case SCI_HOMEDISPLAYEXTEND:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, true), -1), true);
+                                  StartEndDisplayLine(currentPos, true), -1), true);
                SetLastXChosen();
                break;
        case SCI_LINEENDDISPLAY:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, false), 1));
+                                  StartEndDisplayLine(currentPos, false), 1));
                SetLastXChosen();
                break;
        case SCI_LINEENDDISPLAYEXTEND:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, false), 1), true);
+                                  StartEndDisplayLine(currentPos, false), 1), true);
                SetLastXChosen();
                break;
        }
@@ -3592,8 +4051,8 @@ void Editor::Indent(bool forwards) {
  * @return The position of the found text, -1 if not found.
  */
 long Editor::FindText(
-    uptr_t wParam,     ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
-    ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP.
+    uptr_t wParam,             ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
+    ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
     sptr_t lParam) {                   ///< @c TextToFind structure: The text to search for in the given range.
 
        TextToFind *ft = reinterpret_cast<TextToFind *>(lParam);
@@ -3603,6 +4062,7 @@ long Editor::FindText(
                                 (wParam & SCFIND_WHOLEWORD) != 0,
                                 (wParam & SCFIND_WORDSTART) != 0,
                                 (wParam & SCFIND_REGEXP) != 0,
+                                (wParam & SCFIND_POSIX) != 0,
                                 &lengthFound);
        if (pos != -1) {
                ft->chrgText.cpMin = pos;
@@ -3632,8 +4092,8 @@ void Editor::SearchAnchor() {
  * @return The position of the found text, -1 if not found.
  */
 long Editor::SearchText(
-    unsigned int iMessage,     ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV.
-    uptr_t wParam,     ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
+    unsigned int iMessage,             ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV.
+    uptr_t wParam,             ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
     ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP.
     sptr_t lParam) {                   ///< The text to search for.
 
@@ -3646,6 +4106,7 @@ long Editor::SearchText(
                                     (wParam & SCFIND_WHOLEWORD) != 0,
                                     (wParam & SCFIND_WORDSTART) != 0,
                                     (wParam & SCFIND_REGEXP) != 0,
+                                    (wParam & SCFIND_POSIX) != 0,
                                     &lengthFound);
        } else {
                pos = pdoc->FindText(searchAnchor, 0, txt,
@@ -3653,6 +4114,7 @@ long Editor::SearchText(
                                     (wParam & SCFIND_WHOLEWORD) != 0,
                                     (wParam & SCFIND_WORDSTART) != 0,
                                     (wParam & SCFIND_REGEXP) != 0,
+                                    (wParam & SCFIND_POSIX) != 0,
                                     &lengthFound);
        }
 
@@ -3674,6 +4136,7 @@ long Editor::SearchInTarget(const char *text, int length) {
                                 (searchFlags & SCFIND_WHOLEWORD) != 0,
                                 (searchFlags & SCFIND_WORDSTART) != 0,
                                 (searchFlags & SCFIND_REGEXP) != 0,
+                                (searchFlags & SCFIND_POSIX) != 0,
                                 &lengthFound);
        if (pos != -1) {
                targetStart = pos;
@@ -3943,7 +4406,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                SetEmptySelection(newPos);
                bool doubleClick = false;
                // Stop mouse button bounce changing selection type
-               if (curTime != lastClickTime) {
+               if (!Platform::MouseButtonBounce() || curTime != lastClickTime) {
                        if (selectionType == selChar) {
                                selectionType = selWord;
                                doubleClick = true;
@@ -3967,13 +4430,15 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                        lineAnchor = LineFromLocation(pt);
                        SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
                        //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
-               }
-               else {
+               } else {
                        SetEmptySelection(currentPos);
                }
                //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos);
-               if (doubleClick)
+               if (doubleClick) {
                        NotifyDoubleClick(pt, shift);
+                       if (PositionIsHotspot(newPos))
+                               NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt);
+               }
        } else {        // Single click
                if (inSelMargin) {
                        selType = selStream;
@@ -4003,6 +4468,9 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                        SetMouseCapture(true);
                        selectionType = selLine;
                } else {
+                       if (PositionIsHotspot(newPos)) {
+                               NotifyHotSpotClicked(newPos, shift, ctrl, alt);
+                       }
                        if (!shift) {
                                inDragDrop = PointInSelection(pt);
                        }
@@ -4029,6 +4497,53 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
        ShowCaretAtCurrentPosition();
 }
 
+bool Editor::PositionIsHotspot(int position) {
+       return vs.styles[pdoc->StyleAt(position)].hotspot;
+}
+
+bool Editor::PointIsHotspot(Point pt) {
+       int pos = PositionFromLocation(pt);
+       return PositionIsHotspot(pos);
+}
+
+void Editor::SetHotSpotRange(Point *pt) {
+       if (pt) {
+               int pos = PositionFromLocation(*pt);
+
+               // If we don't limit this to word characters then the
+               // range can encompass more than the run range and then
+               // the underline will not be drawn properly.
+               int hsStart_ = pdoc->ExtendStyleRange(pos, -1);
+               int hsEnd_ = pdoc->ExtendStyleRange(pos, 1);
+
+               // Only invalidate the range if the hotspot range has changed...
+               if (hsStart_ != hsStart || hsEnd_ != hsEnd) {
+                       if (hsStart != -1) {
+                               InvalidateRange(hsStart, hsEnd);
+                       }
+                       hsStart = hsStart_;
+                       hsEnd = hsEnd_;
+                       InvalidateRange(hsStart, hsEnd);
+               }
+       } else {
+               if (hsStart != -1) {
+                       int hsStart_ = hsStart;
+                       int hsEnd_ = hsEnd;
+                       hsStart = -1;
+                       hsEnd = -1;
+                       InvalidateRange(hsStart_, hsEnd_);
+               } else {
+                       hsStart = -1;
+                       hsEnd = -1;
+               }
+       }
+}
+
+void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) {
+       hsStart_ = hsStart;
+       hsEnd_ = hsEnd;
+}
+
 void Editor::ButtonMove(Point pt) {
        if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) {
                DwellEnd(true);
@@ -4072,6 +4587,9 @@ void Editor::ButtonMove(Point pt) {
                PRectangle rcClient = GetClientRectangle();
                if (pt.y > rcClient.bottom) {
                        int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
+                       if (lineMove < 0) {
+                               lineMove = cs.DisplayFromDoc(pdoc->LinesTotal() - 1);
+                       }
                        ScrollTo(lineMove - LinesOnScreen() + 5);
                        Redraw();
                } else if (pt.y < rcClient.top) {
@@ -4081,6 +4599,9 @@ void Editor::ButtonMove(Point pt) {
                }
                EnsureCaretVisible(false, false, true);
 
+               if (hsStart != -1 && !PositionIsHotspot(movePos))
+                       SetHotSpotRange(NULL);
+
        } else {
                if (vs.fixedColumnWidth > 0) {  // There is a margin
                        if (PointInSelMargin(pt)) {
@@ -4089,10 +4610,15 @@ void Editor::ButtonMove(Point pt) {
                        }
                }
                // Display regular (drag) cursor over selection
-               if (PointInSelection(pt))
+               if (PointInSelection(pt)) {
                        DisplayCursor(Window::cursorArrow);
-               else
+               } else if (PointIsHotspot(pt)) {
+                       DisplayCursor(Window::cursorHand);
+                       SetHotSpotRange(&pt);
+               } else {
                        DisplayCursor(Window::cursorText);
+                       SetHotSpotRange(NULL);
+               }
        }
 
 }
@@ -4104,6 +4630,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
                        DisplayCursor(Window::cursorReverseArrow);
                } else {
                        DisplayCursor(Window::cursorText);
+                       SetHotSpotRange(NULL);
                }
                xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
                ptMouseLast = pt;
@@ -4117,7 +4644,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
                                if (drag.len) {
                                        if (ctrl) {
                                                if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-                                               SetSelection(newPos, newPos + drag.len);
+                                                       SetSelection(newPos, newPos + drag.len);
                                                }
                                        } else if (newPos < selStart) {
                                                pdoc->DeleteChars(selStart, drag.len);
@@ -4169,8 +4696,8 @@ void Editor::Tick() {
                }
        }
        if ((dwellDelay < SC_TIME_FOREVER) &&
-               (ticksToDwell > 0) &&
-               (!HaveMouseCapture())) {
+               (ticksToDwell > 0) &&
+               (!HaveMouseCapture())) {
                ticksToDwell -= timer.tickSize;
                if (ticksToDwell <= 0) {
                        dwelling = true;
@@ -4185,6 +4712,7 @@ void Editor::SetFocusState(bool focusState) {
        if (hasFocus) {
                ShowCaretAtCurrentPosition();
        } else {
+               CancelModes();
                DropCaret();
        }
 }
@@ -4329,6 +4857,13 @@ void Editor::SetDocPointer(Document *document) {
                pdoc = document;
        }
        pdoc->AddRef();
+
+       // Ensure all positions within document
+       currentPos = 0;
+       anchor = 0;
+       targetStart = 0;
+       targetEnd = 0;
+
        // Reset the contraction state to fully shown.
        cs.Clear();
        cs.InsertLines(0, pdoc->LinesTotal() - 1);
@@ -4337,7 +4872,10 @@ void Editor::SetDocPointer(Document *document) {
 
        pdoc->AddWatcher(this, 0);
        Redraw();
-       SetScrollBars();
+       // Removed because of reentrance problems of GTK+ 2.x
+       // where changing a scroll bar position causes synchronous
+       // painting before lexer and styling state is set up.
+       //SetScrollBars();
 }
 
 // Recursively expand a fold, making lines visible except where they have an unexpanded parent
@@ -4407,7 +4945,7 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
                                SetVerticalScrollPos();
                                Redraw();
                        } else if ((lineDisplay > topLine + LinesOnScreen() - 1) ||
-                                          ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) {
+                                  ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) {
                                SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, 0, MaxScrollPos()));
                                SetVerticalScrollPos();
                                Redraw();
@@ -4444,6 +4982,13 @@ bool Editor::IsUnicodeMode() const {
        return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage);
 }
 
+int Editor::CodePage() const {
+       if (pdoc)
+               return pdoc->dbcsCodePage;
+       else
+               return 0;
+}
+
 static bool ValidMargin(unsigned long wParam) {
        return wParam < ViewStyle::margins;
 }
@@ -4461,8 +5006,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        switch (iMessage) {
 
-       case SCI_GETTEXT:
-               {
+       case SCI_GETTEXT: {
                        if (lParam == 0)
                                return 0;
                        if (wParam == 0)
@@ -4475,8 +5019,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        return iChar;
                }
 
-       case SCI_SETTEXT:
-               {
+       case SCI_SETTEXT: {
                        if (lParam == 0)
                                return 0;
                        pdoc->DeleteChars(0, pdoc->Length());
@@ -4593,7 +5136,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                //      return -1;
                return pdoc->LineStart(wParam);
 
-       // Replacement of the old Scintilla interpretation of EM_LINELENGTH
+               // Replacement of the old Scintilla interpretation of EM_LINELENGTH
        case SCI_LINELENGTH:
                if ((static_cast<int>(wParam) < 0) ||
                        (static_cast<int>(wParam) > pdoc->LineFromPosition(pdoc->Length())))
@@ -4627,6 +5170,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETTARGETEND:
                return targetEnd;
 
+       case SCI_TARGETFROMSELECTION:
+               if (currentPos < anchor) {
+                       targetStart = currentPos;
+                       targetEnd = anchor;
+               } else {
+                       targetStart = anchor;
+                       targetEnd = currentPos;
+               }
+               break;
+
        case SCI_REPLACETARGET:
                PLATFORM_ASSERT(lParam);
                return ReplaceTarget(false, CharPtrFromSPtr(lParam), wParam);
@@ -4653,12 +5206,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_SETXOFFSET:
                xOffset = wParam;
+               SetHorizontalScrollPos();
                Redraw();
                break;
 
        case SCI_GETXOFFSET:
                return xOffset;
 
+       case SCI_CHOOSECARETX:
+               SetLastXChosen();
+               break;
+
        case SCI_SCROLLCARET:
                EnsureCaretVisible();
                break;
@@ -4763,6 +5321,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        return 0;
                }
 
+       case SCI_APPENDTEXT:
+               pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam);
+               return 0;
+
        case SCI_CLEARALL:
                ClearAll();
                return 0;
@@ -4848,6 +5410,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETPRINTCOLOURMODE:
                return printColourMode;
 
+       case SCI_SETPRINTWRAPMODE:
+               printWrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone;
+               break;
+
+       case SCI_GETPRINTWRAPMODE:
+               return printWrapState;
+
        case SCI_GETSTYLEAT:
                if (static_cast<short>(wParam) >= pdoc->Length())
                        return 0;
@@ -4948,7 +5517,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                pdoc->SetStyleFor(wParam, static_cast<char>(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, CharPtrFromSPtr(lParam));
@@ -4961,6 +5530,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETBUFFEREDDRAW:
                return bufferedDraw;
 
+       case SCI_GETTWOPHASEDRAW:
+               return twoPhaseDraw;
+
+       case SCI_SETTWOPHASEDRAW:
+               twoPhaseDraw = wParam != 0;
+               InvalidateStyleRedraw();
+               break;
+
        case SCI_SETTABWIDTH:
                if (wParam > 0)
                        pdoc->tabInChars = wParam;
@@ -5052,8 +5629,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETSCROLLWIDTH:
                return scrollWidth;
 
+       case SCI_LINESJOIN:
+               LinesJoin();
+               break;
+
+       case SCI_LINESSPLIT:
+               LinesSplit(wParam);
+               break;
+
        case SCI_TEXTWIDTH:
-               PLATFORM_ASSERT((wParam >= 0) && (wParam <= STYLE_MAX));
+               PLATFORM_ASSERT(wParam <= STYLE_MAX);
                PLATFORM_ASSERT(lParam);
                return TextWidth(wParam, CharPtrFromSPtr(lParam));
 
@@ -5061,7 +5646,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return vs.lineHeight;
 
        case SCI_SETENDATLASTLINE:
-               PLATFORM_ASSERT((wParam == 0) || (wParam ==1));
+               PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
                if (endAtLastLine != (wParam != 0)) {
                        endAtLastLine = wParam != 0;
                        SetScrollBars();
@@ -5085,6 +5670,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETHSCROLLBAR:
                return horizontalScrollBarVisible;
 
+       case SCI_SETVSCROLLBAR:
+               if (verticalScrollBarVisible != (wParam != 0)) {
+                       verticalScrollBarVisible = wParam != 0;
+                       SetScrollBars();
+                       ReconfigureScrollBars();
+               }
+               break;
+
+       case SCI_GETVSCROLLBAR:
+               return verticalScrollBarVisible;
+
        case SCI_SETINDENTATIONGUIDES:
                vs.viewIndentationGuides = wParam != 0;
                Redraw();
@@ -5174,6 +5770,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                }
                return -1;
 
+       case SCI_MARKERDEFINEPIXMAP:
+               if (wParam <= MARKER_MAX) {
+                       vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam));
+               };
+               InvalidateStyleData();
+               RedrawSelMargin();
+               break;
+
        case SCI_SETMARGINTYPEN:
                if (ValidMargin(wParam)) {
                        vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL);
@@ -5305,6 +5909,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        InvalidateStyleRedraw();
                }
                break;
+       case SCI_STYLESETHOTSPOT:
+               if (wParam <= STYLE_MAX) {
+                       vs.styles[wParam].hotspot = lParam != 0;
+                       InvalidateStyleRedraw();
+               }
+               break;
 
        case SCI_STYLERESETDEFAULT:
                vs.ResetDefaultStyle();
@@ -5412,10 +6022,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_SEARCHPREV:
                return SearchText(iMessage, wParam, lParam);
 
-       case SCI_SETCARETPOLICY:        // Deprecated
+#ifdef INCLUDE_DEPRECATED_FEATURES
+       case SCI_SETCARETPOLICY:        // Deprecated
                caretXPolicy = caretYPolicy = wParam;
                caretXSlop = caretYSlop = lParam;
                break;
+#endif
 
        case SCI_SETXCARETPOLICY:
                caretXPolicy = wParam;
@@ -5468,8 +6080,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return vs.caretcolour.desired.AsLong();
 
        case SCI_SETCARETWIDTH:
-               if (wParam <= 1)
-                       vs.caretWidth = 1;
+               if (wParam <= 0)
+                       vs.caretWidth = 0;
                else if (wParam >= 3)
                        vs.caretWidth = 3;
                else
@@ -5516,8 +6128,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_LINEDOWN:
        case SCI_LINEDOWNEXTEND:
+       case SCI_PARADOWN:
+       case SCI_PARADOWNEXTEND:
        case SCI_LINEUP:
        case SCI_LINEUPEXTEND:
+       case SCI_PARAUP:
+       case SCI_PARAUPEXTEND:
        case SCI_CHARLEFT:
        case SCI_CHARLEFTEXTEND:
        case SCI_CHARRIGHT:
@@ -5530,6 +6146,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_HOMEEXTEND:
        case SCI_LINEEND:
        case SCI_LINEENDEXTEND:
+       case SCI_HOMEWRAP:
+       case SCI_HOMEWRAPEXTEND:
+       case SCI_LINEENDWRAP:
+       case SCI_LINEENDWRAPEXTEND:
        case SCI_DOCUMENTSTART:
        case SCI_DOCUMENTSTARTEXTEND:
        case SCI_DOCUMENTEND:
@@ -5547,6 +6167,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_FORMFEED:
        case SCI_VCHOME:
        case SCI_VCHOMEEXTEND:
+       case SCI_VCHOMEWRAP:
+       case SCI_VCHOMEWRAPEXTEND:
        case SCI_ZOOMIN:
        case SCI_ZOOMOUT:
        case SCI_DELWORDLEFT:
@@ -5556,6 +6178,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_LINECUT:
        case SCI_LINEDELETE:
        case SCI_LINETRANSPOSE:
+       case SCI_LINEDUPLICATE:
        case SCI_LOWERCASE:
        case SCI_UPPERCASE:
        case SCI_LINESCROLLDOWN:
@@ -5629,12 +6252,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return reinterpret_cast<sptr_t>(pdoc);
 
        case SCI_SETDOCPOINTER:
+               CancelModes();
                SetDocPointer(reinterpret_cast<Document *>(lParam));
                return 0;
 
        case SCI_CREATEDOCUMENT: {
                        Document *doc = new Document();
-                       doc->AddRef();
+                       if (doc) {
+                               doc->AddRef();
+                       }
                        return reinterpret_cast<sptr_t>(doc);
                }
 
@@ -5716,6 +6342,35 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                MoveCaretInsideView();
                break;
 
+       case SCI_SETFOLDMARGINCOLOUR:
+               vs.foldmarginColourSet = wParam != 0;
+               vs.foldmarginColour.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETFOLDMARGINHICOLOUR:
+               vs.foldmarginHighlightColourSet = wParam != 0;
+               vs.foldmarginHighlightColour.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETHOTSPOTACTIVEFORE:
+               vs.hotspotForegroundSet = wParam != 0;
+               vs.hotspotForeground.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETHOTSPOTACTIVEBACK:
+               vs.hotspotBackgroundSet = wParam != 0;
+               vs.hotspotBackground.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETHOTSPOTACTIVEUNDERLINE:
+               vs.hotspotUnderline = wParam != 0;
+               InvalidateStyleRedraw();
+               break;
+
        default:
                return DefWndProc(iMessage, wParam, lParam);
        }
index 800630bbb045a11f90f6841b243864c8a4637b28..2cc7930c47d17e27cba1b0b25a5ce437d055be51 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Editor.h
  ** Defines the main editor class.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef EDITOR_H
@@ -58,6 +58,10 @@ public:
        int *positions;
        char bracePreviousStyles[2];
 
+       // Hotspot support
+       int hsStart;
+       int hsEnd;
+
        // Wrapped line support
        int widthLine;
        int lines;
@@ -131,38 +135,6 @@ public:
        }
 };
 
-/**
- * A smart pointer class to ensure Surfaces are set up and deleted correctly.
- */
-class AutoSurface {
-private:
-       Surface *surf;
-public:
-       AutoSurface(bool unicodeMode) {
-               surf = Surface::Allocate();
-               if (surf) {
-                       surf->Init();
-                       surf->SetUnicodeMode(unicodeMode);
-               }
-       }
-       AutoSurface(SurfaceID sid, bool unicodeMode) {
-               surf = Surface::Allocate();
-               if (surf) {
-                       surf->Init(sid);
-                       surf->SetUnicodeMode(unicodeMode);
-               }
-       }
-       ~AutoSurface() {
-               delete surf;
-       }
-       Surface *operator->() const {
-               return surf;
-       }
-       operator Surface *() const {
-               return surf;
-       }
-};
-
 /**
  */
 class Editor : public DocWatcher {
@@ -184,6 +156,7 @@ protected:  // ScintillaBase subclass needs access to much of Editor
 
        int printMagnification;
        int printColourMode;
+       int printWrapState;
        int cursorMode;
        int controlCharSymbol;
 
@@ -196,11 +169,15 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
         * the screen. This avoids flashing but is about 30% slower. */
        bool bufferedDraw;
+       /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
+       * and then the foreground. This avoids chopping off characters that overlap the next run. */
+       bool twoPhaseDraw;
 
        int xOffset;            ///< Horizontal scrolled amount in pixels
        int xCaretMargin;       ///< Ensure this many pixels visible on both sides of caret
        bool horizontalScrollBarVisible;
        int scrollWidth;
+       bool verticalScrollBarVisible;
        bool endAtLastLine;
 
        Surface *pixmapLine;
@@ -275,6 +252,10 @@ protected: // ScintillaBase subclass needs access to much of Editor
        int foldFlags;
        ContractionState cs;
 
+       // Hotspot support
+       int hsStart;
+       int hsEnd;
+
        // Wrapping support
        enum { eWrapNone, eWrapWord } wrapState;
        int wrapWidth;
@@ -321,12 +302,14 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        void SetSelection(int currentPos_, int anchor_);
        void SetSelection(int currentPos_);
        void SetEmptySelection(int currentPos_);
+       bool RangeContainsProtected(int start, int end) const;
+       bool SelectionContainsProtected() const;
        int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
        int MovePositionTo(int newPos, bool extend=false, bool ensureVisible=true);
        int MovePositionSoVisible(int pos, int moveDir);
        void SetLastXChosen();
 
-       void ScrollTo(int line);
+       void ScrollTo(int line, bool moveThumb=true);
        virtual void ScrollText(int linesToMove);
        void HorizontalScrollTo(int xPos);
        void MoveCaretInsideView(bool ensureVisible=true);
@@ -338,14 +321,22 @@ protected:        // ScintillaBase subclass needs access to much of Editor
 
        void NeedWrapping(int docLineStartWrapping=0);
        bool WrapLines();
+       void LinesJoin();
+       void LinesSplit(int pixelWidth);
 
        int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault);
        void PaintSelMargin(Surface *surface, PRectangle &rc);
        LineLayout *RetrieveLineLayout(int lineNumber);
        void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
                int width=LineLayout::wrapWidthInfinite);
+       ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
+       void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
+       void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
+               int line, int lineEnd, int xStart, int subLine, int subLineStart,
+               bool overrideBackground, ColourAllocated background);
        void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
                PRectangle rcLine, LineLayout *ll, int subLine=0);
+       void RefreshPixMaps(Surface *surfaceWindow);
        void Paint(Surface *surfaceWindow, PRectangle rcArea);
        long FormatRange(bool draw, RangeToFormat *pfr);
        int TextWidth(int style, const char *text);
@@ -385,6 +376,8 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        void NotifySavePoint(bool isSavePoint);
        void NotifyModifyAttempt();
        virtual void NotifyDoubleClick(Point pt, bool shift);
+       void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
+       void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
        void NotifyUpdateUI();
        void NotifyPainted();
        bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
@@ -403,6 +396,7 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        void PageMove(int direction, bool extend=false);
        void ChangeCaseOfSelection(bool makeUpperCase);
        void LineTranspose();
+       void LineDuplicate();
        virtual void CancelModes();
        void NewLine();
        void CursorUpOrDown(int direction, bool extend=false);
@@ -456,6 +450,13 @@ protected: // ScintillaBase subclass needs access to much of Editor
        void EnsureLineVisible(int lineDoc, bool enforcePolicy);
        int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
 
+       bool PositionIsHotspot(int position);
+       bool PointIsHotspot(Point pt);
+       void SetHotSpotRange(Point *pt);
+       void GetHotSpotRange(int& hsStart, int& hsEnd);
+
+       int CodePage() const;
+
        virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
 
 public:
@@ -465,6 +466,45 @@ public:
        virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
        // Public so scintilla_set_id can use it.
        int ctrlID;
+       friend class AutoSurface;
+};
+
+/**
+ * A smart pointer class to ensure Surfaces are set up and deleted correctly.
+ */
+class AutoSurface {
+private:
+       Surface *surf;
+public:
+       AutoSurface(Editor *ed) : surf(0) {
+               if (ed->wMain.GetID()) {
+                       surf = Surface::Allocate();
+                       if (surf) {
+                               surf->Init(ed->wMain.GetID());
+                               surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
+                               surf->SetDBCSMode(ed->CodePage());
+                       }
+               }
+       }
+       AutoSurface(SurfaceID sid, Editor *ed) : surf(0) {
+               if (ed->wMain.GetID()) {
+                       surf = Surface::Allocate();
+                       if (surf) {
+                               surf->Init(sid, ed->wMain.GetID());
+                               surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
+                               surf->SetDBCSMode(ed->CodePage());
+                       }
+               }
+       }
+       ~AutoSurface() {
+               delete surf;
+       }
+       Surface *operator->() const {
+               return surf;
+       }
+       operator Surface *() const {
+               return surf;
+       }
 };
 
 #endif
index c91e6c6cccb8c50ca003e1d95d2fd233eae37abc..12249e5f3c70e903529811febb5d30773b31c82c 100644 (file)
@@ -1,5 +1,5 @@
 // Scintilla source code edit control
-/** @file KeyMap.cxx 
+/** @file KeyMap.cxx
  ** Defines a mapping between keystrokes and commands.
  **/
 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
@@ -13,7 +13,7 @@
 
 KeyMap::KeyMap() : kmap(0), len(0), alloc(0) {
        for (int i = 0; MapDefault[i].key; i++) {
-               AssignCmdKey(MapDefault[i].key, 
+               AssignCmdKey(MapDefault[i].key,
                        MapDefault[i].modifiers,
                        MapDefault[i].msg);
        }
@@ -66,9 +66,13 @@ const KeyToCommand KeyMap::MapDefault[] = {
     {SCK_DOWN,         SCI_NORM,       SCI_LINEDOWN},
     {SCK_DOWN,         SCI_SHIFT,      SCI_LINEDOWNEXTEND},
     {SCK_DOWN,         SCI_CTRL,       SCI_LINESCROLLDOWN},
+    {SCK_DOWN,         SCI_ALT,                SCI_PARADOWN},
+    {SCK_DOWN,         SCI_ASHIFT,     SCI_PARADOWNEXTEND},
     {SCK_UP,                   SCI_NORM,       SCI_LINEUP},
     {SCK_UP,                   SCI_SHIFT,      SCI_LINEUPEXTEND},
     {SCK_UP,                   SCI_CTRL,       SCI_LINESCROLLUP},
+    {SCK_UP,                   SCI_ALT,                SCI_PARAUP},
+    {SCK_UP,                   SCI_ASHIFT,     SCI_PARAUPEXTEND},
     {SCK_LEFT,         SCI_NORM,       SCI_CHARLEFT},
     {SCK_LEFT,         SCI_SHIFT,      SCI_CHARLEFTEXTEND},
     {SCK_LEFT,         SCI_CTRL,       SCI_WORDLEFT},
@@ -109,7 +113,7 @@ const KeyToCommand KeyMap::MapDefault[] = {
     {SCK_BACK,         SCI_SHIFT,      SCI_DELETEBACK},
     {SCK_BACK,         SCI_CTRL,       SCI_DELWORDLEFT},
     {SCK_BACK,                 SCI_ALT,        SCI_UNDO},
-    {SCK_BACK,         SCI_CSHIFT,     SCI_DELLINELEFT},    
+    {SCK_BACK,         SCI_CSHIFT,     SCI_DELLINELEFT},
     {'Z',                      SCI_CTRL,       SCI_UNDO},
     {'Y',                      SCI_CTRL,       SCI_REDO},
     {'X',                      SCI_CTRL,       SCI_CUT},
@@ -127,6 +131,7 @@ const KeyToCommand KeyMap::MapDefault[] = {
     {'L',                      SCI_CTRL,       SCI_LINECUT},
     {'L',                      SCI_CSHIFT,     SCI_LINEDELETE},
     {'T',                      SCI_CTRL,       SCI_LINETRANSPOSE},
+    {'D',                      SCI_CTRL,       SCI_LINEDUPLICATE},
     {'U',                      SCI_CTRL,       SCI_LOWERCASE},
     {'U',                      SCI_CSHIFT,     SCI_UPPERCASE},
     {0,0,0},
index 8a03aa8ac4fbb42e7eb46b1793bfabccb2912682..73ecddf50dc26797a50998d7c8ce9847b155d1d2 100644 (file)
@@ -25,10 +25,10 @@ int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
 LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
        const char *languageName_, LexerFunction fnFolder_,
        const char * const wordListDescriptions_[]) :
-       language(language_), 
-       fnLexer(fnLexer_), 
-       fnFolder(fnFolder_), 
-       wordListDescriptions(wordListDescriptions_), 
+       language(language_),
+       fnLexer(fnLexer_),
+       fnFolder(fnFolder_),
+       wordListDescriptions(wordListDescriptions_),
        languageName(languageName_) {
        next = base;
        base = this;
@@ -62,7 +62,7 @@ const char * LexerModule::GetWordListDescription(int index) const {
                return wordListDescriptions[index];
        }
 }
+
 const LexerModule *LexerModule::Find(int language) {
        const LexerModule *lm = base;
        while (lm) {
@@ -142,15 +142,20 @@ int Scintilla_LinkLexers() {
 //++Autogenerated -- run src/LexGen.py to regenerate
 //**\(\tLINK_LEXER(\*);\n\)
        LINK_LEXER(lmAda);
+       LINK_LEXER(lmAsm);
        LINK_LEXER(lmAVE);
        LINK_LEXER(lmBaan);
        LINK_LEXER(lmBullant);
        LINK_LEXER(lmConf);
        LINK_LEXER(lmCPP);
+       LINK_LEXER(lmCPPNoCase);
        LINK_LEXER(lmTCL);
        LINK_LEXER(lmNncrontab);
+       LINK_LEXER(lmCss);
        LINK_LEXER(lmEiffel);
        LINK_LEXER(lmEiffelkw);
+       LINK_LEXER(lmFortran);
+       LINK_LEXER(lmF77);
        LINK_LEXER(lmHTML);
        LINK_LEXER(lmXML);
        LINK_LEXER(lmASP);
@@ -166,6 +171,7 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmLatex);
        LINK_LEXER(lmPascal);
        LINK_LEXER(lmPerl);
+       LINK_LEXER(lmPOV);
        LINK_LEXER(lmPython);
        LINK_LEXER(lmRuby);
        LINK_LEXER(lmSQL);
index dfd15f02f1866327e4b0fcc38b9ee47e8dc3043d..900aea317cfedb83d63b87269714b81326185bd0 100644 (file)
 // SciTE - Scintilla based Text Editor
 /** @file LexAVE.cxx
  ** Lexer for Avenue.
+ **
+  ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <stdio.h>
 #include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
 
 #include "Platform.h"
 
 #include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-static void ColouriseAveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+static inline bool IsEnumChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch)|| ch == '_');
+}
+static inline bool IsANumberChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' );
+}
+
+inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+inline bool isAveOperator(char ch) {
+       if (isalnum(ch))
+               return false;
+       // '.' left out as it is used to make up numbers
+       if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+               ch == '(' || ch == ')' || ch == '=' ||
+               ch == '{' || ch == '}' ||
+               ch == '[' || ch == ']' || ch == ';' ||
+               ch == '<' || ch == '>' || ch == ',' ||
+               ch == '.'  )
+               return true;
+       return false;
+}
+
+static void ColouriseAveDoc(
+       unsigned int startPos,
+       int length,
+       int initStyle,
+       WordList *keywordlists[],
        Accessor &styler) {
 
        WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2];
+       WordList &keywords4 = *keywordlists[3];
+       WordList &keywords5 = *keywordlists[4];
+       WordList &keywords6 = *keywordlists[5];
+
+       // Do not leak onto next line
+       if (initStyle == SCE_AVE_STRINGEOL) {
+               initStyle = SCE_AVE_DEFAULT;
+       }
 
-       styler.StartAt(startPos);
+       StyleContext sc(startPos, length, initStyle, styler);
 
-       bool fold = styler.GetPropertyInt("fold") != 0;
-       int lineCurrent = styler.GetLine(startPos);
-       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
-       int levelCurrent = levelPrev;
+       for (; sc.More(); sc.Forward()) {
+               if (sc.atLineEnd) {
+                       // Update the line state, so it can be seen by next line
+                       int currentLine = styler.GetLine(sc.currentPos);
+                       styler.SetLineState(currentLine, 0);
+               }
+               if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
+                       // Prevent SCE_AVE_STRINGEOL from leaking back to previous line
+                       sc.SetState(SCE_AVE_STRING);
+               }
 
-       int state = initStyle;
-       if (state == SCE_AVE_STRINGEOL) // Does not leak onto next line
-               state = SCE_AVE_DEFAULT;
-       char chNext = styler[startPos];
-       unsigned int lengthDoc = startPos + length;
-       int visibleChars = 0;
-       styler.StartSegment(startPos);
 
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
-               chNext = styler.SafeGetCharAt(i + 1);
-               if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-                       // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-                       // Avoid triggering two times on Dos/Win
-                       // End of line
-                       if (state == SCE_AVE_STRINGEOL) {
-                               styler.ColourTo(i, state);
-                               state = SCE_AVE_DEFAULT;
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_AVE_OPERATOR) {
+                       sc.SetState(SCE_AVE_DEFAULT);
+               } else if (sc.state == SCE_AVE_NUMBER) {
+                       if (!IsANumberChar(sc.ch)) {
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-                       if (fold) {
-                               int lev = levelPrev;
-                               if (visibleChars == 0)
-                                       lev |= SC_FOLDLEVELWHITEFLAG;
-                               if ((levelCurrent > levelPrev) && (visibleChars > 0))
-                                       lev |= SC_FOLDLEVELHEADERFLAG;
-                               styler.SetLevel(lineCurrent, lev);
-                               lineCurrent++;
-                               levelPrev = levelCurrent;
+               } else if (sc.state == SCE_AVE_ENUM) {
+                       if (!IsEnumChar(sc.ch)) {
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-                       visibleChars = 0;
-               }
-               if (!isspace(ch))
-                       visibleChars++;
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       i += 1;
-                       continue;
-               }
-
-               if (state == SCE_AVE_DEFAULT) {
-                       if (iswordstart(ch) || (ch == '.') )  {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_IDENTIFIER;
-                       } else if (ch == '\'') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_COMMENT;
-                       } else if (ch == '\"') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_STRING;
-                       } else if (ch == '#') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_ENUM;
-                       } else if (isoperator(ch) ) {
-                               styler.ColourTo(i-1, state);
-                               styler.ColourTo(i, SCE_AVE_OPERATOR);
+               } else if (sc.state == SCE_AVE_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+                               char s[100];
+                               //sc.GetCurrent(s, sizeof(s));
+                               sc.GetCurrentLowered(s, sizeof(s));
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD2);
+                               } else if (keywords3.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD3);
+                               } else if (keywords4.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD4);
+                               } else if (keywords5.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD5);
+                               } else if (keywords6.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD6);
+                               }
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-               }
-               else if (state == SCE_AVE_COMMENT) {
-                       if (ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_DEFAULT;
+               } else if (sc.state == SCE_AVE_COMMENT) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-               }
-               else if (state == SCE_AVE_ENUM) {
-                       if (isoperator(ch)  || ch == ' ' || ch == '\'' || ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_DEFAULT;
+               } else if (sc.state == SCE_AVE_STRING) {
+                        if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_AVE_DEFAULT);
+                       } else if (sc.atLineEnd) {
+                               sc.ChangeState(SCE_AVE_STRINGEOL);
+                               sc.ForwardSetState(SCE_AVE_DEFAULT);
                        }
                }
-               else if (state == SCE_AVE_STRING) {
-                       if (ch == '\"') {
-                               if (chNext == '\"') {
-                                       i++;
-                                       ch = chNext;
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               } else
-                               {
-                                       styler.ColourTo(i, state);
-                                       state = SCE_AVE_DEFAULT;
-                               }
-                       } else if (chNext == '\r' || chNext == '\n') {
-                               styler.ColourTo(i-1, SCE_AVE_STRINGEOL);
-                               state = SCE_AVE_STRINGEOL;
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_AVE_DEFAULT) {
+                       if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_AVE_NUMBER);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_AVE_IDENTIFIER);
+                       } else if (sc.Match('\"')) {
+                               sc.SetState(SCE_AVE_STRING);
+                       } else if (sc.Match('\'')) {
+                               sc.SetState(SCE_AVE_COMMENT);
+                               sc.Forward();
+                       } else if (isAveOperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_AVE_OPERATOR);
+                       } else if (sc.Match('#')) {
+                               sc.SetState(SCE_AVE_ENUM);
+                               sc.Forward();
                        }
                }
-               if ((state == SCE_AVE_IDENTIFIER)) {
-                       if (!iswordchar(ch) || ch == '.' ) {
-                               char s[100];
-                               unsigned int start = styler.GetStartSegment();
-                               unsigned int end = i - 1;
-                               for (unsigned int ii = 0; ii < end - start + 1 && ii < 30; ii++)        {
-                                       s[ii] = static_cast<char>(tolower(styler[start + ii]));
-                                       s[ii + 1] = '\0';
-                               }
-
-                               char chAttr = SCE_AVE_IDENTIFIER;
-
-                               if (isdigit(s[0]))
-                                       chAttr = SCE_AVE_NUMBER;
-                               else {
-                                       if ((strcmp(s, "for") == 0) || (strcmp(s, "if") == 0) || (strcmp(s, "while") == 0))
-                                       {
-                                               levelCurrent +=1;
-                                               chAttr = SCE_AVE_STATEMENT;
-                                       }
-
-                                       if (strcmp(s, "end") == 0)
-                                       {
-                                               levelCurrent -=1;
-                                               chAttr = SCE_AVE_STATEMENT;
-                                       }
+       }
+       sc.Complete();
+}
 
-                                       if ( (strcmp(s, "then") == 0) ||  (strcmp(s, "else") == 0)       || (strcmp(s, "break") == 0) ||
-                                               (strcmp(s, "each") == 0) ||
-                                               (strcmp(s, "exit") == 0) ||  (strcmp(s, "continue") == 0) || (strcmp(s, "return") == 0) ||
-                                               (strcmp(s, "by") == 0)   ||  (strcmp(s, "in") == 0)          || (strcmp(s, "elseif") == 0))
-                                       {
-                                               chAttr = SCE_AVE_STATEMENT;
-                                       }
+static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+                       Accessor &styler) {
+       unsigned int lengthDoc = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = static_cast<char>(tolower(styler[startPos]));
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       int styleNext = styler.StyleAt(startPos);
+       char s[10];
 
-                                       if ((strcmp(s, "av") == 0) || (strcmp(s, "self") == 0))
-                                       {
-                                               chAttr = SCE_AVE_KEYWORD;
+       for (unsigned int i = startPos; i < lengthDoc; i++) {
+               char ch = static_cast<char>(tolower(chNext));
+               chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
+               int style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (style == SCE_AVE_WORD) {
+                       if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
+                               for (unsigned int j = 0; j < 6; j++) {
+                                       if (!iswordchar(styler[i + j])) {
+                                               break;
                                        }
+                                       s[j] = static_cast<char>(tolower(styler[i + j]));
+                                       s[j + 1] = '\0';
+                               }
 
-                                       if (keywords.InList(s))
-                                       {
-                                               chAttr = SCE_AVE_WORD;
-                                       }
+                               if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
+                                       levelCurrent++;
                                }
-                               styler.ColourTo(end, chAttr);
-                               state = SCE_AVE_DEFAULT;
-
-                               if (ch == '\'') {
-                                       state = SCE_AVE_COMMENT;
-                               } else if (ch == '\"') {
-                                       state = SCE_AVE_STRING;
-                               } else if (isoperator(ch)) {
-                                       styler.ColourTo(i, SCE_AVE_OPERATOR);
+                               if ((strcmp(s, "end") == 0)) {
+                                       levelCurrent--;
                                }
                        }
+               } else if (style == SCE_AVE_OPERATOR) {
+                       if (ch == '{' || ch == '(') {
+                               levelCurrent++;
+                       } else if (ch == '}' || ch == ')') {
+                               levelCurrent--;
+                       }
                }
 
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact) {
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       }
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       }
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch)) {
+                       visibleChars++;
+               }
        }
-       styler.ColourTo(lengthDoc - 1, state);
-
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
-       if (fold) {
-               int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
-               styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 
-       }
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave");
+LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);
+
index 0d8fb9d5dd7148fd42b792ca6927e3dd4595684e..263f7da4564910053ca7f3259afe693cf2193f32 100644 (file)
-// SciTE - Scintilla based Text Editor
-// LexAda.cxx - lexer for Ada95
-// by Tahir Karaca <tahir@bigfoot.de>
+// Scintilla source code edit control
+/** @file LexAda.cxx
+ ** Lexer for Ada 95
+ **/
+// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
 // The License.txt file describes the conditions under which this software may be distributed.
 
-#include <stdlib.h> 
-#include <string.h> 
-#include <ctype.h> 
-#include <stdio.h> 
-#include <stdarg.h> 
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
 
 #include "Platform.h"
 
-#include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
+#include "PropSet.h"
 #include "KeyWords.h"
-#include "Scintilla.h"
 #include "SciLexer.h"
+#include "SString.h"
+
+/*
+ * Interface
+ */
+
+static void ColouriseDocument(
+    unsigned int startPos,
+    int length,
+    int initStyle,
+    WordList *keywordlists[],
+    Accessor &styler);
+
+static const char * const adaWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
+
+/*
+ * Implementation
+ */
+
+// Functions that have apostropheStartsAttribute as a parameter set it according to whether
+// an apostrophe encountered after processing the current token will start an attribute or
+// a character literal.
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+
+static inline bool IsDelimiterCharacter(int ch);
+static inline bool IsNumberStartCharacter(int ch);
+static inline bool IsNumberCharacter(int ch);
+static inline bool IsSeparatorOrDelimiterCharacter(int ch);
+static bool IsValidIdentifier(const SString& identifier);
+static bool IsValidNumber(const SString& number);
+static inline bool IsWordStartCharacter(int ch);
+static inline bool IsWordCharacter(int ch);
 
-inline void classifyWordAda(unsigned int start, unsigned int end,
-       WordList &keywords, Accessor &styler) {
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
 
-       static const unsigned KEWORD_LEN_MAX = 30;
+       sc.SetState(SCE_ADA_CHARACTER);
 
-       char wordLower[KEWORD_LEN_MAX + 1];
-       unsigned i;
-       for(i = 0; ( i < KEWORD_LEN_MAX ) && ( i < end - start + 1 ); i++) {
-               wordLower[i] = static_cast<char>(tolower(styler[start + i]));           
+       // Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
+       // is handled correctly)
+       sc.Forward();
+       sc.Forward();
+
+       ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
+}
+
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
+       while (!sc.atLineEnd && !sc.Match(chEnd)) {
+               sc.Forward();
        }
-       wordLower[i] = '\0';
-               
-//     int levelChange = 0;
-       char chAttr = SCE_ADA_IDENTIFIER;
-       if (keywords.InList(wordLower)) {
-               chAttr = SCE_ADA_WORD;
 
-// Folding doesn't work this way since the semantics of some keywords depends
-// on the current context.
-// E.g. - "cond1 and THEN cond2" <-> "if ... THEN ..."         
-//      - "procedure X IS ... end X;" <-> "procedure X IS new Y;"
-//             if (strcmp(wordLower, "is") == 0 || strcmp(wordLower, "then") == 0)
-//                     levelChange=1;
-//             else if (strcmp(wordLower, "end") == 0)
-//                     levelChange=-1;
+       if (!sc.atLineEnd) {
+               sc.ForwardSetState(SCE_ADA_DEFAULT);
+       } else {
+               sc.ChangeState(stateEOL);
        }
-       styler.ColourTo(end, chAttr);
-       
-//     return levelChange;
 }
 
+static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+       // Apostrophe meaning is not changed, but the parameter is present for uniformity
 
-static inline bool isAdaOperator(char ch) {
-       
-       if (ch == '&' || ch == '\'' || ch == '(' || ch == ')' ||
-               ch == '*' || ch == '+' || ch == ',' || ch == '-' ||
-               ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
-               ch == '<' || ch == '=' || ch == '>')
-               return true;
-       return false;
-}
-
-
-inline void styleTokenBegin(char beginChar, unsigned int pos, int &state,
-       Accessor &styler) {
-               
-       if (isalpha(beginChar)) {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_IDENTIFIER;
-       } else if (isdigit(beginChar)) {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_NUMBER;
-       } else if (beginChar == '-' && styler.SafeGetCharAt(pos + 1) == '-') {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_COMMENT;
-       } else if (beginChar == '\"') {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_STRING;
-       } else if (beginChar == '\'' && styler.SafeGetCharAt(pos + 2) == '\'') {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_CHARACTER;
-       } else if (isAdaOperator(beginChar)) {
-               styler.ColourTo(pos-1, state);
-               styler.ColourTo(pos, SCE_ADA_OPERATOR);
-       }
-}
-
-
-static void ColouriseAdaDoc(unsigned int startPos, int length, int initStyle,
-       WordList *keywordlists[], Accessor &styler) {
-       
+       sc.SetState(SCE_ADA_COMMENTLINE);
+
+       while (!sc.atLineEnd) {
+               sc.Forward();
+       }
+}
+
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = sc.Match (')');
+       sc.SetState(SCE_ADA_DELIMITER);
+       sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = false;
+
+       sc.SetState(SCE_ADA_LABEL);
+
+       // Skip "<<"
+       sc.Forward();
+       sc.Forward();
+
+       SString identifier;
+
+       while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+               identifier += static_cast<char>(tolower(sc.ch));
+               sc.Forward();
+       }
+
+       // Skip ">>"
+       if (sc.Match('>', '>')) {
+               sc.Forward();
+               sc.Forward();
+       } else {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+       }
+
+       // If the name is an invalid identifier or a keyword, then make it invalid label
+       if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+       }
+
+       sc.SetState(SCE_ADA_DEFAULT);
+
+}
+
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
+
+       SString number;
+       sc.SetState(SCE_ADA_NUMBER);
+
+       // Get all characters up to a delimiter or a separator, including points, but excluding
+       // double points (ranges).
+       while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
+               number += static_cast<char>(sc.ch);
+               sc.Forward();
+       }
+
+       // Special case: exponent with sign
+       if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+               (sc.ch == '+' || sc.ch == '-')) {
+               number += static_cast<char>(sc.ch);
+               sc.Forward ();
+
+               while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+                       number += static_cast<char>(sc.ch);
+                       sc.Forward();
+               }
+       }
+
+       if (!IsValidNumber(number)) {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+       }
+
+       sc.SetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
+
+       sc.SetState(SCE_ADA_STRING);
+       sc.Forward();
+
+       ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
+}
+
+static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+       // Apostrophe meaning is not changed, but the parameter is present for uniformity
+       sc.SetState(SCE_ADA_DEFAULT);
+       sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
+       sc.SetState(SCE_ADA_IDENTIFIER);
+
+       SString word;
+
+       while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+               word += static_cast<char>(tolower(sc.ch));
+               sc.Forward();
+       }
+
+       if (!IsValidIdentifier(word)) {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+
+       } else if (keywords.InList(word.c_str())) {
+               sc.ChangeState(SCE_ADA_WORD);
+
+               if (word != "all") {
+                       apostropheStartsAttribute = false;
+               }
+       }
+
+       sc.SetState(SCE_ADA_DEFAULT);
+}
+
+//
+// ColouriseDocument
+//
+
+static void ColouriseDocument(
+    unsigned int startPos,
+    int length,
+    int initStyle,
+    WordList *keywordlists[],
+    Accessor &styler) {
        WordList &keywords = *keywordlists[0];
-       
-       styler.StartAt(startPos);
-       
-//     bool fold = styler.GetPropertyInt("fold");
-//     int lineCurrent = styler.GetLine(startPos);
-//     int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
-//     int levelCurrent = levelPrev;
-
-       int state = initStyle;
-       if (state == SCE_ADA_STRINGEOL) // Does not leak onto next line
-               state = SCE_ADA_DEFAULT;
-       char chNext = styler[startPos];
-       const unsigned int lengthDoc = startPos + length;
-       //int visibleChars = 0;
-       styler.StartSegment(startPos);
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
-               chNext = styler.SafeGetCharAt(i + 1);
-
-               if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-                       // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-                       // Avoid triggering two times on Dos/Win
-                       if (state == SCE_ADA_STRINGEOL) {
-                               styler.ColourTo(i, state);
-                               state = SCE_ADA_DEFAULT;
-                       }
-//                     if (fold) {
-//                             int lev = levelPrev;
-//                             if (visibleChars == 0)
-//                                     lev |= SC_FOLDLEVELWHITEFLAG;
-//                             if ((levelCurrent > levelPrev) && (visibleChars > 0))
-//                                     lev |= SC_FOLDLEVELHEADERFLAG;
-//                             styler.SetLevel(lineCurrent, lev);
-//                             lineCurrent++;
-//                             levelPrev = levelCurrent;
-//                     }
-                       //visibleChars = 0;
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       int lineCurrent = styler.GetLine(startPos);
+       bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
+
+       while (sc.More()) {
+               if (sc.atLineEnd) {
+                       // Go to the next line
+                       sc.Forward();
+                       lineCurrent++;
+
+                       // Remember the line state for future incremental lexing
+                       styler.SetLineState(lineCurrent, apostropheStartsAttribute);
+
+                       // Don't continue any styles on the next line
+                       sc.SetState(SCE_ADA_DEFAULT);
                }
-               //if (!isspacechar(ch))
-               //      visibleChars++;
 
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       i += 1;
-                       continue;
+               // Comments
+               if (sc.Match('-', '-')) {
+                       ColouriseComment(sc, apostropheStartsAttribute);
+
+               // Strings
+               } else if (sc.Match('"')) {
+                       ColouriseString(sc, apostropheStartsAttribute);
+
+               // Characters
+               } else if (sc.Match('\'') && !apostropheStartsAttribute) {
+                       ColouriseCharacter(sc, apostropheStartsAttribute);
+
+               // Labels
+               } else if (sc.Match('<', '<')) {
+                       ColouriseLabel(sc, keywords, apostropheStartsAttribute);
+
+               // Whitespace
+               } else if (isspace(sc.ch)) {
+                       ColouriseWhiteSpace(sc, apostropheStartsAttribute);
+
+               // Delimiters
+               } else if (IsDelimiterCharacter(sc.ch)) {
+                       ColouriseDelimiter(sc, apostropheStartsAttribute);
+
+               // Numbers
+               } else if (isdigit(sc.ch) || sc.ch == '#') {
+                       ColouriseNumber(sc, apostropheStartsAttribute);
+
+               // Keywords or identifiers
+               } else {
+                       ColouriseWord(sc, keywords, apostropheStartsAttribute);
+               }
+       }
+
+       sc.Complete();
+}
+
+static inline bool IsDelimiterCharacter(int ch) {
+       switch (ch) {
+       case '&':
+       case '\'':
+       case '(':
+       case ')':
+       case '*':
+       case '+':
+       case ',':
+       case '-':
+       case '.':
+       case '/':
+       case ':':
+       case ';':
+       case '<':
+       case '=':
+       case '>':
+       case '|':
+               return true;
+       default:
+               return false;
+       }
+}
+
+static inline bool IsNumberCharacter(int ch) {
+       return IsNumberStartCharacter(ch) ||
+              ch == '_' ||
+              ch == '.' ||
+              ch == '#' ||
+              (ch >= 'a' && ch <= 'f') ||
+              (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool IsNumberStartCharacter(int ch) {
+       return isdigit(ch) != 0;
+}
+
+static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
+       return isspace(ch) || IsDelimiterCharacter(ch);
+}
+
+static bool IsValidIdentifier(const SString& identifier) {
+       // First character can't be '_', so initialize the flag to true
+       bool lastWasUnderscore = true;
+
+       int length = identifier.length();
+
+       // Zero-length identifiers are not valid (these can occur inside labels)
+       if (length == 0) {
+               return false;
+       }
+
+       // Check for valid character at the start
+       if (!IsWordStartCharacter(identifier[0])) {
+               return false;
+       }
+
+       // Check for only valid characters and no double underscores
+       for (int i = 0; i < length; i++) {
+               if (!IsWordCharacter(identifier[i]) ||
+                       (identifier[i] == '_' && lastWasUnderscore)) {
+                       return false;
                }
+               lastWasUnderscore = identifier[i] == '_';
+       }
+
+       // Check for underscore at the end
+       if (lastWasUnderscore == true) {
+               return false;
+       }
 
-               if (state == SCE_ADA_DEFAULT) {
-                       styleTokenBegin(ch, i, state, styler);
-               } else if (state == SCE_ADA_IDENTIFIER) {
-                       if (!iswordchar(ch)) {
-                               classifyWordAda(styler.GetStartSegment(),
-                                                               i - 1,
-                                                               keywords,
-                                                               styler);
-                               state = SCE_ADA_DEFAULT;
-                               styleTokenBegin(ch, i, state, styler);
+       // All checks passed
+       return true;
+}
+
+static bool IsValidNumber(const SString& number) {
+       int hashPos = number.search("#");
+       bool seenDot = false;
+
+       int i = 0;
+       int length = number.length();
+
+       if (length == 0)
+               return false; // Just in case
+
+       // Decimal number
+       if (hashPos == -1) {
+               bool canBeSpecial = false;
+
+               for (; i < length; i++) {
+                       if (number[i] == '_') {
+                               if (!canBeSpecial) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                       } else if (number[i] == '.') {
+                               if (!canBeSpecial || seenDot) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                               seenDot = true;
+                       } else if (isdigit(number[i])) {
+                               canBeSpecial = true;
+                       } else {
+                               break;
                        }
-               } else if (state == SCE_ADA_COMMENT) {
-                       if (ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_ADA_DEFAULT;
+               }
+
+               if (!canBeSpecial)
+                       return false;
+       } else {
+               // Based number
+               bool canBeSpecial = false;
+               int base = 0;
+
+               // Parse base
+               for (; i < length; i++) {
+                       int ch = number[i];
+                       if (ch == '_') {
+                               if (!canBeSpecial)
+                                       return false;
+                               canBeSpecial = false;
+                       } else if (isdigit (ch)) {
+                               base = base * 10 + (ch - '0');
+                               if (base > 16)
+                                       return false;
+                               canBeSpecial = true;
+                       } else if (ch == '#' && canBeSpecial) {
+                               break;
+                       } else {
+                               return false;
                        }
-               } else if (state == SCE_ADA_STRING) {
-                       if (ch == '"' ) {
-                               if( chNext == '"' ) {
-                                       i++;
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               } else {                                        
-                                       styler.ColourTo(i, state);
-                                       state = SCE_ADA_DEFAULT;
+               }
+
+               if (base < 2)
+                       return false;
+               if (i == length)
+                       return false;
+
+               i++; // Skip over '#'
+
+               // Parse number
+               canBeSpecial = false;
+
+               for (; i < length; i++) {
+                       int ch = tolower(number[i]);
+
+                       if (ch == '_') {
+                               if (!canBeSpecial) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+
+                       } else if (ch == '.') {
+                               if (!canBeSpecial || seenDot) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                               seenDot = true;
+
+                       } else if (isdigit (ch)) {
+                               if (ch - '0' >= base) {
+                                       return false;
+                               }
+                               canBeSpecial = true;
+
+                       } else if (ch >= 'a' && ch <= 'f') {
+                               if (ch - 'a' + 10 >= base) {
+                                       return false;
                                }
-                       } else if (chNext == '\r' || chNext == '\n') {
-                               styler.ColourTo(i-1, SCE_ADA_STRINGEOL);
-                               state = SCE_ADA_STRINGEOL;
+                               canBeSpecial = true;
+
+                       } else if (ch == '#' && canBeSpecial) {
+                               break;
+
+                       } else {
+                               return false;
                        }
-               } else if (state == SCE_ADA_CHARACTER) {
-                       if (ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, SCE_ADA_STRINGEOL);
-                               state = SCE_ADA_STRINGEOL;
-                       } else if (ch == '\'' && styler.SafeGetCharAt(i - 2) == '\'') {
-                               styler.ColourTo(i, state);
-                               state = SCE_ADA_DEFAULT;
+               }
+
+               if (i == length) {
+                       return false;
+               }
+
+               i++;
+       }
+
+       // Exponent (optional)
+       if (i < length) {
+               if (number[i] != 'e' && number[i] != 'E')
+                       return false;
+
+               i++; // Move past 'E'
+
+               if (i == length) {
+                       return false;
+               }
+
+               if (number[i] == '+')
+                       i++;
+               else if (number[i] == '-') {
+                       if (seenDot) {
+                               i++;
+                       } else {
+                               return false; // Integer literals should not have negative exponents
                        }
-               } else if (state == SCE_ADA_NUMBER) {
-                       if ( !( isdigit(ch) || ch == '.' || ch == '_' || ch == '#'
-                                   || ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D'
-                                       || ch == 'E' || ch == 'F'
-                                       || ch == 'a' || ch == 'b' || ch == 'c' || ch == 'd'
-                                       || ch == 'e' || ch == 'f' ) ) {
-                               styler.ColourTo(i-1, SCE_ADA_NUMBER);
-                               state = SCE_ADA_DEFAULT;
-                               styleTokenBegin(ch, i, state, styler);
+               }
+
+               if (i == length) {
+                       return false;
+               }
+
+               bool canBeSpecial = false;
+
+               for (; i < length; i++) {
+                       if (number[i] == '_') {
+                               if (!canBeSpecial) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                       } else if (isdigit(number[i])) {
+                               canBeSpecial = true;
+                       } else {
+                               return false;
                        }
                }
 
+               if (!canBeSpecial)
+                       return false;
        }
-       styler.ColourTo(lengthDoc - 1, state);
 
-//     // Fill in the real level of the next line, keeping the current flags as they will be filled in later
-//     if (fold) {
-//             int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
-//             styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-//     }
+       // if i == length, number was parsed successfully.
+       return i == length;
+}
+
+static inline bool IsWordCharacter(int ch) {
+       return IsWordStartCharacter(ch) || isdigit(ch);
 }
 
-LexerModule lmAda(SCLEX_ADA, ColouriseAdaDoc, "ada");
+static inline bool IsWordStartCharacter(int ch) {
+       return isalpha(ch) || ch == '_';
+}
diff --git a/contrib/src/stc/scintilla/src/LexAsm.cxx b/contrib/src/stc/scintilla/src/LexAsm.cxx
new file mode 100644 (file)
index 0000000..1eecf9b
--- /dev/null
@@ -0,0 +1,142 @@
+// Scintilla source code edit control
+/** @file LexAsm.cxx
+ ** Lexer for Assembler, just for the Masm Syntax
+ ** Written by The Black Horus
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
+}
+
+static inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+}
+
+inline bool isAsmOperator(char ch) {
+       if (isalnum(ch))
+               return false;
+       // '.' left out as it is used to make up numbers
+       if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+               ch == '(' || ch == ')' || ch == '=' ||
+               ch == '[' || ch == ']' || ch == '<' ||
+               ch == '>' || ch == ',' ||
+               ch == '.' || ch == '%' || ch == ':')
+               return true;
+       return false;
+}
+
+static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+
+       WordList &cpuInstruction = *keywordlists[0];
+       WordList &mathInstruction = *keywordlists[1];
+       WordList &registers = *keywordlists[2];
+       WordList &directive = *keywordlists[3];
+       WordList &directiveOperand = *keywordlists[4];
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       for (; sc.More(); sc.Forward())
+       {
+               // Handle line continuation generically.
+               if (sc.ch == '\\') {
+                       if (sc.Match("\\\n")) {
+                               sc.Forward();
+                               continue;
+                       }
+                       if (sc.Match("\\\r\n")) {
+                               sc.Forward();
+                               sc.Forward();
+                               continue;
+                       }
+               }
+
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_ASM_OPERATOR) {
+                       sc.SetState(SCE_ASM_DEFAULT);
+               }else if (sc.state == SCE_ASM_NUMBER) {
+                       if (!IsAWordChar(sc.ch)) {
+                               sc.SetState(SCE_ASM_DEFAULT);
+                       }
+               } else if (sc.state == SCE_ASM_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) ) {
+                       char s[100];
+                       sc.GetCurrentLowered(s, sizeof(s));
+
+                       if (cpuInstruction.InList(s)) {
+                               sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
+                       } else if (mathInstruction.InList(s)) {
+                               sc.ChangeState(SCE_ASM_MATHINSTRUCTION);
+                       } else if (registers.InList(s)) {
+                               sc.ChangeState(SCE_ASM_REGISTER);
+                       }  else if (directive.InList(s)) {
+                               sc.ChangeState(SCE_ASM_DIRECTIVE);
+                       } else if (directiveOperand.InList(s)) {
+                               sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
+                       }
+                       sc.SetState(SCE_ASM_DEFAULT);
+                       }
+               }
+               else if (sc.state == SCE_ASM_COMMENT ) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_ASM_DEFAULT);
+                       }
+               } else if (sc.state == SCE_ASM_STRING) {
+                       if (sc.ch == '\\') {
+                               if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+                                       sc.Forward();
+                               }
+                       } else if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_ASM_DEFAULT);
+                       } else if (sc.atLineEnd) {
+                               sc.ForwardSetState(SCE_ASM_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               else if (sc.state == SCE_ASM_DEFAULT) {
+                       if (sc.ch == ';'){
+                               sc.SetState(SCE_ASM_COMMENT);
+                       } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+                               sc.SetState(SCE_ASM_NUMBER);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_ASM_IDENTIFIER);
+                       } else if (sc.Match('\"')) {
+                               sc.SetState(SCE_ASM_STRING);
+                       }
+               }
+
+       }
+       sc.Complete();
+}
+
+static const char * const asmWordListDesc[] = {
+       "CPU instructions",
+       "FPU instructions",
+       "Registers",
+       "Directives",
+       "Directive operands",
+       0
+};
+
+LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);
+
index 1f76ffcf00189795df47952d5b0b377664fa308e..902f89c1e481b34037dec8d71cac87aeb559e046 100644 (file)
@@ -30,18 +30,6 @@ static int classifyWordBullant(unsigned int start, unsigned int end, WordList &k
        else {
                if (keywords.InList(s)) {
                        chAttr = SCE_C_WORD;
-/*                     if (strcmp(s, "end method") == 0 ||
-                               strcmp(s, "end case") == 0 ||
-                               strcmp(s, "end class") == 0 ||
-                               strcmp(s, "end debug") == 0 ||
-                               strcmp(s, "end test") == 0 ||
-                               strcmp(s, "end if") == 0 ||
-                               strcmp(s, "end lock") == 0 ||
-                               strcmp(s, "end transaction") == 0 ||
-                               strcmp(s, "end trap") == 0 ||
-                               strcmp(s, "end until") == 0 ||
-                               strcmp(s, "end while") == 0)
-                               lev = -1;*/
                        if (strcmp(s, "end") == 0)
                                lev = -1;
                        else if (strcmp(s, "method") == 0 ||
@@ -80,7 +68,6 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
        char chNext = styler[startPos];
        unsigned int lengthDoc = startPos + length;
        int visibleChars = 0;
-       // int blockChange = 0;
        styler.StartSegment(startPos);
        int endFoundThisLine = 0;
        for (unsigned int i = startPos; i < lengthDoc; i++) {
@@ -230,4 +217,9 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
        }
 }
 
-LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant");
+static const char * const bullantWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
index 39f458da7397171b0148ce2bed11c2b6c72d13e6..661b968cd75c3138b798bea9c369027e73a08367 100644 (file)
@@ -20,6 +20,9 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#define KEYWORD_BOXHEADER 1
+#define KEYWORD_FOLDCONTRACTED 2
+
 static bool IsOKBeforeRE(const int ch) {
        return (ch == '(') || (ch == '=') || (ch == ',');
 }
@@ -34,17 +37,17 @@ static inline bool IsAWordStart(const int ch) {
 
 static inline bool IsADoxygenChar(const int ch) {
        return (islower(ch) || ch == '$' || ch == '@' ||
-                   ch == '\\' || ch == '&' || ch == '<' ||
-                       ch == '>' || ch == '#' || ch == '{' ||
-                       ch == '}' || ch == '[' || ch == ']');
+               ch == '\\' || ch == '&' || ch == '<' ||
+               ch == '>' || ch == '#' || ch == '{' ||
+               ch == '}' || ch == '[' || ch == ']');
 }
 
 static inline bool IsStateComment(const int state) {
        return ((state == SCE_C_COMMENT) ||
-                     (state == SCE_C_COMMENTLINE) ||
-                     (state == SCE_C_COMMENTDOC) ||
-                     (state == SCE_C_COMMENTDOCKEYWORD) ||
-                     (state == SCE_C_COMMENTDOCKEYWORDERROR));
+               (state == SCE_C_COMMENTLINE) ||
+               (state == SCE_C_COMMENTDOC) ||
+               (state == SCE_C_COMMENTDOCKEYWORD) ||
+               (state == SCE_C_COMMENTDOCKEYWORDERROR));
 }
 
 static inline bool IsStateString(const int state) {
@@ -52,7 +55,7 @@ static inline bool IsStateString(const int state) {
 }
 
 static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
+                            Accessor &styler, bool caseSensitive) {
 
        WordList &keywords = *keywordlists[0];
        WordList &keywords2 = *keywordlists[1];
@@ -71,7 +74,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
        StyleContext sc(startPos, length, initStyle, styler);
 
        for (; sc.More(); sc.Forward()) {
-       
+
                if (sc.atLineStart && (sc.state == SCE_C_STRING)) {
                        // Prevent SCE_C_STRINGEOL from leaking back to previous line
                        sc.SetState(SCE_C_STRING);
@@ -98,7 +101,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                } else if (sc.state == SCE_C_IDENTIFIER) {
                        if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
                                char s[100];
-                               sc.GetCurrent(s, sizeof(s));
+                               if (caseSensitive) {
+                                       sc.GetCurrent(s, sizeof(s));
+                               } else {
+                                       sc.GetCurrentLowered(s, sizeof(s));
+                               }
                                if (keywords.InList(s)) {
                                        lastWordWasUUID = strcmp(s, "uuid") == 0;
                                        sc.ChangeState(SCE_C_WORD);
@@ -141,8 +148,12 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                sc.ForwardSetState(SCE_C_DEFAULT);
                        } else if (!IsADoxygenChar(sc.ch)) {
                                char s[100];
-                               sc.GetCurrent(s, sizeof(s));
-                               if (!isspace(sc.ch) || !keywords3.InList(s+1)) {
+                               if (caseSensitive) {
+                                       sc.GetCurrent(s, sizeof(s));
+                               } else {
+                                       sc.GetCurrentLowered(s, sizeof(s));
+                               }
+                               if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
                                        sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
                                }
                                sc.SetState(SCE_C_COMMENTDOC);
@@ -237,7 +248,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                // Skip whitespace between # and preprocessor word
                                do {
                                        sc.Forward();
-                               } while ((sc.ch == ' ') && (sc.ch == '\t') && sc.More());
+                               } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
                                if (sc.atLineEnd) {
                                        sc.SetState(SCE_C_DEFAULT);
                                }
@@ -245,9 +256,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                sc.SetState(SCE_C_OPERATOR);
                        }
                }
-               
+
                if (sc.atLineEnd) {
-                       // Reset states to begining of colourise so no surprises 
+                       // Reset states to begining of colourise so no surprises
                        // if different sets of lines lexed.
                        chPrevNonWhite = ' ';
                        visibleChars = 0;
@@ -262,13 +273,234 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 }
 
 static bool IsStreamCommentStyle(int style) {
-       return style == SCE_C_COMMENT || 
-               style == SCE_C_COMMENTDOC ||
-               style == SCE_C_COMMENTDOCKEYWORD ||
-               style == SCE_C_COMMENTDOCKEYWORDERROR;
+       return style == SCE_C_COMMENT ||
+              style == SCE_C_COMMENTDOC ||
+              style == SCE_C_COMMENTDOCKEYWORD ||
+              style == SCE_C_COMMENTDOCKEYWORDERROR;
 }
 
-static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+static bool matchKeyword(unsigned int start, WordList &keywords, Accessor &styler, int keywordtype) {
+       bool FoundKeyword = false;
+
+       for (unsigned int i = 0;
+               strlen(keywords[i]) > 0 && !FoundKeyword;
+               i++) {
+               if (atoi(keywords[i]) == keywordtype) {
+                       FoundKeyword = styler.Match(start, ((char *)keywords[i]) + 2);
+               }
+       }
+       return FoundKeyword;
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+       unsigned int Pos = styler.LineStart(line);
+       while (styler.GetLine(Pos) == line) {
+               int PosStyle = styler.StyleAt(Pos);
+
+               if (    !IsStreamCommentStyle(PosStyle)
+                       &&
+                       PosStyle != SCE_C_COMMENTLINEDOC
+                       &&
+                       PosStyle != SCE_C_COMMENTLINE
+                       &&
+                       !IsASpace(styler.SafeGetCharAt(Pos))
+                  )
+                       return false;
+               Pos++;
+       }
+
+       return true;
+}
+
+static void FoldBoxCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                          Accessor &styler) {
+
+       WordList &keywords4 = *keywordlists[3];
+
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       bool firstLine = true;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       int levelPrevPrev;
+       int levelFlags = 0;
+       int levelUnindent = 0;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+
+       if (lineCurrent == 0) {
+               levelPrevPrev = levelPrev;
+       } else {
+               levelPrevPrev = styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK;
+       }
+
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+               if (foldComment && IsStreamCommentStyle(style)) {
+                       if (!IsStreamCommentStyle(stylePrev)) {
+                               levelCurrent++;
+                       } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+                               // Comments don't end at end of line and the next character may be unstyled.
+                               levelCurrent--;
+                       }
+               }
+
+               if (foldComment && (style == SCE_C_COMMENTLINE)) {
+                       if ((ch == '/') && (chNext == '/')) {
+                               char chNext2 = styler.SafeGetCharAt(i + 2);
+                               if (chNext2 == '{') {
+                                       levelCurrent++;
+                               } else if (chNext2 == '}') {
+                                       levelCurrent--;
+                               }
+                       }
+               }
+
+               if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+                       if (ch == '#') {
+                               unsigned int j = i + 1;
+                               while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+                                       j++;
+                               }
+
+                               if (styler.Match(j, "region") || styler.Match(j, "if")) {
+                                       levelCurrent++;
+                               } else if (styler.Match(j, "end")) {
+                                       levelCurrent--;
+                               }
+                       }
+               }
+
+               if (style == SCE_C_OPERATOR
+                       ||
+                       style == SCE_C_COMMENT
+                       ||
+                       style == SCE_C_COMMENTLINE) {
+
+                       if (ch == '{') {
+                               levelCurrent++;
+                               // Special handling if line has closing brace followed by opening brace.
+                               if (levelCurrent == levelPrev) {
+                                       if (firstLine)
+                                               levelUnindent = 1;
+                                       else
+                                               levelUnindent = -1;
+                               }
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+
+               /* Check for fold header keyword at beginning of word */
+               if ((style == SCE_C_WORD || style == SCE_C_COMMENT || style == SCE_C_COMMENTLINE)
+                       &&
+                       (style != stylePrev)) {
+                       if (matchKeyword(i, keywords4, styler, KEYWORD_BOXHEADER)) {
+                               int line;
+                               /* Loop backwards all empty or comment lines */
+                               for (line = lineCurrent - 1;
+                                       line >= 0
+                                       &&
+                                       levelCurrent == (styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK)
+                                       &&
+                                       (styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0
+                                       &&
+                                       IsCommentLine(line, styler);
+                                       line--) {
+                                       /* just loop backwards */;
+                               }
+
+                               line++;
+                               /* Set Box header flag (if the previous line has no footer line) */
+                               if ((styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0) {
+                                       if (line == lineCurrent) {
+                                               /* in current line */
+                                               levelFlags |= SC_FOLDLEVELBOXHEADERFLAG;
+                                       } else {
+                                               /* at top of all preceding comment lines */
+                                               styler.SetLevel(line, styler.LevelAt(line)
+                                                               | SC_FOLDLEVELBOXHEADERFLAG);
+                                       }
+                               }
+                       }
+               }
+
+               if (matchKeyword(i, keywords4, styler, KEYWORD_FOLDCONTRACTED)) {
+                       levelFlags |= SC_FOLDLEVELCONTRACTED;
+               }
+
+               if (atEOL) {
+                       int lev;
+                       // Compute level correction for special case: '} else {'
+                       if (levelUnindent < 0) {
+                               levelPrev += levelUnindent;
+                       } else {
+                               levelCurrent += levelUnindent;
+                       }
+
+                       lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       // Produce additional footer line (e.g. after closed if)
+                       if (visibleChars == 0
+                               &&
+                               (levelPrev < levelPrevPrev))
+                               lev |= SC_FOLDLEVELBOXFOOTERFLAG;
+                       // Produce footer line at line before (special handling for '} else {'
+                       if (levelPrev < levelPrevPrev) {
+                               styler.SetLevel(lineCurrent - 1,
+                                               styler.LevelAt(lineCurrent - 1) | SC_FOLDLEVELBOXFOOTERFLAG);
+                       }
+                       // Mark the fold header (the line that is always visible)
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       // Show a footer line at end of fold
+                       if (levelCurrent < levelPrev)
+                               lev |= SC_FOLDLEVELBOXFOOTERFLAG;
+                       /* Show a footer line at the end of each procedure (level == SC_FOLDLEVELBASE) */
+                       if ((levelPrev == SC_FOLDLEVELBASE)
+                               &&
+                               (levelPrevPrev > SC_FOLDLEVELBASE)
+                               &&
+                               (visibleChars == 0)) {
+                               lev |= SC_FOLDLEVELBOXFOOTERFLAG;
+                       }
+
+                       lev |= levelFlags;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+
+                       lineCurrent++;
+                       levelPrevPrev = levelPrev;
+                       levelPrev = levelCurrent;
+                       levelUnindent = 0;
+                       visibleChars = 0;
+                       levelFlags = 0;
+                       firstLine = false;
+               }
+
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static void FoldNoBoxCppDoc(unsigned int startPos, int length, int initStyle,
                             Accessor &styler) {
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
        bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
@@ -308,8 +540,8 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordLis
                }
                if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
                        if (ch == '#') {
-                               unsigned int j=i+1;
-                               while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+                               unsigned int j = i + 1;
+                               while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
                                        j++;
                                }
                                if (styler.Match(j, "region") || styler.Match(j, "if")) {
@@ -347,12 +579,37 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordLis
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
+static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                       Accessor &styler) {
+
+       int foldFlags = styler.GetPropertyInt("fold.flags") ;
+       bool foldBox = ((foldFlags & SC_FOLDFLAG_BOX) == SC_FOLDFLAG_BOX);
+
+       if (foldBox) {
+               FoldBoxCppDoc(startPos, length, initStyle, keywordlists, styler);
+       } else {
+               FoldNoBoxCppDoc(startPos, length, initStyle, styler);
+       }
+}
+
 static const char * const cppWordLists[] = {
-       "Primary keywords and identifiers",
-       "Secondary keywords and identifiers",
-       "Documentation comment keywords",
-       0,
-};
-
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmTCL(SCLEX_TCL, ColouriseCppDoc, "tcl", FoldCppDoc, cppWordLists);
+            "Primary keywords and identifiers",
+            "Secondary keywords and identifiers",
+            "Documentation comment keywords",
+            "Fold header keywords",
+            0,
+        };
+
+static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                     Accessor &styler) {
+       ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                       Accessor &styler) {
+       ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+LexerModule lmTCL(SCLEX_TCL, ColouriseCppDocSensitive, "tcl", FoldCppDoc, cppWordLists);
diff --git a/contrib/src/stc/scintilla/src/LexCSS.cxx b/contrib/src/stc/scintilla/src/LexCSS.cxx
new file mode 100644 (file)
index 0000000..b89f7ea
--- /dev/null
@@ -0,0 +1,260 @@
+// Scintilla source code edit control
+/** @file LexCSS.cxx
+ ** Lexer for Cascade Style Sheets
+ ** Written by Jakub Vrána
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static inline bool IsAWordChar(const unsigned int ch) {
+       return (isalnum(ch) || ch == '-' || ch == '_' || ch >= 161); // _ is not in fact correct CSS word-character
+}
+
+inline bool IsCssOperator(const char ch) {
+       if (!isalnum(ch) && (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' || ch == '.' || ch == '#' || ch == '!' || ch == '@'))
+               return true;
+       return false;
+}
+
+static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+       WordList &keywords = *keywordlists[0];
+       WordList &pseudoClasses = *keywordlists[1];
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       int lastState = -1; // before operator
+       int lastStateC = -1; // before comment
+       int op = ' '; // last operator
+
+       for (; sc.More(); sc.Forward()) {
+               if (sc.state == SCE_CSS_COMMENT && sc.Match('*', '/')) {
+                       if (lastStateC == -1) {
+                               // backtrack to get last state
+                               unsigned int i = startPos;
+                               for (; i > 0; i--) {
+                                       if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
+                                               if (lastStateC == SCE_CSS_OPERATOR) {
+                                                       op = styler.SafeGetCharAt(i-1);
+                                                       while (--i) {
+                                                               lastState = styler.StyleAt(i-1);
+                                                               if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
+                                                                       break;
+                                                       }
+                                                       if (i == 0)
+                                                               lastState = SCE_CSS_DEFAULT;
+                                               }
+                                               break;
+                                       }
+                               }
+                               if (i == 0)
+                                       lastStateC = SCE_CSS_DEFAULT;
+                       }
+                       sc.Forward();
+                       sc.ForwardSetState(lastStateC);
+               }
+
+               if (sc.state == SCE_CSS_COMMENT)
+                       continue;
+
+               if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {
+                       if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
+                               continue;
+                       unsigned int i = sc.currentPos;
+                       while (i && styler[i-1] == '\\')
+                               i--;
+                       if ((sc.currentPos - i) % 2 == 1)
+                               continue;
+                       sc.ForwardSetState(SCE_CSS_VALUE);
+               }
+
+               if (sc.state == SCE_CSS_OPERATOR) {
+                       if (op == ' ') {
+                               unsigned int i = startPos;
+                               op = styler.SafeGetCharAt(i-1);
+                               while (--i) {
+                                       lastState = styler.StyleAt(i-1);
+                                       if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
+                                               break;
+                               }
+                       }
+                       switch (op) {
+                       case '@':
+                               if (lastState == SCE_CSS_DEFAULT)
+                                       sc.SetState(SCE_CSS_DIRECTIVE);
+                               break;
+                       case '{':
+                               if (lastState == SCE_CSS_DIRECTIVE)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               else if (lastState == SCE_CSS_TAG)
+                                       sc.SetState(SCE_CSS_IDENTIFIER);
+                               break;
+                       case '}':
+                               if (lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT || lastState == SCE_CSS_IDENTIFIER)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               break;
+                       case ':':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID)
+                                       sc.SetState(SCE_CSS_PSEUDOCLASS);
+                               else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
+                                       sc.SetState(SCE_CSS_VALUE);
+                               break;
+                       case '.':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+                                       sc.SetState(SCE_CSS_CLASS);
+                               break;
+                       case '#':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+                                       sc.SetState(SCE_CSS_ID);
+                               break;
+                       case ',':
+                               if (lastState == SCE_CSS_TAG)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               break;
+                       case ';':
+                               if (lastState == SCE_CSS_DIRECTIVE)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               else if (lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT)
+                                       sc.SetState(SCE_CSS_IDENTIFIER);
+                               break;
+                       case '!':
+                               if (lastState == SCE_CSS_VALUE)
+                                       sc.SetState(SCE_CSS_IMPORTANT);
+                               break;
+                       }
+               }
+
+               if (IsAWordChar(sc.ch)) {
+                       if (sc.state == SCE_CSS_DEFAULT)
+                               sc.SetState(SCE_CSS_TAG);
+                       continue;
+               }
+
+               if (IsAWordChar(sc.chPrev) && (
+                       sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_UNKNOWN_IDENTIFIER
+                       || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
+                       || sc.state == SCE_CSS_IMPORTANT
+               )) {
+                       char s[100];
+                       sc.GetCurrentLowered(s, sizeof(s));
+                       char *s2 = s;
+                       while (*s2 && !IsAWordChar(*s2))
+                               s2++;
+                       switch (sc.state) {
+                       case SCE_CSS_IDENTIFIER:
+                               if (!keywords.InList(s2))
+                                       sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
+                               break;
+                       case SCE_CSS_UNKNOWN_IDENTIFIER:
+                               if (keywords.InList(s2))
+                                       sc.ChangeState(SCE_CSS_IDENTIFIER);
+                               break;
+                       case SCE_CSS_PSEUDOCLASS:
+                               if (!pseudoClasses.InList(s2))
+                                       sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
+                               break;
+                       case SCE_CSS_UNKNOWN_PSEUDOCLASS:
+                               if (pseudoClasses.InList(s2))
+                                       sc.ChangeState(SCE_CSS_PSEUDOCLASS);
+                               break;
+                       case SCE_CSS_IMPORTANT:
+                               if (strcmp(s2, "important") != 0)
+                                       sc.ChangeState(SCE_CSS_VALUE);
+                               break;
+                       }
+               }
+
+               if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS || sc.state == SCE_CSS_ID))
+                       sc.SetState(SCE_CSS_TAG);
+
+               if (sc.Match('/', '*')) {
+                       lastStateC = sc.state;
+                       sc.SetState(SCE_CSS_COMMENT);
+                       sc.Forward();
+               } else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
+                       sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
+               } else if (IsCssOperator(static_cast<char>(sc.ch))
+                       && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
+                       && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
+               ) {
+                       if (sc.state != SCE_CSS_OPERATOR)
+                               lastState = sc.state;
+                       sc.SetState(SCE_CSS_OPERATOR);
+                       op = sc.ch;
+               }
+       }
+
+       sc.Complete();
+}
+
+static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int style = styler.StyleAt(i);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment) {
+                       if (!inComment && (style == SCE_CSS_COMMENT))
+                               levelCurrent++;
+                       else if (inComment && (style != SCE_CSS_COMMENT))
+                               levelCurrent--;
+                       inComment = (style == SCE_CSS_COMMENT);
+               }
+               if (style == SCE_CSS_OPERATOR) {
+                       if (ch == '{') {
+                               levelCurrent++;
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const cssWordListDesc[] = {
+       "Keywords",
+       "Pseudo classes",
+       0
+};
+
+LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);
index c8441f41ec6e2dccc99f9e19fdfa24ce6cbe1962..c33cdb5ce68edcf8ebc85dd7f7307edceac73508 100644 (file)
@@ -175,4 +175,10 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
        delete []buffer;
 }
 
-LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf");
+static const char * const confWordListDesc[] = {
+       "Directives",
+       "Parameters",
+       0
+};
+
+LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
index 37729cbfdd73c682a055420854dc65b1731a89c9..d139bb4f144778f532d7b2c89389191954c80c3d 100644 (file)
@@ -62,7 +62,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
                                        state = SCE_NNCRONTAB_TASK;
                                        styler.ColourTo(i,SCE_NNCRONTAB_TASK);
                                }
-                                 else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' || 
+                                 else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
                                                                                 styler.SafeGetCharAt(i+1) == '\t')) {
                                        // signals the start of an extended comment...
                                        state = SCE_NNCRONTAB_COMMENT;
@@ -208,4 +208,11 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
        delete []buffer;
 }
 
-LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab");
+static const char * const cronWordListDesc[] = {
+       "Section keywords and Forth words",
+       "nnCrontab keywords",
+       "Modifiers",
+       0
+};
+
+LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);
index a0bf26a5ea2e46955cc66273588f133097c69b8d..974efd9a72e1d9a3a5071fb4315b2c92e296ee68 100644 (file)
@@ -28,7 +28,7 @@ static inline bool isEiffelOperator(unsigned int ch) {
                ch == '{' || ch == '}' || ch == '~' ||
                ch == '[' || ch == ']' || ch == ';' ||
                ch == '<' || ch == '>' || ch == ',' ||
-               ch == '.' || ch == '^' || ch == '%' || ch == ':' || 
+               ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
                ch == '!' || ch == '@' || ch == '?';
 }
 
@@ -187,19 +187,19 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init
                        s[j] = '\0';
 
                        if (
-                               (strcmp(s, "check") == 0) || 
-                               (strcmp(s, "debug") == 0) || 
-                               (strcmp(s, "deferred") == 0) || 
-                               (strcmp(s, "do") == 0) || 
+                               (strcmp(s, "check") == 0) ||
+                               (strcmp(s, "debug") == 0) ||
+                               (strcmp(s, "deferred") == 0) ||
+                               (strcmp(s, "do") == 0) ||
                                (strcmp(s, "from") == 0) ||
                                (strcmp(s, "if") == 0) ||
-                               (strcmp(s, "inspect") == 0) || 
+                               (strcmp(s, "inspect") == 0) ||
                                (strcmp(s, "once") == 0)
                        )
                                levelCurrent++;
                        if (!lastDeferred && (strcmp(s, "class") == 0))
                                levelCurrent++;
-                       if (strcmp(s, "end") == 0) 
+                       if (strcmp(s, "end") == 0)
                                levelCurrent--;
                        lastDeferred = strcmp(s, "deferred") == 0;
                }
@@ -226,5 +226,10 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent);
-LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords);
+static const char * const eiffelWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc);
+LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc);
diff --git a/contrib/src/stc/scintilla/src/LexFortran.cxx b/contrib/src/stc/scintilla/src/LexFortran.cxx
new file mode 100644 (file)
index 0000000..e2109a0
--- /dev/null
@@ -0,0 +1,310 @@
+// Scintilla source code edit control
+/** @file LexFortran.cxx
+ ** Lexer for Fortran.
+ ** Writen by Chuan-jian Shen, Last changed Nov. 2002
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
+}
+
+static inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch));
+}
+
+inline bool IsABlank(unsigned int ch) {
+    return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
+}
+static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler, bool isFixFormat) {
+
+       WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2];
+
+       int posLineStart = 0, prevState = 0;
+       int endPos = startPos + length;
+
+       // backtrack to the beginning of the document, this may be slow for big documents.
+       // initStyle = SCE_F_DEFAULT;
+       // StyleContext sc(0, startPos+length, initStyle, styler);
+
+       // backtrack to the nearest keyword
+       while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
+               startPos--;
+       }
+       startPos = styler.LineStart(styler.GetLine(startPos));
+       initStyle = styler.StyleAt(startPos - 1);
+       StyleContext sc(startPos, endPos-startPos, initStyle, styler);
+
+       for (; sc.More(); sc.Forward()) {
+
+               // remember the position of the line
+               if (sc.atLineStart) {
+                       posLineStart = sc.currentPos;
+                       sc.SetState(SCE_F_DEFAULT);
+               }
+
+               // Handle line continuation generically.
+               if (sc.ch == '&') {
+                       char chTemp = ' ';
+                       int j = 1;
+                       while (IsABlank(chTemp) && j<132) {
+                               chTemp = static_cast<char>(sc.GetRelative(j));
+                               j ++;
+                       }
+                       if (chTemp == '!') {
+                               sc.SetState(SCE_F_CONTINUATION);
+                               if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
+                       } else if (chTemp == '\r' || chTemp == '\n') {
+                               int currentState = sc.state;
+                               sc.SetState(SCE_F_CONTINUATION);
+                               if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       while (IsASpace(sc.ch) && sc.More()) sc.Forward();
+                                       if (sc.ch == '&') {
+                                               sc.SetState(SCE_F_CONTINUATION);
+                                               sc.Forward();
+                                       }
+                                       sc.SetState(currentState);
+                               }
+                       }
+                       continue;
+               }
+
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_F_OPERATOR) {
+                       sc.SetState(SCE_F_DEFAULT);
+               } else if (sc.state == SCE_F_NUMBER) {
+                       if (!IsAWordChar(sc.ch)) {
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
+                               char s[100];
+                               sc.GetCurrentLowered(s, sizeof(s));
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_F_WORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_F_WORD2);
+                               } else if (keywords3.InList(s)) {
+                                       sc.ChangeState(SCE_F_WORD3);
+                               }
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_COMMENT) {
+                       if (sc.ch == '\r' || sc.ch == '\n') {
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_STRING1) {
+                       prevState = sc.state;
+                       if (sc.ch == '\'') {
+                               if (sc.chNext == '\'') {
+                                       sc.Forward();
+                               } else {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       prevState = SCE_F_DEFAULT;
+                               }
+                       } else if (sc.atLineEnd) {
+                               if (isFixFormat) {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       posLineStart = sc.currentPos;
+                               } else {
+                                       sc.ChangeState(SCE_F_STRINGEOL);
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                               }
+                       }
+               } else if (sc.state == SCE_F_STRING2) {
+                       prevState = sc.state;
+                       if (sc.atLineEnd) {
+                               if (isFixFormat) {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       posLineStart = sc.currentPos;
+                               } else {
+                                       sc.ChangeState(SCE_F_STRINGEOL);
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                               }
+                       } else if (sc.ch == '\"') {
+                               if (sc.chNext == '\"') {
+                                       sc.Forward();
+                               } else {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       prevState = SCE_F_DEFAULT;
+                               }
+                       }
+               } else if (sc.state == SCE_F_OPERATOR2) {
+                       if (sc.ch == '.') {
+                               sc.ForwardSetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_CONTINUATION) {
+                       sc.SetState(SCE_F_DEFAULT);
+               } else if (sc.state == SCE_F_LABEL) {
+                       if (sc.currentPos >= static_cast<unsigned int>(posLineStart+5)) {
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_F_DEFAULT) {
+                       int toLineStart = sc.currentPos - posLineStart;
+                       if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
+                               if (sc.atLineStart && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') {
+                                       sc.SetState(SCE_F_COMMENT);
+                               } else if (toLineStart > 72) {
+                                       sc.SetState(SCE_F_COMMENT);
+                               } else if (toLineStart < 5 && !IsASpace(sc.ch)) {
+                                       sc.SetState(SCE_F_LABEL);
+                               } else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) {
+                                       sc.SetState(SCE_F_CONTINUATION);
+                                       sc.ForwardSetState(prevState);
+                               }
+                       } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_F_NUMBER);
+                       } else if (sc.ch == '.' && isalpha(sc.chNext)) {
+                               sc.SetState(SCE_F_OPERATOR2);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_F_IDENTIFIER);
+                       } else if (sc.ch == '!') {
+                               sc.SetState(SCE_F_COMMENT);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_F_STRING2);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_F_STRING1);
+                       } else if (isoperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_F_OPERATOR);
+                       }
+               }
+       }
+       sc.Complete();
+}
+
+// The folding depends on the mercy of the programer.
+static int classifyFoldPointFortran(const char* s, const char* prevWord) {
+       int lev = 0;
+       if (strcmp(prevWord, "end") == 0) return lev;
+       if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
+               return -1;
+       if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
+           || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
+           || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
+           || strcmp(s, "forall") == 0 || strcmp(s, "function") == 0
+           || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0
+           || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0
+           || strcmp(s, "then") == 0 || strcmp(s, "where") == 0) {
+               lev = 1;
+       } else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0
+           || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
+           || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
+           || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
+           || strcmp(s, "endif") == 0
+           || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0
+           || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0
+           || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0
+           || strcmp(s, "endwhere") == 0 || strcmp(s, "procedure") == 0 ) {
+               lev = -1;
+       }
+       return lev;
+}
+static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+       //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       // Do not know how to fold the comment at the moment.
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+
+       int lastStart = 0;
+       char prevWord[32] = "";
+
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+               if (stylePrev == SCE_F_DEFAULT && style == SCE_F_WORD)
+               {
+                       // Store last word start point.
+                       lastStart = i;
+               }
+
+               if (style == SCE_F_WORD) {
+                       if(iswordchar(ch) && !iswordchar(chNext)) {
+                               char s[32];
+                               unsigned int j;
+                               for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
+                                       s[j] = static_cast<char>(tolower(styler[lastStart + j]));
+                               }
+                               s[j] = '\0';
+                               levelCurrent += classifyFoldPointFortran(s, prevWord);
+                               strcpy(prevWord, s);
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+                       strcpy(prevWord, "");
+               }
+
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const FortranWordLists[] = {
+       "Primary keywords and identifiers",
+       "Intrinsic functions",
+       "Extended and user defined functions",
+       0,
+};
+
+static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+       ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+       ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+
+LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDoc, FortranWordLists);
+LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDoc, FortranWordLists);
index 545bbfd553317abf95674c83caf0fe4e1bd4de0f..345b15edcb3b1c6c6a931d7340e8aae2fc996a1a 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LexHTML.cxx
  ** Lexer for HTML.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -197,16 +197,30 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
 }
 
 static int classifyTagHTML(unsigned int start, unsigned int end,
-                           WordList &keywords, Accessor &styler) {
-       char s[30 + 1];
+                           WordList &keywords, Accessor &styler, bool &tagDontFold,
+                          bool caseSensitive) {
+       char s[30 + 2];
        // Copy after the '<'
        unsigned int i = 0;
        for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
                char ch = styler[cPos];
-               if ((ch != '<') && (ch != '/'))
-                       s[i++] = static_cast<char>(tolower(ch));
+               if ((ch != '<') && (ch != '/')) {
+                       s[i++] = caseSensitive ? ch : static_cast<char>(tolower(ch));
+               }
        }
+
+       //The following is only a quick hack, to see if this whole thing would work
+       //we first need the tagname with a trailing space...
+       s[i] = ' ';
+       s[i+1] = '\0';
+
+       //...to find it in the list of no-container-tags
+       // (There are many more. We will need a keywordlist in the property file for this)
+       tagDontFold = (NULL != strstr("meta link img area br hr input ",s));
+
+       //now we can remove the trailing space
        s[i] = '\0';
+
        bool isScript = false;
        char chAttr = SCE_H_TAGUNKNOWN;
        if (s[0] == '!') {
@@ -368,6 +382,14 @@ static inline bool issgmlwordchar(char ch) {
        return isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[';
 }
 
+static inline bool IsPhpWordStart(const unsigned char ch) {
+       return isalpha(ch) || (ch == '_') || (ch >= 0x7f);
+}
+
+static inline bool IsPhpWordChar(char ch) {
+       return isdigit(ch) || IsPhpWordStart(ch);
+}
+
 static bool InTagState(int state) {
        return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
               state == SCE_H_SCRIPT ||
@@ -433,6 +455,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
        bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag
        bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag
+       bool tagDontFold = false; //some HTML tags should not be folded
        script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name
        script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name
        int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
@@ -440,8 +463,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        script_type scriptLanguage = ScriptOfState(state);
 
        const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
-       const bool fold = foldHTML && styler.GetPropertyInt("fold");
+       const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
+       const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
        const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
 
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
        int levelCurrent = levelPrev;
@@ -481,7 +506,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        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 ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
+                               //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
+                               //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
                                        if ((ch == '{') || (ch == '}')) {
                                                levelCurrent += (ch == '{') ? 1 : -1;
                                        }
@@ -600,9 +627,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        else
                                inScriptType = eNonHtmlPreProc;
                        // fold whole script
-                       levelCurrent++;
-                       if (scriptLanguage == eScriptXML)
-                               levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
+                       if (foldHTMLPreprocessor){
+                               levelCurrent++;
+                               if (scriptLanguage == eScriptXML)
+                                       levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
+                       }
                        // should be better
                        ch = styler.SafeGetCharAt(i);
                        continue;
@@ -640,7 +669,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        scriptLanguage = eScriptVBS;
                        styler.ColourTo(i, SCE_H_ASP);
                        // fold whole script
-                       levelCurrent++;
+                       if (foldHTMLPreprocessor)
+                               levelCurrent++;
                        // should be better
                        ch = styler.SafeGetCharAt(i);
                        continue;
@@ -665,8 +695,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                state = SCE_H_SGML_COMMAND; // wait for a pending command
                        }
                        // fold whole tag (-- when closing the tag)
-
-                       levelCurrent++;
+                       if (foldHTMLPreprocessor)
+                               levelCurrent++;
                        continue;
                }
 
@@ -723,7 +753,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                inScriptType = eHtml;
                        scriptLanguage = eScriptNone;
                        // unfold all scripting languages
-                       levelCurrent--;
+                       if (foldHTMLPreprocessor)
+                               levelCurrent--;
                        continue;
                }
                /////////////////////////////////////
@@ -904,7 +935,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        break;
                case SCE_H_TAGUNKNOWN:
                        if (!ishtmlwordchar(ch) && !((ch == '/') && (chPrev == '<')) && ch != '[') {
-                               int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler);
+                               int eClass = classifyTagHTML(styler.GetStartSegment(),
+                                       i - 1, keywords, styler, tagDontFold, caseSensitive);
                                if (eClass == SCE_H_SCRIPT) {
                                        if (!tagClosing) {
                                                inScriptType = eNonHtmlScript;
@@ -923,10 +955,12 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                state = SCE_H_DEFAULT;
                                        }
                                        tagOpened = false;
-                                       if (tagClosing) {
-                                               levelCurrent--;
-                                       } else {
-                                               levelCurrent++;
+                                       if (!tagDontFold){
+                                               if (tagClosing) {
+                                                       levelCurrent--;
+                                               } else {
+                                                       levelCurrent++;
+                                               }
                                        }
                                        tagClosing = false;
                                } else if (ch == '/' && chNext == '>') {
@@ -969,10 +1003,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                state = SCE_H_DEFAULT;
                                        }
                                        tagOpened = false;
-                                       if (tagClosing)
-                                               levelCurrent--;
-                                       else
-                                               levelCurrent++;
+                                       if (!tagDontFold){
+                                               if (tagClosing){
+                                                       levelCurrent--;
+                                               } else {
+                                                       levelCurrent++;
+                                               }
+                                       }
                                        tagClosing = false;
                                } else if (ch == '=') {
                                        styler.ColourTo(i, SCE_H_OTHER);
@@ -992,10 +1029,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                        state = SCE_H_DEFAULT;
                                }
                                tagOpened = false;
-                               if (tagClosing)
-                                       levelCurrent--;
-                               else
-                                       levelCurrent++;
+                               if (!tagDontFold){
+                                       if (tagClosing){
+                                               levelCurrent--;
+                                       } else {
+                                               levelCurrent++;
+                                       }
+                               }
                                tagClosing = false;
                        } else if (ch == '\"') {
                                styler.ColourTo(i - 1, StateToPrint);
@@ -1044,10 +1084,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        break;
                case SCE_H_VALUE:
                        if (!ishtmlwordchar(ch)) {
-                               if (ch == '\"') {
+                               if (ch == '\"' && chPrev == '=') {
                                        // Should really test for being first character
                                        state = SCE_H_DOUBLESTRING;
-                               } else if (ch == '\'') {
+                               } else if (ch == '\'' && chPrev == '=') {
                                        state = SCE_H_SINGLESTRING;
                                } else {
                                        if (IsNumber(styler.GetStartSegment(), styler)) {
@@ -1063,10 +1103,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                        state = SCE_H_DEFAULT;
                                                }
                                                tagOpened = false;
-                                               if (tagClosing)
-                                                       levelCurrent--;
-                                               else
-                                                       levelCurrent++;
+                                               if (!tagDontFold){
+                                                       if (tagClosing){
+                                                               levelCurrent--;
+                                                       } else {
+                                                               levelCurrent++;
+                                                       }
+                                               }
                                                tagClosing = false;
                                        } else {
                                                state = SCE_H_OTHER;
@@ -1397,7 +1440,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        break;
                        ///////////// start - PHP state handling
                case SCE_HPHP_WORD:
-                       if (!iswordstart(ch)) {
+                       if (!iswordchar(ch)) {
                                classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
                                if (ch == '/' && chNext == '*') {
                                        i++;
@@ -1411,7 +1454,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                        state = SCE_HPHP_HSTRING;
                                } else if (ch == '\'') {
                                        state = SCE_HPHP_SIMPLESTRING;
-                               } else if (ch == '$') {
+                               } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                        state = SCE_HPHP_VARIABLE;
                                } else if (isoperator(ch)) {
                                        state = SCE_HPHP_OPERATOR;
@@ -1430,7 +1473,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        break;
                case SCE_HPHP_VARIABLE:
-                       if (!iswordstart(ch)) {
+                       if (!IsPhpWordChar(ch)) {
                                styler.ColourTo(i - 1, SCE_HPHP_VARIABLE);
                                if (isoperator(ch))
                                        state = SCE_HPHP_OPERATOR;
@@ -1454,7 +1497,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        if (ch == '\\') {
                                // skip the next char
                                i++;
-                       } else if (ch == '$') {
+                       } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                styler.ColourTo(i - 1, StateToPrint);
                                state = SCE_HPHP_HSTRING_VARIABLE;
                        } else if (ch == '\"') {
@@ -1472,7 +1515,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        break;
                case SCE_HPHP_HSTRING_VARIABLE:
-                       if (!iswordstart(ch)) {
+                       if (!IsPhpWordChar(ch)) {
                                styler.ColourTo(i - 1, StateToPrint);
                                i--; // strange but it works
                                state = SCE_HPHP_HSTRING;
@@ -1497,7 +1540,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                state = SCE_HPHP_HSTRING;
                        } else if (ch == '\'') {
                                state = SCE_HPHP_SIMPLESTRING;
-                       } else if (ch == '$') {
+                       } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                state = SCE_HPHP_VARIABLE;
                        } else if (isoperator(ch)) {
                                state = SCE_HPHP_OPERATOR;
@@ -1553,7 +1596,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        }
 
        StateToPrint = statePrintForState(state, inScriptType);
-       styler.ColourTo(lengthDoc - 1, StateToPrint);
+               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) {
@@ -1701,9 +1744,9 @@ static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) {
                        sc.SetState(SCE_H_ENTITY);
                }
        } else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) {
-               if (sc.ch == '\"') {
+               if (sc.ch == '\"' && sc.chPrev == '=') {
                        sc.SetState(SCE_H_DOUBLESTRING);
-               } else if (sc.ch == '\'') {
+               } else if (sc.ch == '\'' && sc.chPrev == '=') {
                        sc.SetState(SCE_H_SINGLESTRING);
                } else if (IsADigit(sc.ch)) {
                        sc.SetState(SCE_H_NUMBER);
@@ -1780,7 +1823,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
 
        // Handle some PHP script
        if (sc.state == SCE_HPHP_WORD) {
-               if (!IsAWordStart(sc.ch)) {
+               if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_DEFAULT);
                }
        } else if (sc.state == SCE_HPHP_COMMENTLINE) {
@@ -1802,7 +1845,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
                        sc.ForwardSetState(SCE_HPHP_DEFAULT);
                }
        } else if (sc.state == SCE_HPHP_VARIABLE) {
-               if (!IsAWordStart(sc.ch)) {
+               if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_DEFAULT);
                }
        } else if (sc.state == SCE_HPHP_OPERATOR) {
@@ -1822,7 +1865,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
                }
        }
        if (sc.state == SCE_HPHP_DEFAULT) {
-               if (IsAWordStart(sc.ch)) {
+               if (IsPhpWordStart(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_WORD);
                } else if (sc.ch == '#') {
                        sc.SetState(SCE_HPHP_COMMENTLINE);
@@ -1836,7 +1879,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
                        sc.SetState(SCE_HPHP_HSTRING);
                } else if (sc.ch == '\'') {
                        sc.SetState(SCE_HPHP_SIMPLESTRING);
-               } else if (sc.ch == '$') {
+               } else if (sc.ch == '$' && IsPhpWordStart(static_cast<char>(sc.chNext))) {
                        sc.SetState(SCE_HPHP_VARIABLE);
                } else if (isoperator(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_OPERATOR);
index cb150ff76deb3ac0eaf435785eced7fe939c81ff..9cd5433c89630299cb796c5b1c9b464464483b62 100644 (file)
@@ -98,7 +98,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                        if (isLispwordstart(ch)) {
                                styler.ColourTo(i - 1, state);
                                state = SCE_LISP_IDENTIFIER;
-                       } 
+                       }
                        else if (ch == ';') {
                                styler.ColourTo(i - 1, state);
                                state = SCE_LISP_COMMENT;
@@ -107,7 +107,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                                styler.ColourTo(i - 1, state);
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
                        }
-                       
+
                        else if (ch == '\"') {
                                        state = SCE_LISP_STRING;
                        }
@@ -115,12 +115,12 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                        if (!isLispwordstart(ch)) {
                                classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler);
                                state = SCE_LISP_DEFAULT;
-                       } /*else*/ 
+                       } /*else*/
                        if (isLispoperator(ch) || ch=='\'') {
                                styler.ColourTo(i - 1, state);
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
                        }
-                       
+
                } else {
                        if (state == SCE_LISP_COMMENT) {
                                if (atEOL) {
@@ -192,4 +192,9 @@ static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */,
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc);
+static const char * const lispWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);
index fc9607e25d24300256ea201cd1bf598f47151378..159bc1585d14f4347fd258c3114944a873613bb8 100644 (file)
@@ -23,8 +23,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#define SCE_LUA_LAST_STYLE     SCE_LUA_WORD6
-
 static inline bool IsAWordChar(const int ch) {
        return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
 }
@@ -61,14 +59,16 @@ static void ColouriseLuaDoc(
        WordList &keywords5 = *keywordlists[4];
        WordList &keywords6 = *keywordlists[5];
 
-       // Must initialize the literal string nesting level, if we are inside such a string.
+       int currentLine = styler.GetLine(startPos);
+       // Initialize the literal string [[ ... ]] nesting level, if we are inside such a string.
        int literalStringLevel = 0;
        if (initStyle == SCE_LUA_LITERALSTRING) {
-               literalStringLevel = 1;
+               literalStringLevel = styler.GetLineState(currentLine - 1);
        }
-       // We use states above the last one to indicate nesting level of literal strings
-       if (initStyle > SCE_LUA_LAST_STYLE) {
-               literalStringLevel = initStyle - SCE_LUA_LAST_STYLE + 1;
+       // Initialize the block comment --[[ ... ]] nesting level, if we are inside such a comment
+       int blockCommentLevel = 0;
+       if (initStyle == SCE_LUA_COMMENT) {
+               blockCommentLevel = styler.GetLineState(currentLine - 1);
        }
 
        // Do not leak onto next line
@@ -78,9 +78,28 @@ static void ColouriseLuaDoc(
 
        StyleContext sc(startPos, length, initStyle, styler);
        if (startPos == 0 && sc.ch == '#') {
+               // shbang line: # is a comment only if first char of the script
                sc.SetState(SCE_LUA_COMMENTLINE);
        }
        for (; sc.More(); sc.Forward()) {
+               if (sc.atLineEnd) {
+                       // Update the line state, so it can be seen by next line
+                       currentLine = styler.GetLine(sc.currentPos);
+                       switch (sc.state) {
+                       case SCE_LUA_LITERALSTRING:
+                               // Inside a literal string, we set the line state
+                               styler.SetLineState(currentLine, literalStringLevel);
+                               break;
+                       case SCE_LUA_COMMENT:   // Block comment
+                               // Inside a block comment, we set the line state
+                               styler.SetLineState(currentLine, blockCommentLevel);
+                               break;
+                       default:
+                               // Reset the line state
+                               styler.SetLineState(currentLine, 0);
+                               break;
+                       }
+               }
                if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {
                        // Prevent SCE_LUA_STRINGEOL from leaking back to previous line
                        sc.SetState(SCE_LUA_STRING);
@@ -88,7 +107,7 @@ static void ColouriseLuaDoc(
 
                // Handle string line continuation
                if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&
-                               sc.ch == '\\') {
+                       sc.ch == '\\') {
                        if (sc.chNext == '\n' || sc.chNext == '\r') {
                                sc.Forward();
                                if (sc.ch == '\r' && sc.chNext == '\n') {
@@ -154,22 +173,31 @@ static void ColouriseLuaDoc(
                                sc.ChangeState(SCE_LUA_STRINGEOL);
                                sc.ForwardSetState(SCE_LUA_DEFAULT);
                        }
-               } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state > SCE_LUA_LAST_STYLE) {
+               } else if (sc.state == SCE_LUA_LITERALSTRING) {
                        if (sc.Match('[', '[')) {
                                literalStringLevel++;
-                               sc.SetState(SCE_LUA_LAST_STYLE + literalStringLevel - 1);
+                               sc.Forward();
+                               sc.SetState(SCE_LUA_LITERALSTRING);
                        } else if (sc.Match(']', ']') && literalStringLevel > 0) {
                                literalStringLevel--;
                                sc.Forward();
                                if (literalStringLevel == 0) {
                                        sc.ForwardSetState(SCE_LUA_DEFAULT);
-                               } else if (literalStringLevel == 1) {
-                                       sc.ForwardSetState(SCE_LUA_LITERALSTRING);
-                               } else {
-                                       sc.ForwardSetState(SCE_LUA_LAST_STYLE + literalStringLevel - 1);
+                               }
+                       }
+               } else if (sc.state == SCE_LUA_COMMENT) {       // Lua 5.0's block comment
+                       if (sc.Match('[', '[')) {
+                               blockCommentLevel++;
+                               sc.Forward();
+                       } else if (sc.Match(']', ']') && blockCommentLevel > 0) {
+                               blockCommentLevel--;
+                               sc.Forward();
+                               if (blockCommentLevel == 0) {
+                                       sc.ForwardSetState(SCE_LUA_DEFAULT);
                                }
                        }
                }
+
                // Determine if a new state should be entered.
                if (sc.state == SCE_LUA_DEFAULT) {
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
@@ -184,12 +212,16 @@ static void ColouriseLuaDoc(
                                literalStringLevel = 1;
                                sc.SetState(SCE_LUA_LITERALSTRING);
                                sc.Forward();
+                       } else if (sc.Match("--[[")) {  // Lua 5.0's block comment
+                               blockCommentLevel = 1;
+                               sc.SetState(SCE_LUA_COMMENT);
+                               sc.Forward(3);
                        } else if (sc.Match('-', '-')) {
                                sc.SetState(SCE_LUA_COMMENTLINE);
                                sc.Forward();
-                       } else if (sc.Match('$') && sc.atLineStart) {
+                       } else if (sc.atLineStart && sc.Match('$')) {
                                sc.SetState(SCE_LUA_PREPROCESSOR);      // Obsolete since Lua 4.0, but still in old code
-                       }  else if (isLuaOperator(static_cast<char>(sc.ch))) {
+                       } else if (isLuaOperator(static_cast<char>(sc.ch))) {
                                sc.SetState(SCE_LUA_OPERATOR);
                        }
                }
@@ -197,7 +229,6 @@ static void ColouriseLuaDoc(
        sc.Complete();
 }
 
-
 static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
                        Accessor &styler) {
        unsigned int lengthDoc = startPos + length;
@@ -266,4 +297,14 @@ static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, W
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc);
+static const char * const luaWordListDesc[] = {
+       "Keywords",
+       "Basic functions",
+       "String & math functions",
+       "I/O & system facilities",
+       "XXX",
+       "XXX",
+       0
+};
+
+LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);
index f75d15c7ab99379b7185898a8a9f13afe7a94b72..5f4dff3b8e4661d83ceeb034ae2b457677bcca24 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LexMatlab.cxx
  ** Lexer for Matlab.
  ** Written by José Fonseca
- **/ 
+ **/
 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
@@ -165,4 +165,9 @@ static void FoldMatlabDoc(unsigned int startPos, int length, int,
        }
 }
 
-LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc);
+static const char * const matlabWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
index babb3a0d3771da2336bbc61dc70633f21ae11815..6d537c9b6c2294e3200158f56738a9e2e35b58df 100644 (file)
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+static bool Is0To9(char ch) {
+       return (ch >= '0') && (ch <= '9');
+}
+
+static bool Is1To9(char ch) {
+       return (ch >= '1') && (ch <= '9');
+}
+
 static inline bool AtEOL(Accessor &styler, unsigned int i) {
        return (styler[i] == '\n') ||
                ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
@@ -85,7 +93,7 @@ static void ColouriseBatchLine(
                while (offset < lengthLine) {
                        if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
                                styler.ColourTo(startLine + offset - 1, state);
-                               if (isdigit(lineBuffer[offset + 1])) {
+                               if (Is0To9(lineBuffer[offset + 1])) {
                                        styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
                                        offset += 2;
                                } else if (lineBuffer[offset + 1] == '%' &&
@@ -164,13 +172,17 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
                styler.ColourTo(endLine, SCE_DIFF_HEADER);
        } else if (0 == strncmp(lineBuffer, "+++ ", 3)) {
                styler.ColourTo(endLine, SCE_DIFF_HEADER);
-       } else if (0 == strncmp(lineBuffer, "***", 3)) {
+       } else if (0 == strncmp(lineBuffer, "====", 4)) {  // For p4's diff
+               styler.ColourTo(endLine, SCE_DIFF_HEADER);
+       } else if (0 == strncmp(lineBuffer, "***", 3)) {
+               styler.ColourTo(endLine, SCE_DIFF_HEADER);
+       } else if (0 == strncmp(lineBuffer, "? ", 2)) {    // For difflib
                styler.ColourTo(endLine, SCE_DIFF_HEADER);
        } else if (lineBuffer[0] == '@') {
                styler.ColourTo(endLine, SCE_DIFF_POSITION);
-       } else if (lineBuffer[0] == '-') {
+       } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
                styler.ColourTo(endLine, SCE_DIFF_DELETED);
-       } else if (lineBuffer[0] == '+') {
+       } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
                styler.ColourTo(endLine, SCE_DIFF_ADDED);
        } else if (lineBuffer[0] != ' ') {
                styler.ColourTo(endLine, SCE_DIFF_COMMENT);
@@ -264,7 +276,7 @@ static void ColouriseMakeLine(
     Accessor &styler) {
 
        unsigned int i = 0;
-        unsigned int lastNonSpace = 0;
+       int lastNonSpace = -1;
        unsigned int state = SCE_MAKE_DEFAULT;
        bool bSpecial = false;
        // Skip initial spaces
@@ -291,13 +303,15 @@ static void ColouriseMakeLine(
                        if (lineBuffer[i] == ':') {
                                // We should check that no colouring was made since the beginning of the line,
                                // to avoid colouring stuff like /OUT:file
-                               styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
+                               if (lastNonSpace >= 0)
+                                       styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
                                styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
                                styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
                                bSpecial = true;        // Only react to the first ':' of the line
                                state = SCE_MAKE_DEFAULT;
                        } else if (lineBuffer[i] == '=') {
-                               styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
+                               if (lastNonSpace >= 0)
+                                       styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
                                styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
                                styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
                                bSpecial = true;        // Only react to the first '=' of the line
@@ -337,12 +351,17 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[
        }
 }
 
+static bool strstart(char *haystack, char *needle) {
+       return strncmp(haystack, needle, strlen(needle)) == 0;
+}
+
 static void ColouriseErrorListLine(
     char *lineBuffer,
     unsigned int lengthLine,
     //         unsigned int startLine,
     unsigned int endPos,
     Accessor &styler) {
+       const int unRecognized = 99;
        if (lineBuffer[0] == '>') {
                // Command or return status
                styler.ColourTo(endPos, SCE_ERR_CMD);
@@ -359,10 +378,19 @@ static void ColouriseErrorListLine(
                styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION);
        } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
                styler.ColourTo(endPos, SCE_ERR_PYTHON);
-       } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) {
+       } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
+               styler.ColourTo(endPos, SCE_ERR_PHP);
+       } else if ((strstart(lineBuffer, "Error ") ||
+               strstart(lineBuffer, "Warning ")) &&
+               strstr(lineBuffer, " at (") &&
+               strstr(lineBuffer, ") : ") &&
+               (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
+               // Intel Fortran Compiler error/warning message
+               styler.ColourTo(endPos, SCE_ERR_IFC);
+       } else if (strstart(lineBuffer, "Error ")) {
                // Borland error message
                styler.ColourTo(endPos, SCE_ERR_BORLAND);
-       } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) {
+       } else if (strstart(lineBuffer, "Warning ")) {
                // Borland warning message
                styler.ColourTo(endPos, SCE_ERR_BORLAND);
        } else if (strstr(lineBuffer, "at line " ) &&
@@ -374,54 +402,87 @@ static void ColouriseErrorListLine(
        } else if (strstr(lineBuffer, " at " ) &&
                   (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
                   strstr(lineBuffer, " line ") &&
-                  (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine))) {
+                  (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
+                          (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
                // perl error message
                styler.ColourTo(endPos, SCE_ERR_PERL);
        } else if ((memcmp(lineBuffer, "   at ", 6) == 0) &&
                strstr(lineBuffer, ":line ")) {
                // A .NET traceback
                styler.ColourTo(endPos, SCE_ERR_NET);
+       } else if (strstart(lineBuffer, "Line ") &&
+               strstr(lineBuffer, ", file ")) {
+               // Essential Lahey Fortran error message
+               styler.ColourTo(endPos, SCE_ERR_ELF);
        } else {
-               // Look for <filename>:<line>:message
-               // Look for <filename>(line)message
-               // Look for <filename>(line,pos)message
+               // Look for GCC <filename>:<line>:message
+               // Look for Microsoft <filename>(line) :message
+               // Look for Microsoft <filename>(line,pos)message
+               // Look for CTags \tmessage
                int state = 0;
                for (unsigned int i = 0; i < lengthLine; i++) {
-                       if ((state == 0) && (lineBuffer[i] == ':') && isdigit(lineBuffer[i + 1])) {
-                               state = 1;
-                       } else if ((state == 0) && (lineBuffer[i] == '(')) {
-                               state = 10;
-                       } else if ((state == 0) && (lineBuffer[i] == '\t')) {
-                               state = 20;
-                       } else if ((state == 1) && isdigit(lineBuffer[i])) {
-                               state = 2;
-                       } else if ((state == 2) && (lineBuffer[i] == ':')) {
-                               state = 3;
-                               break;
-                       } else if ((state == 2) && !isdigit(lineBuffer[i])) {
-                               state = 99;
-                       } else if ((state == 10) && isdigit(lineBuffer[i])) {
-                               state = 11;
-                       } else if ((state == 11) && (lineBuffer[i] == ',')) {
-                               state = 14;
-                       } else if ((state == 11) && (lineBuffer[i] == ')')) {
-                               state = 12;
-                       } else if ((state == 12) && (lineBuffer[i] == ':')) {
-                               state = 13;
-                       } else if ((state == 14) && (lineBuffer[i] == ')')) {
-                               state = 15;
-                               break;
-                       } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) {
-                               state = 99;
-                       } else if ((state == 20) && (lineBuffer[i-1] == '\t') && 
-                               ((lineBuffer[i] == '/' && lineBuffer[i+1] == '^') || isdigit(lineBuffer[i]))) {
-                               state = 24;
-                               break;
-                       } else if ((state == 20) && ((lineBuffer[i] == '/') && (lineBuffer[i+1] == '^'))) {
-                               state = 21;
+                       char ch = lineBuffer[i];
+                       char chNext = ' ';
+                       if ((i+1) < lengthLine)
+                               chNext = lineBuffer[i+1];
+                       if (state == 0) {
+                               if (ch == ':') {
+                                       // May be GCC
+                                       if ((chNext != '\\') && (chNext != '/')) {
+                                               // This check is not completely accurate as may be on
+                                               // GTK+ with a file name that includes ':'.
+                                               state = 1;
+                                       }
+                               } else if ((ch == '(') && Is1To9(chNext)) {
+                                       // May be Microsoft
+                                       // Check againt '0' often removes phone numbers
+                                       state = 10;
+                               } else if (ch == '\t') {
+                                       // May be CTags
+                                       state = 20;
+                               }
+                       } else if (state == 1) {
+                               state = Is1To9(ch) ? 2 : unRecognized;
+                       } else if (state == 2) {
+                               if (ch == ':') {
+                                       state = 3;      // :9.*: is GCC
+                                       break;
+                               } else if (!Is0To9(ch)) {
+                                       state = unRecognized;
+                               }
+                       } else if (state == 10) {
+                               state = Is0To9(ch) ? 11 : unRecognized;
+                       } else if (state == 11) {
+                               if (ch == ',') {
+                                       state = 14;
+                               } else if (ch == ')') {
+                                       state = 12;
+                               } else if ((ch != ' ') && !Is0To9(ch)) {
+                                       state = unRecognized;
+                               }
+                       } else if (state == 12) {
+                               if ((ch == ' ') && (chNext == ':'))
+                                       state = 13;
+                               else
+                                       state = unRecognized;
+                       } else if (state == 14) {
+                               if (ch == ')') {
+                                       state = 15;
+                                       break;
+                               } else if ((ch != ' ') && !Is0To9(ch)) {
+                                       state = unRecognized;
+                               }
+                       } else if (state == 20) {
+                               if ((lineBuffer[i-1] == '\t') &&
+                                       ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) {
+                                       state = 24;
+                                       break;
+                               } else if ((ch == '/') && (lineBuffer[i+1] == '^')) {
+                                       state = 21;
+                               }
                        } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) {
                                state = 22;
-                               break;          
+                               break;
                        }
                }
                if (state == 3) {
@@ -429,7 +490,7 @@ static void ColouriseErrorListLine(
                } else if ((state == 13) || (state == 14) || (state == 15)) {
                        styler.ColourTo(endPos, SCE_ERR_MS);
                } else if (((state == 22) || (state == 24)) && (lineBuffer[0] != '\t')) {
-                       styler.ColourTo(endPos, SCE_ERR_CTAG);  
+                       styler.ColourTo(endPos, SCE_ERR_CTAG);
                } else {
                        styler.ColourTo(endPos, SCE_ERR_DEFAULT);
                }
@@ -553,12 +614,21 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
                        }
                }
        }
-       styler.ColourTo(lengthDoc, state);
+       styler.ColourTo(lengthDoc-1, state);
 }
 
-LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch");
-LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff");
-LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props");
-LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile");
-LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist");
-LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex");
+static const char * const batchWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+static const char * const emptyWordListDesc[] = {
+       0
+};
+
+LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
+LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", 0, emptyWordListDesc);
+LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", 0, emptyWordListDesc);
+LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
+LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
+LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
diff --git a/contrib/src/stc/scintilla/src/LexPOV.cxx b/contrib/src/stc/scintilla/src/LexPOV.cxx
new file mode 100644 (file)
index 0000000..1e44450
--- /dev/null
@@ -0,0 +1,222 @@
+// Scintilla source code edit control
+/** @file LexPOV.cxx
+ ** Lexer for POV-Ray, based on lexer for C++.
+ **/
+// Copyright 2003 by Steven te Brinke <steven.t.b@zonnet.nl>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#define KEYWORD_BOXHEADER 1
+#define KEYWORD_FOLDCONTRACTED 2
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsStateComment(const int state) {
+       return ((state == SCE_POV_COMMENT) ||
+               (state == SCE_POV_COMMENTLINE) ||
+               (state == SCE_POV_COMMENTDOC));
+}
+
+static inline bool IsStateString(const int state) {
+       return ((state == SCE_POV_STRING));
+}
+
+static void ColourisePOVDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+
+       WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+
+       // Do not leak onto next line
+       /*if (initStyle == SCE_POV_STRINGEOL)
+               initStyle = SCE_POV_DEFAULT;*/
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       bool caseSensitive = styler.GetPropertyInt("pov.case.sensitive", 1) != 0;
+
+       for (; sc.More(); sc.Forward()) {
+
+               /*if (sc.atLineStart && (sc.state == SCE_POV_STRING)) {
+                       // Prevent SCE_POV_STRINGEOL from leaking back to previous line
+                       sc.SetState(SCE_POV_STRING);
+               }*/
+
+               // Handle line continuation generically.
+               if (sc.ch == '\\') {
+                       if (sc.chNext == '\n' || sc.chNext == '\r') {
+                               sc.Forward();
+                               if (sc.ch == '\r' && sc.chNext == '\n') {
+                                       sc.Forward();
+                               }
+                               continue;
+                       }
+               }
+
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_POV_OPERATOR || sc.state == SCE_POV_BRACE) {
+                       sc.SetState(SCE_POV_DEFAULT);
+               } else if (sc.state == SCE_POV_NUMBER) {
+                       if (!IsADigit(sc.ch) || sc.ch != '.') {
+                               sc.SetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+                               char s[100];
+                               if (caseSensitive) {
+                                       sc.GetCurrent(s, sizeof(s));
+                               } else {
+                                       sc.GetCurrentLowered(s, sizeof(s));
+                               }
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_POV_WORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_POV_WORD2);
+                               }
+                               sc.SetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_COMMENT) {
+                       if (sc.Match('*', '/')) {
+                               sc.Forward();
+                               sc.ForwardSetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_COMMENTDOC) {
+                       if (sc.Match('*', '/')) {
+                               sc.Forward();
+                               sc.ForwardSetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_COMMENTLINE) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_STRING) {
+                       if (sc.ch == '\\') {
+                               if (sc.chNext == '\"' || sc.chNext == '\\') {
+                                       sc.Forward();
+                               }
+                       } else if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_POV_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_POV_DEFAULT) {
+                       if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_POV_NUMBER);
+                       } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
+                               sc.SetState(SCE_POV_IDENTIFIER);
+                       } else if (sc.Match('/', '*')) {
+                               sc.SetState(SCE_POV_COMMENT);
+                               sc.Forward();   // Eat the * so it isn't used for the end of the comment
+                       } else if (sc.Match('/', '/')) {
+                               sc.SetState(SCE_POV_COMMENTLINE);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_POV_STRING);
+                               //} else if (isoperator(static_cast<char>(sc.ch))) {
+                       } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
+                               sc.SetState(SCE_POV_OPERATOR);
+                       } else if (sc.ch == '{' || sc.ch == '}') {
+                               sc.SetState(SCE_POV_BRACE);
+                       }
+               }
+
+       }
+       sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+       return style == SCE_POV_COMMENT ||
+              style == SCE_POV_COMMENTDOC;
+}
+
+static void FoldNoBoxPOVDoc(unsigned int startPos, int length, int initStyle,
+                            Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment && IsStreamCommentStyle(style)) {
+                       if (!IsStreamCommentStyle(stylePrev)) {
+                               levelCurrent++;
+                       } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+                               // Comments don't end at end of line and the next character may be unstyled.
+                               levelCurrent--;
+                       }
+               }
+               if (style == SCE_POV_BRACE) {
+                       if (ch == '{') {
+                               levelCurrent++;
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static void FoldPOVDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+       FoldNoBoxPOVDoc(startPos, length, initStyle, styler);
+}
+
+static const char * const POVWordLists[] = {
+            "Primary keywords and identifiers",
+            "Secondary keywords and identifiers",
+            0,
+        };
+
+static void ColourisePOVDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                     Accessor &styler) {
+       ColourisePOVDoc(startPos, length, initStyle, keywordlists, styler);
+}
+
+LexerModule lmPOV(SCLEX_POV, ColourisePOVDocSensitive, "pov", FoldPOVDoc, POVWordLists);
index 37e5e995fb4164ee2009cf553edfbf47e34c6361..c3bea6773df0f57a15b27e6fc1c52f391a3a21aa 100644 (file)
@@ -34,7 +34,7 @@ static void getRange(unsigned int start,
 }
 
 static bool IsStreamCommentStyle(int style) {
-       return style == SCE_C_COMMENT || 
+       return style == SCE_C_COMMENT ||
                style == SCE_C_COMMENTDOC ||
                style == SCE_C_COMMENTDOCKEYWORD ||
                style == SCE_C_COMMENTDOCKEYWORDERROR;
@@ -50,7 +50,7 @@ static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &
 
        WordList& keywords = *keywordlists[0];
        WordList& classwords = *keywordlists[1];
-       
+
        char s[100];
        getRange(start, end, styler, s, sizeof(s));
 
@@ -119,7 +119,7 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle,
        styler.StartSegment(startPos);
        for (unsigned int i = startPos; i < lengthDoc; i++) {
                char ch = chNext;
-               
+
                chNext = styler.SafeGetCharAt(i + 1);
 
                if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
@@ -329,7 +329,7 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
                        levelPrev = levelCurrent;
                        visibleChars = 0;
                }
-               
+
                if (!isspacechar(ch))
                        visibleChars++;
        }
@@ -339,4 +339,10 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc);
+static const char * const pascalWordListDesc[] = {
+       "Keywords",
+       "Classwords",
+       0
+};
+
+LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc);
index 1715009c9d0d064a08f2bbd095e614d8e86902e5..211c3b8751e83e47db835eb76ec4c0f9fc53e5c7 100644 (file)
@@ -659,9 +659,64 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
        styler.ColourTo(lengthDoc - 1, state);
 }
 
+static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
+                            Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment && (style == SCE_PL_COMMENTLINE)) {
+                       if ((ch == '/') && (chNext == '/')) {
+                               char chNext2 = styler.SafeGetCharAt(i + 2);
+                               if (chNext2 == '{') {
+                                       levelCurrent++;
+                               } else if (chNext2 == '}') {
+                                       levelCurrent--;
+                               }
+                       }
+               }
+               if (style == SCE_C_OPERATOR) {
+                       if (ch == '{') {
+                               levelCurrent++;
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
 static const char * const perlWordListDesc[] = {
-       "Perl keywords",
+       "Keywords",
        0
 };
 
-LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", 0, perlWordListDesc);
+LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc);
index bfaa08f0e9daba30327b4f269832a9c0abdc5085..47974d1bced8911196416eb131c7334c0563e14f 100644 (file)
@@ -1,7 +1,7 @@
 // Scintilla source code edit control
 /** @file LexPython.cxx
  ** Lexer for Python.
- **/ 
+ **/
 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
@@ -42,7 +42,7 @@ static bool IsPyStringStart(int ch, int chNext, int chNext2) {
 }
 
 /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
-static int GetPyStringState(Accessor &styler, int i, int *nextIndex) {
+static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex) {
        char ch = styler.SafeGetCharAt(i);
        char chNext = styler.SafeGetCharAt(i + 1);
 
@@ -99,7 +99,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
        int lineCurrent = styler.GetLine(startPos);
        if (startPos > 0) {
                if (lineCurrent > 0) {
-                       startPos = styler.LineStart(lineCurrent - 1);
+                       lineCurrent--;
+                       startPos = styler.LineStart(lineCurrent);
                        if (startPos == 0)
                                initStyle = SCE_P_DEFAULT;
                        else
@@ -139,6 +140,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        } else if (whingeLevel == 4) {
                                chFlags = (spaceFlags & wsTab) ? chBad : chGood;
                        }
+                       sc.SetState(sc.state);
                        styler.SetFlags(chFlags, static_cast<char>(sc.state));
                }
 
@@ -148,7 +150,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                (sc.state == SCE_P_TRIPLEDOUBLE)) {
                                // Perform colourisation of white space and triple quoted strings at end of each line to allow
                                // tab marking to work inside white space and triple quoted strings
-                               sc.ForwardSetState(sc.state);
+                               sc.SetState(sc.state);
                        }
                        lineCurrent++;
                        styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
@@ -160,6 +162,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                break;
                }
 
+               bool needEOLCheck = false;
+
                // Check for a state end
                if (sc.state == SCE_P_OPERATOR) {
                        kwLast = kwOther;
@@ -212,8 +216,10 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                sc.Forward();
                        } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        }
                } else if (sc.state == SCE_P_TRIPLE) {
                        if (sc.ch == '\\') {
@@ -222,6 +228,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                sc.Forward();
                                sc.Forward();
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        }
                } else if (sc.state == SCE_P_TRIPLEDOUBLE) {
                        if (sc.ch == '\\') {
@@ -230,9 +237,18 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                sc.Forward();
                                sc.Forward();
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        }
                }
 
+               // State exit code may have moved on to end of line
+               if (needEOLCheck && sc.atLineEnd) {
+                       lineCurrent++;
+                       styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
+                       if (!sc.More())
+                               break;
+               }
+
                // Check for a new state starting character
                if (sc.state == SCE_P_DEFAULT) {
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
@@ -247,7 +263,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        } else if (sc.ch == '#') {
                                sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
                        } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2))) {
-                               int nextIndex = 0;
+                               unsigned int nextIndex = 0;
                                sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
                                while (nextIndex > (sc.currentPos + 1)) {
                                        sc.Forward();
@@ -357,34 +373,40 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
                        lev = lev + 1;
                }
 
-               // Skip past any blank lines for next indent level info; we skip also comments
-               // starting in column 0 which effectively folds them into surrounding code rather
+               // Skip past any blank lines for next indent level info; we skip also
+               // comments (all comments, not just those starting in column 0)
+               // which effectively folds them into surrounding code rather
                // than screwing up folding.
-               const int saveIndentNext = indentNext;
+
                while (!quote &&
                        (lineNext < docLines) &&
                        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
-                        (lineNext <= docLines && styler[styler.LineStart(lineNext)] == '#'))) {
+                        (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
 
                        lineNext++;
                        indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
                }
 
-               // Next compute max indent level of current line and next non-blank line.
-               // This is the level to which we set all the intervening blank or comment lines.
-               const int skip_level = Platform::Maximum(indentCurrentLevel,
-                                      indentNext & SC_FOLDLEVELNUMBERMASK);
+               const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+               const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
 
                // Now set all the indent levels on the lines we skipped
-               int skipLine = lineCurrent + 1;
-               int skipIndentNext = saveIndentNext;
-               while (skipLine < lineNext) {
-                       int skipLineLevel = skip_level;
-                       if (skipIndentNext & SC_FOLDLEVELWHITEFLAG)
-                               skipLineLevel = SC_FOLDLEVELWHITEFLAG | skipLineLevel;
-                       styler.SetLevel(skipLine, skipLineLevel);
-                       skipLine++;
-                       skipIndentNext = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+               // Do this from end to start.  Once we encounter one line
+               // which is indented more than the line after the end of
+               // the comment-block, use the level of the block before
+
+               int skipLine = lineNext;
+               int skipLevel = levelAfterComments;
+
+               while (--skipLine > lineCurrent) {
+                       int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+                       if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+                               skipLevel = levelBeforeComments;
+
+                       int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+                       styler.SetLevel(skipLine, skipLevel | whiteFlag);
                }
 
                // Set fold header on non-quote/non-comment line
@@ -409,9 +431,9 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 }
 
 static const char * const pythonWordListDesc[] = {
-       "Python keywords",
+       "Keywords",
        0
 };
 
-LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, 
+LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
                                         pythonWordListDesc);
index 35804e7107a3d4eccbc37771746af94dc5fdbdc0..43a874968d5f6c18aedccdff15ad9740a5326e20 100644 (file)
@@ -221,7 +221,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                        } else if (isoperator(ch)) {
                                styler.ColourTo(i - 1, state);
                                styler.ColourTo(i, SCE_P_OPERATOR);
-                       } 
+                       }
                        } else if (state == SCE_P_WORD) {
                        if (!iswordchar(ch)) {
                                ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
@@ -351,5 +351,10 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
                }
        }
 }
-                                                  
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc);
+
+static const char * const rubyWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
index 5af86d9f4acbbf0b3f1b1796e222a7e1beae81b1..0520c00ed6fcefb48dd7e6ce0ba71cfaae0b5788 100644 (file)
@@ -155,4 +155,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length,
        styler.ColourTo(lengthDoc - 1, state);
 }
 
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql");
+static const char * const sqlWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
index bd1248e044be8c76e90b559e821ceba9109ed6d1..72fdb9c3cf86c4699fb6f812614f2728f9f32261 100644 (file)
@@ -37,7 +37,7 @@ static inline bool IsAWordStart(const int ch) {
 }
 
 static inline bool IsADateCharacter(const int ch) {
-       return (ch < 0x80) && 
+       return (ch < 0x80) &&
                (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
 }
 
@@ -49,7 +49,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
        styler.StartAt(startPos);
 
        int visibleChars = 0;
-                                  
+
        StyleContext sc(startPos, length, initStyle, styler);
 
        for (; sc.More(); sc.Forward()) {
@@ -83,7 +83,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                                sc.SetState(SCE_B_DEFAULT);
                        }
                } else if (sc.state == SCE_B_STRING) {
-                       // VB doubles quotes to preserve them, so just end this string 
+                       // VB doubles quotes to preserve them, so just end this string
                        // state now as a following quote will start again
                        if (sc.ch == '\"') {
                                if (tolower(sc.chNext) == 'c') {
@@ -104,7 +104,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                                sc.ForwardSetState(SCE_B_DEFAULT);
                        }
                }
-               
+
                if (sc.state == SCE_B_DEFAULT) {
                        if (sc.ch == '\'') {
                                sc.SetState(SCE_B_COMMENT);
@@ -116,7 +116,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                        } else if (sc.ch == '#') {
                                int n = 1;
                                int chSeek = ' ';
-                               while (chSeek == ' ' || chSeek == '\t') {
+                               while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
                                        chSeek = sc.GetRelative(n);
                                        n++;
                                }
@@ -137,7 +137,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                                sc.SetState(SCE_B_OPERATOR);
                        }
                }
-               
+
                if (sc.atLineEnd) {
                        visibleChars = 0;
                }
@@ -200,6 +200,11 @@ static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyl
        ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
 }
 
-LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc);
-LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc);
+static const char * const vbWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
+LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);
 
index 009ea4ea50e869a30542dd1e6b1fa3278c522822..ec9c86f74f2f8c208fc03dd86b79895a2a8446b1 100644 (file)
@@ -2,14 +2,37 @@
 /** @file LineMarker.cxx
  ** Defines the look of a line marker in the margin .
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#include <string.h>
+
 #include "Platform.h"
 
 #include "Scintilla.h"
+#include "XPM.h"
 #include "LineMarker.h"
 
+void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
+       pal.WantFind(fore, want);
+       pal.WantFind(back, want);
+       if (pxpm) {
+               pxpm->RefreshColourPalette(pal, want);
+       }
+}
+
+void LineMarker::SetXPM(const char *textForm) {
+       delete pxpm;
+       pxpm = new XPM(textForm);
+       markType = SC_MARK_PIXMAP;
+}
+
+void LineMarker::SetXPM(const char * const *linesForm) {
+       delete pxpm;
+       pxpm = new XPM(linesForm);
+       markType = SC_MARK_PIXMAP;
+}
+
 static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
        PRectangle rc;
        rc.left = centreX - armSize;
@@ -41,6 +64,10 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
 }
 
 void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
+       if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
+               pxpm->Draw(surface, rcWhole);
+               return;
+       }
        // Restrict most shapes a bit
        PRectangle rc = rcWhole;
        rc.top++;
@@ -122,121 +149,121 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
                rcSmall.right = rc.right - 1;
                rcSmall.bottom = rc.bottom - 2;
                surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
-               
+
        } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
                // An invisible marker so don't draw anything
-               
+
        } else if (markType == SC_MARK_VLINE) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
        } else if (markType == SC_MARK_LCORNER) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rc.top + dimOn2);
                surface->LineTo(rc.right - 2, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_TCORNER) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rcWhole.bottom);
                surface->MoveTo(centreX, rc.top + dimOn2);
                surface->LineTo(rc.right - 2, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_LCORNERCURVE) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rc.top + dimOn2-3);
                surface->LineTo(centreX+3, rc.top + dimOn2);
                surface->LineTo(rc.right - 1, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_TCORNERCURVE) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rc.top + dimOn2-3);
                surface->LineTo(centreX+3, rc.top + dimOn2);
                surface->LineTo(rc.right - 1, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_BOXPLUS) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
        } else if (markType == SC_MARK_BOXPLUSCONNECTED) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType == SC_MARK_BOXMINUS) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
        } else if (markType == SC_MARK_BOXMINUSCONNECTED) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType == SC_MARK_CIRCLEPLUS) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
        } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType == SC_MARK_CIRCLEMINUS) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
        } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType >= SC_MARK_CHARACTER) {
                char character[1];
                character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
                int width = surface->WidthText(fontForCharacter, character, 1);
                rc.left += (rc.Width() - width) / 2;
                rc.right = rc.left + width;
-               surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, 
+               surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
                        character, 1, fore.allocated, back.allocated);
 
        } else if (markType == SC_MARK_DOTDOTDOT) {
index 7897aa7759355665b7f2992d6d34f964064e274b..ef5924f7511e1207fce82854915880125fef8125 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LineMarker.h
  ** Defines the look of a line marker in the margin .
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef LINEMARKER_H
@@ -15,11 +15,35 @@ public:
        int markType;
        ColourPair fore;
        ColourPair back;
+       XPM *pxpm;
        LineMarker() {
                markType = SC_MARK_CIRCLE;
                fore = ColourDesired(0,0,0);
                back = ColourDesired(0xff,0xff,0xff);
+               pxpm = NULL;
        }
+       LineMarker(const LineMarker &) {
+               // Defined to avoid pxpm being blindly copied, not as real copy constructor
+               markType = SC_MARK_CIRCLE;
+               fore = ColourDesired(0,0,0);
+               back = ColourDesired(0xff,0xff,0xff);
+               pxpm = NULL;
+       }
+       ~LineMarker() {
+               delete pxpm;
+       }
+       LineMarker &operator=(const LineMarker &) {
+               // Defined to avoid pxpm being blindly copied, not as real assignment operator
+               markType = SC_MARK_CIRCLE;
+               fore = ColourDesired(0,0,0);
+               back = ColourDesired(0xff,0xff,0xff);
+               delete pxpm;
+               pxpm = NULL;
+               return *this;
+       }
+       void RefreshColourPalette(Palette &pal, bool want);
+       void SetXPM(const char *textForm);
+       void SetXPM(const char * const *linesForm);
        void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
 };
 
index b527c385ce15f54beff0d2fb63a006dc2e0b2896..18544aef23c87b54b8e09c91b7edffa1944895b6 100644 (file)
@@ -2,14 +2,14 @@
 /** @file PropSet.cxx
  ** A Java style properties file module.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 // Maintain a dictionary of properties
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
+//#include <ctype.h>
 #include <stdio.h>
 
 #include "Platform.h"
@@ -30,6 +30,10 @@ static inline bool IsLetter(char ch) {
        return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
 }
 
+inline bool IsASpace(unsigned int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
 int CompareCaseInsensitive(const char *a, const char *b) {
        while (*a && *b) {
                if (*a != *b) {
@@ -98,13 +102,13 @@ void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
                lenVal = static_cast<int>(strlen(val));
        unsigned int hash = HashString(key, lenKey);
        for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-               if ((hash == p->hash) && 
-                       ((strlen(p->key) == static_cast<unsigned int>(lenKey)) && 
+               if ((hash == p->hash) &&
+                       ((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
                                (0 == strncmp(p->key, key, lenKey)))) {
                        // Replace current value
                        delete [](p->val);
                        p->val = StringDup(val, lenVal);
-                       return ;
+                       return;
                }
        }
        // Not found
@@ -119,7 +123,7 @@ void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
 }
 
 void PropSet::Set(const char *keyVal) {
-       while (isspace(*keyVal))
+       while (IsASpace(*keyVal))
                keyVal++;
        const char *endVal = keyVal;
        while (*endVal && (*endVal != '\n'))
@@ -181,7 +185,8 @@ SString PropSet::GetExpanded(const char *key) {
 SString PropSet::Expand(const char *withVars) {
        char *base = StringDup(withVars);
        char *cpvar = strstr(base, "$(");
-       while (cpvar) {
+       int maxExpands = 1000;  // Avoid infinite expansion of recursive definitions
+       while (cpvar && (maxExpands > 0)) {
                char *cpendvar = strchr(cpvar, ')');
                if (cpendvar) {
                        int lenvar = cpendvar - cpvar - 2;      // Subtract the $()
@@ -197,6 +202,7 @@ SString PropSet::Expand(const char *withVars) {
                        base = newbase;
                }
                cpvar = strstr(base, "$(");
+               maxExpands--;
        }
        SString sret = base;
        delete []base;
@@ -257,7 +263,7 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {
                                if (keyfile == NULL)
                                        keyfile = orgkeyfile;
 
-                               for (; ; ) {
+                               for (;;) {
                                        char *del = strchr(keyfile, ';');
                                        if (del == NULL)
                                                del = keyfile + strlen(keyfile);
@@ -300,7 +306,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {
 SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
        char *base = StringDup(GetWild(keybase, filename).c_str());
        char *cpvar = strstr(base, "$(");
-       while (cpvar) {
+       int maxExpands = 1000;  // Avoid infinite expansion of recursive definitions
+       while (cpvar && (maxExpands > 0)) {
                char *cpendvar = strchr(cpvar, ')');
                if (cpendvar) {
                        int lenvar = cpendvar - cpvar - 2;      // Subtract the $()
@@ -316,6 +323,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
                        base = newbase;
                }
                cpvar = strstr(base, "$(");
+               maxExpands--;
        }
        SString sret = base;
        delete []base;
@@ -328,9 +336,9 @@ void PropSet::Clear() {
                while (p) {
                        Property *pNext = p->next;
                        p->hash = 0;
-                       delete p->key;
+                       delete []p->key;
                        p->key = 0;
-                       delete p->val;
+                       delete []p->val;
                        p->val = 0;
                        delete p;
                        p = pNext;
@@ -626,7 +634,7 @@ static unsigned int LengthWord(const char *word, char otherSeparator) {
        if (endWord > word) {
                endWord--;      // Back from the '(', ':', or '\0'
                // Move backwards over any spaces
-               while ((endWord > word) && (isspace(*endWord))) {
+               while ((endWord > word) && (IsASpace(*endWord))) {
                        endWord--;
                }
        }
@@ -669,13 +677,13 @@ char *WordList::GetNearestWords(
                        if (!cond) {
                                // Find first match
                                while ((pivot > start) &&
-                                       (0 == CompareNCaseInsensitive(wordStart, 
+                                       (0 == CompareNCaseInsensitive(wordStart,
                                                wordsNoCase[pivot-1], searchLen))) {
                                        --pivot;
                                }
                                // Grab each match
                                while ((pivot <= end) &&
-                                       (0 == CompareNCaseInsensitive(wordStart, 
+                                       (0 == CompareNCaseInsensitive(wordStart,
                                                wordsNoCase[pivot], searchLen))) {
                                        wordlen = LengthWord(wordsNoCase[pivot], otherSeparator) + 1;
                                        wordsNear.append(wordsNoCase[pivot], wordlen, ' ');
@@ -695,14 +703,14 @@ char *WordList::GetNearestWords(
                        if (!cond) {
                                // Find first match
                                while ((pivot > start) &&
-                                       (0 == strncmp(wordStart, 
-                                               words[pivot-1], searchLen))) { 
+                                       (0 == strncmp(wordStart,
+                                               words[pivot-1], searchLen))) {
                                        --pivot;
                                }
                                // Grab each match
                                while ((pivot <= end) &&
-                                       (0 == strncmp(wordStart, 
-                                               words[pivot], searchLen))) { 
+                                       (0 == strncmp(wordStart,
+                                               words[pivot], searchLen))) {
                                        wordlen = LengthWord(words[pivot], otherSeparator) + 1;
                                        wordsNear.append(words[pivot], wordlen, ' ');
                                        ++pivot;
index f176bbf19e02107aac4100a5fc1492f5d4596343..656570a24b9b2309c765f7756eb1e07e8f4b0faa 100644 (file)
  *      Dept. of Computer Science
  *      York University
  *
- * Original code available from http://www.cs.yorku.ca/~oz/ 
+ * Original code available from http://www.cs.yorku.ca/~oz/
  * Translation to C++ by Neil Hodgson neilh@scintilla.org
  * Removed all use of register.
  * Converted to modern function prototypes.
- * Put all global/static variables into an object so this code can be 
+ * Put all global/static variables into an object so this code can be
  * used from multiple threads etc.
  *
  * These routines are the PUBLIC DOMAIN equivalents of regex
  * Modification history:
  *
  * $Log$
- * Revision 1.5  2002/09/11 00:55:27  RD
- * Update to Scintilla 1.48
+ * Revision 1.6  2003/04/19 19:59:49  RD
+ * Updated Scintilla to 1.52 (on the trunk this time too)
+ *
+ * Revision 1.9  2003/03/21 10:36:08  nyamatongwe
+ * Detect patterns too long in regular expression search.
+ *
+ * Revision 1.8  2003/03/04 10:53:59  nyamatongwe
+ * Patch from Jakub to optionally implement more POSIX compatible regular
+ * expressions. \(..\) changes to (..)
+ * Fixes problem where find previous would not find earlier matches on same
+ * line.
+ *
+ * Revision 1.8  2003/03/03 20:12:56  vrana
+ * Added posix syntax.
+ *
+ * Revision 1.7  2002/09/28 00:33:28  nyamatongwe
+ * Fixed problem with character ranges caused by expansion to 8 bits.
  *
  * Revision 1.6  2001/04/29 13:32:10  nyamatongwe
  * Addition of new target methods - versions of ReplaceTarget that take counted
  *
  * Revision 1.2  88/08/28  15:36:04  oz
  * Use a complement bitmap to represent NCL.
- * This removes the need to have seperate 
- * code in the PMatch case block - it is 
+ * This removes the need to have seperate
+ * code in the PMatch case block - it is
  * just CCL code now.
- * 
+ *
  * Use the actual CCL code in the CLO
  * section of PMatch. No need for a recursive
  * PMatch call.
- * 
+ *
  * Use a bitmap table to set char bits in an
  * 8-bit chunk.
- * 
+ *
  * Interfaces:
  *      RESearch::Compile:        compile a regular expression into a NFA.
  *
  *                     void re_fail(msg, op)
  *                     char *msg;
  *                     char op;
- *  
+ *
  * Regular Expressions:
  *
  *      [1]     char    matches itself, unless it is a special
  *
  *      [3]     \       matches the character following it, except
  *                     when followed by a left or right round bracket,
- *                     a digit 1 to 9 or a left or right angle bracket. 
+ *                     a digit 1 to 9 or a left or right angle bracket.
  *                     (see [7], [8] and [9])
- *                     It is used as an escape character for all 
+ *                     It is used as an escape character for all
  *                     other meta-characters, and itself. When used
  *                     in a set ([4]), it is treated as an ordinary
  *                     character.
  *
  *      [4]     [set]   matches one of the characters in the set.
  *                      If the first character in the set is "^",
- *                      it matches a character NOT in the set, i.e. 
- *                     complements the set. A shorthand S-E is 
- *                     used to specify a set of characters S upto 
- *                     E, inclusive. The special characters "]" and 
- *                     "-" have no special meaning if they appear 
+ *                      it matches a character NOT in the set, i.e.
+ *                     complements the set. A shorthand S-E is
+ *                     used to specify a set of characters S upto
+ *                     E, inclusive. The special characters "]" and
+ *                     "-" have no special meaning if they appear
  *                     as the first chars in the set.
  *                      examples:        match:
  *
  * Notes:
  *
  *     This implementation uses a bit-set representation for character
- *     classes for speed and compactness. Each character is represented 
- *     by one bit in a 128-bit block. Thus, CCL always takes a 
+ *     classes for speed and compactness. Each character is represented
+ *     by one bit in a 128-bit block. Thus, CCL always takes a
  *     constant 16 bytes in the internal nfa, and RESearch::Execute does a single
  *     bit comparison to locate the character in the set.
  *
  *     compile:        CHR f CHR o CLO CHR o END CLO ANY END END
  *     matches:        fo foo fooo foobar fobar foxx ...
  *
- *     pattern:        fo[ob]a[rz]     
+ *     pattern:        fo[ob]a[rz]
  *     compile:        CHR f CHR o CCL bitset CHR a CCL bitset END
  *     matches:        fobar fooar fobaz fooaz
  *
 const char bitarr[] = {1,2,4,8,16,32,64,'\200'};
 
 #define badpat(x)      (*nfa = END, x)
+
 RESearch::RESearch() {
        Init();
 }
@@ -332,10 +347,11 @@ const char escapeValue(char ch) {
        return 0;
 }
 
-const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
+const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) {
        char *mp=nfa;          /* nfa pointer       */
        char *lp;              /* saved pointer..   */
        char *sp=nfa;          /* another one..     */
+    char *mpMax = mp + MAXNFA - BITBLK - 10;
 
        int tagi = 0;          /* tag stack index   */
        int tagc = 1;          /* actual tag count  */
@@ -343,7 +359,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
        int n;
        char mask;              /* xor mask -CCL/NCL */
        int c1, c2;
-               
+
        if (!pat || !length)
                if (sta)
                        return 0;
@@ -353,6 +369,8 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
 
        const char *p=pat;               /* pattern pointer   */
        for (int i=0; i<length; i++, p++) {
+               if (mp > mpMax)
+                       return badpat("Pattern too long");
                lp = mp;
                switch(*p) {
 
@@ -383,7 +401,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
 
                        i++;
                        if (*++p == '^') {
-                               mask = '\377';  
+                               mask = '\377';
                                i++;
                                p++;
                        } else
@@ -427,7 +445,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
 
                        for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
                                *mp++ = static_cast<char>(mask ^ bittab[n]);
-       
+
                        break;
 
                case '*':               /* match 0 or more.. */
@@ -467,25 +485,6 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
                        i++;
                        switch(*++p) {
 
-                       case '(':
-                               if (tagc < MAXTAG) {
-                                       tagstk[++tagi] = tagc;
-                                       *mp++ = BOT;
-                                       *mp++ = static_cast<char>(tagc++);
-                               }
-                               else
-                                       return badpat("Too many \\(\\) pairs");
-                               break;
-                       case ')':
-                               if (*sp == BOT)
-                                       return badpat("Null pattern inside \\(\\)");
-                               if (tagi > 0) {
-                                       *mp++ = static_cast<char>(EOT);
-                                       *mp++ = static_cast<char>(tagstk[tagi--]);
-                               }
-                               else
-                                       return badpat("Unmatched \\)");
-                               break;
                        case '<':
                                *mp++ = BOW;
                                break;
@@ -524,13 +523,49 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
                                *mp++ = escapeValue(*p);
                                break;
                        default:
-                               *mp++ = CHR;
-                               *mp++ = *p;
+                               if (!posix && *p == '(') {
+                                       if (tagc < MAXTAG) {
+                                               tagstk[++tagi] = tagc;
+                                               *mp++ = BOT;
+                                               *mp++ = static_cast<char>(tagc++);
+                                       }
+                                       else
+                                               return badpat("Too many \\(\\) pairs");
+                               } else if (!posix && *p == ')') {
+                                       if (*sp == BOT)
+                                               return badpat("Null pattern inside \\(\\)");
+                                       if (tagi > 0) {
+                                               *mp++ = static_cast<char>(EOT);
+                                               *mp++ = static_cast<char>(tagstk[tagi--]);
+                                       }
+                                       else
+                                               return badpat("Unmatched \\)");
+                               } else {
+                                       *mp++ = CHR;
+                                       *mp++ = *p;
+                               }
                        }
                        break;
 
                default :               /* an ordinary char  */
-                       if (caseSensitive) {
+                       if (posix && *p == '(') {
+                               if (tagc < MAXTAG) {
+                                       tagstk[++tagi] = tagc;
+                                       *mp++ = BOT;
+                                       *mp++ = static_cast<char>(tagc++);
+                               }
+                               else
+                                       return badpat("Too many () pairs");
+                       } else if (posix && *p == ')') {
+                               if (*sp == BOT)
+                                       return badpat("Null pattern inside ()");
+                               if (tagi > 0) {
+                                       *mp++ = static_cast<char>(EOT);
+                                       *mp++ = static_cast<char>(tagstk[tagi--]);
+                               }
+                               else
+                                       return badpat("Unmatched )");
+                       } else if (caseSensitive) {
                                *mp++ = CHR;
                                *mp++ = *p;
                        } else {
@@ -545,7 +580,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
                sp = lp;
        }
        if (tagi > 0)
-               return badpat("Unmatched \\(");
+               return badpat((posix ? "Unmatched (" : "Unmatched \\("));
        *mp = END;
        sta = OKP;
        return 0;
@@ -555,7 +590,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
  * RESearch::Execute:
  *     execute nfa to find a match.
  *
- *     special cases: (nfa[0]) 
+ *     special cases: (nfa[0])
  *             BOL
  *                     Match only once, starting from the
  *                     beginning.
@@ -580,7 +615,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
 
        bol = lp;
        failure = 0;
-       
+
        Clear();
 
        switch(*ap) {
@@ -621,7 +656,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
        return 1;
 }
 
-/* 
+/*
  * PMatch: internal routine for the hard part
  *
  *     This code is partly snarfed from an early grep written by
@@ -647,7 +682,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
  *
  *     At the end of a successful match, bopat[n] and eopat[n]
  *     are set to the beginning and end of subpatterns matched
- *     by tagged expressions (n = 1 to 9).     
+ *     by tagged expressions (n = 1 to 9).
  *
  */
 
@@ -658,23 +693,23 @@ extern void re_fail(char *,char);
  * and EOW. the reason for not using ctype macros is that we can
  * let the user add into our own table. see RESearch::ModifyWord. This table
  * is not in the bitset form, since we may wish to extend it in the
- * future for other character classifications. 
+ * future for other character classifications.
  *
  *     TRUE for 0-9 A-Z a-z _
  */
 static char chrtyp[MAXCHR] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
-       0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+       0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 0, 0, 0, 0, 0
        };
 
@@ -688,7 +723,7 @@ static char chrtyp[MAXCHR] = {
 
 #define ANYSKIP        2       /* [CLO] ANY END ...         */
 #define CHRSKIP        3       /* [CLO] CHR chr END ...     */
-#define CCLSKIP 18     /* [CLO] CCL 16bytes END ... */
+#define CCLSKIP 34     /* [CLO] CCL 32bytes END ... */
 
 int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
        int op, c, n;
@@ -796,10 +831,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
  *     the compact bitset representation for the default table]
  */
 
-static char deftab[16] = {     
-       0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207',  
-       '\376', '\377', '\377', 007 
-}; 
+static char deftab[16] = {
+       0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207',
+       '\376', '\377', '\377', 007
+};
 
 void RESearch::ModifyWord(char *s) {
        int i;
@@ -846,7 +881,7 @@ int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) {
                                pin = c - '0';
                                break;
                        }
-                       
+
                default:
                        *dst++ = c;
                        continue;
index 28238bfb7c03ad20138bf54084ab5c5dbeb853ee..d676e0f3181b072260ba48b188c60a9c0c553ba7 100644 (file)
  * The following defines are not meant to be changeable.
  * They are for readability only.
  */
-#define MAXCHR 128
+#define MAXCHR 256
 #define CHRBIT 8
 #define BITBLK MAXCHR/CHRBIT
 
 class CharacterIndexer {
-public: 
+public:
        virtual char CharAt(int index)=0;
 };
 
@@ -32,7 +32,7 @@ public:
        bool GrabMatches(CharacterIndexer &ci);
        void ChSet(char c);
        void ChSetWithCase(char c, bool caseSensitive);
-       const char *Compile(const char *pat, int length, bool caseSensitive);
+       const char *Compile(const char *pat, int length, bool caseSensitive, bool posix);
        int Execute(CharacterIndexer &ci, int lp, int endp);
        void ModifyWord(char *s);
        int Substitute(CharacterIndexer &ci, char *src, char *dst);
index c8edb513bc3fdca89e6ef43f7341ee4a73f5ed13..9c3235d580f08e6c44edd76705e99dbb2f5bf124 100644 (file)
  */
 class SVector {
        enum { allocSize = 4000 };
-       
+
        int *v;                         ///< The vector
        unsigned int size;      ///< Number of elements allocated
        unsigned int len;       ///< Number of elements used in vector
        bool allocFailure;      ///< A memory allocation call has failed
-       
+
        /** Internally allocate more elements than the user wants
         * to avoid thrashing the memory allocator. */
        void SizeTo(int newSize) {
                if (newSize < allocSize)
                        newSize += allocSize;
-               else 
+               else
                        newSize = (newSize * 3) / 2;
                int* newv = new int[newSize];
                if (!newv) {
@@ -44,7 +44,7 @@ class SVector {
                delete []v;
                v = newv;
        }
-       
+
 public:
        SVector() {
                allocFailure = false;
index ab6e9a19b45e6c2620d041ca6fe04cd73770b262..ea2e2d1d6db9eef8e3a48ccc347a2ea13c6b3aa1 100644 (file)
@@ -2,7 +2,7 @@
 /** @file ScintillaBase.cxx
  ** An enhanced subclass of Editor with calltips, autocomplete and context menu.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -26,6 +26,7 @@
 #include "CallTip.h"
 #include "KeyMap.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
 #include "ViewStyle.h"
@@ -211,7 +212,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                        return;
                }
        }
-       ac.Start(wMain, idAutoComplete, currentPos, lenEntered);
+       ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode());
 
        PRectangle rcClient = GetClientRectangle();
        Point pt = LocationFromPosition(currentPos - lenEntered);
@@ -224,7 +225,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                pt = LocationFromPosition(currentPos);
        }
        PRectangle rcac;
-       rcac.left = pt.x - 5;
+       rcac.left = pt.x - ac.lb->CaretFromEdge();
        if (pt.y >= rcClient.bottom - heightLB &&  // Wont fit below.
                pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above.
                rcac.top = pt.y - heightLB;
@@ -237,19 +238,19 @@ 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[STYLE_DEFAULT].font);
-       ac.lb.SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth);
-       ac.lb.SetDoubleClickAction(AutoCompleteDoubleClick, this);
+       ac.lb->SetPositionRelative(rcac, wMain);
+       ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
+       ac.lb->SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth);
+       ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
 
        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.GetDesiredRect();
+       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.left = pt.x - ac.lb->CaretFromEdge();
        rcList.right = rcList.left + widthLB;
        if (((pt.y + vs.lineHeight) >= (rcClient.bottom - heightAlloced)) &&  // Wont fit below.
                ((pt.y + vs.lineHeight / 2) >= (rcClient.bottom + rcClient.top) / 2)) { // and there is more room above.
@@ -258,7 +259,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                rcList.top = pt.y + vs.lineHeight;
        }
        rcList.bottom = rcList.top + heightAlloced;
-       ac.lb.SetPositionRelative(rcList, wMain);
+       ac.lb->SetPositionRelative(rcList, wMain);
        ac.Show();
        if (lenEntered != 0) {
                AutoCompleteMoveToCurrentWord();
@@ -304,10 +305,11 @@ void ScintillaBase::AutoCompleteCharacterDeleted() {
 }
 
 void ScintillaBase::AutoCompleteCompleted() {
-       int item = ac.lb.GetSelection();
+       int item = ac.lb->GetSelection();
        char selected[1000];
+       selected[0] = '\0';
        if (item != -1) {
-               ac.lb.GetValue(item, selected, sizeof(selected));
+               ac.lb->GetValue(item, selected, sizeof(selected));
        }
        ac.Cancel();
 
@@ -343,6 +345,36 @@ void ScintillaBase::AutoCompleteCompleted() {
        pdoc->EndUndoAction();
 }
 
+void ScintillaBase::CallTipShow(Point pt, const char *defn) {
+       AutoCompleteCancel();
+       pt.y += vs.lineHeight;
+       PRectangle rc = ct.CallTipStart(currentPos, pt,
+                                                                       defn,
+                                                                       vs.styles[STYLE_DEFAULT].fontName,
+                                                                       vs.styles[STYLE_DEFAULT].sizeZoomed,
+                                                                       IsUnicodeMode(),
+                                                                       wMain);
+       // If the call-tip window would be out of the client
+       // space, adjust so it displays above the text.
+       PRectangle rcClient = GetClientRectangle();
+       if (rc.bottom > rcClient.bottom) {
+               int offset = vs.lineHeight + rc.Height();
+               rc.top -= offset;
+               rc.bottom -= offset;
+       }
+       // Now display the window.
+       CreateCallTipWindow(rc);
+       ct.wCallTip.SetPositionRelative(rc, wMain);
+       ct.wCallTip.Show();
+}
+
+void ScintillaBase::CallTipClick() {
+       SCNotification scn;
+       scn.nmhdr.code = SCN_CALLTIPCLICK;
+       scn.position = ct.clickPlace;
+       NotifyParent(scn);
+}
+
 void ScintillaBase::ContextMenu(Point pt) {
        if (displayPopupMenu) {
                bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
@@ -509,30 +541,24 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
        case SCI_AUTOCGETDROPRESTOFWORD:
                return ac.dropRestOfWord;
 
-       case SCI_CALLTIPSHOW: {
-                       AutoCompleteCancel();
-                       if (!ct.wCallTip.Created()) {
-                               Point pt = LocationFromPosition(wParam);
-                               pt.y += vs.lineHeight;
-                               PRectangle rc = ct.CallTipStart(currentPos, pt,
-                                                               reinterpret_cast<char *>(lParam),
-                                                               vs.styles[STYLE_DEFAULT].fontName,
-                                                               vs.styles[STYLE_DEFAULT].sizeZoomed,
-                                                                                               IsUnicodeMode());
-                               // If the call-tip window would be out of the client
-                               // space, adjust so it displays above the text.
-                               PRectangle rcClient = GetClientRectangle();
-                               if (rc.bottom > rcClient.bottom) {
-                                       int offset = vs.lineHeight + rc.Height();
-                                       rc.top -= offset;
-                                       rc.bottom -= offset;
-                               }
-                               // Now display the window.
-                               CreateCallTipWindow(rc);
-                               ct.wCallTip.SetPositionRelative(rc, wMain);
-                               ct.wCallTip.Show();
-                       }
-               }
+       case SCI_REGISTERIMAGE:
+               ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
+               break;
+
+       case SCI_CLEARREGISTEREDIMAGES:
+               ac.lb->ClearRegisteredImages();
+               break;
+
+       case SCI_AUTOCSETTYPESEPARATOR:
+               ac.SetTypesep(static_cast<char>(wParam));
+               break;
+
+       case SCI_AUTOCGETTYPESEPARATOR:
+               return ac.GetTypesep();
+
+       case SCI_CALLTIPSHOW:
+               CallTipShow(LocationFromPosition(wParam),
+                       reinterpret_cast<const char *>(lParam));
                break;
 
        case SCI_CALLTIPCANCEL:
@@ -554,6 +580,16 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
                InvalidateStyleRedraw();
                break;
 
+       case SCI_CALLTIPSETFORE:
+               ct.colourUnSel = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_CALLTIPSETFOREHLT:
+               ct.colourSel = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
        case SCI_USEPOPUP:
                displayPopupMenu = wParam != 0;
                break;
index e68aeb60841415ac4fb29da25d89b17a29eb0d92..bf0b92d57da6acee322f33c3b9f2c058a5ba1366 100644 (file)
@@ -43,7 +43,7 @@ protected:
        int lexLanguage;
        const LexerModule *lexCurrent;
        PropSet props;
-       enum {numWordLists=6};
+       enum {numWordLists=9};
        WordList *keyWordLists[numWordLists+1];
        void SetLexer(uptr_t wParam);
        void SetLexerLanguage(const char *languageName);
@@ -71,6 +71,8 @@ protected:
        void AutoCompleteMoveToCurrentWord();
        static void AutoCompleteDoubleClick(void* p);
 
+       void CallTipClick();
+       void CallTipShow(Point pt, const char *defn);
        virtual void CreateCallTipWindow(PRectangle rc) = 0;
 
        virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0;
index 2ee09f57d27745227b286be46e27675c7dfa81a1..40a8dba6a456b8a63433b9dd0796208f415e63bd 100644 (file)
@@ -16,13 +16,13 @@ Style::Style() {
        aliasOfDefaultFont = true;
        Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
              Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
-             false, false, false, false, caseMixed, true, true);
+             false, false, false, false, caseMixed, true, true, false);
 }
 
 Style::Style(const Style &source) {
        Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
              0, 0, 0,
-             false, false, false, false, caseMixed, true, true);
+             false, false, false, false, caseMixed, true, true, false);
        fore.desired = source.fore.desired;
        back.desired = source.back.desired;
        characterSet = source.characterSet;
@@ -34,6 +34,7 @@ Style::Style(const Style &source) {
        caseForce = source.caseForce;
        visible = source.visible;
        changeable = source.changeable;
+       hotspot = source.hotspot;
 }
 
 Style::~Style() {
@@ -49,7 +50,7 @@ Style &Style::operator=(const Style &source) {
                return * this;
        Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
              0, 0, SC_CHARSET_DEFAULT,
-             false, false, false, false, caseMixed, true, true);
+             false, false, false, false, caseMixed, true, true, false);
        fore.desired = source.fore.desired;
        back.desired = source.back.desired;
        characterSet = source.characterSet;
@@ -66,9 +67,9 @@ Style &Style::operator=(const Style &source) {
 
 void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
                   const char *fontName_, int characterSet_,
-                  bool bold_, bool italic_, bool eolFilled_, 
-                  bool underline_, ecaseForced caseForce_, 
-                 bool visible_, bool changeable_) {
+                  bool bold_, bool italic_, bool eolFilled_,
+                  bool underline_, ecaseForced caseForce_,
+                 bool visible_, bool changeable_, bool hotspot_) {
        fore.desired = fore_;
        back.desired = back_;
        characterSet = characterSet_;
@@ -81,6 +82,7 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
        caseForce = caseForce_;
        visible = visible_;
        changeable = changeable_;
+       hotspot = hotspot_;
        if (aliasOfDefaultFont)
                font.SetID(0);
        else
@@ -100,8 +102,9 @@ void Style::ClearTo(const Style &source) {
                source.eolFilled,
                source.underline,
                source.caseForce,
-               source.visible, 
-               source.changeable);
+               source.visible,
+               source.changeable,
+               source.hotspot);
 }
 
 bool Style::EquivalentFontTo(const Style *other) const {
index 63259b1a93b9edf6bfc41ea9995b81eebef5a75a..2f1e57586089f7dc1d6289caabe4d40cf7591861 100644 (file)
@@ -26,6 +26,7 @@ public:
        ecaseForced caseForce;
        bool visible;
        bool changeable;
+       bool hotspot;
 
        Font font;
        int sizeZoomed;
@@ -43,13 +44,13 @@ public:
        void Clear(ColourDesired fore_, ColourDesired back_,
                   int size_,
                   const char *fontName_, int characterSet_,
-                  bool bold_, bool italic_, bool eolFilled_, 
-                  bool underline_, ecaseForced caseForce_, 
-                  bool visible_, bool changeable_);
+                  bool bold_, bool italic_, bool eolFilled_,
+                  bool underline_, ecaseForced caseForce_,
+                  bool visible_, bool changeable_, bool hotspot_);
        void ClearTo(const Style &source);
        bool EquivalentFontTo(const Style *other) const;
        void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0);
-       bool IsProtected() { return !(changeable && visible);} ;
+       bool IsProtected() const { return !(changeable && visible);};
 };
 
 #endif
index bdae28196f57314bf3d420c157f54ca57ece689d..64fc7a048e0be5cc7d11a2e0dd679ec9d2a6ac5c 100644 (file)
@@ -29,7 +29,7 @@ static void getRange(unsigned int start,
        s[i] = '\0';
 }
 
-void StyleContext::GetCurrent(char *s, int len) {
+void StyleContext::GetCurrent(char *s, unsigned int len) {
        getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len);
 }
 
@@ -46,6 +46,6 @@ static void getRangeLowered(unsigned int start,
        s[i] = '\0';
 }
 
-void StyleContext::GetCurrentLowered(char *s, int len) {
+void StyleContext::GetCurrentLowered(char *s, unsigned int len) {
        getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
 }
index 4c9352916da7925aa4f3c7f4c968576cbeefdd4c..f2f8305c940b1dbc8e06c7d8dc5eea8c7f4b9b22 100644 (file)
@@ -2,21 +2,35 @@
 /** @file StyleContext.cxx
  ** Lexer infrastructure.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 // This file is in the public domain.
 
 // All languages handled so far can treat all characters >= 0x80 as one class
 // which just continues the current token or starts an identifier if in default.
-// DBCS treated specially as the second character can be < 0x80 and hence 
+// DBCS treated specially as the second character can be < 0x80 and hence
 // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
 class StyleContext {
        Accessor &styler;
-       int endPos;
+       unsigned int endPos;
        StyleContext& operator=(const StyleContext&) {
                return *this;
        }
+       void GetNextChar(unsigned int pos) {
+               chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
+               if (styler.IsLeadByte(static_cast<char>(chNext))) {
+                       chNext = chNext << 8;
+                       chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+               }
+               // End of line?
+               // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
+               // or on LF alone (Unix). Avoid triggering two times on Dos/Win.
+               atLineEnd = (ch == '\r' && chNext != '\n') ||
+                                       (ch == '\n') ||
+                                       (currentPos >= endPos);
+       }
+
 public:
-       int currentPos;
+       unsigned int currentPos;
        bool atLineStart;
        bool atLineEnd;
        int state;
@@ -24,32 +38,27 @@ public:
        int ch;
        int chNext;
 
-       StyleContext(unsigned int startPos, int length,
-                        int initStyle, Accessor &styler_, char chMask=31) : 
+       StyleContext(unsigned int startPos, unsigned int length,
+                        int initStyle, Accessor &styler_, char chMask=31) :
                styler(styler_),
                endPos(startPos + length),
-               currentPos(startPos), 
+               currentPos(startPos),
                atLineStart(true),
                atLineEnd(false),
-               state(initStyle), 
+               state(initStyle),
                chPrev(0),
-               ch(0), 
+               ch(0),
                chNext(0) {
                styler.StartAt(startPos, chMask);
                styler.StartSegment(startPos);
-               int pos = currentPos;
+               unsigned int pos = currentPos;
                ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
                if (styler.IsLeadByte(static_cast<char>(ch))) {
                        pos++;
                        ch = ch << 8;
                        ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
                }
-               chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
-               if (styler.IsLeadByte(static_cast<char>(chNext))) {
-                       chNext = chNext << 8;
-                       chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
-               }
-               atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos);
+               GetNextChar(pos);
        }
        void Complete() {
                styler.ColourTo(currentPos - 1, state);
@@ -60,21 +69,12 @@ public:
        void Forward() {
                if (currentPos < endPos) {
                        atLineStart = atLineEnd;
-                       // A lot of this is repeated from the constructor - TODO: merge code
                        chPrev = ch;
                        currentPos++;
                        if (ch >= 0x100)
                                currentPos++;
                        ch = chNext;
-                       chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+1));
-                       if (styler.IsLeadByte(static_cast<char>(chNext))) {
-                               chNext = chNext << 8;
-                               chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + 2));
-                       }
-                       // 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
-                       atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos);
+                       GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
                } else {
                        atLineStart = false;
                        chPrev = ' ';
@@ -83,6 +83,11 @@ public:
                        atLineEnd = true;
                }
        }
+       void Forward(int nb) {
+               for (int i = 0; i < nb; i++) {
+                       Forward();
+               }
+       }
        void ChangeState(int state_) {
                state = state_;
        }
@@ -136,8 +141,8 @@ public:
                return true;
        }
        // Non-inline
-       void GetCurrent(char *s, int len);
-       void GetCurrentLowered(char *s, int len);
+       void GetCurrent(char *s, unsigned int len);
+       void GetCurrentLowered(char *s, unsigned int len);
 };
 
 inline bool IsASpace(unsigned int ch) {
index 12e1406aa440db3930e2e8d1ae8f51f36b4b8bcc..eb8e54f2f8b3759d6acafc41111a1c47e6b0a231 100644 (file)
@@ -2,7 +2,7 @@
 /** @file ViewStyle.cxx
  ** Store information on how the document is to be viewed.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <string.h>
@@ -11,6 +11,7 @@
 
 #include "Scintilla.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
 #include "ViewStyle.h"
@@ -72,6 +73,18 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
        selbackset = source.selbackset;
        selbackground.desired = source.selbackground.desired;
        selbackground2.desired = source.selbackground2.desired;
+
+       foldmarginColourSet = source.foldmarginColourSet;
+       foldmarginColour.desired = source.foldmarginColour.desired;
+       foldmarginHighlightColourSet = source.foldmarginHighlightColourSet;
+       foldmarginHighlightColour.desired = source.foldmarginHighlightColour.desired;
+
+       hotspotForegroundSet = source.hotspotForegroundSet;
+       hotspotForeground.desired = source.hotspotForeground.desired;
+       hotspotBackgroundSet = source.hotspotBackgroundSet;
+       hotspotBackground.desired = source.hotspotBackground.desired;
+       hotspotUnderline = source.hotspotUnderline;
+
        whitespaceForegroundSet = source.whitespaceForegroundSet;
        whitespaceForeground.desired = source.whitespaceForeground.desired;
        whitespaceBackgroundSet = source.whitespaceBackgroundSet;
@@ -124,6 +137,12 @@ void ViewStyle::Init() {
        selbackset = true;
        selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0);
        selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0);
+
+       foldmarginColourSet = false;
+       foldmarginColour.desired = ColourDesired(0xff, 0, 0);
+       foldmarginHighlightColourSet = false;
+       foldmarginHighlightColour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+
        whitespaceForegroundSet = false;
        whitespaceForeground.desired = ColourDesired(0, 0, 0);
        whitespaceBackgroundSet = false;
@@ -138,6 +157,13 @@ void ViewStyle::Init() {
        edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
        edgeState = EDGE_NONE;
        caretWidth = 1;
+       someStylesProtected = false;
+
+       hotspotForegroundSet = false;
+       hotspotForeground.desired = ColourDesired(0, 0, 0xff);
+       hotspotBackgroundSet = false;
+       hotspotBackground.desired = ColourDesired(0xff, 0xff, 0xff);
+       hotspotUnderline = true;
 
        leftMarginWidth = 1;
        rightMarginWidth = 1;
@@ -148,9 +174,7 @@ void ViewStyle::Init() {
        ms[1].width = 16;
        ms[1].mask = ~SC_MASK_FOLDERS;
        ms[2].symbol = true;
-       ms[2].width = 14;       // Nice width for arrows
-       ms[2].mask = SC_MASK_FOLDERS;
-       ms[2].width = 0;        // Nice width for arrows
+       ms[2].width = 0;
        ms[2].mask = 0;
        fixedColumnWidth = leftMarginWidth;
        symbolMargin = false;
@@ -178,12 +202,15 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
                pal.WantFind(indicators[i].fore, want);
        }
        for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) {
-               pal.WantFind(markers[i].fore, want);
-               pal.WantFind(markers[i].back, want);
+               markers[i].RefreshColourPalette(pal, want);
        }
        pal.WantFind(selforeground, want);
        pal.WantFind(selbackground, want);
        pal.WantFind(selbackground2, want);
+
+       pal.WantFind(foldmarginColour, want);
+       pal.WantFind(foldmarginHighlightColour, want);
+
        pal.WantFind(whitespaceForeground, want);
        pal.WantFind(whitespaceBackground, want);
        pal.WantFind(selbar, want);
@@ -191,6 +218,8 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(caretcolour, want);
        pal.WantFind(caretLineBackground, want);
        pal.WantFind(edgecolour, want);
+       pal.WantFind(hotspotForeground, want);
+       pal.WantFind(hotspotBackground, want);
 }
 
 void ViewStyle::Refresh(Surface &surface) {
@@ -199,6 +228,7 @@ void ViewStyle::Refresh(Surface &surface) {
        styles[STYLE_DEFAULT].Realise(surface, zoomLevel);
        maxAscent = styles[STYLE_DEFAULT].ascent;
        maxDescent = styles[STYLE_DEFAULT].descent;
+       someStylesProtected = false;
        for (unsigned int i=0;i<(sizeof(styles)/sizeof(styles[0]));i++) {
                if (i != STYLE_DEFAULT) {
                        styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT]);
@@ -207,6 +237,9 @@ void ViewStyle::Refresh(Surface &surface) {
                        if (maxDescent < styles[i].descent)
                                maxDescent = styles[i].descent;
                }
+               if (styles[i].IsProtected()) {
+                       someStylesProtected = true;
+               }
        }
 
        lineHeight = maxAscent + maxDescent;
@@ -225,11 +258,11 @@ void ViewStyle::Refresh(Surface &surface) {
 }
 
 void ViewStyle::ResetDefaultStyle() {
-       styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), 
+       styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
                ColourDesired(0xff,0xff,0xff),
                Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
                SC_CHARSET_DEFAULT,
-               false, false, false, false, Style::caseMixed, true, true);
+               false, false, false, false, Style::caseMixed, true, true, false);
 }
 
 void ViewStyle::ClearStyles() {
@@ -245,3 +278,7 @@ void ViewStyle::ClearStyles() {
 void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
        styles[styleIndex].fontName = fontNames.Save(name);
 }
+
+bool ViewStyle::ProtectionActive() const {
+    return someStylesProtected;
+}
index 887170eaac1ee17685c9a17dc174965f9a6c4db6..ff38efef2eb5ca328d52bbf274d5942080963930 100644 (file)
@@ -59,6 +59,15 @@ public:
        ColourPair whitespaceBackground;
        ColourPair selbar;
        ColourPair selbarlight;
+       bool foldmarginColourSet;
+       ColourPair foldmarginColour;
+       bool foldmarginHighlightColourSet;
+       ColourPair foldmarginHighlightColour;
+       bool hotspotForegroundSet;
+       ColourPair hotspotForeground;
+       bool hotspotBackgroundSet;
+       ColourPair hotspotBackground;
+       bool hotspotUnderline;
        /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin
        enum { margins=3 };
        int leftMarginWidth;    ///< Spacing margin on left of text
@@ -78,7 +87,8 @@ public:
        ColourPair edgecolour;
        int edgeState;
        int caretWidth;
-       
+       bool someStylesProtected;
+
        ViewStyle();
        ViewStyle(const ViewStyle &source);
        ~ViewStyle();
@@ -88,6 +98,7 @@ public:
        void ResetDefaultStyle();
        void ClearStyles();
        void SetStyleFontName(int styleIndex, const char *name);
+       bool ProtectionActive() const;
 };
 
 #endif
index ce42534e7bffa52b588207e0dcd4ef38854102eb..d70ddf5c3472752facb5f2b4144f67f517e5f0f5 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h> 
+#include <ctype.h>
 #include <stdio.h>
 
 #include "Platform.h"
@@ -24,7 +24,7 @@ bool WindowAccessor::InternalIsLeadByte(char ch) {
        if (SC_CP_UTF8 == codePage)
                // For lexing, all characters >= 0x80 are treated the
                // same so none is considered a lead byte.
-               return false;   
+               return false;
        else
                return Platform::IsDBCSLeadByte(codePage, ch);
 }
@@ -71,10 +71,10 @@ int WindowAccessor::LevelAt(int line) {
        return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0);
 }
 
-int WindowAccessor::Length() { 
-       if (lenDoc == -1) 
+int WindowAccessor::Length() {
+       if (lenDoc == -1)
                lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0);
-       return lenDoc; 
+       return lenDoc;
 }
 
 int WindowAccessor::GetLineState(int line) {
@@ -125,7 +125,7 @@ void WindowAccessor::Flush() {
        startPos = extremePosition;
        lenDoc = -1;
        if (validLen > 0) {
-               Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen, 
+               Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
                        styleBuf);
                validLen = 0;
        }
@@ -134,12 +134,12 @@ void WindowAccessor::Flush() {
 int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
        int end = Length();
        int spaceFlags = 0;
-       
-       // Determines the indentation level of the current line and also checks for consistent 
+
+       // Determines the indentation level of the current line and also checks for consistent
        // indentation compared to the previous line.
-       // Indentation is judged consistent when the indentation whitespace of each line lines 
+       // Indentation is judged consistent when the indentation whitespace of each line lines
        // the same or the indentation of one line is a prefix of the other.
-       
+
        int pos = LineStart(line);
        char ch = (*this)[pos];
        int indent = 0;
@@ -166,7 +166,7 @@ int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsC
                }
                ch = (*this)[++pos];
        }
-       
+
        *flags = spaceFlags;
        indent += SC_FOLDLEVELBASE;
        // if completely empty line or the start of a comment...
diff --git a/contrib/src/stc/scintilla/src/XPM.cxx b/contrib/src/stc/scintilla/src/XPM.cxx
new file mode 100644 (file)
index 0000000..c4e4f88
--- /dev/null
@@ -0,0 +1,297 @@
+// Scintilla source code edit control
+/** @file XPM.cxx
+ ** Define a class that holds data in the X Pixmap (XPM) format,
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "Platform.h"
+
+#include "XPM.h"
+
+static const char *NextField(const char *s) {
+       while (*s && *s != ' ') {
+               s++;
+       }
+       while (*s && *s == ' ') {
+               s++;
+       }
+       return s;
+}
+
+// Data lines in XPM can be terminated either with NUL or "
+static size_t MeasureLength(const char *s) {
+       size_t i = 0;
+       while (s[i] && (s[i] != '\"'))
+               i++;
+       return i;
+}
+
+ColourAllocated XPM::ColourFromCode(int ch) {
+       return colourCodeTable[ch]->allocated;
+#ifdef SLOW
+       for (int i=0;i<nColours;i++) {
+               if (codes[i] == ch) {
+                       return colours[i].allocated;
+               }
+       }
+       return colours[0].allocated;
+#endif
+}
+
+void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
+       if ((code != codeTransparent) && (startX != x)) {
+               PRectangle rc(startX, y, x, y+1);
+               surface->FillRectangle(rc, ColourFromCode(code));
+       }
+}
+
+XPM::XPM(const char *textForm) :
+       data(0),        codes(0), colours(0), lines(0) {
+       Init(textForm);
+}
+
+XPM::XPM(const char * const *linesForm) :
+       data(0),        codes(0), colours(0), lines(0) {
+       Init(linesForm);
+}
+
+XPM::~XPM() {
+       Clear();
+}
+
+void XPM::Init(const char *textForm) {
+       Clear();
+       // Test done is two parts to avoid possibility of overstepping the memory
+       // if memcmp implemented strangely. Must be 4 bytes at least at destination.
+       if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
+               // Build the lines form out of the text form
+               const char **linesForm = LinesFormFromTextForm(textForm);
+               Init(linesForm);
+               delete []linesForm;
+       } else {
+               // It is really in line form
+               Init(reinterpret_cast<const char * const *>(textForm));
+       }
+}
+
+void XPM::Init(const char * const *linesForm) {
+       Clear();
+       height = 1;
+       width = 1;
+       nColours = 1;
+       data = NULL;
+       codeTransparent = ' ';
+       codes = NULL;
+       colours = NULL;
+       lines = NULL;
+       if (!linesForm)
+               return;
+
+       const char *line0 = linesForm[0];
+       width = atoi(line0);
+       line0 = NextField(line0);
+       height = atoi(line0);
+       line0 = NextField(line0);
+       nColours = atoi(line0);
+       codes = new char[nColours];
+       colours = new ColourPair[nColours];
+
+       int strings = 1+height+nColours;
+       lines = new char *[strings];
+       int allocation = 0;
+       for (int i=0; i<strings; i++) {
+               allocation += MeasureLength(linesForm[i]) + 1;
+       }
+       data = new char[allocation];
+       char *nextBit = data;
+       for (int j=0; j<strings; j++) {
+               lines[j] = nextBit;
+               size_t len = MeasureLength(linesForm[j]);
+               memcpy(nextBit, linesForm[j], len);
+               nextBit += len;
+               *nextBit++ = '\0';
+       }
+
+       for (int code=0;code<256; code++) {
+               colourCodeTable[code] = 0;
+       }
+
+       for (int c=0; c<nColours; c++) {
+               const char *colourDef = linesForm[c+1];
+               codes[c] = colourDef[0];
+               colourDef += 4;
+               if (*colourDef == '#') {
+                       colours[c].desired.Set(colourDef);
+               } else {
+                       colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
+                       codeTransparent = codes[c];
+               }
+               colourCodeTable[static_cast<unsigned char>(codes[c])] = &(colours[c]);
+       }
+}
+
+void XPM::Clear() {
+       delete []data;
+       data = 0;
+       delete []codes;
+       codes = 0;
+       delete []colours;
+       colours = 0;
+       delete []lines;
+       lines = 0;
+}
+
+void XPM::RefreshColourPalette(Palette &pal, bool want) {
+       if (!data || !codes || !colours || !lines) {
+               return;
+       }
+       for (int i=0;i<nColours;i++) {
+               pal.WantFind(colours[i], want);
+       }
+}
+
+void XPM::CopyDesiredColours() {
+       if (!data || !codes || !colours || !lines) {
+               return;
+       }
+       for (int i=0;i<nColours;i++) {
+               colours[i].Copy();
+       }
+}
+
+void XPM::Draw(Surface *surface, PRectangle &rc) {
+       if (!data || !codes || !colours || !lines) {
+               return;
+       }
+       // Centre the pixmap
+       int startY = rc.top + (rc.Height() - height) / 2;
+       int startX = rc.left + (rc.Width() - width) / 2;
+       for (int y=0;y<height;y++) {
+               int prevCode = 0;
+               int xStartRun = 0;
+               for (int x=0; x<width; x++) {
+                       int code = lines[y+nColours+1][x];
+                       if (code != prevCode) {
+                               FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x);
+                               xStartRun = x;
+                               prevCode = code;
+                       }
+               }
+               FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width);
+       }
+}
+
+const char **XPM::LinesFormFromTextForm(const char *textForm) {
+       // Build the lines form out of the text form
+       const char **linesForm = 0;
+       int countQuotes = 0;
+       int strings=1;
+       for (int j=0; countQuotes < (2*strings); j++) {
+               if (textForm[j] == '\"') {
+                       if (countQuotes == 0) {
+                               const char *line0 = textForm + j + 1;
+                               // Skip width
+                               line0 = NextField(line0);
+                               // Add 1 line for each pixel of height
+                               strings += atoi(line0);
+                               line0 = NextField(line0);
+                               // Add 1 line for each colour
+                               strings += atoi(line0);
+                               linesForm = new const char *[strings];
+                       }
+                       if (linesForm && ((countQuotes & 1) == 0)) {
+                               linesForm[countQuotes / 2] = textForm + j + 1;
+                       }
+                       countQuotes++;
+               }
+       }
+       return linesForm;
+}
+
+// In future, may want to minimize search time by sorting and using a binary search.
+
+XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
+}
+
+XPMSet::~XPMSet() {
+       Clear();
+}
+
+void XPMSet::Clear() {
+       for (int i=0;i<maximum;i++) {
+               delete set[i];
+       }
+       delete []set;
+       set = 0;
+       len = 0;
+       maximum = 0;
+       height = -1;
+       width = -1;
+}
+
+void XPMSet::Add(int id, const char *textForm) {
+       // Invalidate cached dimensions
+       height = -1;
+       width = -1;
+
+       // Replace if this id already present
+       for (int i=0;i<maximum;i++) {
+               if (set[i]->GetId() == id) {
+                       set[i]->Init(textForm);
+                       return;
+               }
+       }
+
+       // No present, so add to end
+       XPM *pxpm = new XPM(textForm);
+       if (pxpm) {
+               pxpm->SetId(id);
+               pxpm->CopyDesiredColours();
+               if (len == maximum) {
+                       int lenNew = len + 100;
+                       XPM **setNew = new XPM *[lenNew];
+                       for (int i=0; i<maximum; i++) {
+                               setNew[i] = set[i];
+                       }
+                       delete []set;
+                       set = setNew;
+               }
+               set[maximum] = pxpm;
+               maximum++;
+       }
+}
+
+XPM *XPMSet::Get(int id) {
+       for (int i=0;i<maximum;i++) {
+               if (set[i]->GetId() == id) {
+                       return set[i];
+               }
+       }
+       return 0;
+}
+
+int XPMSet::GetHeight() {
+       if (height < 0) {
+               for (int i=0; i<maximum; i++) {
+                       if (height < set[i]->GetHeight()) {
+                               height = set[i]->GetHeight();
+                       }
+               }
+       }
+       return (height > 0) ? height : 0;
+}
+
+int XPMSet::GetWidth() {
+       if (width < 0) {
+               for (int i=0; i<maximum; i++) {
+                       if (width < set[i]->GetWidth()) {
+                               width = set[i]->GetWidth();
+                       }
+               }
+       }
+       return (width > 0) ? width : 0;
+}
diff --git a/contrib/src/stc/scintilla/src/XPM.h b/contrib/src/stc/scintilla/src/XPM.h
new file mode 100644 (file)
index 0000000..948e557
--- /dev/null
@@ -0,0 +1,67 @@
+// Scintilla source code edit control
+/** @file XPM.h
+ ** Define a class that holds data in the X Pixmap (XPM) format,
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef XPM_H
+#define XPM_H
+
+/**
+ * Hold a pixmap in XPM format.
+ */
+class XPM {
+       int id;         // Assigned by container
+       int height;
+       int width;
+       int nColours;
+       char *data;
+       char codeTransparent;
+       char *codes;
+       ColourPair *colours;
+       ColourAllocated ColourFromCode(int ch);
+       void FillRun(Surface *surface, int code, int startX, int y, int x);
+       char **lines;
+       ColourPair *colourCodeTable[256];
+public:
+       XPM(const char *textForm);
+       XPM(const char * const *linesForm);
+       ~XPM();
+       void Init(const char *textForm);
+       void Init(const char * const *linesForm);
+       void Clear();
+       // Similar to same named method in ViewStyle:
+       void RefreshColourPalette(Palette &pal, bool want);
+       // No palette used, so just copy the desired colours to the allocated colours:
+       void CopyDesiredColours();
+       // Decompose image into runs and use FillRectangle for each run:
+       void Draw(Surface *surface, PRectangle &rc);
+       char **InLinesForm() { return lines; }
+       void SetId(int id_) { id = id_; }
+       int GetId() { return id; }
+       int GetHeight() { return height; }
+       int GetWidth() { return width; }
+       static const char **LinesFormFromTextForm(const char *textForm);
+};
+
+/**
+ * A collection of pixmaps indexed by integer id.
+ */
+class XPMSet {
+       XPM **set;
+       int len;
+       int maximum;
+       int height;
+       int width;
+public:
+       XPMSet();
+       ~XPMSet();
+       void Clear();
+       void Add(int id, const char *textForm);
+       XPM *Get(int id);
+       int GetHeight();
+       int GetWidth();
+};
+
+#endif
index 17cf6ee40604404f5468ea286be7eb5b62927cb6..c4a9d0c4e13027df6e96c10123eb1b6b193c0c6c 100644 (file)
 #include "wx/stc/stc.h"
 #include "ScintillaWX.h"
 
+#include <wx/wx.h>
 #include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
 
 
 //----------------------------------------------------------------------
@@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG )
 DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER )
 DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP )
 DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+
 
 
 BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
@@ -201,7 +208,7 @@ int wxStyledTextCtrl::GetLength() {
 
 // Returns the character byte at the position.
 int wxStyledTextCtrl::GetCharAt(int pos) {
-                       return (unsigned char)SendMsg(2007, pos, 0);
+         return (unsigned char)SendMsg(2007, pos, 0);
 }
 
 // Returns the position of the caret.
@@ -216,7 +223,7 @@ int wxStyledTextCtrl::GetAnchor() {
 
 // Returns the style byte at the position.
 int wxStyledTextCtrl::GetStyleAt(int pos) {
-                       return (unsigned char)SendMsg(2010, pos, 0);
+         return (unsigned char)SendMsg(2010, pos, 0);
 }
 
 // Redoes the next action on the undo history.
@@ -243,21 +250,21 @@ void wxStyledTextCtrl::SetSavePoint() {
 
 // Retrieve a buffer of cells.
 wxMemoryBuffer wxStyledTextCtrl::GetStyledText(int startPos, int endPos) {
-                          wxMemoryBuffer buf;
-                          if (endPos < startPos) {
-                              int temp = startPos;
-                              startPos = endPos;
-                              endPos = temp;
-                          }
-                          int len = endPos - startPos;
-                          if (!len) return buf;
-                          TextRange tr;
-                          tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
-                          tr.chrg.cpMin = startPos;
-                          tr.chrg.cpMax = endPos;
-                          len = SendMsg(2015, 0, (long)&tr);
-                          buf.UngetWriteBuf(len);
-                          return buf;
+        wxMemoryBuffer buf;
+        if (endPos < startPos) {
+            int temp = startPos;
+            startPos = endPos;
+            endPos = temp;
+        }
+        int len = endPos - startPos;
+        if (!len) return buf;
+        TextRange tr;
+        tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
+        tr.chrg.cpMin = startPos;
+        tr.chrg.cpMax = endPos;
+        len = SendMsg(2015, 0, (long)&tr);
+        buf.UngetWriteBuf(len);
+        return buf;
 }
 
 // Are there any redoable actions in the undo history?
@@ -293,7 +300,7 @@ void wxStyledTextCtrl::SetViewWhiteSpace(int viewWS) {
 
 // Find the position from a point within the window.
 int wxStyledTextCtrl::PositionFromPoint(wxPoint pt) {
-                              return SendMsg(2022, pt.x, pt.y);
+        return SendMsg(2022, pt.x, pt.y);
 }
 
 // Find the position from a point within the window but return
@@ -321,20 +328,20 @@ void wxStyledTextCtrl::SetAnchor(int posAnchor) {
 // Retrieve the text of the line containing the caret.
 // Returns the index of the caret on the line.
 wxString wxStyledTextCtrl::GetCurLine(int* linePos) {
-                       int len = LineLength(GetCurrentLine());
-                       if (!len) {
-                           if (linePos)  *linePos = 0;
-                           return wxEmptyString;
-                       }
+        int len = LineLength(GetCurrentLine());
+        if (!len) {
+            if (linePos)  *linePos = 0;
+            return wxEmptyString;
+        }
 
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
+        wxMemoryBuffer mbuf(len+1);
+        char* buf = (char*)mbuf.GetWriteBuf(len+1);
 
-                       int pos = SendMsg(2027, len+1, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       if (linePos)  *linePos = pos;
-                       return stc2wx(buf);
+        int pos = SendMsg(2027, len+1, (long)buf);
+        mbuf.UngetWriteBuf(len);
+        mbuf.AppendByte(0);
+        if (linePos)  *linePos = pos;
+        return stc2wx(buf);
 }
 
 // Retrieve the position of the last correctly styled character.
@@ -399,20 +406,20 @@ void wxStyledTextCtrl::SetCodePage(int codePage) {
     wxASSERT_MSG(codePage != wxSTC_CP_UTF8,
                  wxT("wxSTC_CP_UTF8 may not be used when wxUSE_UNICODE is off."));
 #endif
-                 SendMsg(2037, codePage);
+    SendMsg(2037, codePage);
 }
 
 // Set the symbol used for a particular marker number,
 // and optionally the fore and background colours.
 void wxStyledTextCtrl::MarkerDefine(int markerNumber, int markerSymbol,
-                            const wxColour& foreground,
-                            const wxColour& background) {
+                const wxColour& foreground,
+                const wxColour& background) {
 
-                            SendMsg(2040, markerNumber, markerSymbol);
-                            if (foreground.Ok())
-                                MarkerSetForeground(markerNumber, foreground);
-                            if (background.Ok())
-                                MarkerSetBackground(markerNumber, background);
+                SendMsg(2040, markerNumber, markerSymbol);
+                if (foreground.Ok())
+                    MarkerSetForeground(markerNumber, foreground);
+                if (background.Ok())
+                    MarkerSetBackground(markerNumber, background);
 }
 
 // Set the foreground colour used for a particular marker number.
@@ -455,6 +462,21 @@ int wxStyledTextCtrl::MarkerPrevious(int lineStart, int markerMask) {
     return SendMsg(2048, lineStart, markerMask);
 }
 
+// Define a marker from a bitmap
+void wxStyledTextCtrl::MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(2049, markerNumber, (long)buff);
+        delete [] buff;
+        
+}
+
 // Set a margin to be either numeric or symbolic.
 void wxStyledTextCtrl::SetMarginType(int margin, int marginType) {
     SendMsg(2240, margin, marginType);
@@ -555,6 +577,11 @@ void wxStyledTextCtrl::StyleSetCharacterSet(int style, int characterSet) {
     SendMsg(2066, style, characterSet);
 }
 
+// Set a style to be a hotspot or not.
+void wxStyledTextCtrl::StyleSetHotSpot(int style, bool hotspot) {
+    SendMsg(2409, style, hotspot);
+}
+
 // Set the foreground colour of the selection and whether to use this setting.
 void wxStyledTextCtrl::SetSelForeground(bool useSetting, const wxColour& fore) {
     SendMsg(2067, useSetting, wxColourAsLong(fore));
@@ -572,12 +599,12 @@ void wxStyledTextCtrl::SetCaretForeground(const wxColour& fore) {
 
 // When key+modifier combination km is pressed perform msg.
 void wxStyledTextCtrl::CmdKeyAssign(int key, int modifiers, int cmd) {
-                          SendMsg(2070, MAKELONG(key, modifiers), cmd);
+         SendMsg(2070, MAKELONG(key, modifiers), cmd);
 }
 
 // When key+modifier combination km do nothing.
 void wxStyledTextCtrl::CmdKeyClear(int key, int modifiers) {
-                          SendMsg(2071, MAKELONG(key, modifiers));
+         SendMsg(2071, MAKELONG(key, modifiers));
 }
 
 // Drop all key mappings.
@@ -587,7 +614,7 @@ void wxStyledTextCtrl::CmdKeyClearAll() {
 
 // Set the styles for a segment of the document.
 void wxStyledTextCtrl::SetStyleBytes(int length, char* styleBytes) {
-                          SendMsg(2073, length, (long)styleBytes);
+        SendMsg(2073, length, (long)styleBytes);
 }
 
 // Set a style to be visible or not.
@@ -818,6 +845,37 @@ bool wxStyledTextCtrl::AutoCompGetDropRestOfWord() {
     return SendMsg(2271, 0, 0) != 0;
 }
 
+// Register an image for use in autocompletion lists.
+void wxStyledTextCtrl::RegisterImage(int type, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(2405, type, (long)buff);
+        delete [] buff;
+     
+}
+
+// Clear all the registered images.
+void wxStyledTextCtrl::ClearRegisteredImages() {
+    SendMsg(2408, 0, 0);
+}
+
+// Retrieve the auto-completion list type-separator character.
+int wxStyledTextCtrl::AutoCompGetTypeSeparator() {
+    return SendMsg(2285, 0, 0);
+}
+
+// Change the type-separator character in the string setting up an auto-completion list.
+// Default is '?' but can be changed if items contain '?'.
+void wxStyledTextCtrl::AutoCompSetTypeSeparator(int separatorCharacter) {
+    SendMsg(2286, separatorCharacter, 0);
+}
+
 // Set the number of spaces used for one level of indentation.
 void wxStyledTextCtrl::SetIndent(int indentSize) {
     SendMsg(2122, indentSize, 0);
@@ -958,64 +1016,64 @@ int wxStyledTextCtrl::GetPrintColourMode() {
 
 // Find some text in the document.
 int wxStyledTextCtrl::FindText(int minPos, int maxPos,
-                            const wxString& text,
-                            int flags) {
-                     TextToFind  ft;
-                     ft.chrg.cpMin = minPos;
-                     ft.chrg.cpMax = maxPos;
-                     wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                     ft.lpstrText = (char*)(const char*)buf;
+               const wxString& text,
+               int flags) {
+            TextToFind  ft;
+            ft.chrg.cpMin = minPos;
+            ft.chrg.cpMax = maxPos;
+            wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+            ft.lpstrText = (char*)(const char*)buf;
 
-                     return SendMsg(2150, flags, (long)&ft);
+            return SendMsg(2150, flags, (long)&ft);
 }
 
 // On Windows, will draw the document into a display context such as a printer.
  int wxStyledTextCtrl::FormatRange(bool   doDraw,
-                                int    startPos,
-                                int    endPos,
-                                wxDC*  draw,
-                                wxDC*  target,  // Why does it use two? Can they be the same?
-                                wxRect renderRect,
-                                wxRect pageRect) {
-                            RangeToFormat fr;
-
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            fr.hdc = draw;
-                            fr.hdcTarget = target;
-                            fr.rc.top = renderRect.GetTop();
-                            fr.rc.left = renderRect.GetLeft();
-                            fr.rc.right = renderRect.GetRight();
-                            fr.rc.bottom = renderRect.GetBottom();
-                            fr.rcPage.top = pageRect.GetTop();
-                            fr.rcPage.left = pageRect.GetLeft();
-                            fr.rcPage.right = pageRect.GetRight();
-                            fr.rcPage.bottom = pageRect.GetBottom();
-                            fr.chrg.cpMin = startPos;
-                            fr.chrg.cpMax = endPos;
-
-                            return SendMsg(2151, doDraw, (long)&fr);
-}
-
-// Retrieve the line at the top of the display.
+                int    startPos,
+                int    endPos,
+                wxDC*  draw,
+                wxDC*  target,  // Why does it use two? Can they be the same?
+                wxRect renderRect,
+                wxRect pageRect) {
+             RangeToFormat fr;
+
+             if (endPos < startPos) {
+                 int temp = startPos;
+                 startPos = endPos;
+                 endPos = temp;
+             }
+             fr.hdc = draw;
+             fr.hdcTarget = target;
+             fr.rc.top = renderRect.GetTop();
+             fr.rc.left = renderRect.GetLeft();
+             fr.rc.right = renderRect.GetRight();
+             fr.rc.bottom = renderRect.GetBottom();
+             fr.rcPage.top = pageRect.GetTop();
+             fr.rcPage.left = pageRect.GetLeft();
+             fr.rcPage.right = pageRect.GetRight();
+             fr.rcPage.bottom = pageRect.GetBottom();
+             fr.chrg.cpMin = startPos;
+             fr.chrg.cpMax = endPos;
+
+             return SendMsg(2151, doDraw, (long)&fr);
+}
+
+// Retrieve the display line at the top of the display.
 int wxStyledTextCtrl::GetFirstVisibleLine() {
     return SendMsg(2152, 0, 0);
 }
 
 // Retrieve the contents of a line.
 wxString wxStyledTextCtrl::GetLine(int line) {
-                       int len = LineLength(line);
-                       if (!len) return wxEmptyString;
+         int len = LineLength(line);
+         if (!len) return wxEmptyString;
 
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                       SendMsg(2153, line, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       return stc2wx(buf);
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(2153, line, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Returns the number of lines in the document. There is always at least one.
@@ -1055,40 +1113,40 @@ void wxStyledTextCtrl::SetSelection(int start, int end) {
 
 // Retrieve the selected text.
 wxString wxStyledTextCtrl::GetSelectedText() {
-                            int   start;
-                            int   end;
+         int   start;
+         int   end;
 
-                            GetSelection(&start, &end);
-                            int   len  = end - start;
-                            if (!len) return wxEmptyString;
+         GetSelection(&start, &end);
+         int   len  = end - start;
+         if (!len) return wxEmptyString;
 
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                            SendMsg(2161, 0, (long)buf);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(2161, 0, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Retrieve a range of text.
 wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) {
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            int   len  = endPos - startPos;
-                            if (!len) return wxEmptyString;
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len);
-                            TextRange tr;
-                            tr.lpstrText = buf;
-                            tr.chrg.cpMin = startPos;
-                            tr.chrg.cpMax = endPos;
-                            SendMsg(2162, 0, (long)&tr);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);
+         if (endPos < startPos) {
+             int temp = startPos;
+             startPos = endPos;
+             endPos = temp;
+         }
+         int   len  = endPos - startPos;
+         if (!len) return wxEmptyString;
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len);
+         TextRange tr;
+         tr.lpstrText = buf;
+         tr.chrg.cpMin = startPos;
+         tr.chrg.cpMax = endPos;
+         SendMsg(2162, 0, (long)&tr);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Draw the selection in normal style or with selection highlighted.
@@ -1173,13 +1231,13 @@ void wxStyledTextCtrl::SetText(const wxString& text) {
 
 // Retrieve all the text in the document.
 wxString wxStyledTextCtrl::GetText() {
-                        int len  = GetTextLength();
-                        wxMemoryBuffer mbuf(len+1);   // leave room for the null...
-                        char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                        SendMsg(2182, len+1, (long)buf);
-                        mbuf.UngetWriteBuf(len);
-                        mbuf.AppendByte(0);
-                        return stc2wx(buf);
+         int len  = GetTextLength();
+         wxMemoryBuffer mbuf(len+1);   // leave room for the null...
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(2182, len+1, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Retrieve the number of characters in the document.
@@ -1233,9 +1291,9 @@ int wxStyledTextCtrl::GetTargetEnd() {
 // Text is counted so it can contain nulls.
 // Returns the length of the replacement text.
 
-                       int wxStyledTextCtrl::ReplaceTarget(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(2194, strlen(buf), (long)(const char*)buf);
+     int wxStyledTextCtrl::ReplaceTarget(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(2194, strlen(buf), (long)(const char*)buf);
 }
 
 // Replace the target text with the argument text after \d processing.
@@ -1245,18 +1303,18 @@ int wxStyledTextCtrl::GetTargetEnd() {
 // Returns the length of the replacement text including any change
 // caused by processing the \d patterns.
 
-                       int wxStyledTextCtrl::ReplaceTargetRE(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(2195, strlen(buf), (long)(const char*)buf);
+     int wxStyledTextCtrl::ReplaceTargetRE(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(2195, strlen(buf), (long)(const char*)buf);
 }
 
 // Search for a counted string in the target and set the target to the found
 // range. Text is counted so it can contain nulls.
 // Returns length of range or -1 for failure in which case target is not moved.
 
-                       int wxStyledTextCtrl::SearchInTarget(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(2197, strlen(buf), (long)(const char*)buf);
+     int wxStyledTextCtrl::SearchInTarget(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(2197, strlen(buf), (long)(const char*)buf);
 }
 
 // Set the search flags used by SearchInTarget.
@@ -1299,6 +1357,16 @@ void wxStyledTextCtrl::CallTipSetBackground(const wxColour& back) {
     SendMsg(2205, wxColourAsLong(back), 0);
 }
 
+// Set the foreground colour for the call tip.
+void wxStyledTextCtrl::CallTipSetForeground(const wxColour& fore) {
+    SendMsg(2206, wxColourAsLong(fore), 0);
+}
+
+// Set the foreground colour for the highlighted part of the call tip.
+void wxStyledTextCtrl::CallTipSetForegroundHighlight(const wxColour& fore) {
+    SendMsg(2207, wxColourAsLong(fore), 0);
+}
+
 // Find the display line of a document line taking hidden lines into account.
 int wxStyledTextCtrl::VisibleFromDocLine(int line) {
     return SendMsg(2220, line, 0);
@@ -1366,7 +1434,7 @@ void wxStyledTextCtrl::EnsureVisible(int line) {
     SendMsg(2232, line, 0);
 }
 
-// Set some debugging options for folding.
+// Set some style options for folding.
 void wxStyledTextCtrl::SetFoldFlags(int flags) {
     SendMsg(2233, flags, 0);
 }
@@ -1472,6 +1540,61 @@ int wxStyledTextCtrl::TextHeight(int line) {
     return SendMsg(2279, line, 0);
 }
 
+// Show or hide the vertical scroll bar.
+void wxStyledTextCtrl::SetUseVerticalScrollBar(bool show) {
+    SendMsg(2280, show, 0);
+}
+
+// Is the vertical scroll bar visible?
+bool wxStyledTextCtrl::GetUseVerticalScrollBar() {
+    return SendMsg(2281, 0, 0) != 0;
+}
+
+// Append a string to the end of the document without changing the selection.
+void wxStyledTextCtrl::AppendText(int length, const wxString& text) {
+    SendMsg(2282, length, (long)(const char*)wx2stc(text));
+}
+
+// Is drawing done in two phases with backgrounds drawn before foregrounds?
+bool wxStyledTextCtrl::GetTwoPhaseDraw() {
+    return SendMsg(2283, 0, 0) != 0;
+}
+
+// In twoPhaseDraw mode, drawing is performed in two phases, first the background
+// and then the foreground. This avoids chopping off characters that overlap the next run.
+void wxStyledTextCtrl::SetTwoPhaseDraw(bool twoPhase) {
+    SendMsg(2284, twoPhase, 0);
+}
+
+// Make the target range start and end be the same as the selection range start and end.
+void wxStyledTextCtrl::TargetFromSelection() {
+    SendMsg(2287, 0, 0);
+}
+
+// Join the lines in the target.
+void wxStyledTextCtrl::LinesJoin() {
+    SendMsg(2288, 0, 0);
+}
+
+// Split the lines in the target into lines that are less wide than pixelWidth
+// where possible.
+void wxStyledTextCtrl::LinesSplit(int pixelWidth) {
+    SendMsg(2289, pixelWidth, 0);
+}
+
+// Set the colours used as a chequerboard pattern in the fold margin
+void wxStyledTextCtrl::SetFoldMarginColour(bool useSetting, const wxColour& back) {
+    SendMsg(2290, useSetting, wxColourAsLong(back));
+}
+void wxStyledTextCtrl::SetFoldMarginHiColour(bool useSetting, const wxColour& fore) {
+    SendMsg(2291, useSetting, wxColourAsLong(fore));
+}
+
+// Duplicate the current line.
+void wxStyledTextCtrl::LineDuplicate() {
+    SendMsg(2404, 0, 0);
+}
+
 // Move caret to first position on display line.
 void wxStyledTextCtrl::HomeDisplay() {
     SendMsg(2345, 0, 0);
@@ -1531,12 +1654,12 @@ void wxStyledTextCtrl::SetViewEOL(bool visible) {
 
 // Retrieve a pointer to the document object.
 void* wxStyledTextCtrl::GetDocPointer() {
-                           return (void*)SendMsg(2357);
+         return (void*)SendMsg(2357);
 }
 
 // Change the document object used.
 void wxStyledTextCtrl::SetDocPointer(void* docPointer) {
-                           SendMsg(2358, 0, (long)docPointer);
+         SendMsg(2358, 0, (long)docPointer);
 }
 
 // Set which document modification events are sent to the container.
@@ -1624,17 +1747,17 @@ int wxStyledTextCtrl::GetZoom() {
 // Create a new document object.
 // Starts with reference count of 1 and not selected into editor.
 void* wxStyledTextCtrl::CreateDocument() {
-                           return (void*)SendMsg(2375);
+         return (void*)SendMsg(2375);
 }
 
 // Extend life of document.
 void wxStyledTextCtrl::AddRefDocument(void* docPointer) {
-                           SendMsg(2376, 0, (long)docPointer);
+         SendMsg(2376, 0, (long)docPointer);
 }
 
 // Release a reference to the document, deleting document if it fades to black.
 void wxStyledTextCtrl::ReleaseDocument(void* docPointer) {
-                           SendMsg(2377, 0, (long)docPointer);
+         SendMsg(2377, 0, (long)docPointer);
 }
 
 // Get which document modification events are sent to the container.
@@ -1739,6 +1862,11 @@ int wxStyledTextCtrl::GetXOffset() {
     return SendMsg(2398, 0, 0);
 }
 
+// Set the last x chosen value to be the caret x position
+void wxStyledTextCtrl::ChooseCaretX() {
+    SendMsg(2399, 0, 0);
+}
+
 // Set the way the caret is kept visible when going sideway.
 // The exclusion zone is given in pixels.
 void wxStyledTextCtrl::SetXCaretPolicy(int caretPolicy, int caretSlop) {
@@ -1751,6 +1879,31 @@ void wxStyledTextCtrl::SetYCaretPolicy(int caretPolicy, int caretSlop) {
     SendMsg(2403, caretPolicy, caretSlop);
 }
 
+// Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).
+void wxStyledTextCtrl::SetPrintWrapMode(int mode) {
+    SendMsg(2406, mode, 0);
+}
+
+// Is printing line wrapped.
+int wxStyledTextCtrl::GetPrintWrapMode() {
+    return SendMsg(2407, 0, 0);
+}
+
+// Set a fore colour for active hotspots.
+void wxStyledTextCtrl::SetHotspotActiveForeground(bool useSetting, const wxColour& fore) {
+    SendMsg(2410, useSetting, wxColourAsLong(fore));
+}
+
+// Set a back colour for active hotspots.
+void wxStyledTextCtrl::SetHotspotActiveBackground(bool useSetting, const wxColour& back) {
+    SendMsg(2411, useSetting, wxColourAsLong(back));
+}
+
+// Enable / Disable underlining active hotspots.
+void wxStyledTextCtrl::SetHotspotActiveUnderline(bool underline) {
+    SendMsg(2412, underline, 0);
+}
+
 // Start notifying the container of all key presses and commands.
 void wxStyledTextCtrl::StartRecord() {
     SendMsg(3001, 0, 0);
@@ -1928,9 +2081,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) {
 
 void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) {
     wxPaintDC dc(this);
-    wxRegion  region = GetUpdateRegion();
-
-    m_swx->DoPaint(&dc, region.GetBox());
+    m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
 }
 
 void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
@@ -2196,6 +2347,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
         evt.SetEventType(wxEVT_STC_ZOOM);
         break;
 
+    case SCN_HOTSPOTCLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK);
+        break;
+
+    case SCN_HOTSPOTDOUBLECLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK);
+        break;
+
+    case SCN_CALLTIPCLICK:
+        evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
+        break;
+
     default:
         return;
     }
index 0ab9afdc5e1390ed9d460243356de8630e84ac50..66434747989357d29e48838b585aff223876d947 100644 (file)
 #include "wx/stc/stc.h"
 #include "ScintillaWX.h"
 
+#include <wx/wx.h>
 #include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
 
 
 //----------------------------------------------------------------------
@@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG )
 DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER )
 DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP )
 DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+
 
 
 BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
@@ -306,9 +313,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) {
 
 void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) {
     wxPaintDC dc(this);
-    wxRegion  region = GetUpdateRegion();
-
-    m_swx->DoPaint(&dc, region.GetBox());
+    m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
 }
 
 void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
@@ -574,6 +579,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
         evt.SetEventType(wxEVT_STC_ZOOM);
         break;
 
+    case SCN_HOTSPOTCLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK);
+        break;
+
+    case SCN_HOTSPOTDOUBLECLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK);
+        break;
+
+    case SCN_CALLTIPCLICK:
+        evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
+        break;
+
     default:
         return;
     }
index 7a54289b2c8147c1bce9f594b24087a0ea7ee3c9..baeaf0d437f4b2d890740316668fe2e6ad9504f4 100644 (file)
@@ -225,11 +225,11 @@ private:
     void NotifyChange();
     void NotifyParent(SCNotification* scn);
 
-
-private:
     DECLARE_EVENT_TABLE()
     DECLARE_CLASS(wxStyledTextCtrl)
 
+protected:
+
     ScintillaWX*        m_swx;
     wxStopWatch         m_stopWatch;
     wxScrollBar*        m_vScrollBar;
@@ -348,6 +348,8 @@ private:
 #endif
 };
 
+
+
 #ifndef SWIG
 BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE,                  1650)
@@ -373,6 +375,9 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER,               1670)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP,                 1671)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM,                    1672)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK,           1673)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK,          1674)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK,           1675)
 END_DECLARE_EVENT_TYPES()
 #else
     enum {
@@ -399,6 +404,9 @@ END_DECLARE_EVENT_TYPES()
         wxEVT_STC_DRAG_OVER,
         wxEVT_STC_DO_DROP,
         wxEVT_STC_ZOOM,
+        wxEVT_STC_HOTSPOT_CLICK,
+        wxEVT_STC_HOTSPOT_DCLICK,
+        wxEVT_STC_CALLTIP_CLICK
     };
 #endif
 
@@ -430,6 +438,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&);
 #define EVT_STC_DRAG_OVER(id, fn)               DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER,             id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_DO_DROP(id, fn)                 DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP,               id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_ZOOM(id, fn)                    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM,                  id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_CLICK(id, fn)           DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK,         id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_DCLICK(id, fn)          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK,        id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_CALLTIP_CLICK(id, fn))          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK          id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+
 #endif
 
 //----------------------------------------------------------------------
index 096949085a8d66a873fb1eaddee11d5fad045afa..41e36f3e8b3dacb4147c06589acb6ccb8c73c96e 100644 (file)
@@ -77,6 +77,9 @@
 // The SC_CP_UTF8 value can be used to enter Unicode mode.
 // This is the same value as CP_UTF8 in Windows
 #define wxSTC_CP_UTF8 65001
+
+// The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+#define wxSTC_CP_DBCS 1
 #define wxSTC_MARKER_MAX 31
 #define wxSTC_MARK_CIRCLE 0
 #define wxSTC_MARK_ROUNDRECT 1
 #define wxSTC_MARK_BACKGROUND 22
 #define wxSTC_MARK_DOTDOTDOT 23
 #define wxSTC_MARK_ARROWS 24
+#define wxSTC_MARK_PIXMAP 25
 #define wxSTC_MARK_CHARACTER 10000
 
 // Markers used for outlining column.
 #define wxSTC_FIND_MATCHCASE 4
 #define wxSTC_FIND_WORDSTART 0x00100000
 #define wxSTC_FIND_REGEXP 0x00200000
+#define wxSTC_FIND_POSIX 0x00400000
 #define wxSTC_FOLDLEVELBASE 0x400
 #define wxSTC_FOLDLEVELWHITEFLAG 0x1000
 #define wxSTC_FOLDLEVELHEADERFLAG 0x2000
+#define wxSTC_FOLDLEVELBOXHEADERFLAG 0x4000
+#define wxSTC_FOLDLEVELBOXFOOTERFLAG 0x8000
+#define wxSTC_FOLDLEVELCONTRACTED 0x10000
+#define wxSTC_FOLDLEVELUNINDENT 0x20000
 #define wxSTC_FOLDLEVELNUMBERMASK 0x0FFF
+#define wxSTC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002
+#define wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004
+#define wxSTC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
+#define wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
+#define wxSTC_FOLDFLAG_LEVELNUMBERS 0x0040
+#define wxSTC_FOLDFLAG_BOX 0x0001
 #define wxSTC_TIME_FOREVER 10000000
 #define wxSTC_WRAP_NONE 0
 #define wxSTC_WRAP_WORD 1
 #define wxSTC_EDGE_LINE 1
 #define wxSTC_EDGE_BACKGROUND 2
 #define wxSTC_CURSORNORMAL -1
-#define wxSTC_CURSORWAIT 3
+#define wxSTC_CURSORWAIT 4
 
 // Constants for use with SetVisiblePolicy, similar to SetCaretPolicy.
 #define wxSTC_VISIBLE_SLOP 0x01
 #define wxSTC_LEX_BAAN 31
 #define wxSTC_LEX_MATLAB 32
 #define wxSTC_LEX_SCRIPTOL 33
+#define wxSTC_LEX_ASM 34
+#define wxSTC_LEX_CPPNOCASE 35
+#define wxSTC_LEX_FORTRAN 36
+#define wxSTC_LEX_F77 37
+#define wxSTC_LEX_CSS 38
+#define wxSTC_LEX_POV 39
 
 // When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 // value assigned in sequence from SCLEX_AUTOMATIC+1.
 #define wxSTC_ERR_DIFF_ADDITION 11
 #define wxSTC_ERR_DIFF_DELETION 12
 #define wxSTC_ERR_DIFF_MESSAGE 13
+#define wxSTC_ERR_PHP 14
+#define wxSTC_ERR_ELF 15
+#define wxSTC_ERR_IFC 16
 
 // Lexical states for SCLEX_BATCH
 #define wxSTC_BAT_DEFAULT 0
 #define wxSTC_AVE_COMMENT 1
 #define wxSTC_AVE_NUMBER 2
 #define wxSTC_AVE_WORD 3
-#define wxSTC_AVE_KEYWORD 4
-#define wxSTC_AVE_STATEMENT 5
 #define wxSTC_AVE_STRING 6
 #define wxSTC_AVE_ENUM 7
 #define wxSTC_AVE_STRINGEOL 8
 #define wxSTC_AVE_IDENTIFIER 9
 #define wxSTC_AVE_OPERATOR 10
+#define wxSTC_AVE_WORD1 11
+#define wxSTC_AVE_WORD2 12
+#define wxSTC_AVE_WORD3 13
+#define wxSTC_AVE_WORD4 14
+#define wxSTC_AVE_WORD5 15
+#define wxSTC_AVE_WORD6 16
 
 // Lexical states for SCLEX_ADA
 #define wxSTC_ADA_DEFAULT 0
-#define wxSTC_ADA_COMMENT 1
-#define wxSTC_ADA_NUMBER 2
-#define wxSTC_ADA_WORD 3
-#define wxSTC_ADA_STRING 4
+#define wxSTC_ADA_WORD 1
+#define wxSTC_ADA_IDENTIFIER 2
+#define wxSTC_ADA_NUMBER 3
+#define wxSTC_ADA_DELIMITER 4
 #define wxSTC_ADA_CHARACTER 5
-#define wxSTC_ADA_OPERATOR 6
-#define wxSTC_ADA_IDENTIFIER 7
+#define wxSTC_ADA_CHARACTEREOL 6
+#define wxSTC_ADA_STRING 7
 #define wxSTC_ADA_STRINGEOL 8
+#define wxSTC_ADA_LABEL 9
+#define wxSTC_ADA_COMMENTLINE 10
+#define wxSTC_ADA_ILLEGAL 11
 
 // Lexical states for SCLEX_BAAN
 #define wxSTC_BAAN_DEFAULT 0
 #define wxSTC_SCRIPTOL_COMMENTDOCKEYWORDERROR 18
 #define wxSTC_SCRIPTOL_COMMENTBASIC 19
 
+// Lexical states for SCLEX_ASM
+#define wxSTC_ASM_DEFAULT 0
+#define wxSTC_ASM_COMMENT 1
+#define wxSTC_ASM_NUMBER 2
+#define wxSTC_ASM_STRING 3
+#define wxSTC_ASM_OPERATOR 4
+#define wxSTC_ASM_IDENTIFIER 5
+#define wxSTC_ASM_CPUINSTRUCTION 6
+#define wxSTC_ASM_MATHINSTRUCTION 7
+#define wxSTC_ASM_REGISTER 8
+#define wxSTC_ASM_DIRECTIVE 9
+#define wxSTC_ASM_DIRECTIVEOPERAND 10
+
+// Lexical states for SCLEX_FORTRAN
+#define wxSTC_F_DEFAULT 0
+#define wxSTC_F_COMMENT 1
+#define wxSTC_F_NUMBER 2
+#define wxSTC_F_STRING1 3
+#define wxSTC_F_STRING2 4
+#define wxSTC_F_STRINGEOL 5
+#define wxSTC_F_OPERATOR 6
+#define wxSTC_F_IDENTIFIER 7
+#define wxSTC_F_WORD 8
+#define wxSTC_F_WORD2 9
+#define wxSTC_F_WORD3 10
+#define wxSTC_F_PREPROCESSOR 11
+#define wxSTC_F_OPERATOR2 12
+#define wxSTC_F_LABEL 13
+#define wxSTC_F_CONTINUATION 14
+
+// Lexical states for SCLEX_CSS
+#define wxSTC_CSS_DEFAULT 0
+#define wxSTC_CSS_TAG 1
+#define wxSTC_CSS_CLASS 2
+#define wxSTC_CSS_PSEUDOCLASS 3
+#define wxSTC_CSS_UNKNOWN_PSEUDOCLASS 4
+#define wxSTC_CSS_OPERATOR 5
+#define wxSTC_CSS_IDENTIFIER 6
+#define wxSTC_CSS_UNKNOWN_IDENTIFIER 7
+#define wxSTC_CSS_VALUE 8
+#define wxSTC_CSS_COMMENT 9
+#define wxSTC_CSS_ID 10
+#define wxSTC_CSS_IMPORTANT 11
+#define wxSTC_CSS_DIRECTIVE 12
+#define wxSTC_CSS_DOUBLESTRING 13
+#define wxSTC_CSS_SINGLESTRING 14
+
+// Lexical states for SCLEX_POV
+#define wxSTC_POV_DEFAULT 0
+#define wxSTC_POV_COMMENT 1
+#define wxSTC_POV_COMMENTLINE 2
+#define wxSTC_POV_COMMENTDOC 3
+#define wxSTC_POV_NUMBER 4
+#define wxSTC_POV_WORD 5
+#define wxSTC_POV_STRING 6
+#define wxSTC_POV_OPERATOR 7
+#define wxSTC_POV_IDENTIFIER 8
+#define wxSTC_POV_BRACE 9
+#define wxSTC_POV_WORD2 10
+
 
 //-----------------------------------------
 // Commands that can be bound to keystrokes
 // Switch the current line with the previous.
 #define wxSTC_CMD_LINETRANSPOSE 2339
 
+// Duplicate the current line.
+#define wxSTC_CMD_LINEDUPLICATE 2404
+
 // Transform the selection to lower case.
 #define wxSTC_CMD_LOWERCASE 2340
 
 // caret position.
 #define wxSTC_CMD_LINEENDDISPLAYEXTEND 2348
 
+// These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)?
+// except they behave differently when word-wrap is enabled:
+// They go first to the start / end of the display line, like (Home|LineEnd)Display
+// The difference is that, the cursor is already at the point, it goes on to the start
+// or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend.
+#define wxSTC_CMD_HOMEWRAP 2349
+#define wxSTC_CMD_HOMEWRAPEXTEND 2450
+#define wxSTC_CMD_LINEENDWRAP 2451
+#define wxSTC_CMD_LINEENDWRAPEXTEND 2452
+#define wxSTC_CMD_VCHOMEWRAP 2453
+#define wxSTC_CMD_VCHOMEWRAPEXTEND 2454
+
 // Move to the previous change in capitalisation.
 #define wxSTC_CMD_WORDPARTLEFT 2390
 
 // Delete forwards from the current position to the end of the line.
 #define wxSTC_CMD_DELLINERIGHT 2396
 
+// Move caret between paragraphs (delimited by empty lines)
+#define wxSTC_CMD_PARADOWN 2413
+#define wxSTC_CMD_PARADOWNEXTEND 2414
+#define wxSTC_CMD_PARAUP 2415
+#define wxSTC_CMD_PARAUPEXTEND 2416
+
 
 // END of generated section
 //----------------------------------------------------------------------
@@ -1091,8 +1203,8 @@ public:
     // Set the symbol used for a particular marker number,
     // and optionally the fore and background colours.
     void MarkerDefine(int markerNumber, int markerSymbol,
-                         const wxColour& foreground = wxNullColour,
-                         const wxColour& background = wxNullColour);
+                const wxColour& foreground = wxNullColour,
+                const wxColour& background = wxNullColour);
 
     // Set the foreground colour used for a particular marker number.
     void MarkerSetForeground(int markerNumber, const wxColour& fore);
@@ -1118,6 +1230,9 @@ public:
     // Find the previous line before lineStart that includes a marker in mask.
     int MarkerPrevious(int lineStart, int markerMask);
 
+    // Define a marker from a bitmap
+    void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp);
+
     // Set a margin to be either numeric or symbolic.
     void SetMarginType(int margin, int marginType);
 
@@ -1178,6 +1293,9 @@ public:
     // Set the character set of the font in a style.
     void StyleSetCharacterSet(int style, int characterSet);
 
+    // Set a style to be a hotspot or not.
+    void StyleSetHotSpot(int style, bool hotspot);
+
     // Set the foreground colour of the selection and whether to use this setting.
     void SetSelForeground(bool useSetting, const wxColour& fore);
 
@@ -1339,6 +1457,19 @@ public:
     // after the inserted text upon completion.
     bool AutoCompGetDropRestOfWord();
 
+    // Register an image for use in autocompletion lists.
+    void RegisterImage(int type, const wxBitmap& bmp);
+
+    // Clear all the registered images.
+    void ClearRegisteredImages();
+
+    // Retrieve the auto-completion list type-separator character.
+    int AutoCompGetTypeSeparator();
+
+    // Change the type-separator character in the string setting up an auto-completion list.
+    // Default is '?' but can be changed if items contain '?'.
+    void AutoCompSetTypeSeparator(int separatorCharacter);
+
     // Set the number of spaces used for one level of indentation.
     void SetIndent(int indentSize);
 
@@ -1427,14 +1558,14 @@ public:
 
     // On Windows, will draw the document into a display context such as a printer.
     int FormatRange(bool   doDraw,
-                               int    startPos,
-                               int    endPos,
-                               wxDC*  draw,
-                               wxDC*  target,  // Why does it use two? Can they be the same?
-                               wxRect renderRect,
-                               wxRect pageRect);
-
-    // Retrieve the line at the top of the display.
+               int    startPos,
+               int    endPos,
+               wxDC*  draw,
+               wxDC*  target,  // Why does it use two? Can they be the same?
+               wxRect renderRect,
+               wxRect pageRect);
+
+    // Retrieve the display line at the top of the display.
     int GetFirstVisibleLine();
 
     // Retrieve the contents of a line.
@@ -1589,6 +1720,12 @@ public:
     // Set the background colour for the call tip.
     void CallTipSetBackground(const wxColour& back);
 
+    // Set the foreground colour for the call tip.
+    void CallTipSetForeground(const wxColour& fore);
+
+    // Set the foreground colour for the highlighted part of the call tip.
+    void CallTipSetForegroundHighlight(const wxColour& fore);
+
     // Find the display line of a document line taking hidden lines into account.
     int VisibleFromDocLine(int line);
 
@@ -1630,7 +1767,7 @@ public:
     // Ensure a particular line is visible by expanding any header line hiding it.
     void EnsureVisible(int line);
 
-    // Set some debugging options for folding.
+    // Set some style options for folding.
     void SetFoldFlags(int flags);
 
     // Ensure a particular line is visible by expanding any header line hiding it.
@@ -1696,6 +1833,39 @@ public:
     // Retrieve the height of a particular line of text in pixels.
     int TextHeight(int line);
 
+    // Show or hide the vertical scroll bar.
+    void SetUseVerticalScrollBar(bool show);
+
+    // Is the vertical scroll bar visible?
+    bool GetUseVerticalScrollBar();
+
+    // Append a string to the end of the document without changing the selection.
+    void AppendText(int length, const wxString& text);
+
+    // Is drawing done in two phases with backgrounds drawn before foregrounds?
+    bool GetTwoPhaseDraw();
+
+    // In twoPhaseDraw mode, drawing is performed in two phases, first the background
+    // and then the foreground. This avoids chopping off characters that overlap the next run.
+    void SetTwoPhaseDraw(bool twoPhase);
+
+    // Make the target range start and end be the same as the selection range start and end.
+    void TargetFromSelection();
+
+    // Join the lines in the target.
+    void LinesJoin();
+
+    // Split the lines in the target into lines that are less wide than pixelWidth
+    // where possible.
+    void LinesSplit(int pixelWidth);
+
+    // Set the colours used as a chequerboard pattern in the fold margin
+    void SetFoldMarginColour(bool useSetting, const wxColour& back);
+    void SetFoldMarginHiColour(bool useSetting, const wxColour& fore);
+
+    // Duplicate the current line.
+    void LineDuplicate();
+
     // Move caret to first position on display line.
     void HomeDisplay();
 
@@ -1860,6 +2030,9 @@ public:
     void SetXOffset(int newOffset);
     int GetXOffset();
 
+    // Set the last x chosen value to be the caret x position
+    void ChooseCaretX();
+
     // Set the way the caret is kept visible when going sideway.
     // The exclusion zone is given in pixels.
     void SetXCaretPolicy(int caretPolicy, int caretSlop);
@@ -1868,6 +2041,21 @@ public:
     // The exclusion zone is given in lines.
     void SetYCaretPolicy(int caretPolicy, int caretSlop);
 
+    // Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).
+    void SetPrintWrapMode(int mode);
+
+    // Is printing line wrapped.
+    int GetPrintWrapMode();
+
+    // Set a fore colour for active hotspots.
+    void SetHotspotActiveForeground(bool useSetting, const wxColour& fore);
+
+    // Set a back colour for active hotspots.
+    void SetHotspotActiveBackground(bool useSetting, const wxColour& back);
+
+    // Enable / Disable underlining active hotspots.
+    void SetHotspotActiveUnderline(bool underline);
+
     // Start notifying the container of all key presses and commands.
     void StartRecord();
 
@@ -2005,11 +2193,11 @@ private:
     void NotifyChange();
     void NotifyParent(SCNotification* scn);
 
-
-private:
     DECLARE_EVENT_TABLE()
     DECLARE_CLASS(wxStyledTextCtrl)
 
+protected:
+
     ScintillaWX*        m_swx;
     wxStopWatch         m_stopWatch;
     wxScrollBar*        m_vScrollBar;
@@ -2128,6 +2316,8 @@ private:
 #endif
 };
 
+
+
 #ifndef SWIG
 BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE,                  1650)
@@ -2153,6 +2343,9 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER,               1670)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP,                 1671)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM,                    1672)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK,           1673)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK,          1674)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK,           1675)
 END_DECLARE_EVENT_TYPES()
 #else
     enum {
@@ -2179,6 +2372,9 @@ END_DECLARE_EVENT_TYPES()
         wxEVT_STC_DRAG_OVER,
         wxEVT_STC_DO_DROP,
         wxEVT_STC_ZOOM,
+        wxEVT_STC_HOTSPOT_CLICK,
+        wxEVT_STC_HOTSPOT_DCLICK,
+        wxEVT_STC_CALLTIP_CLICK
     };
 #endif
 
@@ -2210,6 +2406,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&);
 #define EVT_STC_DRAG_OVER(id, fn)               DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER,             id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_DO_DROP(id, fn)                 DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP,               id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_ZOOM(id, fn)                    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM,                  id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_CLICK(id, fn)           DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK,         id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_DCLICK(id, fn)          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK,        id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_CALLTIP_CLICK(id, fn))          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK          id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+
 #endif
 
 //----------------------------------------------------------------------
index 578044d546c8b6d6dc88965ef2cd93c723faac2d..538d00ef98aa4f05126fb8554833d3bbea89bdfb 100644 (file)
@@ -40,7 +40,26 @@ public:
 };
 
 //----------------------------------------------------------------------
+//  Make an editor class
 
+class MySTC : public wxStyledTextCtrl
+{
+public:
+    MySTC(wxWindow *parent, wxWindowID id,
+          const wxPoint& pos = wxDefaultPosition,
+          const wxSize& size = wxDefaultSize, long style = 0);
+
+    void OnKeyPressed(wxKeyEvent& evt);
+
+private:
+    DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(MySTC, wxStyledTextCtrl)
+    EVT_KEY_DOWN(MySTC::OnKeyPressed)
+END_EVENT_TABLE()
+
+//----------------------------------------------------------------------
 // Define a new frame type: this is going to be our main frame
 class MyFrame : public wxFrame
 {
@@ -51,7 +70,7 @@ public:
     void OnAbout(wxCommandEvent& event);
 
 private:
-    wxStyledTextCtrl* ed;
+    MySTC* ed;
 
     DECLARE_EVENT_TABLE()
 };
@@ -79,7 +98,7 @@ IMPLEMENT_APP(MyApp)
 bool MyApp::OnInit()
 {
     MyFrame *frame = new MyFrame(_T("Testing wxStyledTextCtrl"),
-                                 wxPoint(5, 5), wxSize(400, 600));
+                                 wxPoint(5, 5), wxSize(600, 600));
 
     frame->Show(TRUE);
     return TRUE;
@@ -123,32 +142,71 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
 
     //----------------------------------------
     // Setup the editor
-    ed = new wxStyledTextCtrl(this, ID_ED);
+    ed = new MySTC(this, ID_ED);
+}
+
+
+// event handlers
+
+void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+    // TRUE is to force the frame to close
+    Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+    wxString msg;
+    msg.Printf( _T("Testing wxStyledTextCtrl...\n"));
 
+    wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this);
+}
+
+
+//----------------------------------------------------------------------
+
+wxChar* keywords =
+_T("asm auto bool break case catch char class const \
+const_cast continue default delete do double \
+dynamic_cast else enum explicit export extern \
+false float for friend goto if inline int long \
+mutable namespace new operator private protected \
+public register reinterpret_cast return short signed \
+sizeof static static_cast struct switch template this \
+throw true try typedef typeid typename union unsigned \
+using virtual void volatile wchar_t while");
+
+
+
+MySTC::MySTC(wxWindow *parent, wxWindowID id,
+             const wxPoint& pos, const wxSize& size,
+             long style)
+    : wxStyledTextCtrl(parent, id, pos, size, style)
+{
     // Default font
     wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL);
-    ed->StyleSetFont(wxSTC_STYLE_DEFAULT, font);
-    ed->StyleClearAll();
-
-    ed->StyleSetForeground(0,  wxColour(0x80, 0x80, 0x80));
-    ed->StyleSetForeground(1,  wxColour(0x00, 0x7f, 0x00));
-    //ed->StyleSetForeground(2,  wxColour(0x00, 0x7f, 0x00));
-    ed->StyleSetForeground(3,  wxColour(0x7f, 0x7f, 0x7f));
-    ed->StyleSetForeground(4,  wxColour(0x00, 0x7f, 0x7f));
-    ed->StyleSetForeground(5,  wxColour(0x00, 0x00, 0x7f));
-    ed->StyleSetForeground(6,  wxColour(0x7f, 0x00, 0x7f));
-    ed->StyleSetForeground(7,  wxColour(0x7f, 0x00, 0x7f));
-    ed->StyleSetForeground(8,  wxColour(0x00, 0x7f, 0x7f));
-    ed->StyleSetForeground(9,  wxColour(0x7f, 0x7f, 0x7f));
-    ed->StyleSetForeground(10, wxColour(0x00, 0x00, 0x00));
-    ed->StyleSetForeground(11, wxColour(0x00, 0x00, 0x00));
-    ed->StyleSetBold(5,  TRUE);
-    ed->StyleSetBold(10, TRUE);
+    StyleSetFont(wxSTC_STYLE_DEFAULT, font);
+    StyleClearAll();
+
+    StyleSetForeground(0,  wxColour(0x80, 0x80, 0x80));
+    StyleSetForeground(1,  wxColour(0x00, 0x7f, 0x00));
+    //StyleSetForeground(2,  wxColour(0x00, 0x7f, 0x00));
+    StyleSetForeground(3,  wxColour(0x7f, 0x7f, 0x7f));
+    StyleSetForeground(4,  wxColour(0x00, 0x7f, 0x7f));
+    StyleSetForeground(5,  wxColour(0x00, 0x00, 0x7f));
+    StyleSetForeground(6,  wxColour(0x7f, 0x00, 0x7f));
+    StyleSetForeground(7,  wxColour(0x7f, 0x00, 0x7f));
+    StyleSetForeground(8,  wxColour(0x00, 0x7f, 0x7f));
+    StyleSetForeground(9,  wxColour(0x7f, 0x7f, 0x7f));
+    StyleSetForeground(10, wxColour(0x00, 0x00, 0x00));
+    StyleSetForeground(11, wxColour(0x00, 0x00, 0x00));
+    StyleSetBold(5,  TRUE);
+    StyleSetBold(10, TRUE);
 
 #ifdef __WXMSW__
-    ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9"));
+    StyleSetSpec(2, _T("fore:#007f00,bold,face:Arial,size:9"));
 #else
-    ed->StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9"));
+    StyleSetSpec(2, _T("fore:#007f00,bold,face:Helvetica,size:9"));
 #endif
 
     // give it some text to play with
@@ -161,36 +219,36 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
     st = wxString::FromAscii(buf);
     delete[] buf;
 
-    ed->InsertText(0, st);
-    ed->EmptyUndoBuffer();
+    InsertText(0, st);
+    EmptyUndoBuffer();
 
-    ed->SetLexer(wxSTC_LEX_CPP);
-    ed->SetKeyWords(0,
-_T("asm auto bool break case catch char class const \
-const_cast continue default delete do double \
-dynamic_cast else enum explicit export extern \
-false float for friend goto if inline int long \
-mutable namespace new operator private protected \
-public register reinterpret_cast return short signed \
-sizeof static static_cast struct switch template this \
-throw true try typedef typeid typename union unsigned \
-using virtual void volatile wchar_t while"));
-
-}
-
-
-// event handlers
-
-void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
-{
-    // TRUE is to force the frame to close
-    Close(TRUE);
+    SetLexer(wxSTC_LEX_CPP);
+    SetKeyWords(0, keywords);
 }
 
-void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+void MySTC::OnKeyPressed(wxKeyEvent& evt)
 {
-    wxString msg;
-    msg.Printf( _T("Testing wxStyledTextCtrl...\n"));
-
-    wxMessageBox(msg, _T("About This Test"), wxOK | wxICON_INFORMATION, this);
+    if (CallTipActive())
+        CallTipCancel();
+
+    int key = evt.GetKeyCode();
+    if ( key == WXK_SPACE && evt.ControlDown()) {
+        int pos = GetCurrentPos();
+
+        if (evt.ShiftDown()) {
+            // show how to do CallTips
+            CallTipSetBackground(wxColour(_T("YELLOW")));
+            CallTipShow(pos, _T("lots of of text: blah, blah, blah\n\n"
+                                "show some suff, maybe parameters..\n\n"
+                                "fubar(param1, param2)"));
+        }
+        else {
+            // show how to do AutoComplete
+            AutoCompSetIgnoreCase(false);
+            AutoCompShow(0, keywords);   // reuse the keyword list here
+            // normally you would build a string of completion texts...
+        }
+    }
+    else
+        evt.Skip();
 }
index 042da17f87d235ddad1f1daef70465841f540b11..9df25a3db22d00b80ef3e735339d44554e906a0a 100644 (file)
@@ -34,18 +34,22 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
         KeyMap.o               \
         KeyWords.o             \
        LexAVE.o                \
+       LexAda.o                \
+       LexAsm.o                \
        LexBaan.o               \
        LexBullant.o            \
        LexMatlab.o             \
-       LexAda.o                \
        LexCPP.o                \
        LexConf.o               \
        LexCrontab.o            \
+       LexCSS.o                \
        LexEiffel.o             \
+       LexFortran.o            \
        LexHTML.o               \
        LexLisp.o               \
        LexLua.o                \
        LexOthers.o             \
+       LexPOV.o                \
        LexPascal.o             \
        LexPerl.o               \
        LexPython.o             \
@@ -61,6 +65,8 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
        UniConversion.o         \
         ViewStyle.o            \
        WindowAccessor.o        \
+       XPM.o                   \
+
 
 DEPFILES=$(OBJECTS:.o=.d)
 
index fbf1faf2a370d9db55d4eb62d7bfadcdd8298f63..80f8f795ce95279d8ebf75ffaca32a66a3546f8d 100644 (file)
@@ -8,7 +8,10 @@
 
 #include <wx/wx.h>
 #include <wx/encconv.h>
-
+#include <wx/listctrl.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
+#include <wx/imaglist.h>
 
 #include "Platform.h"
 #include "PlatWX.h"
@@ -189,9 +192,6 @@ void Font::Create(const char *faceName, int characterSet, int size, bool bold, b
                     false,
                     stc2wx(faceName),
                     encoding);
-#ifdef __WXMAC__
-        ((wxFont*)id)->SetNoAntiAliasing( true ) ;
-#endif
 }
 
 
@@ -216,42 +216,44 @@ public:
     SurfaceImpl();
     ~SurfaceImpl();
 
-    void Init();
-    void Init(SurfaceID sid);
-    void InitPixMap(int width, int height, Surface *surface_);
-
-    void Release();
-    bool Initialised();
-    void PenColour(ColourAllocated fore);
-    int LogPixelsY();
-    int DeviceHeightFont(int points);
-    void MoveTo(int x_, int y_);
-    void LineTo(int x_, int y_);
-    void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
-    void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
-    void FillRectangle(PRectangle rc, ColourAllocated back);
-    void FillRectangle(PRectangle rc, Surface &surfacePattern);
-    void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
-    void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
-    void Copy(PRectangle rc, Point from, Surface &surfaceSource);
-
-    void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
-    void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
-    void MeasureWidths(Font &font_, const char *s, int len, int *positions);
-    int WidthText(Font &font_, const char *s, int len);
-    int WidthChar(Font &font_, char ch);
-    int Ascent(Font &font_);
-    int Descent(Font &font_);
-    int InternalLeading(Font &font_);
-    int ExternalLeading(Font &font_);
-    int Height(Font &font_);
-    int AverageCharWidth(Font &font_);
-
-    int SetPalette(Palette *pal, bool inBackGround);
-    void SetClip(PRectangle rc);
-    void FlushCachedState();
-
-    void SetUnicodeMode(bool unicodeMode_);
+    virtual void Init(WindowID wid);
+    virtual void Init(SurfaceID sid, WindowID wid);
+    virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid);
+
+    virtual void Release();
+    virtual bool Initialised();
+    virtual void PenColour(ColourAllocated fore);
+    virtual int LogPixelsY();
+    virtual int DeviceHeightFont(int points);
+    virtual void MoveTo(int x_, int y_);
+    virtual void LineTo(int x_, int y_);
+    virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
+    virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+    virtual void FillRectangle(PRectangle rc, ColourAllocated back);
+    virtual void FillRectangle(PRectangle rc, Surface &surfacePattern);
+    virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+    virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+    virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource);
+
+    virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
+    virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
+    virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore);
+    virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions);
+    virtual int WidthText(Font &font_, const char *s, int len);
+    virtual int WidthChar(Font &font_, char ch);
+    virtual int Ascent(Font &font_);
+    virtual int Descent(Font &font_);
+    virtual int InternalLeading(Font &font_);
+    virtual int ExternalLeading(Font &font_);
+    virtual int Height(Font &font_);
+    virtual int AverageCharWidth(Font &font_);
+
+    virtual int SetPalette(Palette *pal, bool inBackGround);
+    virtual void SetClip(PRectangle rc);
+    virtual void FlushCachedState();
+
+    virtual void SetUnicodeMode(bool unicodeMode_);
+    virtual void SetDBCSMode(int codePage);
 
     void BrushColour(ColourAllocated back);
     void SetFont(Font &font_);
@@ -268,25 +270,7 @@ SurfaceImpl::~SurfaceImpl() {
     Release();
 }
 
-void SurfaceImpl::Release() {
-    if (bitmap) {
-        ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
-        delete bitmap;
-        bitmap = 0;
-    }
-    if (hdcOwned) {
-        delete hdc;
-        hdc = 0;
-        hdcOwned = false;
-    }
-}
-
-
-bool SurfaceImpl::Initialised() {
-    return hdc != 0;
-}
-
-void SurfaceImpl::Init() {
+void SurfaceImpl::Init(WindowID wid) {
 #if 0
     Release();
     hdc = new wxMemoryDC();
@@ -295,16 +279,16 @@ void SurfaceImpl::Init() {
     // On Mac and GTK the DC is not really valid until it has a bitmap
     // selected into it.  So instead of just creating the DC with no bitmap,
     // go ahead and give it one.
-    InitPixMap(1,1,NULL);
+    InitPixMap(1,1,NULL,wid);
 #endif
 }
 
-void SurfaceImpl::Init(SurfaceID hdc_) {
+void SurfaceImpl::Init(SurfaceID hdc_, WindowID) {
     Release();
     hdc = (wxDC*)hdc_;
 }
 
-void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
+void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID) {
     Release();
     hdc = new wxMemoryDC();
     hdcOwned = true;
@@ -314,6 +298,26 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) {
     ((wxMemoryDC*)hdc)->SelectObject(*bitmap);
 }
 
+
+void SurfaceImpl::Release() {
+    if (bitmap) {
+        ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
+        delete bitmap;
+        bitmap = 0;
+    }
+    if (hdcOwned) {
+        delete hdc;
+        hdc = 0;
+        hdcOwned = false;
+    }
+}
+
+
+bool SurfaceImpl::Initialised() {
+    return hdc != 0;
+}
+
+
 void SurfaceImpl::PenColour(ColourAllocated fore) {
     hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));
 }
@@ -401,7 +405,7 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase,
     SetFont(font);
     hdc->SetTextForeground(wxColourFromCA(fore));
     hdc->SetTextBackground(wxColourFromCA(back));
-    FillRectangle(rc, back);
+    //FillRectangle(rc, back);
 
     // ybase is where the baseline should be, but wxWin uses the upper left
     // corner, so I need to calculate the real position for the text...
@@ -414,28 +418,36 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase,
     SetFont(font);
     hdc->SetTextForeground(wxColourFromCA(fore));
     hdc->SetTextBackground(wxColourFromCA(back));
-    FillRectangle(rc, back);
+    //FillRectangle(rc, back);
     hdc->SetClippingRegion(wxRectFromPRectangle(rc));
 
     // see comments above
     hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
-    hdc->DestroyClippingRegion();
 }
 
-int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
+
+void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase,
+                                      const char *s, int len,
+                                      ColourAllocated fore) {
+
     SetFont(font);
-    int w;
-    int h;
+    hdc->SetTextForeground(wxColourFromCA(fore));
+    hdc->SetBackgroundMode(wxTRANSPARENT);
 
-    hdc->GetTextExtent(stc2wx(s, len), &w, &h);
-    return w;
+    // ybase is where the baseline should be, but wxWin uses the upper left
+    // corner, so I need to calculate the real position for the text...
+    hdc->DrawText(stc2wx(s, len), rc.left, ybase - font.ascent);
+
+    hdc->SetBackgroundMode(wxSOLID);
 }
 
 
 void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) {
+
     wxString str = stc2wx(s, len);
     SetFont(font);
 
+#ifndef __WXMAC__
     // Calculate the position of each character based on the widths of
     // the previous characters
     int* tpos = new int[len];
@@ -447,9 +459,26 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio
         totalWidth += w;
         tpos[i] = totalWidth;
     }
+#else
+    // Instead of a running total, remeasure from the begining of the
+    // text for each character's position.  This is because with AA fonts
+    // on OS X widths can be fractions of pixels wide when more than one
+    // are drawn together, so the sum of all character widths is not necessarily
+    // (and probably not) the same as the whole string width.
+    int* tpos = new int[len];
+    size_t i;
+    for (i=0; i<str.Length(); i++) {
+        int w, h;
+        hdc->GetTextExtent(str.Left(i+1), &w, &h);
+        tpos[i] = w;
+    }
+#endif
+
 
 #if wxUSE_UNICODE
     // Map the widths for UCS-2 characters back to the UTF-8 input string
+    // NOTE:  I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2
+    // so figure it out and fix it!
     i = 0;
     size_t ui = 0;
     while (i < len) {
@@ -475,6 +504,16 @@ void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positio
 }
 
 
+int SurfaceImpl::WidthText(Font &font, const char *s, int len) {
+    SetFont(font);
+    int w;
+    int h;
+
+    hdc->GetTextExtent(stc2wx(s, len), &w, &h);
+    return w;
+}
+
+
 int SurfaceImpl::WidthChar(Font &font, char ch) {
     SetFont(font);
     int w;
@@ -545,6 +584,11 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
 #endif
 }
 
+void SurfaceImpl::SetDBCSMode(int codePage) {
+    // dbcsMode = codePage == SC_CP_DBCS;
+}
+
+
 Surface *Surface::Allocate() {
     return new SurfaceImpl;
 }
@@ -559,8 +603,10 @@ Window::~Window() {
 }
 
 void Window::Destroy() {
-    if (id)
+    if (id) {
+        Show(FALSE);
         GETWIN(id)->Destroy();
+    }
     id = 0;
 }
 
@@ -569,6 +615,7 @@ bool Window::HasFocus() {
 }
 
 PRectangle Window::GetPosition() {
+    if (! id) return PRectangle();
     wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
     return PRectangleFromwxRect(rc);
 }
@@ -583,6 +630,7 @@ void Window::SetPositionRelative(PRectangle rc, Window) {
 }
 
 PRectangle Window::GetClientPosition() {
+    if (! id) return PRectangle();
     wxSize sz = GETWIN(id)->GetClientSize();
     return  PRectangle(0, 0, sz.x, sz.y);
 }
@@ -631,6 +679,8 @@ void Window::SetCursor(Cursor curs) {
     case cursorReverseArrow:
         cursorId = wxCURSOR_RIGHT_ARROW;
         break;
+    case cursorHand:
+        cursorId = wxCURSOR_HAND;
     default:
         cursorId = wxCURSOR_ARROW;
         break;
@@ -653,199 +703,347 @@ void Window::SetTitle(const char *s) {
 // Helper classes for ListBox
 
 
-#if 1 // defined(__WXMAC__)
-class wxSTCListBoxWin : public wxListBox {
+// This is a simple subclass of wxLIstView that just resets focus to the
+// parent when it gets it.
+class wxSTCListBox : public wxListView {
 public:
-    wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
-        : wxListBox(parent, id, wxDefaultPosition, wxSize(0,0),
-                    0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER) {
-        SetCursor(wxCursor(wxCURSOR_ARROW));
-        Hide();
-    }
+    wxSTCListBox(wxWindow* parent, wxWindowID id,
+                 const wxPoint& pos, const wxSize& size,
+                 long style)
+        : wxListView(parent, id, pos, size, style)
+    {}
 
     void OnFocus(wxFocusEvent& event) {
         GetParent()->SetFocus();
         event.Skip();
     }
 
-    wxListBox* GetLB() { return this; }
-
 private:
     DECLARE_EVENT_TABLE()
 };
 
-
-BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxListBox)
-    EVT_SET_FOCUS(wxSTCListBoxWin::OnFocus)
+BEGIN_EVENT_TABLE(wxSTCListBox, wxListView)
+    EVT_SET_FOCUS( wxSTCListBox::OnFocus)
 END_EVENT_TABLE()
 
 
 
-#else
-
 
-class wxSTCListBox : public wxListBox {
+// A window to place the wxSTCListBox upon
+class wxSTCListBoxWin : public wxWindow {
+private:
+    wxListView*         lv;
+    CallBackAction      doubleClickAction;
+    void*               doubleClickActionData;
 public:
-    wxSTCListBox(wxWindow* parent, wxWindowID id)
-        : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize,
-                    0, NULL, wxLB_SINGLE | wxSIMPLE_BORDER | wxWANTS_CHARS)
-        {}
-
-    void OnKeyDown(wxKeyEvent& event) {
-        // Give the key events to the STC.  It will then update
-        // the listbox as needed.
-        GetGrandParent()->GetEventHandler()->ProcessEvent(event);
+    wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
+        wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxNO_BORDER )
+    {
+
+        SetBackgroundColour(*wxBLACK);
+        lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
+                              wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxNO_BORDER);
+        lv->SetCursor(wxCursor(wxCURSOR_ARROW));
+        lv->InsertColumn(0, wxEmptyString);
+        lv->InsertColumn(1, wxEmptyString);
+        Hide();
     }
 
-private:
-    DECLARE_EVENT_TABLE()
-};
-
-BEGIN_EVENT_TABLE(wxSTCListBox, wxListBox)
-    EVT_KEY_DOWN(wxSTCListBox::OnKeyDown)
-    EVT_CHAR(wxSTCListBox::OnKeyDown)
-END_EVENT_TABLE()
-
+    int IconWidth() {
+        wxImageList* il = lv->GetImageList(wxIMAGE_LIST_SMALL);
+        if (il != NULL) {
+            int w, h;
+            il->GetSize(0, w, h);
+            return w;
+        }
+        return 0;
+    }
 
 
-#undef  wxSTC_USE_POPUP
-#define wxSTC_USE_POPUP 0  // wxPopupWindow just doesn't work well in this case...
+    void SetDoubleClickAction(CallBackAction action, void *data) {
+        doubleClickAction = action;
+        doubleClickActionData = data;
+    }
 
-// A window to place the listbox upon.  If wxPopupWindow is supported then
-// that will be used so the listbox can extend beyond the client area of the
-// wxSTC if needed.
-#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
-#include <wx/popupwin.h>
-#define wxSTCListBoxWinBase wxPopupWindow
-#define param2  wxBORDER_NONE  // popup's 2nd param is flags
-#else
-#define wxSTCListBoxWinBase wxWindow
-#define param2 -1 // wxWindow's 2nd param is ID
-#endif
 
-class wxSTCListBoxWin : public wxSTCListBoxWinBase {
-public:
-    wxSTCListBoxWin(wxWindow* parent, wxWindowID id)
-        : wxSTCListBoxWinBase(parent, param2) {
-        lb = new wxSTCListBox(this, id);
-        lb->SetCursor(wxCursor(wxCURSOR_ARROW));
-        lb->SetFocus();
-   }
+    void OnFocus(wxFocusEvent& event) {
+        GetParent()->SetFocus();
+        event.Skip();
+    }
 
     void OnSize(wxSizeEvent& event) {
-        lb->SetSize(GetSize());
+        // resize the child, leaving a 1 pixel border
+        wxSize sz = GetClientSize();
+        lv->SetSize(1, 1, sz.x-2, sz.y-2);
+        // reset the column widths
+        lv->SetColumnWidth(0, IconWidth()+4);
+        lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
+                           wxSystemSettings::GetMetric(wxSYS_VSCROLL_X));
+        event.Skip();
     }
 
-    wxListBox* GetLB() { return lb; }
-
-#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
-    virtual void DoSetSize(int x, int y,
-                           int width, int height,
-                           int sizeFlags = wxSIZE_AUTO) {
-        if (x != -1)
-            GetParent()->ClientToScreen(&x, NULL);
-        if (y != -1)
-            GetParent()->ClientToScreen(NULL, &y);
-        wxSTCListBoxWinBase::DoSetSize(x, y, width, height, sizeFlags);
+    void OnActivate(wxListEvent& event) {
+        doubleClickAction(doubleClickActionData);
     }
-#endif
+
+    wxListView* GetLB() { return lv; }
 
 private:
-    wxSTCListBox* lb;
     DECLARE_EVENT_TABLE()
 };
 
-BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxSTCListBoxWinBase)
-    EVT_SIZE(wxSTCListBoxWin::OnSize)
+
+BEGIN_EVENT_TABLE(wxSTCListBoxWin, wxWindow)
+    EVT_SET_FOCUS          (    wxSTCListBoxWin::OnFocus)
+    EVT_SIZE               (    wxSTCListBoxWin::OnSize)
+    EVT_LIST_ITEM_ACTIVATED(-1, wxSTCListBoxWin::OnActivate)
 END_EVENT_TABLE()
-#endif
 
-inline wxListBox* GETLB(WindowID win) {
-    return (((wxSTCListBoxWin*)win)->GetLB());
+
+
+inline wxSTCListBoxWin* GETLBW(WindowID win) {
+    return ((wxSTCListBoxWin*)win);
+}
+
+inline wxListView* GETLB(WindowID win) {
+    return GETLBW(win)->GetLB();
 }
 
 //----------------------------------------------------------------------
 
-ListBox::ListBox() {
+class ListBoxImpl : public ListBox {
+private:
+    int                 lineHeight;
+    bool                unicodeMode;
+    int                 desiredVisibleRows;
+    int                 aveCharWidth;
+    int                 maxStrWidth;
+    wxImageList*        imgList;
+    wxArrayInt*         imgTypeMap;
+
+public:
+    ListBoxImpl();
+    ~ListBoxImpl();
+
+    virtual void SetFont(Font &font);
+    virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_);
+    virtual void SetAverageCharWidth(int width);
+    virtual void SetVisibleRows(int rows);
+    virtual PRectangle GetDesiredRect();
+    virtual int CaretFromEdge();
+    virtual void Clear();
+    virtual void Append(char *s, int type = -1);
+    virtual int Length();
+    virtual void Select(int n);
+    virtual int GetSelection();
+    virtual int Find(const char *prefix);
+    virtual void GetValue(int n, char *value, int len);
+    virtual void Sort();
+    virtual void RegisterImage(int type, const char *xpm_data);
+    virtual void ClearRegisteredImages();
+    virtual void SetDoubleClickAction(CallBackAction, void *);
+
+};
+
+
+ListBoxImpl::ListBoxImpl()
+    : lineHeight(10), unicodeMode(false),
+      desiredVisibleRows(5), aveCharWidth(8), maxStrWidth(0),
+      imgList(NULL), imgTypeMap(NULL)
+{
 }
 
-ListBox::~ListBox() {
+ListBoxImpl::~ListBoxImpl() {
+    if (imgList) {
+        delete imgList;
+        imgList = NULL;
+    }
+    if (imgTypeMap) {
+        delete imgTypeMap;
+        imgTypeMap = NULL;
+    }
 }
 
-void ListBox::Create(Window &parent, int ctrlID) {
+
+void ListBoxImpl::SetFont(Font &font) {
+    GETLB(id)->SetFont(*((wxFont*)font.GetID()));
+}
+
+
+void ListBoxImpl::Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_) {
+    lineHeight =  lineHeight_;
+    unicodeMode = unicodeMode_;
+    maxStrWidth = 0;
     id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
+    if (imgList != NULL)
+        GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
 }
 
-void ListBox::SetVisibleRows(int rows) {
+
+void ListBoxImpl::SetAverageCharWidth(int width) {
+    aveCharWidth = width;
+}
+
+
+void ListBoxImpl::SetVisibleRows(int rows) {
     desiredVisibleRows = rows;
 }
 
-PRectangle ListBox::GetDesiredRect() {
-    wxSize sz = GETLB(id)->GetBestSize();
+
+PRectangle ListBoxImpl::GetDesiredRect() {
+    // wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
+    // the max size in Append and calculate it here...
+    int maxw = maxStrWidth;
+    int maxh = 0;
+
+    // give it a default if there are no lines, and/or add a bit more
+    if (maxw == 0) maxw = 100;
+    maxw += aveCharWidth * 3 +
+            GETLBW(id)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
+    if (maxw > 350)
+        maxw = 350;
+
+    // estimate a desired height
+    int count = GETLB(id)->GetItemCount();
+    if (count) {
+        wxRect rect;
+        GETLB(id)->GetItemRect(0, rect);
+        maxh = count * rect.GetHeight();
+        if (maxh > 140)  // TODO:  Use desiredVisibleRows??
+            maxh = 140;
+
+        // Try to make the size an exact multiple of some number of lines
+        int lines = maxh / rect.GetHeight();
+        maxh = (lines + 1) * rect.GetHeight() + 2;
+    }
+    else
+        maxh = 100;
+
     PRectangle rc;
     rc.top = 0;
     rc.left = 0;
-    if (sz.x > 400)
-        sz.x = 400;
-    if (sz.y > 140)  // TODO:  Use desiredVisibleRows??
-        sz.y = 140;
-    rc.right = sz.x;
-    rc.bottom = sz.y;
+    rc.right = maxw;
+    rc.bottom = maxh;
     return rc;
 }
 
-void ListBox::SetAverageCharWidth(int width) {
-    aveCharWidth = width;
-}
 
-void ListBox::SetFont(Font &font) {
-    GETLB(id)->SetFont(*((wxFont*)font.GetID()));
+int ListBoxImpl::CaretFromEdge() {
+    return 4 + GETLBW(id)->IconWidth();
 }
 
-void ListBox::Clear() {
-    GETLB(id)->Clear();
+
+void ListBoxImpl::Clear() {
+    GETLB(id)->DeleteAllItems();
 }
 
-void ListBox::Append(char *s) {
-    GETLB(id)->Append(stc2wx(s));
+
+void ListBoxImpl::Append(char *s, int type) {
+    wxString text = stc2wx(s);
+    long count  = GETLB(id)->GetItemCount();
+    long itemID  = GETLB(id)->InsertItem(count, wxEmptyString);
+    GETLB(id)->SetItem(itemID, 1, text);
+    int itemWidth = 0;
+    GETLB(id)->GetTextExtent(text, &itemWidth, NULL);
+    maxStrWidth = wxMax(maxStrWidth, itemWidth);
+    if (type != -1) {
+        wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
+        long idx = imgTypeMap->Item(type);
+        GETLB(id)->SetItemImage(itemID, idx, idx);
+    }
 }
 
-int ListBox::Length() {
-    return GETLB(id)->GetCount();
+
+int ListBoxImpl::Length() {
+    return GETLB(id)->GetItemCount();
 }
 
-void ListBox::Select(int n) {
+
+void ListBoxImpl::Select(int n) {
     bool select = TRUE;
     if (n == -1) {
         n = 0;
         select = FALSE;
     }
-    GETLB(id)->SetSelection(n, select);
-#ifdef __WXGTK__
-    if (n > 4)
-        n = n - 4;
-    else
-        n = 0;
-    GETLB(id)->SetFirstItem(n);
-#endif
+    GETLB(id)->Focus(n);
+    GETLB(id)->Select(n, select);
 }
 
-int ListBox::GetSelection() {
-    return GETLB(id)->GetSelection();
+
+int ListBoxImpl::GetSelection() {
+    return GETLB(id)->GetFirstSelected();
 }
 
-int ListBox::Find(const char *prefix) {
+
+int ListBoxImpl::Find(const char *prefix) {
     // No longer used
     return -1;
 }
 
-void ListBox::GetValue(int n, char *value, int len) {
-    wxString text = GETLB(id)->GetString(n);
-    strncpy(value, wx2stc(text), len);
+
+void ListBoxImpl::GetValue(int n, char *value, int len) {
+    wxListItem item;
+    item.SetId(n);
+    item.SetColumn(1);
+    item.SetMask(wxLIST_MASK_TEXT);
+    GETLB(id)->GetItem(item);
+    strncpy(value, wx2stc(item.GetText()), len);
     value[len-1] = '\0';
 }
 
-void ListBox::Sort() {
+void ListBoxImpl::Sort() {
+}
+
+
+void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
+    wxMemoryInputStream stream(xpm_data, strlen(xpm_data)+1);
+    wxBitmap bmp(wxImage(stream, wxBITMAP_TYPE_XPM));
+
+    if (! imgList) {
+        // assumes all images are the same size
+        imgList = new wxImageList(bmp.GetWidth(), bmp.GetHeight(), TRUE);
+        imgTypeMap = new wxArrayInt;
+    }
+
+    int idx = imgList->Add(bmp);
+
+    // do we need to extend the mapping array?
+    wxArrayInt& itm = *imgTypeMap;
+    if ( itm.GetCount() < type+1)
+        itm.Add(-1, type - itm.GetCount() + 1);
+
+    // Add an item that maps type to the image index
+    itm[type] = idx;
+}
+
+void ListBoxImpl::ClearRegisteredImages() {
+    if (imgList) {
+        delete imgList;
+        imgList = NULL;
+    }
+    if (imgTypeMap) {
+        delete imgTypeMap;
+        imgTypeMap = NULL;
+    }
+    if (id)
+        GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
+}
+
+
+void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
+    GETLBW(id)->SetDoubleClickAction(action, data);
+}
+
+
+
+ListBox::ListBox() {
+}
+
+ListBox::~ListBox() {
+}
+
+ListBox *ListBox::Allocate() {
+    return new ListBoxImpl();
 }
 
 //----------------------------------------------------------------------
@@ -890,13 +1088,16 @@ const char *Platform::DefaultFont() {
 }
 
 int Platform::DefaultFontSize() {
-    return 8;
+    return wxNORMAL_FONT->GetPointSize();
 }
 
 unsigned int Platform::DoubleClickTime() {
     return 500;   // **** ::GetDoubleClickTime();
 }
 
+bool Platform::MouseButtonBounce() {
+       return FALSE;
+}
 void Platform::DebugDisplay(const char *s) {
     wxLogDebug(stc2wx(s));
 }
@@ -998,6 +1199,13 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) {
     return false;
 }
 
+int Platform::DBCSCharLength(int codePage, const char *s) {
+    return 0;
+}
+
+int Platform::DBCSCharMaxLength() {
+    return 0;
+}
 
 
 //----------------------------------------------------------------------
index 12ad21dafe4403a3aeab97d9023096c8c87ba02b..9aeda729c7301fea568d4bb2df53453ad273090a 100644 (file)
@@ -67,26 +67,28 @@ void  wxSTCDropTarget::OnLeave() {
 #define param2  wxBORDER_NONE  // popup's 2nd param is flags
 #else
 #define wxSTCCallTipBase wxWindow
-#define param2 -1 // wxWindows 2nd param is ID
+#define param2 -1 // wxWindow's 2nd param is ID
 #endif
 
 class wxSTCCallTip : public wxSTCCallTipBase {
 public:
-    wxSTCCallTip(wxWindow* parent, CallTip* ct)
-        : wxSTCCallTipBase(parent, param2)
+    wxSTCCallTip(wxWindow* parent, CallTip* ct, ScintillaWX* swx)
+        : wxSTCCallTipBase(parent, param2),
+          m_ct(ct), m_swx(swx)
         {
-            m_ct = ct;
         }
 
     ~wxSTCCallTip() {
-        if (HasCapture()) ReleaseMouse();
     }
 
+    bool AcceptsFocus() const { return FALSE; }
+
     void OnPaint(wxPaintEvent& evt) {
         wxPaintDC dc(this);
         Surface* surfaceWindow = Surface::Allocate();
-        surfaceWindow->Init(&dc);
+        surfaceWindow->Init(&dc, m_ct->wDraw.GetID());
         m_ct->PaintCT(surfaceWindow);
+        surfaceWindow->Release();
         delete surfaceWindow;
     }
 
@@ -95,6 +97,13 @@ public:
         event.Skip();
     }
 
+    void OnLeftDown(wxMouseEvent& event) {
+        wxPoint pt = event.GetPosition();
+        Point p(pt.x, pt.y);
+        m_ct->MouseClick(p);
+        m_swx->CallTipClick();
+    }
+
 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP
     virtual void DoSetSize(int x, int y,
                            int width, int height,
@@ -105,32 +114,18 @@ public:
             GetParent()->ClientToScreen(NULL, &y);
         wxSTCCallTipBase::DoSetSize(x, y, width, height, sizeFlags);
     }
-
-    virtual bool Show( bool show = TRUE ) {
-        bool retval = wxSTCCallTipBase::Show(show);
-        if (show)
-            CaptureMouse();
-        else
-            if (HasCapture()) ReleaseMouse();
-        return retval;
-    }
-
-    void OnLeftDown(wxMouseEvent& ) {
-        Show(FALSE);
-    }
 #endif
 
 private:
-    CallTip*    m_ct;
+    CallTip*      m_ct;
+    ScintillaWX*  m_swx;
     DECLARE_EVENT_TABLE()
 };
 
 BEGIN_EVENT_TABLE(wxSTCCallTip, wxSTCCallTipBase)
     EVT_PAINT(wxSTCCallTip::OnPaint)
     EVT_SET_FOCUS(wxSTCCallTip::OnFocus)
-#if wxUSE_POPUPWIN && wxSTC_USE_POPUP
     EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown)
-#endif
 END_EVENT_TABLE()
 
 
@@ -139,6 +134,7 @@ END_EVENT_TABLE()
 
 
 ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
+    capturedMouse = false;
     wMain = win;
     stc   = win;
     wheelRotation = 0;
@@ -220,15 +216,16 @@ void ScintillaWX::SetTicking(bool on) {
 
 
 void ScintillaWX::SetMouseCapture(bool on) {
-    if (on && !stc->HasCapture())
+    if (on && !capturedMouse)
         stc->CaptureMouse();
-    else if (!on && stc->HasCapture())
+    else if (!on && capturedMouse && stc->HasCapture())
         stc->ReleaseMouse();
+    capturedMouse = on;
 }
 
 
 bool ScintillaWX::HaveMouseCapture() {
-    return stc->HasCapture();
+    return capturedMouse;
 }
 
 
@@ -387,8 +384,10 @@ bool ScintillaWX::CanPaste() {
 }
 
 void ScintillaWX::CreateCallTipWindow(PRectangle) {
-    ct.wCallTip = new wxSTCCallTip(stc, &ct);
-    ct.wDraw = ct.wCallTip;
+    if (! ct.wCallTip.Created() ) {
+        ct.wCallTip = new wxSTCCallTip(stc, &ct, this);
+        ct.wDraw = ct.wCallTip;
+    }
 }
 
 
@@ -436,37 +435,37 @@ long ScintillaWX::WndProc(unsigned int iMessage, unsigned long wParam, long lPar
       switch (iMessage) {
       case SCI_CALLTIPSHOW: {
           // NOTE: This is copied here from scintilla/src/ScintillaBase.cxx
-          // because of the little tweak that needs done below.  When updating
-          // new versions double check that this is still needed, and that any
-          // new code there is copied here too.
+          // because of the little tweak that needs done below for wxGTK.
+          // When updating new versions double check that this is still
+          // needed, and that any new code there is copied here too.
+          Point pt = LocationFromPosition(wParam);
+          char* defn = reinterpret_cast<char *>(lParam);
           AutoCompleteCancel();
-          if (!ct.wCallTip.Created()) {
-              Point pt = LocationFromPosition(wParam);
-              pt.y += vs.lineHeight;
-              PRectangle rc = ct.CallTipStart(currentPos, pt,
-                                              reinterpret_cast<char *>(lParam),
-                                              vs.styles[STYLE_DEFAULT].fontName,
-                                              vs.styles[STYLE_DEFAULT].sizeZoomed,
-                                              IsUnicodeMode());
-              // If the call-tip window would be out of the client
-              // space, adjust so it displays above the text.
-              PRectangle rcClient = GetClientRectangle();
-              if (rc.bottom > rcClient.bottom) {
+          pt.y += vs.lineHeight;
+          PRectangle rc = ct.CallTipStart(currentPos, pt,
+                                          defn,
+                                          vs.styles[STYLE_DEFAULT].fontName,
+                                          vs.styles[STYLE_DEFAULT].sizeZoomed,
+                                          IsUnicodeMode(),
+                                          wMain);
+          // If the call-tip window would be out of the client
+          // space, adjust so it displays above the text.
+          PRectangle rcClient = GetClientRectangle();
+          if (rc.bottom > rcClient.bottom) {
 #ifdef __WXGTK__
-                  int offset = int(vs.lineHeight * 1.25)  + rc.Height();
+              int offset = int(vs.lineHeight * 1.25)  + rc.Height();
 #else
-                  int offset = vs.lineHeight + rc.Height();
+              int offset = vs.lineHeight + rc.Height();
 #endif
-                  rc.top -= offset;
-                  rc.bottom -= offset;
-              }
-              // Now display the window.
-              CreateCallTipWindow(rc);
-              ct.wCallTip.SetPositionRelative(rc, wMain);
-              ct.wCallTip.Show();
+              rc.top -= offset;
+              rc.bottom -= offset;
           }
-      }
+          // Now display the window.
+          CreateCallTipWindow(rc);
+          ct.wCallTip.SetPositionRelative(rc, wMain);
+          ct.wCallTip.Show();
           break;
+      }
 
       default:
           return ScintillaBase::WndProc(iMessage, wParam, lParam);
@@ -483,22 +482,22 @@ void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
 
     paintState = painting;
     Surface* surfaceWindow = Surface::Allocate();
-    surfaceWindow->Init(dc);
-    PRectangle rcPaint = PRectangleFromwxRect(rect);
+    surfaceWindow->Init(dc, wMain.GetID());
+    rcPaint = PRectangleFromwxRect(rect);
+    PRectangle rcClient = GetClientRectangle();
+    paintingAllText = rcPaint.Contains(rcClient);
+
     dc->BeginDrawing();
+    ClipChildren(*dc, rcPaint);
     Paint(surfaceWindow, rcPaint);
     dc->EndDrawing();
+
     delete surfaceWindow;
     if (paintState == paintAbandoned) {
         // Painting area was insufficient to cover new styling or brace highlight positions
         FullPaint();
     }
     paintState = notPainting;
-#ifdef __WXGTK__
-    // On wxGTK the editor window paints can overwrite the listbox...
-    if (ac.Active())
-        ((wxWindow*)ac.lb.GetID())->Refresh(TRUE);
-#endif
 }
 
 
@@ -775,16 +774,18 @@ void ScintillaWX::DoDragLeave() {
 // Redraw all of text area. This paint will not be abandoned.
 void ScintillaWX::FullPaint() {
     paintState = painting;
-    rcPaint = GetTextRectangle();
+    rcPaint = GetClientRectangle();
     paintingAllText = true;
     wxClientDC dc(stc);
     Surface* surfaceWindow = Surface::Allocate();
-    surfaceWindow->Init(&dc);
-    Paint(surfaceWindow, rcPaint);
-    delete surfaceWindow;
+    surfaceWindow->Init(&dc, wMain.GetID());
 
-//     stc->Refresh(FALSE);
+    dc.BeginDrawing();
+    ClipChildren(dc, rcPaint);
+    Paint(surfaceWindow, rcPaint);
+    dc.EndDrawing();
 
+    delete surfaceWindow;
     paintState = notPainting;
 }
 
@@ -798,6 +799,21 @@ void ScintillaWX::DoScrollToColumn(int column) {
     HorizontalScrollTo(column * vs.spaceWidth);
 }
 
+void ScintillaWX::ClipChildren(wxDC& dc, PRectangle rect) {
+#ifdef __WXGTK__
+    wxRegion rgn(wxRectFromPRectangle(rect));
+    if (ac.Active()) {
+        wxRect childRect = ((wxWindow*)ac.lb->GetID())->GetRect();
+        rgn.Subtract(childRect);
+    }
+    if (ct.inCallTipMode) {
+        wxRect childRect = ((wxWindow*)ct.wCallTip.GetID())->GetRect();
+        rgn.Subtract(childRect);
+    }
+
+    dc.SetClippingRegion(rgn);
+#endif
+}
 
 
 //----------------------------------------------------------------------
index 04b2ac03334234128380d6be32010656e2b09033..4c6b35c6e3276e05ca65aa4743b1284a840829bb 100644 (file)
@@ -27,6 +27,7 @@
 #include "Platform.h"
 
 #include "Scintilla.h"
+#include "XPM.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
 #include "PropSet.h"
@@ -149,8 +150,10 @@ public:
     bool GetHideSelection() { return hideSelection; }
     void DoScrollToLine(int line);
     void DoScrollToColumn(int column);
+    void ClipChildren(wxDC& dc, PRectangle rect);
 
 private:
+    bool                capturedMouse;
     wxStyledTextCtrl*   stc;
 
 #if wxUSE_DRAG_AND_DROP
@@ -158,6 +161,9 @@ private:
     wxDragResult        dragResult;
 #endif
     int                 wheelRotation;
+
+
+    friend class wxSTCCallTip;
 };
 
 //----------------------------------------------------------------------
index a6c2c4ce95dad7c2ab2e0b5d1925a8596c2b7399..7007794571f48ddf4980591b93af0125df90a566 100644 (file)
@@ -282,6 +282,10 @@ SOURCE=.\scintilla\src\LexAda.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexAsm.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexAVE.cxx
 # End Source File
 # Begin Source File
@@ -306,10 +310,18 @@ SOURCE=.\scintilla\src\LexCrontab.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexCSS.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexEiffel.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexFortran.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexHTML.cxx
 # End Source File
 # Begin Source File
@@ -330,6 +342,10 @@ SOURCE=.\scintilla\src\LexOthers.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\LexPOV.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\src\LexPascal.cxx
 # End Source File
 # Begin Source File
@@ -446,6 +462,10 @@ SOURCE=.\scintilla\src\WindowAccessor.cxx
 # End Source File
 # Begin Source File
 
+SOURCE=.\scintilla\src\XPM.cxx
+# End Source File
+# Begin Source File
+
 SOURCE=.\scintilla\include\WindowAccessor.h
 # End Source File
 # End Group
index 668938046684a360c1626c342c873d4696c4d617..885357f398abddf8e4799deb61bcb78d0916ec2b 100644 (file)
@@ -42,6 +42,9 @@ cmdValues = [ (2300, 2349),
               (2176, 2180),
               (2390, 2393),
               (2395, 2396),
+              2404,
+              (2413, 2416),
+              (2450, 2454),
             ]
 
 
@@ -88,90 +91,114 @@ methodOverrideMap = {
     'GetViewWS' : ( 'GetViewWhiteSpace', 0, 0, 0),
     'SetViewWS' : ( 'SetViewWhiteSpace', 0, 0, 0),
 
-    'GetCharAt' : ( 0, 0,
-                    '''int %s(int pos) {
-                       return (unsigned char)SendMsg(%s, pos, 0);''',
-                    0),
-
-    'GetStyleAt' : ( 0, 0,
-                    '''int %s(int pos) {
-                       return (unsigned char)SendMsg(%s, pos, 0);''',
-                    0),
-
-    'GetStyledText' : (0,
-                       'wxMemoryBuffer %s(int startPos, int endPos);',
-
-                       '''wxMemoryBuffer %s(int startPos, int endPos) {
-                          wxMemoryBuffer buf;
-                          if (endPos < startPos) {
-                              int temp = startPos;
-                              startPos = endPos;
-                              endPos = temp;
-                          }
-                          int len = endPos - startPos;
-                          if (!len) return buf;
-                          TextRange tr;
-                          tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
-                          tr.chrg.cpMin = startPos;
-                          tr.chrg.cpMax = endPos;
-                          len = SendMsg(%s, 0, (long)&tr);
-                          buf.UngetWriteBuf(len);
-                          return buf;''',
-
-                       ('Retrieve a buffer of cells.',)),
-
-
-    'PositionFromPoint' : (0,
-                           'int %s(wxPoint pt);',
-
-                           '''int %s(wxPoint pt) {
-                              return SendMsg(%s, pt.x, pt.y);''',
-
-                           0),
-
-    'GetCurLine' : (0,
-                    '#ifdef SWIG\n    wxString %s(int* OUTPUT);\n#else\n    wxString GetCurLine(int* linePos=NULL);\n#endif',
-
-                    '''wxString %s(int* linePos) {
-                       int len = LineLength(GetCurrentLine());
-                       if (!len) {
-                           if (linePos)  *linePos = 0;
-                           return wxEmptyString;
-                       }
-
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
-
-                       int pos = SendMsg(%s, len+1, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       if (linePos)  *linePos = pos;
-                       return stc2wx(buf);''',
-
-                    0),
+    'GetCharAt' :
+    ( 0, 0,
+      '''int %s(int pos) {
+         return (unsigned char)SendMsg(%s, pos, 0);''',
+      0),
+
+    'GetStyleAt' :
+    ( 0, 0,
+      '''int %s(int pos) {
+         return (unsigned char)SendMsg(%s, pos, 0);''',
+      0),
+
+    'GetStyledText' :
+    (0,
+     'wxMemoryBuffer %s(int startPos, int endPos);',
+
+     '''wxMemoryBuffer %s(int startPos, int endPos) {
+        wxMemoryBuffer buf;
+        if (endPos < startPos) {
+            int temp = startPos;
+            startPos = endPos;
+            endPos = temp;
+        }
+        int len = endPos - startPos;
+        if (!len) return buf;
+        TextRange tr;
+        tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
+        tr.chrg.cpMin = startPos;
+        tr.chrg.cpMax = endPos;
+        len = SendMsg(%s, 0, (long)&tr);
+        buf.UngetWriteBuf(len);
+        return buf;''',
+
+     ('Retrieve a buffer of cells.',)),
+
+
+    'PositionFromPoint' :
+    (0,
+     'int %s(wxPoint pt);',
+
+     '''int %s(wxPoint pt) {
+        return SendMsg(%s, pt.x, pt.y);''',
+     0),
+
+    'GetCurLine' :
+    (0,
+     '#ifdef SWIG\n    wxString %s(int* OUTPUT);\n#else\n    wxString GetCurLine(int* linePos=NULL);\n#endif',
+
+        '''wxString %s(int* linePos) {
+        int len = LineLength(GetCurrentLine());
+        if (!len) {
+            if (linePos)  *linePos = 0;
+            return wxEmptyString;
+        }
+
+        wxMemoryBuffer mbuf(len+1);
+        char* buf = (char*)mbuf.GetWriteBuf(len+1);
+
+        int pos = SendMsg(%s, len+1, (long)buf);
+        mbuf.UngetWriteBuf(len);
+        mbuf.AppendByte(0);
+        if (linePos)  *linePos = pos;
+        return stc2wx(buf);''',
+
+     0),
 
     'SetUsePalette' : (None, 0,0,0),
 
     'MarkerSetFore' : ('MarkerSetForeground', 0, 0, 0),
     'MarkerSetBack' : ('MarkerSetBackground', 0, 0, 0),
 
-    'MarkerDefine' : (0,
-                      '''void %s(int markerNumber, int markerSymbol,
-                         const wxColour& foreground = wxNullColour,
-                         const wxColour& background = wxNullColour);''',
-
-                      '''void %s(int markerNumber, int markerSymbol,
-                            const wxColour& foreground,
-                            const wxColour& background) {
-
-                            SendMsg(%s, markerNumber, markerSymbol);
-                            if (foreground.Ok())
-                                MarkerSetForeground(markerNumber, foreground);
-                            if (background.Ok())
-                                MarkerSetBackground(markerNumber, background);''',
+    'MarkerDefine' :
+    (0,
+     '''void %s(int markerNumber, int markerSymbol,
+                const wxColour& foreground = wxNullColour,
+                const wxColour& background = wxNullColour);''',
+
+     '''void %s(int markerNumber, int markerSymbol,
+                const wxColour& foreground,
+                const wxColour& background) {
+
+                SendMsg(%s, markerNumber, markerSymbol);
+                if (foreground.Ok())
+                    MarkerSetForeground(markerNumber, foreground);
+                if (background.Ok())
+                    MarkerSetBackground(markerNumber, background);''',
+
+     ('Set the symbol used for a particular marker number,',
+      'and optionally the fore and background colours.')),
+
+
+    'MarkerDefinePixmap' :
+    ('MarkerDefineBitmap',
+     '''void %s(int markerNumber, const wxBitmap& bmp);''',
+     '''void %s(int markerNumber, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(%s, markerNumber, (long)buff);
+        delete [] buff;
+        ''',
+     ('Define a marker from a bitmap',)),
 
-                      ('Set the symbol used for a particular marker number,',
-                       'and optionally the fore and background colours.')),
 
     'SetMarginTypeN' : ('SetMarginType', 0, 0, 0),
     'GetMarginTypeN' : ('GetMarginType', 0, 0, 0),
@@ -189,32 +216,33 @@ methodOverrideMap = {
     'SetCaretFore' : ('SetCaretForeground', 0, 0, 0),
     'StyleSetFont' : ('StyleSetFaceName', 0, 0, 0),
 
-    'AssignCmdKey' : ('CmdKeyAssign',
-                      'void %s(int key, int modifiers, int cmd);',
+    'AssignCmdKey' :
+    ('CmdKeyAssign',
+     'void %s(int key, int modifiers, int cmd);',
 
-                      '''void %s(int key, int modifiers, int cmd) {
-                          SendMsg(%s, MAKELONG(key, modifiers), cmd);''',
+     '''void %s(int key, int modifiers, int cmd) {
+         SendMsg(%s, MAKELONG(key, modifiers), cmd);''',
+     0),
 
-                      0),
 
-    'ClearCmdKey' : ('CmdKeyClear',
-                      'void %s(int key, int modifiers);',
+    'ClearCmdKey' :
+    ('CmdKeyClear',
+     'void %s(int key, int modifiers);',
 
-                      '''void %s(int key, int modifiers) {
-                          SendMsg(%s, MAKELONG(key, modifiers));''',
-
-                      0),
+     '''void %s(int key, int modifiers) {
+         SendMsg(%s, MAKELONG(key, modifiers));''',
+     0),
 
     'ClearAllCmdKeys' : ('CmdKeyClearAll', 0, 0, 0),
 
 
-    'SetStylingEx' : ('SetStyleBytes',
-                      'void %s(int length, char* styleBytes);',
-
-                      '''void %s(int length, char* styleBytes) {
-                          SendMsg(%s, length, (long)styleBytes);''',
+    'SetStylingEx' :
+    ('SetStyleBytes',
+     'void %s(int length, char* styleBytes);',
 
-                      0),
+     '''void %s(int length, char* styleBytes) {
+        SendMsg(%s, length, (long)styleBytes);''',
+     0),
 
 
     'IndicSetStyle' : ('IndicatorSetStyle', 0, 0, 0),
@@ -245,129 +273,162 @@ methodOverrideMap = {
     'AutoCGetAutoHide' : ('AutoCompGetAutoHide', 0, 0, 0),
     'AutoCSetDropRestOfWord' : ('AutoCompSetDropRestOfWord', 0,0,0),
     'AutoCGetDropRestOfWord' : ('AutoCompGetDropRestOfWord', 0,0,0),
+    'AutoCGetTypeSeparator' : ('AutoCompGetTypeSeparator', 0, 0, 0),
+    'AutoCSetTypeSeparator' : ('AutoCompSetTypeSeparator', 0, 0, 0),
+
+    'RegisterImage' :
+    (0,
+     '''void %s(int type, const wxBitmap& bmp);''',
+     '''void %s(int type, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(%s, type, (long)buff);
+        delete [] buff;
+     ''',
+     ('Register an image for use in autocompletion lists.',)),
+
+
+    'ClearRegisteredImages' : (0, 0, 0,
+                               ('Clear all the registered images.',)),
 
 
     'SetHScrollBar' : ('SetUseHorizontalScrollBar', 0, 0, 0),
     'GetHScrollBar' : ('GetUseHorizontalScrollBar', 0, 0, 0),
 
+    'SetVScrollBar' : ('SetUseVerticalScrollBar', 0, 0, 0),
+    'GetVScrollBar' : ('GetUseVerticalScrollBar', 0, 0, 0),
+
     'GetCaretFore' : ('GetCaretForeground', 0, 0, 0),
 
     'GetUsePalette' : (None, 0, 0, 0),
 
-    'FindText' : (0,
-                  '''int %s(int minPos, int maxPos, const wxString& text, int flags=0);''',
-
-                  '''int %s(int minPos, int maxPos,
-                            const wxString& text,
-                            int flags) {
-                     TextToFind  ft;
-                     ft.chrg.cpMin = minPos;
-                     ft.chrg.cpMax = maxPos;
-                     wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                     ft.lpstrText = (char*)(const char*)buf;
-
-                     return SendMsg(%s, flags, (long)&ft);''',
-                  0),
-
-    'FormatRange' : (0,
-                     '''int %s(bool   doDraw,
-                               int    startPos,
-                               int    endPos,
-                               wxDC*  draw,
-                               wxDC*  target,  // Why does it use two? Can they be the same?
-                               wxRect renderRect,
-                               wxRect pageRect);''',
-                     ''' int %s(bool   doDraw,
-                                int    startPos,
-                                int    endPos,
-                                wxDC*  draw,
-                                wxDC*  target,  // Why does it use two? Can they be the same?
-                                wxRect renderRect,
-                                wxRect pageRect) {
-                            RangeToFormat fr;
-
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            fr.hdc = draw;
-                            fr.hdcTarget = target;
-                            fr.rc.top = renderRect.GetTop();
-                            fr.rc.left = renderRect.GetLeft();
-                            fr.rc.right = renderRect.GetRight();
-                            fr.rc.bottom = renderRect.GetBottom();
-                            fr.rcPage.top = pageRect.GetTop();
-                            fr.rcPage.left = pageRect.GetLeft();
-                            fr.rcPage.right = pageRect.GetRight();
-                            fr.rcPage.bottom = pageRect.GetBottom();
-                            fr.chrg.cpMin = startPos;
-                            fr.chrg.cpMax = endPos;
-
-                            return SendMsg(%s, doDraw, (long)&fr);''',
-                     0),
-
-
-    'GetLine' : (0,
-                    'wxString %s(int line);',
-
-                    '''wxString %s(int line) {
-                       int len = LineLength(line);
-                       if (!len) return wxEmptyString;
-
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                       SendMsg(%s, line, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       return stc2wx(buf);''',
-
-                    ('Retrieve the contents of a line.',)),
+    'FindText' :
+    (0,
+     '''int %s(int minPos, int maxPos, const wxString& text, int flags=0);''',
+
+     '''int %s(int minPos, int maxPos,
+               const wxString& text,
+               int flags) {
+            TextToFind  ft;
+            ft.chrg.cpMin = minPos;
+            ft.chrg.cpMax = maxPos;
+            wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+            ft.lpstrText = (char*)(const char*)buf;
+
+            return SendMsg(%s, flags, (long)&ft);''',
+     0),
+
+    'FormatRange' :
+    (0,
+     '''int %s(bool   doDraw,
+               int    startPos,
+               int    endPos,
+               wxDC*  draw,
+               wxDC*  target,  // Why does it use two? Can they be the same?
+               wxRect renderRect,
+               wxRect pageRect);''',
+     ''' int %s(bool   doDraw,
+                int    startPos,
+                int    endPos,
+                wxDC*  draw,
+                wxDC*  target,  // Why does it use two? Can they be the same?
+                wxRect renderRect,
+                wxRect pageRect) {
+             RangeToFormat fr;
+
+             if (endPos < startPos) {
+                 int temp = startPos;
+                 startPos = endPos;
+                 endPos = temp;
+             }
+             fr.hdc = draw;
+             fr.hdcTarget = target;
+             fr.rc.top = renderRect.GetTop();
+             fr.rc.left = renderRect.GetLeft();
+             fr.rc.right = renderRect.GetRight();
+             fr.rc.bottom = renderRect.GetBottom();
+             fr.rcPage.top = pageRect.GetTop();
+             fr.rcPage.left = pageRect.GetLeft();
+             fr.rcPage.right = pageRect.GetRight();
+             fr.rcPage.bottom = pageRect.GetBottom();
+             fr.chrg.cpMin = startPos;
+             fr.chrg.cpMax = endPos;
+
+             return SendMsg(%s, doDraw, (long)&fr);''',
+     0),
+
+
+    'GetLine' :
+    (0,
+     'wxString %s(int line);',
+
+     '''wxString %s(int line) {
+         int len = LineLength(line);
+         if (!len) return wxEmptyString;
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(%s, line, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+
+     ('Retrieve the contents of a line.',)),
 
     'SetSel' : ('SetSelection', 0, 0, 0),
-    'GetSelText' : ('GetSelectedText',
-                    'wxString %s();',
-
-                    '''wxString %s() {
-                            int   start;
-                            int   end;
-
-                            GetSelection(&start, &end);
-                            int   len  = end - start;
-                            if (!len) return wxEmptyString;
-
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                            SendMsg(%s, 0, (long)buf);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);''',
-
-                    ('Retrieve the selected text.',)),
-
-    'GetTextRange' : (0,
-                      'wxString %s(int startPos, int endPos);',
-
-                      '''wxString %s(int startPos, int endPos) {
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            int   len  = endPos - startPos;
-                            if (!len) return wxEmptyString;
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len);
-                            TextRange tr;
-                            tr.lpstrText = buf;
-                            tr.chrg.cpMin = startPos;
-                            tr.chrg.cpMax = endPos;
-                            SendMsg(%s, 0, (long)&tr);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);''',
-
-                       ('Retrieve a range of text.',)),
+
+    'GetSelText' :
+    ('GetSelectedText',
+     'wxString %s();',
+
+     '''wxString %s() {
+         int   start;
+         int   end;
+
+         GetSelection(&start, &end);
+         int   len  = end - start;
+         if (!len) return wxEmptyString;
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(%s, 0, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+
+     ('Retrieve the selected text.',)),
+
+
+    'GetTextRange' :
+    (0,
+     'wxString %s(int startPos, int endPos);',
+
+     '''wxString %s(int startPos, int endPos) {
+         if (endPos < startPos) {
+             int temp = startPos;
+             startPos = endPos;
+             endPos = temp;
+         }
+         int   len  = endPos - startPos;
+         if (!len) return wxEmptyString;
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len);
+         TextRange tr;
+         tr.lpstrText = buf;
+         tr.chrg.cpMin = startPos;
+         tr.chrg.cpMax = endPos;
+         SendMsg(%s, 0, (long)&tr);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+
+     ('Retrieve a range of text.',)),
 
     'PointXFromPosition' : (None, 0, 0, 0),
     'PointYFromPosition' : (None, 0, 0, 0),
@@ -376,88 +437,104 @@ methodOverrideMap = {
     'ReplaceSel' : ('ReplaceSelection', 0, 0, 0),
     'Null' : (None, 0, 0, 0),
 
-    'GetText' : (0,
-                 'wxString %s();',
+    'GetText' :
+    (0,
+     'wxString %s();',
 
-                 '''wxString %s() {
-                        int len  = GetTextLength();
-                        wxMemoryBuffer mbuf(len+1);   // leave room for the null...
-                        char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                        SendMsg(%s, len+1, (long)buf);
-                        mbuf.UngetWriteBuf(len);
-                        mbuf.AppendByte(0);
-                        return stc2wx(buf);''',
+     '''wxString %s() {
+         int len  = GetTextLength();
+         wxMemoryBuffer mbuf(len+1);   // leave room for the null...
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(%s, len+1, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
 
-                 ('Retrieve all the text in the document.', )),
+     ('Retrieve all the text in the document.', )),
 
     'GetDirectFunction' : (None, 0, 0, 0),
     'GetDirectPointer' : (None, 0, 0, 0),
 
-    'CallTipPosStart' : ('CallTipPosAtStart', 0, 0, 0),
-    'CallTipSetHlt' : ('CallTipSetHighlight', 0, 0, 0),
-    'CallTipSetBack' : ('CallTipSetBackground', 0, 0, 0),
-
-
-    'ReplaceTarget' : (0,
-                       'int %s(const wxString& text);',
-
-                       '''
-                       int %s(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
-                       0),
-
-    'ReplaceTargetRE' : (0,
-                       'int %s(const wxString& text);',
-
-                       '''
-                       int %s(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
-                       0),
-
-    'SearchInTarget' : (0,
-                       'int %s(const wxString& text);',
-
-                       '''
-                       int %s(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
-                       0),
-
-
-    'GetDocPointer' : (0,
-                       'void* %s();',
-                       '''void* %s() {
-                           return (void*)SendMsg(%s);''',
-                       0),
-
-    'SetDocPointer' : (0,
-                       'void %s(void* docPointer);',
-                       '''void %s(void* docPointer) {
-                           SendMsg(%s, 0, (long)docPointer);''',
-                       0),
-
-    'CreateDocument' : (0,
-                       'void* %s();',
-                       '''void* %s() {
-                           return (void*)SendMsg(%s);''',
-                        0),
-
-    'AddRefDocument' : (0,
-                       'void %s(void* docPointer);',
-                       '''void %s(void* docPointer) {
-                           SendMsg(%s, 0, (long)docPointer);''',
-                        0),
-
-    'ReleaseDocument' : (0,
-                       'void %s(void* docPointer);',
-                       '''void %s(void* docPointer) {
-                           SendMsg(%s, 0, (long)docPointer);''',
-                         0),
-    'SetCodePage' : (0,
-                     0,
-                     '''void %s(int codePage) {
+    'CallTipPosStart'   : ('CallTipPosAtStart', 0, 0, 0),
+    'CallTipSetHlt'     : ('CallTipSetHighlight', 0, 0, 0),
+    'CallTipSetBack'    : ('CallTipSetBackground', 0, 0, 0),
+    'CallTipSetFore'    : ('CallTipSetForeground', 0, 0, 0),
+    'CallTipSetForeHlt' : ('CallTipSetForegroundHighlight', 0, 0, 0),
+
+    'SetHotspotActiveFore' : ('SetHotspotActiveForeground', 0, 0, 0),
+    'SetHotspotActiveBack' : ('SetHotspotActiveBackground', 0, 0, 0),
+
+
+    'ReplaceTarget' :
+    (0,
+     'int %s(const wxString& text);',
+
+     '''
+     int %s(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
+     0),
+
+    'ReplaceTargetRE' :
+    (0,
+     'int %s(const wxString& text);',
+
+     '''
+     int %s(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
+     0),
+
+    'SearchInTarget' :
+    (0,
+     'int %s(const wxString& text);',
+
+     '''
+     int %s(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(%s, strlen(buf), (long)(const char*)buf);''',
+     0),
+
+
+    'GetDocPointer' :
+    (0,
+     'void* %s();',
+     '''void* %s() {
+         return (void*)SendMsg(%s);''',
+     0),
+
+    'SetDocPointer' :
+    (0,
+     'void %s(void* docPointer);',
+     '''void %s(void* docPointer) {
+         SendMsg(%s, 0, (long)docPointer);''',
+     0),
+
+    'CreateDocument' :
+    (0,
+     'void* %s();',
+     '''void* %s() {
+         return (void*)SendMsg(%s);''',
+     0),
+
+    'AddRefDocument' :
+    (0,
+     'void %s(void* docPointer);',
+     '''void %s(void* docPointer) {
+         SendMsg(%s, 0, (long)docPointer);''',
+     0),
+
+    'ReleaseDocument' :
+    (0,
+     'void %s(void* docPointer);',
+     '''void %s(void* docPointer) {
+         SendMsg(%s, 0, (long)docPointer);''',
+     0),
+
+    'SetCodePage' :
+    (0,
+     0,
+     '''void %s(int codePage) {
 #if wxUSE_UNICODE
     wxASSERT_MSG(codePage == wxSTC_CP_UTF8,
                  wxT("Only wxSTC_CP_UTF8 may be used when wxUSE_UNICODE is on."));
@@ -465,8 +542,8 @@ methodOverrideMap = {
     wxASSERT_MSG(codePage != wxSTC_CP_UTF8,
                  wxT("wxSTC_CP_UTF8 may not be used when wxUSE_UNICODE is off."));
 #endif
-                 SendMsg(%s, codePage);''',
-                         ("Set the code page used to interpret the bytes of the document as characters.",) ),
+    SendMsg(%s, codePage);''',
+     ("Set the code page used to interpret the bytes of the document as characters.",) ),
 
 
     'GrabFocus' : (None, 0, 0, 0),
@@ -474,6 +551,9 @@ methodOverrideMap = {
     'GetFocus'  : ('GetSTCFocus', 0, 0, 0),
 
 
+    'LoadLexerLibrary' : (None, 0,0,0),
+
+
 
     # Remove all methods that are key commands since they can be
     # executed with CmdKeyExecute
@@ -522,7 +602,16 @@ methodOverrideMap = {
     'LineScrollDown' : (None, 0, 0, 0),
     'LineScrollUp' : (None, 0, 0, 0),
     'DeleteBackNotLine' : (None, 0, 0, 0),
-
+    'HomeWrap' : (None, 0, 0, 0),
+    'HomeWrapExtend' : (None, 0, 0, 0),
+    'LineEndWrap' : (None, 0, 0, 0),
+    'LineEndWrapExtend' : (None, 0, 0, 0),
+    'VCHomeWrap' : (None, 0, 0, 0),
+    'VCHomeWrapExtend' : (None, 0, 0, 0),
+    'ParaDown' : (None, 0, 0, 0),
+    'ParaDownExtend' : (None, 0, 0, 0),
+    'ParaUp' : (None, 0, 0, 0),
+    'ParaUpExtend' : (None, 0, 0, 0),
 
 
 
index 5a9843f863077cb96a351b3658af499d9e606638..345d6590004c8d32f8a07b62bf2a9946fef0f816 100644 (file)
@@ -34,17 +34,21 @@ OBJECTS = \
         KeyWords.obj           \
        LexAVE.obj              \
        LexAda.obj              \
+       LexAsm.obj              \
        LexBaan.obj             \
        LexBullant.obj          \
        LexMatlab.obj           \
        LexCPP.obj              \
        LexConf.obj             \
        LexCrontab.obj          \
+       LexCSS.obj              \
        LexEiffel.obj           \
+       LexFortran.obj          \
        LexHTML.obj             \
        LexLisp.obj             \
        LexLua.obj              \
        LexOthers.obj           \
+       LexPOV.obj              \
        LexPascal.obj           \
        LexPerl.obj             \
        LexPython.obj           \
@@ -60,17 +64,19 @@ OBJECTS = \
        UniConversion.obj       \
         ViewStyle.obj          \
        WindowAccessor.obj      \
+       XPM.obj                 \
                                \
        PlatWX.obj              \
        ScintillaWX.obj         \
        stc.obj                 \
 
+
 STCCFG = stc.cfg
 STCCPPFLAGS=$(DLL_FLAGS) $(EXTRACPPFLAGS) @$(STCCFG)
 
 default: $(STCCFG) $(LIBTARGET)
 
-cleancfg: 
+cleancfg:
        del $(STCCFG)
 
 {$(S)}.cxx.obj:
index 4ae99521f58955ba58d28045ce8ac48b47da85f0..25dd4ad0cdb77a12739326d256be1cd933563e8c 100644 (file)
@@ -22,17 +22,21 @@ OBJECTS = \
         $(S)/KeyWords.$(OBJSUFF)       \
        $(S)/LexAVE.$(OBJSUFF)          \
        $(S)/LexAda.$(OBJSUFF)          \
+       $(S)/LexAsm.$(OBJSUFF)          \
        $(S)/LexBaan.$(OBJSUFF)         \
        $(S)/LexBullant.$(OBJSUFF)      \
        $(S)/LexMatlab.$(OBJSUFF)       \
        $(S)/LexCPP.$(OBJSUFF)          \
        $(S)/LexConf.$(OBJSUFF)         \
        $(S)/LexCrontab.$(OBJSUFF)      \
+       $(S)/LexCSS.$(OBJSUFF)          \
        $(S)/LexEiffel.$(OBJSUFF)       \
+       $(S)/LexFortran.$(OBJSUFF)      \
        $(S)/LexHTML.$(OBJSUFF)         \
        $(S)/LexLisp.$(OBJSUFF)         \
        $(S)/LexLua.$(OBJSUFF)          \
        $(S)/LexOthers.$(OBJSUFF)       \
+       $(S)/LexPOV.$(OBJSUFF)          \
        $(S)/LexPascal.$(OBJSUFF)       \
        $(S)/LexPerl.$(OBJSUFF)         \
        $(S)/LexPython.$(OBJSUFF)       \
@@ -48,11 +52,13 @@ OBJECTS = \
        $(S)/UniConversion.$(OBJSUFF)   \
         $(S)/ViewStyle.$(OBJSUFF)      \
        $(S)/WindowAccessor.$(OBJSUFF)  \
+       $(S)/XPM.$(OBJSUFF)             \
        \
        PlatWX.$(OBJSUFF) \
        ScintillaWX.$(OBJSUFF) \
        stc.$(OBJSUFF)
 
+
 LIBTARGET = $(WXDIR)/lib/libstc.a
 
 include $(WXDIR)/src/makelib.g95
\ No newline at end of file
index 9a3fdc08e79132fe0ee0d16377ed819a0edca812..4aa0e2c352f7b6b05c1a136e7de17098ad5d0409 100644 (file)
@@ -27,17 +27,21 @@ OBJECTS = \
         $(D)\KeyWords.obj              \
        $(D)\LexAVE.obj                 \
        $(D)\LexAda.obj                 \
+       $(D)\LexAsm.obj                 \
        $(D)\LexBaan.obj                \
        $(D)\LexBullant.obj             \
        $(D)\LexMatlab.obj              \
        $(D)\LexCPP.obj                 \
        $(D)\LexConf.obj                \
        $(D)\LexCrontab.obj             \
+       $(D)\LexCSS.obj                 \
        $(D)\LexEiffel.obj              \
+       $(D)\LexFortran.obj             \
        $(D)\LexHTML.obj                \
        $(D)\LexLisp.obj                \
        $(D)\LexLua.obj                 \
        $(D)\LexOthers.obj              \
+       $(D)\LexPOV.obj                 \
        $(D)\LexPascal.obj              \
        $(D)\LexPerl.obj                \
        $(D)\LexPython.obj              \
@@ -53,6 +57,7 @@ OBJECTS = \
        $(D)\UniConversion.obj          \
         $(D)\ViewStyle.obj             \
        $(D)\WindowAccessor.obj         \
+       $(D)\XPM.obj                    \
                                \
        $(D)\PlatWX.obj         \
        $(D)\ScintillaWX.obj    \
index 3a4201775649698be1eb5b1cf444e09277d928d0..76a2985a3bcd5afbfddfc0b312568b8d688bc57a 100644 (file)
@@ -31,17 +31,21 @@ OBJECTS = &
     KeyWords.obj               &
        LexAVE.obj                      &
        LexAda.obj                      &
+       LexAsm.obj                      &
        LexBaan.obj                     &
        LexBullant.obj              &
        LexMatlab.obj           &
        LexCPP.obj                      &
        LexConf.obj                     &
        LexCrontab.obj              &
+       LexCSS.obj                  &
        LexEiffel.obj               &
+       LexFortran.obj              &
        LexHTML.obj                     &
        LexLisp.obj                     &
        LexLua.obj                      &
        LexOthers.obj               &
+       LexPOV.obj                  &
        LexPascal.obj               &
        LexPerl.obj                     &
        LexPython.obj               &
@@ -57,9 +61,10 @@ OBJECTS = &
        UniConversion.obj           &
     ViewStyle.obj                  &
        WindowAccessor.obj          &
+       XPM.obj                     &
        PlatWX.obj              &
        ScintillaWX.obj         &
-       stc.obj     
+       stc.obj
 
 all: $(STCLIB) .SYMBOLIC
 
@@ -67,17 +72,17 @@ $(STCLIB): $(OBJECTS)
        *wlib /b /c /n /P=256 $(STCLIB) $(OBJECTS)
 
 clean:   .SYMBOLIC
-    -erase *.obj 
-    -erase *.bak 
-    -erase *.err 
-    -erase *.pch 
-    -erase $(STCLIB) 
+    -erase *.obj
+    -erase *.bak
+    -erase *.err
+    -erase *.pch
+    -erase $(STCLIB)
     -erase *.lbc
 
 .EXTENSIONS: .cxx
 .cxx: $(S)
 
 .cxx.obj:
-    $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS) 
+    $(CXX) $[*.cxx $(CXXFLAGS) $(STCEXTRACPPFLAGS)
 
 
diff --git a/src/stc/scintilla/License.txt b/src/stc/scintilla/License.txt
new file mode 100644 (file)
index 0000000..cbe25b2
--- /dev/null
@@ -0,0 +1,20 @@
+License for Scintilla and SciTE
+
+Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+
+All Rights Reserved 
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that 
+both that copyright notice and this permission notice appear in 
+supporting documentation. 
+
+NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY 
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 
+OR PERFORMANCE OF THIS SOFTWARE. 
\ No newline at end of file
index 8538707cdeb85e8ae6419a6d4e24074022a4619a..4f5b08f1cb81993e00bd72d2e1ddc16512ae23c2 100644 (file)
@@ -3,5 +3,4 @@ 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.48
-
+The current version of the Scintilla code is 1.52
index 0b2c4baee25cb8a8bc1768adf22a05c9a5fe2358..3f59c07939bad89bbb469d31eb992912022e6b92 100644 (file)
@@ -25,7 +25,7 @@ protected:
        char buf[bufferSize+1];
        int startPos;
        int endPos;
-       int codePage;   
+       int codePage;
 
        virtual bool InternalIsLeadByte(char ch)=0;
        virtual void Fill(int position)=0;
@@ -44,7 +44,7 @@ public:
                if (position < startPos || position >= endPos) {
                        Fill(position);
                        if (position < startPos || position >= endPos) {
-                               // Position is outside range of document 
+                               // Position is outside range of document
                                return chDefault;
                        }
                }
index df4e870c580f507203f57f61f2cc58a7af04a2fe..c51c88ef594b090d6323ac316f73d04651170b1c 100644 (file)
@@ -7,7 +7,7 @@
 
 typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
                   WordList *keywordlists[], Accessor &styler);
-                  
+
 /**
  * A LexerModule is responsible for lexing and folding a particular language.
  * The class maintains a list of LexerModules which can be searched to find a
@@ -26,7 +26,7 @@ protected:
 
 public:
        const char *languageName;
-       LexerModule(int language_, LexerFunction fnLexer_, 
+       LexerModule(int language_, LexerFunction fnLexer_,
                const char *languageName_=0, LexerFunction fnFolder_=0,
                const char * const wordListDescriptions_[] = NULL);
        int GetLanguage() const { return language; }
index 1a8dfaa96e0cad7e1e2e6d66fb1cf81684b1ece7..7f5985c7657bd39d2fec7197cd487aa1be985bd6 100644 (file)
@@ -3,7 +3,7 @@
  ** Interface to platform facilities. Also includes some basic utilities.
  ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef PLATFORM_H
@@ -109,6 +109,12 @@ public:
                return (right > other.left) && (left < other.right) &&
                        (bottom > other.top) && (top < other.bottom);
        }
+       void Move(int xDelta, int yDelta) {
+               left += xDelta;
+               top += yDelta;
+               right += xDelta;
+               bottom += yDelta;
+       }
        int Width() { return right - left; }
        int Height() { return bottom - top; }
 };
@@ -136,7 +142,7 @@ public:
        }
 
        ColourDesired(unsigned int red, unsigned int green, unsigned int blue) {
-               co = red | (green << 8) | (blue << 16);
+               Set(red, green, blue);
        }
 
        bool operator==(const ColourDesired &other) const {
@@ -147,6 +153,31 @@ public:
                co = lcol;
        }
 
+       void Set(unsigned int red, unsigned int green, unsigned int blue) {
+               co = red | (green << 8) | (blue << 16);
+       }
+
+       static inline unsigned int ValueOfHex(const char ch) {
+               if (ch >= '0' && ch <= '9')
+                       return ch - '0';
+               else if (ch >= 'A' && ch <= 'F')
+                       return ch - 'A' + 10;
+               else if (ch >= 'a' && ch <= 'f')
+                       return ch - 'a' + 10;
+               else
+                       return 0;
+       }
+
+       void Set(const char *val) {
+               if (*val == '#') {
+                       val++;
+               }
+               unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]);
+               unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]);
+               unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]);
+               Set(r, g, b);
+       }
+
        long AsLong() const {
                return co;
        }
@@ -196,6 +227,9 @@ struct ColourPair {
                desired = desired_;
                allocated.Set(desired.AsLong());
        }
+       void Copy() {
+               allocated.Set(desired.AsLong());
+       }
 };
 
 class Window;  // Forward declaration for Palette
@@ -271,9 +305,9 @@ public:
        virtual ~Surface() {};
        static Surface *Allocate();
 
-       virtual void Init()=0;
-       virtual void Init(SurfaceID sid)=0;
-       virtual void InitPixMap(int width, int height, Surface *surface_)=0;
+       virtual void Init(WindowID wid)=0;
+       virtual void Init(SurfaceID sid, WindowID wid)=0;
+       virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0;
 
        virtual void Release()=0;
        virtual bool Initialised()=0;
@@ -292,6 +326,7 @@ public:
 
        virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
        virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0;
+       virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0;
        virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0;
        virtual int WidthText(Font &font_, const char *s, int len)=0;
        virtual int WidthChar(Font &font_, char ch)=0;
@@ -307,6 +342,7 @@ public:
        virtual void FlushCachedState()=0;
 
        virtual void SetUnicodeMode(bool unicodeMode_)=0;
+       virtual void SetDBCSMode(int codePage)=0;
 };
 
 /**
@@ -329,8 +365,8 @@ public:
                id = id_;
                return *this;
        }
-       WindowID GetID() { return id; }
-       bool Created() { return id != 0; }
+       WindowID GetID() const { return id; }
+       bool Created() const { return id != 0; }
        void Destroy();
        bool HasFocus();
        PRectangle GetPosition();
@@ -341,7 +377,7 @@ public:
        void InvalidateAll();
        void InvalidateRectangle(PRectangle rc);
        virtual void SetFont(Font &font);
-       enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow };
+       enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
        void SetCursor(Cursor curs);
        void SetTitle(const char *s);
 private:
@@ -353,38 +389,28 @@ private:
  */
 
 class ListBox : public Window {
-private:
-#if PLAT_GTK
-       WindowID list;
-       WindowID scroller;
-       int current;
-#endif
-       int desiredVisibleRows;
-       unsigned int maxItemCharacters;
-       unsigned int aveCharWidth;
-public:
-       CallBackAction doubleClickAction;
-       void *doubleClickActionData;
 public:
        ListBox();
        virtual ~ListBox();
-       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();
-       void Select(int n);
-       int GetSelection();
-       int Find(const char *prefix);
-       void GetValue(int n, char *value, int len);
-       void Sort();
-       void SetDoubleClickAction(CallBackAction action, void *data) {
-               doubleClickAction = action;
-               doubleClickActionData = data;
-       }
+       static ListBox *Allocate();
+
+       virtual void SetFont(Font &font)=0;
+       virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_)=0;
+       virtual void SetAverageCharWidth(int width)=0;
+       virtual void SetVisibleRows(int rows)=0;
+       virtual PRectangle GetDesiredRect()=0;
+       virtual int CaretFromEdge()=0;
+       virtual void Clear()=0;
+       virtual void Append(char *s, int type = -1)=0;
+       virtual int Length()=0;
+       virtual void Select(int n)=0;
+       virtual int GetSelection()=0;
+       virtual int Find(const char *prefix)=0;
+       virtual void GetValue(int n, char *value, int len)=0;
+       virtual void Sort()=0;
+       virtual void RegisterImage(int type, const char *xpm_data)=0;
+       virtual void ClearRegisteredImages()=0;
+       virtual void SetDoubleClickAction(CallBackAction, void *)=0;
 };
 
 /**
@@ -426,6 +452,7 @@ public:
        static const char *DefaultFont();
        static int DefaultFontSize();
        static unsigned int DoubleClickTime();
+       static bool MouseButtonBounce();
        static void DebugDisplay(const char *s);
        static bool IsKeyDown(int key);
        static long SendScintilla(
@@ -433,6 +460,8 @@ public:
        static long SendScintillaPointer(
                WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0);
        static bool IsDBCSLeadByte(int codePage, char ch);
+       static int DBCSCharLength(int codePage, const char *s);
+       static int DBCSCharMaxLength();
 
        // These are utility functions not really tied to a platform
        static int Minimum(int a, int b);
index 59588c62edc08fca5cfa351765eff3c5a1c258da..3f1b64f77fc89ea026e39a9730cfc157e441c6e2 100644 (file)
@@ -60,7 +60,7 @@ public:
        bool onlyLineEnds;      ///< Delimited by any white space or only line ends
        bool sorted;
        int starts[256];
-       WordList(bool onlyLineEnds_ = false) : 
+       WordList(bool onlyLineEnds_ = false) :
                words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), sorted(false) {}
        ~WordList() { Clear(); }
        operator bool() { return len ? true : false; }
@@ -70,9 +70,9 @@ public:
        char *Allocate(int size);
        void SetFromAllocated();
        bool InList(const char *s);
-       const char *GetNearestWord(const char *wordStart, int searchLen = -1, 
+       const char *GetNearestWord(const char *wordStart, int searchLen = -1,
                bool ignoreCase = false, SString wordCharacters="");
-       char *GetNearestWords(const char *wordStart, int searchLen=-1, 
+       char *GetNearestWords(const char *wordStart, int searchLen=-1,
                bool ignoreCase=false, char otherSeparator='\0');
 };
 
index 3c7ccc33a51622610aef1b261992b201fc655602..01602df7816fbc65d28c4fd4f7af1e4b6423fd09 100644 (file)
@@ -238,7 +238,7 @@ public:
                return append(sOther, static_cast<lenpos_t>(measure_length));
        }
        SString &operator+=(const SString &sOther) {
-               return append(sOther.s, sOther.sSize);
+               return append(sOther.s, sOther.sLen);
        }
        SString &operator+=(char ch) {
                return append(&ch, 1);
@@ -369,11 +369,7 @@ public:
  */
 inline char *StringDup(
        const char *s,                  ///< The string to duplicate
-        /* gcc 2.96 doesn't seem to like this syntax: gives
-           'non-local function uses anonymous type'
-           SString::lenpos_t len=SString::measure_length)      ///< The length of memory to allocate. Optional.
-        */
-        SString::lenpos_t len=0xffffffffU)     ///< The length of memory to allocate. Optional.
+       SString::lenpos_t len=SString::measure_length)  ///< The length of memory to allocate. Optional.
 {
        return SString::StringAllocate(s, len);
 }
index a6066cd58519563197cee2a2054a67baa3e38d0e..e1da492b279f122423d359d340eff396e953e7fb 100644 (file)
 #define SCLEX_BAAN 31
 #define SCLEX_MATLAB 32
 #define SCLEX_SCRIPTOL 33
+#define SCLEX_ASM 34
+#define SCLEX_CPPNOCASE 35
+#define SCLEX_FORTRAN 36
+#define SCLEX_F77 37
+#define SCLEX_CSS 38
+#define SCLEX_POV 39
 #define SCLEX_AUTOMATIC 1000
 #define SCE_P_DEFAULT 0
 #define SCE_P_COMMENTLINE 1
 #define SCE_ERR_DIFF_ADDITION 11
 #define SCE_ERR_DIFF_DELETION 12
 #define SCE_ERR_DIFF_MESSAGE 13
+#define SCE_ERR_PHP 14
+#define SCE_ERR_ELF 15
+#define SCE_ERR_IFC 16
 #define SCE_BAT_DEFAULT 0
 #define SCE_BAT_COMMENT 1
 #define SCE_BAT_WORD 2
 #define SCE_AVE_COMMENT 1
 #define SCE_AVE_NUMBER 2
 #define SCE_AVE_WORD 3
-#define SCE_AVE_KEYWORD 4
-#define SCE_AVE_STATEMENT 5
 #define SCE_AVE_STRING 6
 #define SCE_AVE_ENUM 7
 #define SCE_AVE_STRINGEOL 8
 #define SCE_AVE_IDENTIFIER 9
 #define SCE_AVE_OPERATOR 10
+#define SCE_AVE_WORD1 11
+#define SCE_AVE_WORD2 12
+#define SCE_AVE_WORD3 13
+#define SCE_AVE_WORD4 14
+#define SCE_AVE_WORD5 15
+#define SCE_AVE_WORD6 16
 #define SCE_ADA_DEFAULT 0
-#define SCE_ADA_COMMENT 1
-#define SCE_ADA_NUMBER 2
-#define SCE_ADA_WORD 3
-#define SCE_ADA_STRING 4
+#define SCE_ADA_WORD 1
+#define SCE_ADA_IDENTIFIER 2
+#define SCE_ADA_NUMBER 3
+#define SCE_ADA_DELIMITER 4
 #define SCE_ADA_CHARACTER 5
-#define SCE_ADA_OPERATOR 6
-#define SCE_ADA_IDENTIFIER 7
+#define SCE_ADA_CHARACTEREOL 6
+#define SCE_ADA_STRING 7
 #define SCE_ADA_STRINGEOL 8
+#define SCE_ADA_LABEL 9
+#define SCE_ADA_COMMENTLINE 10
+#define SCE_ADA_ILLEGAL 11
 #define SCE_BAAN_DEFAULT 0
 #define SCE_BAAN_COMMENT 1
 #define SCE_BAAN_COMMENTDOC 2
 #define SCE_SCRIPTOL_COMMENTDOCKEYWORD 17
 #define SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR 18
 #define SCE_SCRIPTOL_COMMENTBASIC 19
+#define SCE_ASM_DEFAULT 0
+#define SCE_ASM_COMMENT 1
+#define SCE_ASM_NUMBER 2
+#define SCE_ASM_STRING 3
+#define SCE_ASM_OPERATOR 4
+#define SCE_ASM_IDENTIFIER 5
+#define SCE_ASM_CPUINSTRUCTION 6
+#define SCE_ASM_MATHINSTRUCTION 7
+#define SCE_ASM_REGISTER 8
+#define SCE_ASM_DIRECTIVE 9
+#define SCE_ASM_DIRECTIVEOPERAND 10
+#define SCE_F_DEFAULT 0
+#define SCE_F_COMMENT 1
+#define SCE_F_NUMBER 2
+#define SCE_F_STRING1 3
+#define SCE_F_STRING2 4
+#define SCE_F_STRINGEOL 5
+#define SCE_F_OPERATOR 6
+#define SCE_F_IDENTIFIER 7
+#define SCE_F_WORD 8
+#define SCE_F_WORD2 9
+#define SCE_F_WORD3 10
+#define SCE_F_PREPROCESSOR 11
+#define SCE_F_OPERATOR2 12
+#define SCE_F_LABEL 13
+#define SCE_F_CONTINUATION 14
+#define SCE_CSS_DEFAULT 0
+#define SCE_CSS_TAG 1
+#define SCE_CSS_CLASS 2
+#define SCE_CSS_PSEUDOCLASS 3
+#define SCE_CSS_UNKNOWN_PSEUDOCLASS 4
+#define SCE_CSS_OPERATOR 5
+#define SCE_CSS_IDENTIFIER 6
+#define SCE_CSS_UNKNOWN_IDENTIFIER 7
+#define SCE_CSS_VALUE 8
+#define SCE_CSS_COMMENT 9
+#define SCE_CSS_ID 10
+#define SCE_CSS_IMPORTANT 11
+#define SCE_CSS_DIRECTIVE 12
+#define SCE_CSS_DOUBLESTRING 13
+#define SCE_CSS_SINGLESTRING 14
+#define SCE_POV_DEFAULT 0
+#define SCE_POV_COMMENT 1
+#define SCE_POV_COMMENTLINE 2
+#define SCE_POV_COMMENTDOC 3
+#define SCE_POV_NUMBER 4
+#define SCE_POV_WORD 5
+#define SCE_POV_STRING 6
+#define SCE_POV_OPERATOR 7
+#define SCE_POV_IDENTIFIER 8
+#define SCE_POV_BRACE 9
+#define SCE_POV_WORD2 10
 //--Autogenerated -- end of section automatically generated from Scintilla.iface
 
 #endif
index 30fcf50fc400e9ab082e3dabde2c36fec57980c1..c377d07cc20a90b6957832351f25b69d4b4dda77 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Scintilla.h
  ** Interface to the edit control.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 // Most of this file is automatically generated from the Scintilla.iface interface definition
@@ -83,6 +83,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETTABWIDTH 2036
 #define SCI_GETTABWIDTH 2121
 #define SC_CP_UTF8 65001
+#define SC_CP_DBCS 1
 #define SCI_SETCODEPAGE 2037
 #define SCI_SETUSEPALETTE 2039
 #define MARKER_MAX 31
@@ -111,6 +112,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MARK_BACKGROUND 22
 #define SC_MARK_DOTDOTDOT 23
 #define SC_MARK_ARROWS 24
+#define SC_MARK_PIXMAP 25
 #define SC_MARK_CHARACTER 10000
 #define SC_MARKNUM_FOLDEREND 25
 #define SC_MARKNUM_FOLDEROPENMID 26
@@ -129,6 +131,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_MARKERGET 2046
 #define SCI_MARKERNEXT 2047
 #define SCI_MARKERPREVIOUS 2048
+#define SCI_MARKERDEFINEPIXMAP 2049
 #define SC_MARGIN_SYMBOL 0
 #define SC_MARGIN_NUMBER 1
 #define SCI_SETMARGINTYPEN 2240
@@ -181,6 +184,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_CASE_LOWER 2
 #define SCI_STYLESETCASE 2060
 #define SCI_STYLESETCHARACTERSET 2066
+#define SCI_STYLESETHOTSPOT 2409
 #define SCI_SETSELFORE 2067
 #define SCI_SETSELBACK 2068
 #define SCI_SETCARETFORE 2069
@@ -241,6 +245,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_AUTOCGETAUTOHIDE 2119
 #define SCI_AUTOCSETDROPRESTOFWORD 2270
 #define SCI_AUTOCGETDROPRESTOFWORD 2271
+#define SCI_REGISTERIMAGE 2405
+#define SCI_CLEARREGISTEREDIMAGES 2408
+#define SCI_AUTOCGETTYPESEPARATOR 2285
+#define SCI_AUTOCSETTYPESEPARATOR 2286
 #define SCI_SETINDENT 2122
 #define SCI_GETINDENT 2123
 #define SCI_SETUSETABS 2124
@@ -278,6 +286,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCFIND_MATCHCASE 4
 #define SCFIND_WORDSTART 0x00100000
 #define SCFIND_REGEXP 0x00200000
+#define SCFIND_POSIX 0x00400000
 #define SCI_FINDTEXT 2150
 #define SCI_FORMATRANGE 2151
 #define SCI_GETFIRSTVISIBLELINE 2152
@@ -333,11 +342,17 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_CALLTIPPOSSTART 2203
 #define SCI_CALLTIPSETHLT 2204
 #define SCI_CALLTIPSETBACK 2205
+#define SCI_CALLTIPSETFORE 2206
+#define SCI_CALLTIPSETFOREHLT 2207
 #define SCI_VISIBLEFROMDOCLINE 2220
 #define SCI_DOCLINEFROMVISIBLE 2221
 #define SC_FOLDLEVELBASE 0x400
 #define SC_FOLDLEVELWHITEFLAG 0x1000
 #define SC_FOLDLEVELHEADERFLAG 0x2000
+#define SC_FOLDLEVELBOXHEADERFLAG 0x4000
+#define SC_FOLDLEVELBOXFOOTERFLAG 0x8000
+#define SC_FOLDLEVELCONTRACTED 0x10000
+#define SC_FOLDLEVELUNINDENT 0x20000
 #define SC_FOLDLEVELNUMBERMASK 0x0FFF
 #define SCI_SETFOLDLEVEL 2222
 #define SCI_GETFOLDLEVEL 2223
@@ -350,6 +365,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETFOLDEXPANDED 2230
 #define SCI_TOGGLEFOLD 2231
 #define SCI_ENSUREVISIBLE 2232
+#define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002
+#define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004
+#define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
+#define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
+#define SC_FOLDFLAG_LEVELNUMBERS 0x0040
+#define SC_FOLDFLAG_BOX 0x0001
 #define SCI_SETFOLDFLAGS 2233
 #define SCI_ENSUREVISIBLEENFORCEPOLICY 2234
 #define SCI_SETTABINDENTS 2260
@@ -377,6 +398,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETENDATLASTLINE 2277
 #define SCI_GETENDATLASTLINE 2278
 #define SCI_TEXTHEIGHT 2279
+#define SCI_SETVSCROLLBAR 2280
+#define SCI_GETVSCROLLBAR 2281
+#define SCI_APPENDTEXT 2282
+#define SCI_GETTWOPHASEDRAW 2283
+#define SCI_SETTWOPHASEDRAW 2284
+#define SCI_TARGETFROMSELECTION 2287
+#define SCI_LINESJOIN 2288
+#define SCI_LINESSPLIT 2289
+#define SCI_SETFOLDMARGINCOLOUR 2290
+#define SCI_SETFOLDMARGINHICOLOUR 2291
 #define SCI_LINEDOWN 2300
 #define SCI_LINEDOWNEXTEND 2301
 #define SCI_LINEUP 2302
@@ -417,6 +448,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_LINECUT 2337
 #define SCI_LINEDELETE 2338
 #define SCI_LINETRANSPOSE 2339
+#define SCI_LINEDUPLICATE 2404
 #define SCI_LOWERCASE 2340
 #define SCI_UPPERCASE 2341
 #define SCI_LINESCROLLDOWN 2342
@@ -426,6 +458,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_HOMEDISPLAYEXTEND 2346
 #define SCI_LINEENDDISPLAY 2347
 #define SCI_LINEENDDISPLAYEXTEND 2348
+#define SCI_HOMEWRAP 2349
+#define SCI_HOMEWRAPEXTEND 2450
+#define SCI_LINEENDWRAP 2451
+#define SCI_LINEENDWRAPEXTEND 2452
+#define SCI_VCHOMEWRAP 2453
+#define SCI_VCHOMEWRAPEXTEND 2454
 #define SCI_MOVECARETINSIDEVIEW 2401
 #define SCI_LINELENGTH 2350
 #define SCI_BRACEHIGHLIGHT 2351
@@ -464,7 +502,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETMOUSEDOWNCAPTURES 2384
 #define SCI_GETMOUSEDOWNCAPTURES 2385
 #define SC_CURSORNORMAL -1
-#define SC_CURSORWAIT 3
+#define SC_CURSORWAIT 4
 #define SCI_SETCURSOR 2386
 #define SCI_GETCURSOR 2387
 #define SCI_SETCONTROLCHARSYMBOL 2388
@@ -480,6 +518,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_DELLINERIGHT 2396
 #define SCI_SETXOFFSET 2397
 #define SCI_GETXOFFSET 2398
+#define SCI_CHOOSECARETX 2399
 #define SCI_GRABFOCUS 2400
 #define CARET_SLOP 0x01
 #define CARET_STRICT 0x04
@@ -487,6 +526,15 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define CARET_EVEN 0x08
 #define SCI_SETXCARETPOLICY 2402
 #define SCI_SETYCARETPOLICY 2403
+#define SCI_SETPRINTWRAPMODE 2406
+#define SCI_GETPRINTWRAPMODE 2407
+#define SCI_SETHOTSPOTACTIVEFORE 2410
+#define SCI_SETHOTSPOTACTIVEBACK 2411
+#define SCI_SETHOTSPOTACTIVEUNDERLINE 2412
+#define SCI_PARADOWN 2413
+#define SCI_PARADOWNEXTEND 2414
+#define SCI_PARAUP 2415
+#define SCI_PARAUPEXTEND 2416
 #define SCI_STARTRECORD 3001
 #define SCI_STOPRECORD 3002
 #define SCI_SETLEXER 4001
@@ -495,6 +543,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETPROPERTY 4004
 #define SCI_SETKEYWORDS 4005
 #define SCI_SETLEXERLANGUAGE 4006
+#define SCI_LOADLEXERLIBRARY 4007
 #define SC_MOD_INSERTTEXT 0x1
 #define SC_MOD_DELETETEXT 0x2
 #define SC_MOD_CHANGESTYLE 0x4
@@ -548,6 +597,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCN_DWELLSTART 2016
 #define SCN_DWELLEND 2017
 #define SCN_ZOOM 2018
+#define SCN_HOTSPOTCLICK 2019
+#define SCN_HOTSPOTDOUBLECLICK 2020
+#define SCN_CALLTIPCLICK 2021
 //--Autogenerated -- end of section automatically generated from Scintilla.iface
 
 // These structures are defined to be exactly the same shape as the Win32
index d6383b103bb9300ce08ed383b18630b8cfb2295e..c5dacbdf048033cd972491020e66635bb7f88c05 100644 (file)
@@ -221,6 +221,9 @@ get int GetTabWidth=2121(,)
 # This is the same value as CP_UTF8 in Windows
 val SC_CP_UTF8=65001
 
+# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+val SC_CP_DBCS=1
+
 # Set the code page used to interpret the bytes of the document as characters.
 # The SC_CP_UTF8 value can be used to enter Unicode mode.
 set void SetCodePage=2037(int codePage,)
@@ -260,6 +263,7 @@ val SC_MARK_CIRCLEMINUSCONNECTED=21
 val SC_MARK_BACKGROUND=22
 val SC_MARK_DOTDOTDOT=23
 val SC_MARK_ARROWS=24
+val SC_MARK_PIXMAP=25
 
 val SC_MARK_CHARACTER=10000
 
@@ -302,6 +306,9 @@ fun int MarkerNext=2047(int lineStart, int markerMask)
 # Find the previous line before lineStart that includes a marker in mask.
 fun int MarkerPrevious=2048(int lineStart, int markerMask)
 
+# Define a marker from a pixmap.
+fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
+
 enu MarginType=SC_MARGIN_
 val SC_MARGIN_SYMBOL=0
 val SC_MARGIN_NUMBER=1
@@ -405,6 +412,9 @@ set void StyleSetCase=2060(int style, int caseForce)
 # Set the character set of the font in a style.
 set void StyleSetCharacterSet=2066(int style, int characterSet)
 
+# Set a style to be a hotspot or not.
+set void StyleSetHotSpot=2409(int style, bool hotspot)
+
 # Set the foreground colour of the selection and whether to use this setting.
 fun void SetSelFore=2067(bool useSetting, colour fore)
 
@@ -578,6 +588,19 @@ set void AutoCSetDropRestOfWord=2270(bool dropRestOfWord,)
 # after the inserted text upon completion.
 get bool AutoCGetDropRestOfWord=2271(,)
 
+# Register an XPM image for use in autocompletion lists.
+fun void RegisterImage=2405(int type, string xpmData)
+
+# Clear all the registered XPM images.
+fun void ClearRegisteredImages=2408(,)
+
+# Retrieve the auto-completion list type-separator character.
+get int AutoCGetTypeSeparator=2285(,)
+
+# Change the type-separator character in the string setting up an auto-completion list.
+# Default is '?' but can be changed if items contain '?'.
+set void AutoCSetTypeSeparator=2286(int separatorCharacter,)
+
 # Set the number of spaces used for one level of indentation.
 set void SetIndent=2122(int indentSize,)
 
@@ -681,6 +704,7 @@ val SCFIND_WHOLEWORD=2
 val SCFIND_MATCHCASE=4
 val SCFIND_WORDSTART=0x00100000
 val SCFIND_REGEXP=0x00200000
+val SCFIND_POSIX=0x00400000
 
 # Find some text in the document.
 fun position FindText=2150(int flags, findtext ft)
@@ -688,7 +712,7 @@ fun position FindText=2150(int flags, findtext ft)
 # On Windows, will draw the document into a display context such as a printer.
 fun void FormatRange=2151(bool draw, formatrange fr)
 
-# Retrieve the line at the top of the display.
+# Retrieve the display line at the top of the display.
 get int GetFirstVisibleLine=2152(,)
 
 # Retrieve the contents of a line.
@@ -863,6 +887,12 @@ fun void CallTipSetHlt=2204(int start, int end)
 # Set the background colour for the call tip.
 set void CallTipSetBack=2205(colour back,)
 
+# Set the foreground colour for the call tip.
+set void CallTipSetFore=2206(colour fore,)
+
+# Set the foreground colour for the highlighted part of the call tip.
+set void CallTipSetForeHlt=2207(colour fore,)
+
 # Find the display line of a document line taking hidden lines into account.
 fun int VisibleFromDocLine=2220(int line,)
 
@@ -873,6 +903,10 @@ enu FoldLevel=SC_FOLDLEVEL
 val SC_FOLDLEVELBASE=0x400
 val SC_FOLDLEVELWHITEFLAG=0x1000
 val SC_FOLDLEVELHEADERFLAG=0x2000
+val SC_FOLDLEVELBOXHEADERFLAG=0x4000
+val SC_FOLDLEVELBOXFOOTERFLAG=0x8000
+val SC_FOLDLEVELCONTRACTED=0x10000
+val SC_FOLDLEVELUNINDENT=0x20000
 val SC_FOLDLEVELNUMBERMASK=0x0FFF
 
 # Set the fold level of a line.
@@ -910,7 +944,15 @@ fun void ToggleFold=2231(int line,)
 # Ensure a particular line is visible by expanding any header line hiding it.
 fun void EnsureVisible=2232(int line,)
 
-# Set some debugging options for folding.
+enu FoldFlag=SC_FOLDFLAG_
+val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002
+val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004
+val SC_FOLDFLAG_LINEAFTER_EXPANDED=0x0008
+val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010
+val SC_FOLDFLAG_LEVELNUMBERS=0x0040
+val SC_FOLDFLAG_BOX=0x0001
+
+# Set some style options for folding.
 fun void SetFoldFlags=2233(int flags,)
 
 # Ensure a particular line is visible by expanding any header line hiding it.
@@ -988,6 +1030,38 @@ get int GetEndAtLastLine=2278(,)
 # Retrieve the height of a particular line of text in pixels.
 fun int TextHeight=2279(int line,)
 
+# Show or hide the vertical scroll bar.
+set void SetVScrollBar=2280(bool show,)
+
+# Is the vertical scroll bar visible?
+get bool GetVScrollBar=2281(,)
+
+# Append a string to the end of the document without changing the selection.
+fun void AppendText=2282(int length, string text)
+
+# Is drawing done in two phases with backgrounds drawn before foregrounds?
+get bool GetTwoPhaseDraw=2283(,)
+
+# In twoPhaseDraw mode, drawing is performed in two phases, first the background
+# and then the foreground. This avoids chopping off characters that overlap the next run.
+set void SetTwoPhaseDraw=2284(bool twoPhase,)
+
+# Make the target range start and end be the same as the selection range start and end.
+fun void TargetFromSelection=2287(,)
+
+# Join the lines in the target.
+fun void LinesJoin=2288(,)
+
+# Split the lines in the target into lines that are less wide than pixelWidth
+# where possible.
+fun void LinesSplit=2289(int pixelWidth,)
+
+# Set the colours used as a chequerboard pattern in the fold margin
+fun void SetFoldMarginColour=2290(bool useSetting, colour back)
+fun void SetFoldMarginHiColour=2291(bool useSetting, colour fore)
+
+## New messages go here
+
 ## Start of key messages
 # Move caret down one line.
 fun void LineDown=2300(,)
@@ -1111,6 +1185,9 @@ fun void LineDelete=2338(,)
 # Switch the current line with the previous.
 fun void LineTranspose=2339(,)
 
+# Duplicate the current line.
+fun void LineDuplicate=2404(,)
+
 # Transform the selection to lower case.
 fun void LowerCase=2340(,)
 
@@ -1141,6 +1218,19 @@ fun void LineEndDisplay=2347(,)
 # caret position.
 fun void LineEndDisplayExtend=2348(,)
 
+# These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)?
+# except they behave differently when word-wrap is enabled:
+# They go first to the start / end of the display line, like (Home|LineEnd)Display
+# The difference is that, the cursor is already at the point, it goes on to the start
+# or end of the document line, as appropriate for (Home|LineEnd|VCHome)Extend.
+
+fun void HomeWrap=2349(,)
+fun void HomeWrapExtend=2450(,)
+fun void LineEndWrap=2451(,)
+fun void LineEndWrapExtend=2452(,)
+fun void VCHomeWrap=2453(,)
+fun void VCHomeWrapExtend=2454(,)
+
 # Move the caret inside current view if it's not there already.
 fun void MoveCaretInsideView=2401(,)
 
@@ -1251,7 +1341,7 @@ get bool GetMouseDownCaptures=2385(,)
 
 enu CursorShape=SC_CURSOR
 val SC_CURSORNORMAL=-1
-val SC_CURSORWAIT=3
+val SC_CURSORWAIT=4
 # Sets the cursor to one of the SC_CURSOR* values.
 set void SetCursor=2386(int cursorType,)
 # Get cursor type.
@@ -1291,6 +1381,9 @@ fun void DelLineRight=2396(,)
 set void SetXOffset=2397(int newOffset,)
 get int GetXOffset=2398(,)
 
+# Set the last x chosen value to be the caret x position
+fun void ChooseCaretX=2399(,)
+
 # Set the focus to this Scintilla widget.
 # GTK+ Specific.
 fun void GrabFocus=2400(,)
@@ -1327,6 +1420,27 @@ fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop)
 # The exclusion zone is given in lines.
 fun void SetYCaretPolicy=2403(int caretPolicy, int caretSlop)
 
+# Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).
+set void SetPrintWrapMode=2406(int mode,)
+
+# Is printing line wrapped.
+get int GetPrintWrapMode=2407(,)
+
+# Set a fore colour for active hotspots.
+set void SetHotspotActiveFore=2410(bool useSetting, colour fore)
+
+# Set a back colour for active hotspots.
+set void SetHotspotActiveBack=2411(bool useSetting, colour back)
+
+# Enable / Disable underlining active hotspots.
+set void SetHotspotActiveUnderline=2412(bool underline,)
+
+# Move caret between paragraphs (delimited by empty lines)
+fun void ParaDown=2413(,)
+fun void ParaDownExtend=2414(,)
+fun void ParaUp=2415(,)
+fun void ParaUpExtend=2416(,)
+
 # Start notifying the container of all key presses and commands.
 fun void StartRecord=3001(,)
 
@@ -1351,6 +1465,10 @@ set void SetKeyWords=4005(int keywordSet, string keyWords)
 # Set the lexing language of the document based on string name.
 set void SetLexerLanguage=4006(, string language)
 
+# Load a lexer library (dll / so)
+# NOT YET IMPLEMENTED
+fun void LoadLexerLibrary=4007(, string path)
+
 # Notifications
 # Type of modification and the action which caused the modification.
 # These are defined as a bit mask to make it easy to specify which notifications are wanted.
@@ -1442,6 +1560,12 @@ val SCLEX_PHP=30
 val SCLEX_BAAN=31
 val SCLEX_MATLAB=32
 val SCLEX_SCRIPTOL=33
+val SCLEX_ASM=34
+val SCLEX_CPPNOCASE=35
+val SCLEX_FORTRAN=36
+val SCLEX_F77=37
+val SCLEX_CSS=38
+val SCLEX_POV=39
 
 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 # value assigned in sequence from SCLEX_AUTOMATIC+1.
@@ -1708,6 +1832,9 @@ val SCE_ERR_DIFF_CHANGED=10
 val SCE_ERR_DIFF_ADDITION=11
 val SCE_ERR_DIFF_DELETION=12
 val SCE_ERR_DIFF_MESSAGE=13
+val SCE_ERR_PHP=14
+val SCE_ERR_ELF=15
+val SCE_ERR_IFC=16
 # Lexical states for SCLEX_BATCH
 lex Batch=SCLEX_BATCH SCE_BAT_
 val SCE_BAT_DEFAULT=0
@@ -1754,24 +1881,31 @@ val SCE_AVE_DEFAULT=0
 val SCE_AVE_COMMENT=1
 val SCE_AVE_NUMBER=2
 val SCE_AVE_WORD=3
-val SCE_AVE_KEYWORD=4
-val SCE_AVE_STATEMENT=5
 val SCE_AVE_STRING=6
 val SCE_AVE_ENUM=7
 val SCE_AVE_STRINGEOL=8
 val SCE_AVE_IDENTIFIER=9
 val SCE_AVE_OPERATOR=10
+val SCE_AVE_WORD1=11
+val SCE_AVE_WORD2=12
+val SCE_AVE_WORD3=13
+val SCE_AVE_WORD4=14
+val SCE_AVE_WORD5=15
+val SCE_AVE_WORD6=16
 # Lexical states for SCLEX_ADA
 lex Ada=SCLEX_ADA SCE_ADA_
 val SCE_ADA_DEFAULT=0
-val SCE_ADA_COMMENT=1
-val SCE_ADA_NUMBER=2
-val SCE_ADA_WORD=3
-val SCE_ADA_STRING=4
+val SCE_ADA_WORD=1
+val SCE_ADA_IDENTIFIER=2
+val SCE_ADA_NUMBER=3
+val SCE_ADA_DELIMITER=4
 val SCE_ADA_CHARACTER=5
-val SCE_ADA_OPERATOR=6
-val SCE_ADA_IDENTIFIER=7
+val SCE_ADA_CHARACTEREOL=6
+val SCE_ADA_STRING=7
 val SCE_ADA_STRINGEOL=8
+val SCE_ADA_LABEL=9
+val SCE_ADA_COMMENTLINE=10
+val SCE_ADA_ILLEGAL=11
 # Lexical states for SCLEX_BAAN
 lex Baan=SCLEX_BAAN SCE_BAAN_
 val SCE_BAAN_DEFAULT=0
@@ -1852,7 +1986,67 @@ val SCE_SCRIPTOL_WORD2=16
 val SCE_SCRIPTOL_COMMENTDOCKEYWORD=17
 val SCE_SCRIPTOL_COMMENTDOCKEYWORDERROR=18
 val SCE_SCRIPTOL_COMMENTBASIC=19
-
+# Lexical states for SCLEX_ASM
+lex Asm=SCLEX_ASM SCE_ASM_
+val SCE_ASM_DEFAULT=0
+val SCE_ASM_COMMENT=1
+val SCE_ASM_NUMBER=2
+val SCE_ASM_STRING=3
+val SCE_ASM_OPERATOR=4
+val SCE_ASM_IDENTIFIER=5
+val SCE_ASM_CPUINSTRUCTION=6
+val SCE_ASM_MATHINSTRUCTION=7
+val SCE_ASM_REGISTER=8
+val SCE_ASM_DIRECTIVE=9
+val SCE_ASM_DIRECTIVEOPERAND=10
+# Lexical states for SCLEX_FORTRAN
+lex Fortran=SCLEX_FORTRAN SCE_F_
+lex F77=SCLEX_F77 SCE_F_
+val SCE_F_DEFAULT=0
+val SCE_F_COMMENT=1
+val SCE_F_NUMBER=2
+val SCE_F_STRING1=3
+val SCE_F_STRING2=4
+val SCE_F_STRINGEOL=5
+val SCE_F_OPERATOR=6
+val SCE_F_IDENTIFIER=7
+val SCE_F_WORD=8
+val SCE_F_WORD2=9
+val SCE_F_WORD3=10
+val SCE_F_PREPROCESSOR=11
+val SCE_F_OPERATOR2=12
+val SCE_F_LABEL=13
+val SCE_F_CONTINUATION=14
+# Lexical states for SCLEX_CSS
+lex CSS=SCLEX_CSS SCE_CSS_
+val SCE_CSS_DEFAULT=0
+val SCE_CSS_TAG=1
+val SCE_CSS_CLASS=2
+val SCE_CSS_PSEUDOCLASS=3
+val SCE_CSS_UNKNOWN_PSEUDOCLASS=4
+val SCE_CSS_OPERATOR=5
+val SCE_CSS_IDENTIFIER=6
+val SCE_CSS_UNKNOWN_IDENTIFIER=7
+val SCE_CSS_VALUE=8
+val SCE_CSS_COMMENT=9
+val SCE_CSS_ID=10
+val SCE_CSS_IMPORTANT=11
+val SCE_CSS_DIRECTIVE=12
+val SCE_CSS_DOUBLESTRING=13
+val SCE_CSS_SINGLESTRING=14
+# Lexical states for SCLEX_POV
+lex POV=SCLEX_POV SCE_POV_
+val SCE_POV_DEFAULT=0
+val SCE_POV_COMMENT=1
+val SCE_POV_COMMENTLINE=2
+val SCE_POV_COMMENTDOC=3
+val SCE_POV_NUMBER=4
+val SCE_POV_WORD=5
+val SCE_POV_STRING=6
+val SCE_POV_OPERATOR=7
+val SCE_POV_IDENTIFIER=8
+val SCE_POV_BRACE=9
+val SCE_POV_WORD2=10
 # Events
 
 evt void StyleNeeded=2000(int position)
@@ -1874,6 +2068,9 @@ evt void URIDropped=2015(string text)
 evt void DwellStart=2016(int position)
 evt void DwellEnd=2017(int position)
 evt void Zoom=2018(void)
+evt void HotSpotClick=2019(int modifiers, int position)
+evt void HotSpotDoubleClick=2020(int modifiers, int position)
+evt void CallTipClick=2021(int position)
 
 cat Deprecated
 
index 203f35733923a00babbf6d846cb1c1e5b4a67b63..765fd8594d159e6420d32fdcc3cc420711400b00 100644 (file)
@@ -37,7 +37,8 @@ struct _ScintillaClass {
 guint          scintilla_get_type      (void);
 GtkWidget*     scintilla_new           (void);
 void           scintilla_set_id        (ScintillaObject *sci,int id);
-sptr_t scintilla_send_message  (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+sptr_t         scintilla_send_message  (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+void           scintilla_release_resources(void);
 
 #if GTK_MAJOR_VERSION < 2
 #define SCINTILLA_NOTIFY "notify"
index 6c16b150f267751c1cc38f2e2213b9d934a64da8..43246050170cf5efd355f9e5a38648d772e3ddeb 100644 (file)
@@ -26,8 +26,8 @@ protected:
        bool InternalIsLeadByte(char ch);
        void Fill(int position);
 public:
-       WindowAccessor(WindowID id_, PropSet &props_) : 
-               Accessor(), id(id_), props(props_), 
+       WindowAccessor(WindowID id_, PropSet &props_) :
+               Accessor(), id(id_), props(props_),
                lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
        }
        ~WindowAccessor();
@@ -40,8 +40,8 @@ public:
        void Flush();
        int GetLineState(int line);
        int SetLineState(int line, int state);
-       int GetPropertyInt(const char *key, int defaultValue=0) { 
-               return props.GetInt(key, defaultValue); 
+       int GetPropertyInt(const char *key, int defaultValue=0) {
+               return props.GetInt(key, defaultValue);
        }
        char *GetProperties() {
                return props.ToString();
index d971fa12a09da6b943ee2ac0735a9a0a43427a55..adbd24d038fa5cdc6def23578b7c1ced63ad868e 100644 (file)
@@ -2,7 +2,7 @@
 /** @file AutoComplete.cxx
  ** Defines the auto completion list box.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 #include "PropSet.h"
 #include "AutoComplete.h"
 
-AutoComplete::AutoComplete() : 
+AutoComplete::AutoComplete() :
        active(false),
        separator(' '),
+       typesep('?'),
        ignoreCase(false),
        chooseSingle(false),
+       lb(0),
        posStart(0),
        startLen(0),
        cancelAtStartPos(true),
        autoHide(true),
        dropRestOfWord(false)   {
+       lb = ListBox::Allocate();
        stopChars[0] = '\0';
        fillUpChars[0] = '\0';
 }
 
 AutoComplete::~AutoComplete() {
-       lb.Destroy();
+       if (lb) {
+               lb->Destroy();
+               delete lb;
+               lb = 0;
+       }
 }
 
 bool AutoComplete::Active() {
        return active;
 }
 
-void AutoComplete::Start(Window &parent, int ctrlID, int position, int startLen_) {
-       if (!lb.Created()) {
-               lb.Create(parent, ctrlID);
+void AutoComplete::Start(Window &parent, int ctrlID, int position,
+       int startLen_, int lineHeight, bool unicodeMode) {
+       if (active) {
+               Cancel();
        }
-       lb.Clear();
+       lb->Create(parent, ctrlID, lineHeight, unicodeMode);
+       lb->Clear();
        active = true;
        startLen = startLen_;
        posStart = position;
@@ -63,7 +72,7 @@ void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
 bool AutoComplete::IsFillUpChar(char ch) {
        return ch && strchr(fillUpChars, ch);
 }
+
 void AutoComplete::SetSeparator(char separator_) {
        separator = separator_;
 }
@@ -72,49 +81,65 @@ char AutoComplete::GetSeparator() {
        return separator;
 }
 
+void AutoComplete::SetTypesep(char separator_) {
+       typesep = separator_;
+}
+
+char AutoComplete::GetTypesep() {
+       return typesep;
+}
+
 void AutoComplete::SetList(const char *list) {
-       lb.Clear();
+       lb->Clear();
        char *words = new char[strlen(list) + 1];
        if (words) {
                strcpy(words, list);
                char *startword = words;
+               char *numword = NULL;
                int i = 0;
                for (; words && words[i]; i++) {
                        if (words[i] == separator) {
                                words[i] = '\0';
-                               lb.Append(startword);
+                               if (numword)
+                                       *numword = '\0';
+                               lb->Append(startword, numword?atoi(numword + 1):-1);
                                startword = words + i + 1;
+                               numword = NULL;
+                       } else if (words[i] == typesep) {
+                               numword = words + i;
                        }
                }
                if (startword) {
-                       lb.Append(startword);
+                       if (numword)
+                               *numword = '\0';
+                       lb->Append(startword, numword?atoi(numword + 1):-1);
                }
                delete []words;
        }
 }
 
 void AutoComplete::Show() {
-       lb.Show();
-       lb.Select(0);
+       lb->Show();
+       lb->Select(0);
 }
 
 void AutoComplete::Cancel() {
-       if (lb.Created()) {
-               lb.Destroy();
+       if (lb->Created()) {
+               lb->Destroy();
                active = false;
        }
 }
 
 
 void AutoComplete::Move(int delta) {
-       int count = lb.Length();
-       int current = lb.GetSelection();
+       int count = lb->Length();
+       int current = lb->GetSelection();
        current += delta;
        if (current >= count)
                current = count - 1;
        if (current < 0)
                current = 0;
-       lb.Select(current);
+       lb->Select(current);
 }
 
 void AutoComplete::Select(const char *word) {
@@ -123,10 +148,10 @@ void AutoComplete::Select(const char *word) {
        const int maxItemLen=1000;
        char item[maxItemLen];
        int start = 0; // lower bound of the api array block to search
-       int end = lb.Length() - 1; // upper bound of the api array block to search
+       int end = lb->Length() - 1; // upper bound of the api array block to search
        while ((start <= end) && (location == -1)) { // Binary searching loop
                int pivot = (start + end) / 2;
-               lb.GetValue(pivot, item, maxItemLen);
+               lb->GetValue(pivot, item, maxItemLen);
                int cond;
                if (ignoreCase)
                        cond = CompareNCaseInsensitive(word, item, lenWord);
@@ -135,7 +160,7 @@ void AutoComplete::Select(const char *word) {
                if (!cond) {
                        // Find first match
                        while (pivot > start) {
-                               lb.GetValue(pivot-1, item, maxItemLen);
+                               lb->GetValue(pivot-1, item, maxItemLen);
                                if (ignoreCase)
                                        cond = CompareNCaseInsensitive(word, item, lenWord);
                                else
@@ -154,6 +179,6 @@ void AutoComplete::Select(const char *word) {
        if (location == -1 && autoHide)
                Cancel();
        else
-               lb.Select(location);
+               lb->Select(location);
 }
 
index 622a5666ec5ffdf56357ed4760e4d00b3daea92c..981fb44c061b3110fe747214aaab8d2d1767c9bb 100644 (file)
@@ -2,7 +2,7 @@
 /** @file AutoComplete.h
  ** Defines the auto completion list box.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef AUTOCOMPLETE_H
@@ -15,11 +15,12 @@ class AutoComplete {
        char stopChars[256];
        char fillUpChars[256];
        char separator;
+       char typesep; // Type seperator
 
 public:
        bool ignoreCase;
        bool chooseSingle;
-       ListBox lb;
+       ListBox *lb;
        int posStart;
        int startLen;
        /// Should autocompletion be canceled if editor's currentPos <= startPos?
@@ -34,7 +35,8 @@ public:
        bool Active();
 
        /// Display the auto completion list positioned to be near a character position
-       void Start(Window &parent, int ctrlID, int position, int startLen_);
+       void Start(Window &parent, int ctrlID, int position,
+               int startLen_, int lineHeight, bool unicodeMode);
 
        /// The stop chars are characters which, when typed, cause the auto completion list to disappear
        void SetStopChars(const char *stopChars_);
@@ -48,6 +50,10 @@ public:
        void SetSeparator(char separator_);
        char GetSeparator();
 
+       /// The typesep character is used for seperating the word from the type
+       void SetTypesep(char separator_);
+       char GetTypesep();
+
        /// The list string contains a sequence of words separated by the separator character
        void SetList(const char *list);
 
index d67173b084a5c52ed3116d26c0a7e4585b8c1d25..314f9bfa716df518edc06ab52628633ffdcfbc1a 100644 (file)
@@ -18,6 +18,9 @@ CallTip::CallTip() {
        inCallTipMode = false;
        posStartCallTip = 0;
        val = 0;
+       xUp = -100;
+       xDown = -100;
+       lineHeight = 1;
        startHighlight = 0;
        endHighlight = 0;
 
@@ -35,6 +38,8 @@ CallTip::~CallTip() {
        val = 0;
 }
 
+const int widthArrow = 14;
+
 void CallTip::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(colourBG, want);
        pal.WantFind(colourUnSel, want);
@@ -43,24 +48,98 @@ void CallTip::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(colourLight, want);
 }
 
-void CallTip::PaintCT(Surface *surfaceWindow) {
-       if (!val)
-               return ;
+void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
+       int posStart, int posEnd, int ytext, PRectangle rcClient,
+       bool highlight, bool draw) {
+       s += posStart;
+       int len = posEnd - posStart;
+       int maxEnd = 0;
+       int ends[10];
+       for (int i=0;i<len;i++) {
+               if (s[i] <= '\002') {
+                       if (i > 0)
+                               ends[maxEnd++] = i;
+                       ends[maxEnd++] = i+1;
+               }
+       }
+       ends[maxEnd++] = len;
+       int startSeg = 0;
+       int xEnd;
+       for (int seg = 0; seg<maxEnd; seg++) {
+               int endSeg = ends[seg];
+               if (endSeg > startSeg) {
+                       if (s[startSeg] <= '\002') {
+                               xEnd = x + widthArrow;
+                               offsetMain = xEnd;
+                               if (draw) {
+                                       const int halfWidth = widthArrow / 2 - 3;
+                                       const int centreX = x + widthArrow / 2 - 1;
+                                       const int centreY = (rcClient.top + rcClient.bottom) / 2;
+                                       rcClient.left = x;
+                                       rcClient.right = xEnd;
+                                       surface->FillRectangle(rcClient, colourBG.allocated);
+                                       PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
+                                       surface->FillRectangle(rcClientInner, colourUnSel.allocated);
+
+                                       if (s[startSeg] == '\001') {
+                                               // Up arrow
+                                               Point pts[] = {
+                                               Point(centreX - halfWidth, centreY + halfWidth / 2),
+                                               Point(centreX + halfWidth, centreY + halfWidth / 2),
+                                               Point(centreX, centreY - halfWidth + halfWidth / 2),
+                                               };
+                                               surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
+                                                               colourBG.allocated, colourBG.allocated);
+                                       } else {
+                                               // Down arrow
+                                               Point pts[] = {
+                                               Point(centreX - halfWidth, centreY - halfWidth / 2),
+                                               Point(centreX + halfWidth, centreY - halfWidth / 2),
+                                               Point(centreX, centreY + halfWidth - halfWidth / 2),
+                                               };
+                                               surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
+                                                               colourBG.allocated, colourBG.allocated);
+                                       }
+                               } else {
+                                       if (s[startSeg] == '\001') {
+                                               xUp = x+1;
+                                       } else {
+                                               xDown = x+1;
+                                       }
+                               }
+                       } else {
+                               xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
+                               if (draw) {
+                                       rcClient.left = x;
+                                       rcClient.right = xEnd;
+                                       surface->DrawTextNoClip(rcClient, font, ytext,
+                                                                               s+startSeg, endSeg - startSeg,
+                                                                               highlight ? colourSel.allocated : colourUnSel.allocated,
+                                                                               colourBG.allocated);
+                               }
+                       }
+                       x = xEnd;
+                       startSeg = endSeg;
+               }
+       }
+}
+
+int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
        PRectangle rcClientPos = wCallTip.GetClientPosition();
        PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
                                rcClientPos.bottom - rcClientPos.top);
        PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
 
-       surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
        // To make a nice small call tip window, it is only sized to fit most normal characters without accents
-       int lineHeight = surfaceWindow->Height(font);
        int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
 
        // For each line...
        // Draw the definition in three parts: before highlight, highlighted, after highlight
        int ytext = rcClient.top + ascent + 1;
+       rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
        char *chunkVal = val;
        bool moreChunks = true;
+       int maxWidth = 0;
        while (moreChunks) {
                char *chunkEnd = strchr(chunkVal, '\n');
                if (chunkEnd == NULL) {
@@ -76,36 +155,38 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
                int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
                thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
                thisEndHighlight -= chunkOffset;
-               int x = 5;
-               int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight);
-               rcClient.left = x;
                rcClient.top = ytext - ascent - 1;
-               rcClient.right = xEnd;
-               surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
-                                       chunkVal, thisStartHighlight,
-                                       colourUnSel.allocated, colourBG.allocated);
-               x = xEnd;
-
-               xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight,
-                                                   thisEndHighlight - thisStartHighlight);
-               rcClient.top = ytext;
-               rcClient.left = x;
-               rcClient.right = xEnd;
-               surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
-                                       chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight,
-                                       colourSel.allocated, colourBG.allocated);
-               x = xEnd;
-
-               xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight,
-                                                   chunkLength - thisEndHighlight);
-               rcClient.left = x;
-               rcClient.right = xEnd;
-               surfaceWindow->DrawTextNoClip(rcClient, font, ytext,
-                                       chunkVal + thisEndHighlight, chunkLength - thisEndHighlight,
-                                       colourUnSel.allocated, colourBG.allocated);
+
+               int x = 5;
+
+               DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
+                       ytext, rcClient, false, draw);
+               DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
+                       ytext, rcClient, true, draw);
+               DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
+                       ytext, rcClient, false, draw);
+
                chunkVal = chunkEnd + 1;
                ytext += lineHeight;
+               rcClient.bottom += lineHeight;
+               maxWidth = Platform::Maximum(maxWidth, x);
        }
+       return maxWidth;
+}
+
+void CallTip::PaintCT(Surface *surfaceWindow) {
+       if (!val)
+               return;
+       PRectangle rcClientPos = wCallTip.GetClientPosition();
+       PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
+                               rcClientPos.bottom - rcClientPos.top);
+       PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
+
+       surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
+
+       offsetMain = 5;
+       PaintContents(surfaceWindow, true);
+
        // Draw a raised border around the edges of the window
        surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
        surfaceWindow->PenColour(colourShade.allocated);
@@ -116,20 +197,34 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
        surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
 }
 
+void CallTip::MouseClick(Point pt) {
+       clickPlace = 0;
+       if (pt.y < lineHeight) {
+               if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
+                       clickPlace = 1;
+               } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
+                       clickPlace = 2;
+               }
+       }
+}
+
 PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
-                                 const char *faceName, int size, bool unicodeMode_) {
+                                 const char *faceName, int size,
+                                 int codePage_, Window &wParent) {
+       clickPlace = 0;
        if (val)
                delete []val;
        val = new char[strlen(defn) + 1];
        if (!val)
                return PRectangle();
        strcpy(val, defn);
-       unicodeMode = unicodeMode_;
+       codePage = codePage_;
        Surface *surfaceMeasure = Surface::Allocate();
        if (!surfaceMeasure)
                return PRectangle();
-       surfaceMeasure->Init();
-       surfaceMeasure->SetUnicodeMode(unicodeMode);
+       surfaceMeasure->Init(wParent.GetID());
+       surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
+       surfaceMeasure->SetDBCSMode(codePage);
        startHighlight = 0;
        endHighlight = 0;
        inCallTipMode = true;
@@ -138,23 +233,22 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
        font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false);
        // Look for multiple lines in the text
        // Only support \n here - simply means container must avoid \r!
-       int width = 0;
        int numLines = 1;
        const char *newline;
        const char *look = val;
+       xUp = -100;
+       xDown = -100;
+       offsetMain = 5;
+       int width = PaintContents(surfaceMeasure, false) + 5;
        while ((newline = strchr(look, '\n')) != NULL) {
-               int thisWidth = surfaceMeasure->WidthText(font, look, newline - look);
-               width = Platform::Maximum(width, thisWidth);
                look = newline + 1;
                numLines++;
        }
-       int lastWidth = surfaceMeasure->WidthText(font, look, static_cast<int>(strlen(look)));
-       width = Platform::Maximum(width, lastWidth) + 10;
-       int lineHeight = surfaceMeasure->Height(font);
+       lineHeight = surfaceMeasure->Height(font);
        // Extra line for border and an empty line at top and bottom
        int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
        delete surfaceMeasure;
-       return PRectangle(pt.x -5, pt.y + 1, pt.x + width - 5, pt.y + 1 + height);
+       return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
 }
 
 void CallTip::CallTipCancel() {
index 9f5025f63bafbcb41a9c6092f324b66f9a98a017..ffaedb0771b746a40b1f4ac647b6adb26d993607 100644 (file)
@@ -15,9 +15,17 @@ class CallTip {
        int endHighlight;
        char *val;
        Font font;
+       int xUp;
+       int xDown;
+       int lineHeight;
+       int offsetMain;
        // Private so CallTip objects can not be copied
        CallTip(const CallTip &) {}
        CallTip &operator=(const CallTip &) { return *this; }
+       void DrawChunk(Surface *surface, int &x, const char *s,
+               int posStart, int posEnd, int ytext, PRectangle rcClient,
+               bool highlight, bool draw);
+       int PaintContents(Surface *surfaceWindow, bool draw);
 
 public:
        Window wCallTip;
@@ -29,22 +37,25 @@ public:
        ColourPair colourSel;
        ColourPair colourShade;
        ColourPair colourLight;
-       bool unicodeMode;
-       
+       int codePage;
+       int clickPlace;
+
        CallTip();
        ~CallTip();
-       
+
        /// Claim or accept palette entries for the colours required to paint a calltip.
        void RefreshColourPalette(Palette &pal, bool want);
-       
+
        void PaintCT(Surface *surfaceWindow);
-       
+
+       void MouseClick(Point pt);
+
        /// Setup the calltip and return a rectangle of the area required.
-       PRectangle CallTipStart(int pos, Point pt, const char *defn, 
-               const char *faceName, int size, bool unicodeMode_);
-               
+       PRectangle CallTipStart(int pos, Point pt, const char *defn,
+               const char *faceName, int size, int codePage_, Window &wParent);
+
        void CallTipCancel();
-       
+
        /// Set a range of characters to be displayed in a highlight style.
        /// Commonly used to highlight the current parameter.
        void SetHighlight(int start, int end);
index 420dee6ff70ed50386f9e0bc914797201fdae91e..8f292869d743ed28d3bfc7aaf6f9c3c5de2953b6 100644 (file)
@@ -739,6 +739,7 @@ void CellBuffer::InsertCharStyle(int position, char ch, char style) {
 }
 
 bool CellBuffer::SetStyleAt(int position, char style, char mask) {
+       style &= mask;
        char curVal = ByteAt(position * 2 + 1);
        if ((curVal & mask) != style) {
                SetByteAt(position*2 + 1, static_cast<char>((curVal & ~mask) | style));
index 5cfcbfe1f01fcaac2f1601f029401227dc187f4c..2866d548cb808560373c6d7040c495a0ae277020 100644 (file)
@@ -212,7 +212,7 @@ public:
        int GetMark(int line);
        void DeleteAllMarks(int markerNum);
        int LineFromHandle(int markerHandle);
+
        /// Actions without undo
        void BasicInsertString(int position, char *s, int insertLength);
        void BasicDeleteChars(int position, int deleteLength);
index 7458120442ab5afc9c0814dedd02ecd376d2efe4..20900bcf97ab4ea310e0c89d167fa4857ceff822 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Document.cxx
  ** Text document that handles notifications, DBCS, styling, words and end of line.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -23,6 +23,22 @@ static inline bool isspacechar(unsigned char ch) {
        return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
 }
 
+static inline bool IsPunctuation(char ch) {
+       return isascii(ch) && ispunct(ch);
+}
+
+static inline bool IsADigit(char ch) {
+       return isascii(ch) && isdigit(ch);
+}
+
+static inline bool IsLowerCase(char ch) {
+       return isascii(ch) && islower(ch);
+}
+
+static inline bool IsUpperCase(char ch) {
+       return isascii(ch) && isupper(ch);
+}
+
 Document::Document() {
        refCount = 0;
 #ifdef unix
@@ -218,32 +234,12 @@ bool Document::IsCrLf(int pos) {
        return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
 }
 
-bool Document::IsDBCS(int pos) {
-       if (dbcsCodePage) {
-               if (SC_CP_UTF8 == dbcsCodePage) {
-                       unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
-                       return ch >= 0x80;
-               } else {
-                       // Anchor DBCS calculations at start of line because start of line can
-                       // not be a DBCS trail byte.
-                       int startLine = pos;
-                       while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n')
-                               startLine--;
-                       while (startLine <= pos) {
-                               if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine))) {
-                                       startLine++;
-                                       if (startLine >= pos)
-                                               return true;
-                               }
-                               startLine++;
-                       }
-               }
-       }
-       return false;
-}
+static const int maxBytesInDBCSCharacter=5;
 
 int Document::LenChar(int pos) {
-       if (IsCrLf(pos)) {
+       if (pos < 0) {
+               return 1;
+       } else if (IsCrLf(pos)) {
                return 2;
        } else if (SC_CP_UTF8 == dbcsCodePage) {
                unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
@@ -257,8 +253,14 @@ int Document::LenChar(int pos) {
                        return lengthDoc -pos;
                else
                        return len;
-       } else if (IsDBCS(pos)) {
-               return 2;
+       } else if (dbcsCodePage) {
+               char mbstr[maxBytesInDBCSCharacter+1];
+               int i;
+               for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
+                       mbstr[i] = cb.CharAt(pos+i);
+               }
+               mbstr[i] = '\0';
+               return Platform::DBCSCharLength(dbcsCodePage, mbstr);
        } else {
                return 1;
        }
@@ -308,26 +310,28 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
                        // Anchor DBCS calculations at start of line because start of line can
                        // not be a DBCS trail byte.
                        int startLine = pos;
+
                        while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n')
                                startLine--;
-                       bool atLeadByte = false;
                        while (startLine < pos) {
-                               if (atLeadByte)
-                                       atLeadByte = false;
-                               else if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine)))
-                                       atLeadByte = true;
-                               else
-                                       atLeadByte = false;
-                               startLine++;
-                       }
-
-
-                       if (atLeadByte) {
-                               // Position is between a lead byte and a trail byte
-                               if (moveDir > 0)
-                                       return pos + 1;
-                               else
-                                       return pos - 1;
+                               char mbstr[maxBytesInDBCSCharacter+1];
+                               int i;
+                               for(i=0;i<Platform::DBCSCharMaxLength();i++) {
+                                       mbstr[i] = cb.CharAt(startLine+i);
+                               }
+                               mbstr[i] = '\0';
+
+                               int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+                               if (startLine + mbsize == pos) {
+                                       return pos;
+                               } else if (startLine + mbsize > pos) {
+                                       if (moveDir > 0) {
+                                               return startLine + mbsize;
+                                       } else {
+                                               return startLine;
+                                       }
+                               }
+                               startLine += mbsize;
                        }
                }
        }
@@ -524,7 +528,7 @@ bool Document::InsertString(int position, const char *s, size_t insertLength) {
                        sWithStyle[i*2] = s[i];
                        sWithStyle[i*2 + 1] = 0;
                }
-               changed = InsertStyledString(position*2, sWithStyle, 
+               changed = InsertStyledString(position*2, sWithStyle,
                        static_cast<int>(insertLength*2));
                delete []sWithStyle;
        }
@@ -545,11 +549,9 @@ void Document::DelCharBack(int pos) {
                return;
        } else if (IsCrLf(pos - 2)) {
                DeleteChars(pos - 2, 2);
-       } else if (SC_CP_UTF8 == dbcsCodePage) {
+       } else if (dbcsCodePage) {
                int startChar = MovePositionOutsideChar(pos - 1, -1, false);
                DeleteChars(startChar, pos - startChar);
-       } else if (IsDBCS(pos - 1)) {
-               DeleteChars(pos - 2, 2);
        } else {
                DeleteChars(pos - 1, 1);
        }
@@ -718,6 +720,33 @@ void Document::ConvertLineEnds(int eolModeSet) {
        EndUndoAction();
 }
 
+int Document::ParaDown(int pos) {
+       int line = LineFromPosition(pos);
+       while (line < LinesTotal() && LineStart(line) != LineEnd(line)) { // skip non-empty lines
+               line++;
+       }
+       while (line < LinesTotal() && LineStart(line) == LineEnd(line)) { // skip empty lines
+               line++;
+       }
+       if (line < LinesTotal())
+               return LineStart(line);
+       else // end of a document
+               return LineEnd(line-1);
+}
+
+int Document::ParaUp(int pos) {
+       int line = LineFromPosition(pos);
+       line--;
+       while (line >= 0 && LineStart(line) == LineEnd(line)) { // skip empty lines
+               line--;
+       }
+       while (line >= 0 && LineStart(line) != LineEnd(line)) { // skip non-empty lines
+               line--;
+       }
+       line++;
+       return LineStart(line);
+}
+
 Document::charClassification Document::WordCharClass(unsigned char ch) {
        if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))
                return ccWord;
@@ -745,7 +774,7 @@ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {
 }
 
 /**
- * Find the start of the next word in either a forward (delta >= 0) or backwards direction 
+ * Find the start of the next word in either a forward (delta >= 0) or backwards direction
  * (delta < 0).
  * This is looking for a transition between character classes although there is also some
  * additional movement to transit white space.
@@ -798,7 +827,7 @@ bool Document::IsWordEndAt(int pos) {
 }
 
 /**
- * Check that the given range is has transitions between character classes at both 
+ * Check that the given range is has transitions between character classes at both
  * ends and where the characters on the inside are word or punctuation characters.
  */
 bool Document::IsWordAt(int start, int end) {
@@ -845,7 +874,7 @@ public:
  * Has not been tested with backwards DBCS searches yet.
  */
 long Document::FindText(int minPos, int maxPos, const char *s,
-                        bool caseSensitive, bool word, bool wordStart, bool regExp,
+                        bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix,
                         int *length) {
        if (regExp) {
                if (!pre)
@@ -853,22 +882,16 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                if (!pre)
                        return -1;
 
-               int startPos;
-               int endPos;
+               int increment = (minPos <= maxPos) ? 1 : -1;
 
-               if (minPos <= maxPos) {
-                       startPos = minPos;
-                       endPos = maxPos;
-               } else {
-                       startPos = maxPos;
-                       endPos = minPos;
-               }
+               int startPos = minPos;
+               int endPos = maxPos;
 
                // Range endpoints should not be inside DBCS characters, but just in case, move them.
                startPos = MovePositionOutsideChar(startPos, 1, false);
                endPos = MovePositionOutsideChar(endPos, 1, false);
 
-               const char *errmsg = pre->Compile(s, *length, caseSensitive);
+               const char *errmsg = pre->Compile(s, *length, caseSensitive, posix);
                if (errmsg) {
                        return -1;
                }
@@ -878,7 +901,9 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                //     Replace: $(\1-\2)
                int lineRangeStart = LineFromPosition(startPos);
                int lineRangeEnd = LineFromPosition(endPos);
-               if ((startPos >= LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) {
+               if ((increment == 1) &&
+                       (startPos >= LineEnd(lineRangeStart)) &&
+                       (lineRangeStart < lineRangeEnd)) {
                        // the start position is at end of line or between line end characters.
                        lineRangeStart++;
                        startPos = LineStart(lineRangeStart);
@@ -886,36 +911,54 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                int pos = -1;
                int lenRet = 0;
                char searchEnd = s[*length - 1];
-               if (*length == 1) {
-                       // These produce empty selections so nudge them on if needed
-                       if (s[0] == '^') {
-                               if (startPos == LineStart(lineRangeStart))
-                                       startPos++;
-                       } else if (s[0] == '$') {
-                               if ((startPos == LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd))
-                                       startPos = LineStart(lineRangeStart + 1);
-                       }
-                       lineRangeStart = LineFromPosition(startPos);
-                       lineRangeEnd = LineFromPosition(endPos);
-               }
-               for (int line = lineRangeStart; line <= lineRangeEnd; line++) {
+               int lineRangeBreak = lineRangeEnd + increment;
+               for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
                        int startOfLine = LineStart(line);
                        int endOfLine = LineEnd(line);
-                       if (line == lineRangeStart) {
-                               if ((startPos != startOfLine) && (s[0] == '^'))
-                                       continue;       // Can't match start of line if start position after start of line
-                               startOfLine = startPos;
-                       }
-                       if (line == lineRangeEnd) {
-                               if ((endPos != endOfLine) && (searchEnd == '$'))
-                                       continue;       // Can't match end of line if end position before end of line
-                               endOfLine = endPos;
+                       if (increment == 1) {
+                               if (line == lineRangeStart) {
+                                       if ((startPos != startOfLine) && (s[0] == '^'))
+                                               continue;       // Can't match start of line if start position after start of line
+                                       startOfLine = startPos;
+                               }
+                               if (line == lineRangeEnd) {
+                                       if ((endPos != endOfLine) && (searchEnd == '$'))
+                                               continue;       // Can't match end of line if end position before end of line
+                                       endOfLine = endPos;
+                               }
+                       } else {
+                               if (line == lineRangeEnd) {
+                                       if ((endPos != startOfLine) && (s[0] == '^'))
+                                               continue;       // Can't match start of line if end position after start of line
+                                       startOfLine = endPos;
+                               }
+                               if (line == lineRangeStart) {
+                                       if ((startPos != endOfLine) && (searchEnd == '$'))
+                                               continue;       // Can't match end of line if start position before end of line
+                                       endOfLine = startPos;
+                               }
                        }
+
                        DocumentIndexer di(this, endOfLine);
                        int success = pre->Execute(di, startOfLine, endOfLine);
                        if (success) {
                                pos = pre->bopat[0];
                                lenRet = pre->eopat[0] - pre->bopat[0];
+                               if (increment == -1) {
+                                       // Check for the last match on this line.
+                                       int repetitions = 1000; // Break out of infinite loop
+                                       while (success && (pre->eopat[0] < endOfLine) && (repetitions--)) {
+                                               success = pre->Execute(di, pre->eopat[0], endOfLine);
+                                               if (success) {
+                                                       if (pre->eopat[0] <= minPos) {
+                                                               pos = pre->bopat[0];
+                                                               lenRet = pre->eopat[0] - pre->bopat[0];
+                                                       } else {
+                                                               success = 0;
+                                                       }
+                                               }
+                                       }
+                               }
                                break;
                        }
                }
@@ -1033,16 +1076,17 @@ int Document::LinesTotal() {
 
 void Document::ChangeCase(Range r, bool makeUpperCase) {
        for (int pos = r.start; pos < r.end; pos++) {
-               char ch = CharAt(pos);
-               if (dbcsCodePage && IsDBCS(pos)) {
-                       pos += LenChar(pos);
+               int len = LenChar(pos);
+               if (dbcsCodePage && (len > 1)) {
+                       pos += len;
                } else {
+                       char ch = CharAt(pos);
                        if (makeUpperCase) {
-                               if (islower(ch)) {
+                               if (IsLowerCase(ch)) {
                                        ChangeChar(pos, static_cast<char>(MakeUpperCase(ch)));
                                }
                        } else {
-                               if (isupper(ch)) {
+                               if (IsUpperCase(ch)) {
                                        ChangeChar(pos, static_cast<char>(MakeLowerCase(ch)));
                                }
                        }
@@ -1067,7 +1111,7 @@ void Document::SetWordChars(unsigned char *chars) {
                }
        } else {
                for (ch = 0; ch < 256; ch++) {
-                       if (ch >= 0x80 || isalnum(ch) || ch == '_') 
+                       if (ch >= 0x80 || isalnum(ch) || ch == '_')
                                charClass[ch] = ccWord;
                }
        }
@@ -1092,6 +1136,7 @@ bool Document::SetStyleFor(int length, char style) {
                return false;
        } else {
                enteredCount++;
+               style &= stylingMask;
                int prevEndStyled = endStyled;
                if (cb.SetStyleFor(endStyled, length, style, stylingMask)) {
                        DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
@@ -1206,7 +1251,7 @@ void Document::NotifyModified(DocModification mh) {
 }
 
 bool Document::IsWordPartSeparator(char ch) {
-       return ispunct(ch) && (WordCharClass(ch) == ccWord);
+       return (WordCharClass(ch) == ccWord) && IsPunctuation(ch);
 }
 
 int Document::WordPartLeft(int pos) {
@@ -1221,31 +1266,38 @@ int Document::WordPartLeft(int pos) {
                if (pos > 0) {
                        startChar = cb.CharAt(pos);
                        --pos;
-                       if (islower(startChar)) {
-                               while (pos > 0 && islower(cb.CharAt(pos)))
+                       if (IsLowerCase(startChar)) {
+                               while (pos > 0 && IsLowerCase(cb.CharAt(pos)))
                                        --pos;
-                               if (!isupper(cb.CharAt(pos)) && !islower(cb.CharAt(pos)))
+                               if (!IsUpperCase(cb.CharAt(pos)) && !IsLowerCase(cb.CharAt(pos)))
                                        ++pos;
-                       } else if (isupper(startChar)) {
-                               while (pos > 0 && isupper(cb.CharAt(pos)))
+                       } else if (IsUpperCase(startChar)) {
+                               while (pos > 0 && IsUpperCase(cb.CharAt(pos)))
                                        --pos;
-                               if (!isupper(cb.CharAt(pos)))
+                               if (!IsUpperCase(cb.CharAt(pos)))
                                        ++pos;
-                       } else if (isdigit(startChar)) {
-                               while (pos > 0 && isdigit(cb.CharAt(pos)))
+                       } else if (IsADigit(startChar)) {
+                               while (pos > 0 && IsADigit(cb.CharAt(pos)))
                                        --pos;
-                               if (!isdigit(cb.CharAt(pos)))
+                               if (!IsADigit(cb.CharAt(pos)))
                                        ++pos;
-                       } else if (ispunct(startChar)) {
-                               while (pos > 0 && ispunct(cb.CharAt(pos)))
+                       } else if (IsPunctuation(startChar)) {
+                               while (pos > 0 && IsPunctuation(cb.CharAt(pos)))
                                        --pos;
-                               if (!ispunct(cb.CharAt(pos)))
+                               if (!IsPunctuation(cb.CharAt(pos)))
                                        ++pos;
                        } else if (isspacechar(startChar)) {
                                while (pos > 0 && isspacechar(cb.CharAt(pos)))
                                        --pos;
                                if (!isspacechar(cb.CharAt(pos)))
                                        ++pos;
+                       } else if (!isascii(startChar)) {
+                               while (pos > 0 && !isascii(cb.CharAt(pos)))
+                                       --pos;
+                               if (isascii(cb.CharAt(pos)))
+                                       ++pos;
+                       } else {
+                               ++pos;
                        }
                }
        }
@@ -1260,29 +1312,47 @@ int Document::WordPartRight(int pos) {
                        ++pos;
                startChar = cb.CharAt(pos);
        }
-       if (islower(startChar)) {
-               while (pos < length && islower(cb.CharAt(pos)))
+       if (!isascii(startChar)) {
+               while (pos < length && !isascii(cb.CharAt(pos)))
                        ++pos;
-       } else if (isupper(startChar)) {
-               if (islower(cb.CharAt(pos + 1))) {
+       } else if (IsLowerCase(startChar)) {
+               while (pos < length && IsLowerCase(cb.CharAt(pos)))
                        ++pos;
-                       while (pos < length && islower(cb.CharAt(pos)))
+       } else if (IsUpperCase(startChar)) {
+               if (IsLowerCase(cb.CharAt(pos + 1))) {
+                       ++pos;
+                       while (pos < length && IsLowerCase(cb.CharAt(pos)))
                                ++pos;
                } else {
-                       while (pos < length && isupper(cb.CharAt(pos)))
+                       while (pos < length && IsUpperCase(cb.CharAt(pos)))
                                ++pos;
                }
-               if (islower(cb.CharAt(pos)) && isupper(cb.CharAt(pos - 1)))
+               if (IsLowerCase(cb.CharAt(pos)) && IsUpperCase(cb.CharAt(pos - 1)))
                        --pos;
-       } else if (isdigit(startChar)) {
-               while (pos < length && isdigit(cb.CharAt(pos)))
+       } else if (IsADigit(startChar)) {
+               while (pos < length && IsADigit(cb.CharAt(pos)))
                        ++pos;
-       } else if (ispunct(startChar)) {
-               while (pos < length && ispunct(cb.CharAt(pos)))
+       } else if (IsPunctuation(startChar)) {
+               while (pos < length && IsPunctuation(cb.CharAt(pos)))
                        ++pos;
        } else if (isspacechar(startChar)) {
                while (pos < length && isspacechar(cb.CharAt(pos)))
                        ++pos;
+       } else {
+               ++pos;
+       }
+       return pos;
+}
+
+int Document::ExtendStyleRange(int pos, int delta) {
+       int sStart = cb.StyleAt(pos);
+       if (delta < 0) {
+               while (pos > 0 && (cb.StyleAt(pos) == sStart))
+                       pos--;
+               pos++;
+       } else {
+               while (pos < (Length()) && (cb.StyleAt(pos) == sStart))
+                       pos++;
        }
        return pos;
 }
index 82931207cfcbe8cb7662f9ea07cb1e72a079936e..bcdbe00ca5c888da8a9ba37982beab7f3f448285 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Document.h
  ** Text document that handles notifications, DBCS, styling, words and end of line.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef DOCUMENT_H
@@ -26,10 +26,10 @@ public:
        Position start;
        Position end;
 
-       Range(Position pos=0) : 
+       Range(Position pos=0) :
                start(pos), end(pos) {
        };
-       Range(Position start_, Position end_) : 
+       Range(Position start_, Position end_) :
                start(start_), end(end_) {
        };
 
@@ -60,7 +60,7 @@ public:
        }
 
        bool Overlaps(Range other) const {
-               return 
+               return
                Contains(other.start) ||
                Contains(other.end) ||
                other.Contains(start) ||
@@ -88,7 +88,7 @@ public:
                }
        };
 
-private:       
+private:
        int refCount;
        CellBuffer cb;
        enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
@@ -191,8 +191,8 @@ public:
        int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
        int NextWordStart(int pos, int delta);
        int Length() { return cb.Length(); }
-       long FindText(int minPos, int maxPos, const char *s, 
-               bool caseSensitive, bool word, bool wordStart, bool regExp, int *length);
+       long FindText(int minPos, int maxPos, const char *s,
+               bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length);
        long FindText(int iMessage, unsigned long wParam, long lParam);
        const char *SubstituteByPosition(const char *text, int *length);
        int LinesTotal();
@@ -220,9 +220,11 @@ public:
        bool IsWordPartSeparator(char ch);
        int WordPartLeft(int pos);
        int WordPartRight(int pos);
+       int ExtendStyleRange(int pos, int delta);
+       int ParaUp(int pos);
+       int ParaDown(int pos);
 
 private:
-       bool IsDBCS(int pos);
        charClassification WordCharClass(unsigned char ch);
        bool IsWordStartAt(int pos);
        bool IsWordEndAt(int pos);
@@ -252,7 +254,7 @@ public:
        int foldLevelNow;
        int foldLevelPrev;
 
-       DocModification(int modificationType_, int position_=0, int length_=0, 
+       DocModification(int modificationType_, int position_=0, int length_=0,
                int linesAdded_=0, const char *text_=0) :
                modificationType(modificationType_),
                position(position_),
index 595edf8ba21a276b98a7bd4d8276c8e5b53c730d..b7902df35a1bfc02e764275f2709879440507f3c 100644 (file)
@@ -174,7 +174,7 @@ int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnI
        *flags = spaceFlags;
        indent += SC_FOLDLEVELBASE;
        // if completely empty line or the start of a comment...
-       if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || 
+       if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
                (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
                return indent | SC_FOLDLEVELWHITEFLAG;
        else
index dc591d13ec3142c08216f5451b18e752db0fb6e1..f6523c94f995c1ce37a20ec1b65917b420aefc93 100644 (file)
@@ -32,9 +32,9 @@ protected:
        void Fill(int position);
 
 public:
-       DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : 
+       DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) :
                Accessor(), pdoc(pdoc_), props(props_), id(id_),
-               lenDoc(-1), validLen(0), chFlags(0), chWhile(0), 
+               lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
                startSeg(0), startPosStyling(0) {
        }
        ~DocumentAccessor();
@@ -47,8 +47,8 @@ public:
        void Flush();
        int GetLineState(int line);
        int SetLineState(int line, int state);
-       int GetPropertyInt(const char *key, int defaultValue=0) { 
-               return props.GetInt(key, defaultValue); 
+       int GetPropertyInt(const char *key, int defaultValue=0) {
+               return props.GetInt(key, defaultValue);
        }
        char *GetProperties() {
                return props.ToString();
index f2ba9f088b5e70d193cafd5780c504674dc1eb38..44399a5fb0dc21aa57cae56a337f82e487323971 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Editor.cxx
  ** Main code for the edit control.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -12,7 +12,9 @@
 
 #include "Platform.h"
 
+#ifndef PLAT_QT
 #define INCLUDE_DEPRECATED_FEATURES
+#endif
 #include "Scintilla.h"
 
 #include "ContractionState.h"
@@ -20,6 +22,7 @@
 #include "CellBuffer.h"
 #include "KeyMap.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
 #include "ViewStyle.h"
@@ -52,7 +55,7 @@ LineLayout::LineLayout(int maxLineLength_) :
        positions(0),
        widthLine(wrapWidthInfinite),
        lines(1) {
-               Resize(maxLineLength_);
+       Resize(maxLineLength_);
 }
 
 LineLayout::~LineLayout() {
@@ -96,7 +99,7 @@ void LineLayout::SetLineStart(int line, int start) {
                int *newLineStarts = new int[newMaxLines];
                if (!newLineStarts)
                        return;
-               for (int i=0; i<newMaxLines; i++) {
+               for (int i = 0; i < newMaxLines; i++) {
                        if (i < lenLineStarts)
                                newLineStarts[i] = lineStarts[i];
                        else
@@ -110,7 +113,7 @@ void LineLayout::SetLineStart(int line, int start) {
 }
 
 void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
-       char bracesMatchStyle, int xHighlight) {
+                                    char bracesMatchStyle, int xHighlight) {
        if (rangeLine.ContainsCharacter(braces[0])) {
                int braceOffset = braces[0] - rangeLine.start;
                if (braceOffset < numCharsInLine) {
@@ -126,7 +129,7 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
                }
        }
        if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) ||
-               (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
+               (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
                xHighlightGuide = xHighlight;
        }
 }
@@ -165,9 +168,9 @@ void LineLayoutCache::Allocate(int length_) {
                size = (size / 16 + 1) * 16;
        }
        if (size > 0) {
-               cache = new LineLayout *[size];
+               cache = new LineLayout * [size];
        }
-       for (int i=0; i<size; i++)
+       for (int i = 0; i < size; i++)
                cache[i] = 0;
 }
 
@@ -183,7 +186,7 @@ void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
        if (lengthForLevel > size) {
                Deallocate();
        } else if (lengthForLevel < length) {
-               for (int i=lengthForLevel; i<length; i++) {
+               for (int i = lengthForLevel; i < length; i++) {
                        delete cache[i];
                        cache[i] = 0;
                }
@@ -194,7 +197,7 @@ void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
 }
 
 void LineLayoutCache::Deallocate() {
-       for (int i=0; i<length; i++)
+       for (int i = 0; i < length; i++)
                delete cache[i];
        delete []cache;
        cache = 0;
@@ -203,7 +206,7 @@ void LineLayoutCache::Deallocate() {
 
 void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
        if (cache && !allInvalidated) {
-               for (int i=0; i<length; i++) {
+               for (int i = 0; i < length; i++) {
                        if (cache[i]) {
                                cache[i]->Invalidate(validity_);
                        }
@@ -223,7 +226,7 @@ void LineLayoutCache::SetLevel(int level_) {
 }
 
 LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_,
-       int linesOnScreen, int linesInDoc) {
+                                      int linesOnScreen, int linesInDoc) {
        AllocateForLevel(linesOnScreen, linesInDoc);
        if (styleClock != styleClock_) {
                Invalidate(LineLayout::llCheckTextAndStyle);
@@ -243,7 +246,7 @@ LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChar
                if (cache && (pos < length)) {
                        if (cache[pos]) {
                                if ((cache[pos]->lineNumber != lineNumber) ||
-                                       (cache[pos]->maxLineLength < maxChars)) {
+                                       (cache[pos]->maxLineLength < maxChars)) {
                                        delete cache[pos];
                                        cache[pos] = 0;
                                }
@@ -283,6 +286,7 @@ Editor::Editor() {
 
        printMagnification = 0;
        printColourMode = SC_PRINT_NORMAL;
+       printWrapState = eWrapWord;
        cursorMode = SC_CURSORNORMAL;
        controlCharSymbol = 0;  /* Draw the control characters */
 
@@ -293,6 +297,7 @@ Editor::Editor() {
        mouseDownCaptures = true;
 
        bufferedDraw = true;
+       twoPhaseDraw = true;
 
        lastClickTime = 0;
        dwellDelay = SC_TIME_FOREVER;
@@ -327,6 +332,7 @@ Editor::Editor() {
        xCaretMargin = 50;
        horizontalScrollBarVisible = true;
        scrollWidth = 2000;
+       verticalScrollBarVisible = true;
        endAtLastLine = true;
 
        pixmapLine = Surface::Allocate();
@@ -358,7 +364,7 @@ Editor::Editor() {
        modEventMask = SC_MODEVENTMASKALL;
 
        pdoc = new Document();
-       pdoc ->AddRef();
+       pdoc->AddRef();
        pdoc->AddWatcher(this, 0);
 
        recordingMacro = false;
@@ -368,7 +374,10 @@ Editor::Editor() {
        wrapWidth = LineLayout::wrapWidthInfinite;
        docLineLastWrapped = -1;
 
-       llc.SetLevel(LineLayoutCache::llcDocument);
+       hsStart = -1;
+       hsEnd = -1;
+
+       llc.SetLevel(LineLayoutCache::llcCaret);
 }
 
 Editor::~Editor() {
@@ -414,7 +423,7 @@ void Editor::RefreshColourPalette(Palette &pal, bool want) {
 void Editor::RefreshStyleData() {
        if (!stylesValid) {
                stylesValid = true;
-               AutoSurface surface(IsUnicodeMode());
+               AutoSurface surface(this);
                if (surface) {
                        vs.Refresh(*surface);
                        RefreshColourPalette(palette, true);
@@ -474,10 +483,10 @@ static inline bool IsControlCharacter(char ch) {
 
 const char *ControlCharacterString(unsigned char ch) {
        const char *reps[] = {
-           "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
-           "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
-           "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
-           "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
+               "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
+               "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
+               "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
+               "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
        };
        if (ch < (sizeof(reps) / sizeof(reps[0]))) {
                return reps[ch];
@@ -486,6 +495,29 @@ const char *ControlCharacterString(unsigned char ch) {
        }
 }
 
+// Convenience class to ensure LineLayout objects are always disposed.
+class AutoLineLayout {
+       LineLayoutCache &llc;
+       LineLayout *ll;
+       AutoLineLayout &operator=(const AutoLineLayout &) { return * this; }
+public:
+       AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {}
+       ~AutoLineLayout() {
+               llc.Dispose(ll);
+               ll = 0;
+       }
+       LineLayout *operator->() const {
+               return ll;
+       }
+       operator LineLayout *() const {
+               return ll;
+       }
+       void Set(LineLayout *ll_) {
+               llc.Dispose(ll);
+               ll = ll_;
+       }
+};
+
 Point Editor::LocationFromPosition(int pos) {
        Point pt;
        RefreshStyleData();
@@ -494,8 +526,8 @@ Point Editor::LocationFromPosition(int pos) {
        int line = pdoc->LineFromPosition(pos);
        int lineVisible = cs.DisplayFromDoc(line);
        //Platform::DebugPrintf("line=%d\n", line);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(line);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(line));
        if (surface && ll) {
                // -1 because of adding in for visible lines in following loop.
                pt.y = (lineVisible - topLine - 1) * vs.lineHeight;
@@ -507,8 +539,8 @@ Point Editor::LocationFromPosition(int pos) {
                if (posInLine > ll->maxLineLength) {
                        pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
                }
-               for (int subLine=0; subLine<ll->lines; subLine++) {
-                       if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) {
+               for (int subLine = 0; subLine < ll->lines; subLine++) {
+                       if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) {
                                pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)];
                        }
                        if (posInLine >= ll->LineStart(subLine)) {
@@ -517,7 +549,6 @@ Point Editor::LocationFromPosition(int pos) {
                }
                pt.x += vs.fixedColumnWidth - xOffset;
        }
-       llc.Dispose(ll);
        return pt;
 }
 
@@ -535,6 +566,10 @@ void Editor::SetTopLine(int topLineNew) {
        posTopLine = pdoc->LineStart(topLine);
 }
 
+static inline bool IsEOLChar(char ch) {
+       return (ch == '\r') || (ch == '\n');
+}
+
 int Editor::PositionFromLocation(Point pt) {
        RefreshStyleData();
        pt.x = pt.x - vs.fixedColumnWidth + xOffset;
@@ -547,31 +582,28 @@ int Editor::PositionFromLocation(Point pt) {
        int lineDoc = cs.DocFromDisplay(visibleLine);
        if (lineDoc >= pdoc->LinesTotal())
                return pdoc->Length();
-       AutoSurface surface(IsUnicodeMode());
-       int retVal = 0;
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       unsigned int posLineStart = pdoc->LineStart(lineDoc);
+       int retVal = posLineStart;
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
-               unsigned int posLineStart = pdoc->LineStart(lineDoc);
                int lineStartSet = cs.DisplayFromDoc(lineDoc);
                int subLine = visibleLine - lineStartSet;
                if (subLine < ll->lines) {
                        int lineStart = ll->LineStart(subLine);
-                       int lineEnd = ll->LineStart(subLine+1);
+                       int lineEnd = ll->LineStart(subLine + 1);
                        int subLineStart = ll->positions[lineStart];
                        for (int i = lineStart; i < lineEnd; i++) {
                                if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) ||
-                                       ll->chars[i] == '\r' || ll->chars[i] == '\n') {
-                                       llc.Dispose(ll);
+                                       IsEOLChar(ll->chars[i])) {
                                        return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
                                }
                        }
-                       llc.Dispose(ll);
                        return lineEnd + posLineStart;
                }
                retVal = ll->numCharsInLine + posLineStart;
        }
-       llc.Dispose(ll);
        return retVal;
 }
 
@@ -595,8 +627,8 @@ int Editor::PositionFromLocationClose(Point pt) {
                return INVALID_POSITION;
        if (lineDoc >= pdoc->LinesTotal())
                return INVALID_POSITION;
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
@@ -604,18 +636,16 @@ int Editor::PositionFromLocationClose(Point pt) {
                int subLine = visibleLine - lineStartSet;
                if (subLine < ll->lines) {
                        int lineStart = ll->LineStart(subLine);
-                       int lineEnd = ll->LineStart(subLine+1);
+                       int lineEnd = ll->LineStart(subLine + 1);
                        int subLineStart = ll->positions[lineStart];
                        for (int i = lineStart; i < lineEnd; i++) {
                                if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) ||
-                                       ll->chars[i] == '\r' || ll->chars[i] == '\n') {
-                                       llc.Dispose(ll);
+                                       IsEOLChar(ll->chars[i])) {
                                        return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
                                }
                        }
                }
        }
-       llc.Dispose(ll);
 
        return INVALID_POSITION;
 }
@@ -629,8 +659,8 @@ int Editor::PositionFromLineX(int lineDoc, int x) {
        if (lineDoc >= pdoc->LinesTotal())
                return pdoc->Length();
        //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        int retVal = 0;
        if (surface && ll) {
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
@@ -638,17 +668,16 @@ int Editor::PositionFromLineX(int lineDoc, int x) {
                retVal = ll->numCharsInLine + posLineStart;
                int subLine = 0;
                int lineStart = ll->LineStart(subLine);
-               int lineEnd = ll->LineStart(subLine+1);
+               int lineEnd = ll->LineStart(subLine + 1);
                int subLineStart = ll->positions[lineStart];
                for (int i = lineStart; i < lineEnd; i++) {
                        if (x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) ||
-                               ll->chars[i] == '\r' || ll->chars[i] == '\n') {
+                               IsEOLChar(ll->chars[i])) {
                                retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
                                break;
                        }
                }
        }
-       llc.Dispose(ll);
        return retVal;
 }
 
@@ -820,18 +849,45 @@ void Editor::SetEmptySelection(int currentPos_) {
        SetSelection(currentPos_, currentPos_);
 }
 
+bool Editor::RangeContainsProtected(int start, int end) const {
+       if (vs.ProtectionActive()) {
+               if (start > end) {
+                       int t = start;
+                       start = end;
+                       end = t;
+               }
+               int mask = pdoc->stylingBitsMask;
+               for (int pos = start; pos < end; pos++) {
+                       if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected())
+                               return true;
+               }
+       }
+       return false;
+}
+
+bool Editor::SelectionContainsProtected() const {
+       // TODO: make support rectangular selection
+       return RangeContainsProtected(anchor, 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].IsProtected()))
-                       pos++;
-       } else {
-               while ((pos > 0) &&
-                       (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
-                       pos--;
+       if (vs.ProtectionActive()) {
+               int mask = pdoc->stylingBitsMask;
+               if (moveDir > 0) {
+                       if ((pos > 0) && vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()) {
+                               while ((pos < pdoc->Length()) &&
+                                       (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()))
+                                       pos++;
+                       }
+               } else if (moveDir < 0) {
+                       if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) {
+                               while ((pos > 0) &&
+                                       (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
+                                       pos--;
+                       }
+               }
        }
        return pos;
 }
@@ -845,9 +901,9 @@ int Editor::MovePositionTo(int newPos, bool extend, bool ensureVisible) {
        } else {
                SetEmptySelection(newPos);
        }
+       ShowCaretAtCurrentPosition();
        if (ensureVisible)
                EnsureCaretVisible();
-       ShowCaretAtCurrentPosition();
        NotifyMove(newPos);
        return 0;
 }
@@ -877,7 +933,7 @@ void Editor::SetLastXChosen() {
        lastXChosen = pt.x;
 }
 
-void Editor::ScrollTo(int line) {
+void Editor::ScrollTo(int line, bool moveThumb) {
        int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());
        if (topLineNew != topLine) {
                // Try to optimise small scrolls
@@ -890,7 +946,9 @@ void Editor::ScrollTo(int line) {
                } else {
                        Redraw();
                }
-               SetVerticalScrollPos();
+               if (moveThumb) {
+                       SetVerticalScrollPos();
+               }
        }
 }
 
@@ -916,32 +974,31 @@ void Editor::MoveCaretInsideView(bool ensureVisible) {
        if (pt.y < rcClient.top) {
                MovePositionTo(PositionFromLocation(
                                   Point(lastXChosen, rcClient.top)),
-                                                  false, ensureVisible);
+                              false, ensureVisible);
        } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
                int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
                MovePositionTo(PositionFromLocation(
                                   Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
-                                                  false, ensureVisible);
+                              false, ensureVisible);
        }
 }
 
 int Editor::DisplayFromPosition(int pos) {
        int lineDoc = pdoc->LineFromPosition(pos);
        int lineDisplay = cs.DisplayFromDoc(lineDoc);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(lineDoc);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
                int posInLine = pos - posLineStart;
                lineDisplay--; // To make up for first increment ahead.
-               for (int subLine=0; subLine<ll->lines; subLine++) {
-                       if (posInLine >= ll->LineStart(subLine)) {
+               for (int subLine = 0; subLine < ll->lines; subLine++) {
+                       if (posInLine >= ll->LineStart(subLine)) {
                                lineDisplay++;
                        }
                }
        }
-       llc.Dispose(ll);
        return lineDisplay;
 }
 
@@ -1092,9 +1149,9 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
                }
                newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
                if (newTopLine != topLine) {
+                       Redraw();
                        SetTopLine(newTopLine);
                        SetVerticalScrollPos();
-                       Redraw();
                }
        }
 
@@ -1166,7 +1223,7 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
                        }
                } else {        // No slop
                        if (bStrict ||
-                               (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) {
+                               (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) {
                                // Strict or going out of display
                                if (bEven) {
                                        // Center caret
@@ -1201,6 +1258,14 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
                }
                if (xOffset != xOffsetNew) {
                        xOffset = xOffsetNew;
+                       if (xOffsetNew > 0) {
+                               PRectangle rcText = GetTextRectangle();
+                               if (horizontalScrollBarVisible == true &&
+                                       rcText.Width() + xOffset > scrollWidth) {
+                                       scrollWidth = xOffset + rcText.Width();
+                                       SetScrollBars();
+                               }
+                       }
                        SetHorizontalScrollPos();
                        Redraw();
                }
@@ -1249,7 +1314,7 @@ bool Editor::WrapLines() {
                if (wrapState == eWrapNone) {
                        if (wrapWidth != LineLayout::wrapWidthInfinite) {
                                wrapWidth = LineLayout::wrapWidthInfinite;
-                               for (int lineDoc=0; lineDoc<pdoc->LinesTotal(); lineDoc++) {
+                               for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
                                        cs.SetHeight(lineDoc, 1);
                                }
                                wrapOccurred = true;
@@ -1265,18 +1330,17 @@ bool Editor::WrapLines() {
                        wrapWidth = rcTextArea.Width();
                        // Ensure all of the document is styled.
                        pdoc->EnsureStyledTo(pdoc->Length());
-                       AutoSurface surface(IsUnicodeMode());
+                       AutoSurface surface(this);
                        if (surface) {
                                int lastLineToWrap = pdoc->LinesTotal();
                                while (docLineLastWrapped <= lastLineToWrap) {
                                        docLineLastWrapped++;
-                                       LineLayout *ll = RetrieveLineLayout(docLineLastWrapped);
+                                       AutoLineLayout ll(llc, RetrieveLineLayout(docLineLastWrapped));
                                        int linesWrapped = 1;
                                        if (ll) {
                                                LayoutLine(docLineLastWrapped, surface, vs, ll, wrapWidth);
                                                linesWrapped = ll->lines;
                                        }
-                                       llc.Dispose(ll);
                                        if (cs.SetHeight(docLineLastWrapped, linesWrapped)) {
                                                wrapOccurred = true;
                                        }
@@ -1299,6 +1363,63 @@ bool Editor::WrapLines() {
        return wrapOccurred;
 }
 
+void Editor::LinesJoin() {
+       if (!RangeContainsProtected(targetStart, targetEnd)) {
+               pdoc->BeginUndoAction();
+               bool prevNonWS = true;
+               for (int pos = targetStart; pos < targetEnd; pos++) {
+                       if (IsEOLChar(pdoc->CharAt(pos))) {
+                               targetEnd -= pdoc->LenChar(pos);
+                               pdoc->DelChar(pos);
+                               if (prevNonWS) {
+                                       // Ensure at least one space separating previous lines
+                                       pdoc->InsertChar(pos, ' ');
+                               }
+                       } else {
+                               prevNonWS = pdoc->CharAt(pos) != ' ';
+                       }
+               }
+               pdoc->EndUndoAction();
+       }
+}
+
+const char *StringFromEOLMode(int eolMode) {
+       if (eolMode == SC_EOL_CRLF) {
+               return "\r\n";
+       } else if (eolMode == SC_EOL_CR) {
+               return "\r";
+       } else {
+               return "\n";
+       }
+}
+
+void Editor::LinesSplit(int pixelWidth) {
+       if (!RangeContainsProtected(targetStart, targetEnd)) {
+               if (pixelWidth == 0) {
+                       PRectangle rcText = GetTextRectangle();
+                       pixelWidth = rcText.Width();
+               }
+               int lineStart = pdoc->LineFromPosition(targetStart);
+               int lineEnd = pdoc->LineFromPosition(targetEnd);
+               const char *eol = StringFromEOLMode(pdoc->eolMode);
+               pdoc->BeginUndoAction();
+               for (int line = lineStart; line <= lineEnd; line++) {
+                       AutoSurface surface(this);
+                       AutoLineLayout ll(llc, RetrieveLineLayout(line));
+                       if (surface && ll) {
+                               unsigned int posLineStart = pdoc->LineStart(line);
+                               LayoutLine(line, surface, vs, ll, pixelWidth);
+                               for (int subLine = 1; subLine < ll->lines; subLine++) {
+                                       pdoc->InsertString(posLineStart + (subLine - 1) * strlen(eol) +
+                                               ll->LineStart(subLine), eol);
+                                       targetEnd += strlen(eol);
+                               }
+                       }
+               }
+               pdoc->EndUndoAction();
+       }
+}
+
 int Editor::SubstituteMarkerIfEmpty(int markerCheck, int markerDefault) {
        if (vs.markers[markerCheck].markType == SC_MARK_EMPTY)
                return markerDefault;
@@ -1371,9 +1492,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 
                        // Old code does not know about new markers needed to distinguish all cases
                        int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID,
-                               SC_MARKNUM_FOLDEROPEN);
+                                           SC_MARKNUM_FOLDEROPEN);
                        int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND,
-                               SC_MARKNUM_FOLDER);
+                                                               SC_MARKNUM_FOLDER);
 
                        while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
 
@@ -1385,7 +1506,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 
                                // Decide which fold indicator should be displayed
                                level = pdoc->GetLevel(lineDoc);
-                               int levelNext = pdoc->GetLevel(lineDoc+1);
+                               int levelNext = pdoc->GetLevel(lineDoc + 1);
                                int marks = pdoc->GetMark(lineDoc);
                                if (!firstSubLine)
                                        marks = 0;
@@ -1455,7 +1576,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
                                        number[0] = '\0';
                                        if (firstSubLine)
                                                sprintf(number, "%d", lineDoc + 1);
-                                       if (foldFlags & 64)
+                                       if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS)
                                                sprintf(number, "%X", pdoc->GetLevel(lineDoc));
                                        PRectangle rcNumber = rcMarker;
                                        // Right justify
@@ -1463,9 +1584,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
                                        int xpos = rcNumber.right - width - 3;
                                        rcNumber.left = xpos;
                                        surface->DrawTextNoClip(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);
+                                                               rcNumber.top + vs.maxAscent, number, strlen(number),
+                                                               vs.styles[STYLE_LINENUMBER].fore.allocated,
+                                                               vs.styles[STYLE_LINENUMBER].back.allocated);
                                }
 
                                if (marks) {
@@ -1518,8 +1639,8 @@ LineLayout *Editor::RetrieveLineLayout(int lineNumber) {
        int posLineEnd = pdoc->LineStart(lineNumber + 1);
        int lineCaret = pdoc->LineFromPosition(currentPos);
        return llc.Retrieve(lineNumber, lineCaret,
-               posLineEnd - posLineStart, pdoc->GetStyleClock(),
-               LinesOnScreen() + 1, pdoc->LinesTotal());
+                           posLineEnd - posLineStart, pdoc->GetStyleClock(),
+                           LinesOnScreen() + 1, pdoc->LinesTotal());
 }
 
 /**
@@ -1540,7 +1661,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                int lineLength = 0;
                for (int cid = posLineStart; cid < posLineEnd; cid++) {
                        char chDoc = pdoc->CharAt(cid);
-                       if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
+                       if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
                                lineLength++;
                        }
                }
@@ -1554,20 +1675,20 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) {
                                char chDoc = pdoc->CharAt(charInDoc);
                                styleByte = pdoc->StyleAt(charInDoc);
-                               if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
-                                       allSame = allSame && 
-                                               (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
-                                       allSame = allSame && 
-                                               (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+                               if (vstyle.viewEOL || (!IsEOLChar(chDoc != '\r'))) {
+                                       allSame = allSame &&
+                                                 (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
+                                       allSame = allSame &&
+                                                 (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
                                        if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
-                                               allSame = allSame && 
-                                                       (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+                                               allSame = allSame &&
+                                                         (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
                                        else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
-                                               allSame = allSame && 
-                                                       (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+                                               allSame = allSame &&
+                                                         (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
                                        else
                                                allSame = allSame &&
-                                                       (ll->chars[numCharsInLine] == chDoc);
+                                                         (ll->chars[numCharsInLine] == chDoc);
                                        numCharsInLine++;
                                }
                        }
@@ -1599,7 +1720,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
                        char chDoc = pdoc->CharAt(charInDoc);
                        styleByte = pdoc->StyleAt(charInDoc);
-                       if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) {
+                       if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
                                ll->chars[numCharsInLine] = chDoc;
                                ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
                                ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
@@ -1630,13 +1751,13 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        bool isControl = isControlNext;
                        isControlNext = IsControlCharacter(ll->chars[charInLine + 1]);
                        if ((ll->styles[charInLine] != ll->styles[charInLine + 1]) ||
-                               isControl || isControlNext) {
+                               isControl || isControlNext) {
                                ll->positions[startseg] = 0;
                                if (vstyle.styles[ll->styles[charInLine]].visible) {
                                        if (isControl) {
                                                if (ll->chars[charInLine] == '\t') {
                                                        ll->positions[charInLine + 1] = ((((startsegx + 2) /
-                                                                                         tabWidth) + 1) * tabWidth) - startsegx;
+                                                                                          tabWidth) + 1) * tabWidth) - startsegx;
                                                } else if (controlCharSymbol < 32) {
                                                        const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
                                                        // +3 For a blank on front and rounded edge each side:
@@ -1644,7 +1765,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                                } else {
                                                        char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
                                                        surface->MeasureWidths(ctrlCharsFont, cc, 1,
-                                                                                                  ll->positions + startseg + 1);
+                                                                              ll->positions + startseg + 1);
                                                }
                                                lastSegItalics = false;
                                        } else {        // Regular character
@@ -1656,7 +1777,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                                } else {
                                                        lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
                                                        surface->MeasureWidths(vstyle.styles[ll->styles[charInLine]].font, ll->chars + startseg,
-                                                                              lenSeg, ll->positions + startseg + 1);
+                                                                              lenSeg, ll->positions + startseg + 1);
                                                }
                                        }
                                } else {    // invisible
@@ -1697,19 +1818,19 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        int lastGoodBreak = 0;
                        int lastLineStart = 0;
                        int startOffset = 0;
-                       int p=0;
+                       int p = 0;
                        while (p < ll->numCharsInLine) {
-                               if ((ll->positions[p+1] - startOffset) >= width) {
+                               if ((ll->positions[p + 1] - startOffset) >= width) {
                                        if (lastGoodBreak == lastLineStart) {
                                                // Try moving to start of last character
                                                if (p > 0) {
                                                        lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1)
-                                                               - posLineStart;
+                                                                       - posLineStart;
                                                }
                                                if (lastGoodBreak == lastLineStart) {
                                                        // Ensure at least one character on line.
-                                                       lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart +1, 1)
-                                                               - posLineStart;
+                                                       lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1)
+                                                                       - posLineStart;
                                                }
                                        }
                                        lastLineStart = lastGoodBreak;
@@ -1720,9 +1841,9 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                        continue;
                                }
                                if (p > 0) {
-                                       if (ll->styles[p] != ll->styles[p-1]) {
+                                       if (ll->styles[p] != ll->styles[p - 1]) {
                                                lastGoodBreak = p;
-                                       } else if (IsSpaceOrTab(ll->chars[p-1]) && !IsSpaceOrTab(ll->chars[p])) {
+                                       } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) {
                                                lastGoodBreak = p;
                                        }
                                }
@@ -1734,6 +1855,71 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
        }
 }
 
+ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
+                                       ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+       if (inSelection) {
+               if (vsDraw.selbackset) {
+                       if (primarySelection)
+                               return vsDraw.selbackground.allocated;
+                       else
+                               return vsDraw.selbackground2.allocated;
+               }
+       } else {
+               if ((vsDraw.edgeState == EDGE_BACKGROUND) &&
+                       (i >= ll->edgeColumn) &&
+                       !IsEOLChar(ll->chars[i]))
+                       return vsDraw.edgecolour.allocated;
+               if (inHotspot)
+                       return vsDraw.hotspotBackground.allocated;
+               if (overrideBackground)
+                       return background;
+       }
+       return vsDraw.styles[styleMain].back.allocated;
+}
+
+void Editor::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight) {
+       Point from(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0);
+       PRectangle rcCopyArea(start + 1, rcSegment.top, start + 2, rcSegment.bottom);
+       surface->Copy(rcCopyArea, from,
+                     highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide);
+}
+
+void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
+                     int line, int lineEnd, int xStart, int subLine, int subLineStart,
+                     bool overrideBackground, ColourAllocated background) {
+
+       int styleMask = pdoc->stylingBitsMask;
+       PRectangle rcSegment = rcLine;
+
+       // Fill in a PRectangle representing the end of line characters
+       int xEol = ll->positions[lineEnd] - subLineStart;
+       rcSegment.left = xEol + xStart;
+       rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
+       int posLineEnd = pdoc->LineStart(line + 1);
+       bool eolInSelection = (subLine == (ll->lines - 1)) &&
+                             (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 (overrideBackground) {
+               surface->FillRectangle(rcSegment, background);
+       } else {
+               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+       }
+
+       rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
+       rcSegment.right = rcLine.right;
+       if (overrideBackground) {
+               surface->FillRectangle(rcSegment, background);
+       } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
+               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+       } else {
+               surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
+       }
+}
+
 void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
                       PRectangle rcLine, LineLayout *ll, int subLine) {
 
@@ -1780,29 +1966,93 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                }
        }
 
+       bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) &&
+                                       (!overrideBackground) && (vsDraw.whitespaceBackgroundSet);
+
        bool inIndentation = subLine == 0;      // Do not handle indentation except on first subline.
        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 styleMask = pdoc->stylingBitsMask;
        int startseg = ll->LineStart(subLine);
        int subLineStart = ll->positions[startseg];
        int lineStart = 0;
        int lineEnd = 0;
        if (subLine < ll->lines) {
                lineStart = ll->LineStart(subLine);
-               lineEnd = ll->LineStart(subLine+1);
+               lineEnd = ll->LineStart(subLine + 1);
+       }
+       int i;
+
+       // Background drawing loop
+       for (i = lineStart; twoPhaseDraw && (i < lineEnd); i++) {
+
+               int iDoc = i + posLineStart;
+               // If there is the end of a style run for any reason
+               if ((ll->styles[i] != ll->styles[i + 1]) ||
+                       i == (lineEnd - 1) ||
+                       IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) ||
+                       ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) ||
+                       (i == (ll->edgeColumn - 1))) {
+                       rcSegment.left = ll->positions[startseg] + xStart - subLineStart;
+                       rcSegment.right = ll->positions[i + 1] + xStart - subLineStart;
+                       // 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) && (rcSegment.right >= rcLine.left)) {
+                               int styleMain = ll->styles[i];
+                               bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+                               bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
+                               ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
+                               if (ll->chars[i] == '\t') {
+                                       // Tab display
+                                       if (drawWhitespaceBackground &&
+                                               (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
+                                               textBack = vsDraw.whitespaceBackground.allocated;
+                                       surface->FillRectangle(rcSegment, textBack);
+                               } else if (IsControlCharacter(ll->chars[i])) {
+                                       // Control character display
+                                       inIndentation = false;
+                                       surface->FillRectangle(rcSegment, textBack);
+                               } else {
+                                       // Normal text display
+                                       surface->FillRectangle(rcSegment, textBack);
+                                       if (vsDraw.viewWhitespace != wsInvisible ||
+                                               (inIndentation && vsDraw.viewIndentationGuides)) {
+                                               for (int cpos = 0; cpos <= i - startseg; cpos++) {
+                                                       if (ll->chars[cpos + startseg] == ' ') {
+                                                               if (drawWhitespaceBackground &&
+                                                                       (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) {
+                                                                       PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top,
+                                                                                          ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom);
+                                                                       surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated);
+                                                               }
+                                                       } else {
+                                                               inIndentation = false;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       startseg = i + 1;
+               }
        }
-       for (int i = lineStart; i < lineEnd; i++) {
+
+       if (twoPhaseDraw) {
+               DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd,
+                       xStart, subLine, subLineStart, overrideBackground, background);
+       }
+
+       inIndentation = subLine == 0;   // Do not handle indentation except on first subline.
+       startseg = ll->LineStart(subLine);
+       // Foreground drawing loop
+       for (i = lineStart; i < lineEnd; i++) {
 
                int iDoc = i + posLineStart;
                // If there is the end of a style run for any reason
                if ((ll->styles[i] != ll->styles[i + 1]) ||
-                               i == (lineEnd-1) ||
+                       i == (lineEnd - 1) ||
                        IsControlCharacter(ll->chars[i]) || IsControlCharacter(ll->chars[i + 1]) ||
                        ((ll->selStart != ll->selEnd) && ((iDoc + 1 == ll->selStart) || (iDoc + 1 == ll->selEnd))) ||
                        (i == (ll->edgeColumn - 1))) {
@@ -1812,30 +2062,27 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                        // draw strings that are completely past the right side of the window.
                        if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) {
                                int styleMain = ll->styles[i];
-                               ColourAllocated textBack = vsDraw.styles[styleMain].back.allocated;
                                ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
                                Font &textFont = vsDraw.styles[styleMain].font;
+                               //hotspot foreground
+                               if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) {
+                                       if (vsDraw.hotspotForegroundSet)
+                                               textFore = vsDraw.hotspotForeground.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 (overrideBackground)
-                                               textBack = background;
-                                       if ((vsDraw.edgeState == EDGE_BACKGROUND) && (i >= ll->edgeColumn) && (ll->chars[i] != '\n') && (ll->chars[i] != '\r'))
-                                               textBack = vsDraw.edgecolour.allocated;
+                               if (inSelection && (vsDraw.selforeset)) {
+                                       textFore = vsDraw.selforeground.allocated;
                                }
+                               bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
+                               ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
                                if (ll->chars[i] == '\t') {
-                                       // Manage tab display
-                                       if (!overrideBackground && vsDraw.whitespaceBackgroundSet && (vsDraw.viewWhitespace != wsInvisible) && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
-                                               textBack = vsDraw.whitespaceBackground.allocated;
-                                       surface->FillRectangle(rcSegment, textBack);
+                                       // Tab display
+                                       if (!twoPhaseDraw) {
+                                               if (drawWhitespaceBackground &&
+                                                       (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways))
+                                                       textBack = vsDraw.whitespaceBackground.allocated;
+                                               surface->FillRectangle(rcSegment, textBack);
+                                       }
                                        if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) {
                                                if (vsDraw.whitespaceForegroundSet)
                                                        textFore = vsDraw.whitespaceForeground.allocated;
@@ -1844,29 +2091,29 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                        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);
+                                                               DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIG + xStart, rcSegment,
+                                                                               (ll->xHighlightGuide == xIG));
                                                        }
                                                }
                                        }
                                        if (vsDraw.viewWhitespace != wsInvisible) {
                                                if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
                                                        PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4,
-                                                                        rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
+                                                                        rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
                                                        DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2);
                                                }
                                        }
                                } else if (IsControlCharacter(ll->chars[i])) {
-                                       // Manage control character display
+                                       // Control character display
                                        inIndentation = false;
                                        if (controlCharSymbol < 32) {
                                                // Draw the character
                                                const char *ctrlChar = ControlCharacterString(ll->chars[i]);
-                                               surface->FillRectangle(rcSegment, textBack);
+                                               if (!twoPhaseDraw) {
+                                                       surface->FillRectangle(rcSegment, textBack);
+                                               }
                                                int normalCharHeight = surface->Ascent(ctrlCharsFont) -
-                                                                          surface->InternalLeading(ctrlCharsFont);
+                                                                      surface->InternalLeading(ctrlCharsFont);
                                                PRectangle rcCChar = rcSegment;
                                                rcCChar.left = rcCChar.left + 1;
                                                rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight;
@@ -1879,19 +2126,27 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                rcChar.left++;
                                                rcChar.right--;
                                                surface->DrawTextClipped(rcChar, ctrlCharsFont,
-                                                                        rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar),
-                                                                        textBack, textFore);
+                                                                        rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar),
+                                                                        textBack, textFore);
                                        } else {
                                                char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
                                                surface->DrawTextNoClip(rcSegment, ctrlCharsFont,
-                                                                                 rcSegment.top + vsDraw.maxAscent,
-                                                                                 cc, 1, textBack, textFore);
+                                                                       rcSegment.top + vsDraw.maxAscent,
+                                                                       cc, 1, textBack, textFore);
                                        }
                                } else {
-                                       // Manage normal display
-                                       surface->DrawTextNoClip(rcSegment, textFont,
-                                                         rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
-                                                         i - startseg + 1, textFore, textBack);
+                                       // Normal text display
+                                       if (vsDraw.styles[styleMain].visible) {
+                                               if (twoPhaseDraw) {
+                                                       surface->DrawTextTransparent(rcSegment, textFont,
+                                                                                    rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
+                                                                                    i - startseg + 1, textFore);
+                                               } else {
+                                                       surface->DrawTextNoClip(rcSegment, textFont,
+                                                                               rcSegment.top + vsDraw.maxAscent, ll->chars + startseg,
+                                                                               i - startseg + 1, textFore, textBack);
+                                               }
+                                       }
                                        if (vsDraw.viewWhitespace != wsInvisible ||
                                                (inIndentation && vsDraw.viewIndentationGuides)) {
                                                for (int cpos = 0; cpos <= i - startseg; cpos++) {
@@ -1901,12 +2156,13 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                                                textFore = vsDraw.whitespaceForeground.allocated;
                                                                        if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
                                                                                int xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2;
-                                                                               if (!overrideBackground && vsDraw.whitespaceBackgroundSet) {
+                                                                               if (!twoPhaseDraw && drawWhitespaceBackground &&
+                                                                                       (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) {
                                                                                        textBack = vsDraw.whitespaceBackground.allocated;
                                                                                        PRectangle rcSpace(ll->positions[cpos + startseg] + xStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart, rcSegment.bottom);
                                                                                        surface->FillRectangle(rcSpace, textBack);
                                                                                }
-                                                                               PRectangle rcDot(xmid + xStart  - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
+                                                                               PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
                                                                                rcDot.right = rcDot.left + 1;
                                                                                rcDot.bottom = rcDot.top + 1;
                                                                                surface->FillRectangle(rcDot, textFore);
@@ -1915,10 +2171,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                                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);
+                                                                               DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, startSpace + xStart, rcSegment,
+                                                                                               (ll->xHighlightGuide == ll->positions[cpos + startseg]));
                                                                        }
                                                                }
                                                        } else {
@@ -1927,7 +2181,15 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                }
                                        }
                                }
-                               if (vsDraw.styles[styleMain].underline) {
+                               if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) {
+                                       PRectangle rcUL = rcSegment;
+                                       rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
+                                       rcUL.bottom = rcUL.top + 1;
+                                       if (vsDraw.hotspotForegroundSet)
+                                               surface->FillRectangle(rcUL, vsDraw.hotspotForeground.allocated);
+                                       else
+                                               surface->FillRectangle(rcUL, textFore);
+                               } else if (vsDraw.styles[styleMain].underline) {
                                        PRectangle rcUL = rcSegment;
                                        rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
                                        rcUL.bottom = rcUL.top + 1;
@@ -1964,31 +2226,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        }
        // End of the drawing of the current line
 
-       // Fill in a PRectangle representing the end of line characters
-       int xEol = ll->positions[lineEnd] - subLineStart;
-       rcSegment.left = xEol + xStart;
-       rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
-       bool eolInSelection = (subLine == (ll->lines-1)) &&
-               (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 (overrideBackground) {
-               surface->FillRectangle(rcSegment, background);
-       } else {
-               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
-       }
-
-       rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
-       rcSegment.right = rcLine.right;
-       if (overrideBackground) {
-               surface->FillRectangle(rcSegment, background);
-       } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
-               surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
-       } else {
-               surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
+       if (!twoPhaseDraw) {
+               DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd,
+                       xStart, subLine, subLineStart, overrideBackground, background);
        }
 
        if (vsDraw.edgeState == EDGE_LINE) {
@@ -1999,47 +2239,48 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        }
 }
 
-void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
-       //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
-       //      paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
-
-       RefreshStyleData();
-
-       PRectangle rcClient = GetClientRectangle();
-       //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d)   %d\n",
-       //      rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
-
-       if (WrapLines()) {
-               // The wrapping process has changed the height of some lines so abandon this
-               // paint for a complete repaint.
-               if (AbandonPaint()) {
-                       return;
-               }
-       }
-
+void Editor::RefreshPixMaps(Surface *surfaceWindow) {
        if (!pixmapSelPattern->Initialised()) {
-               pixmapSelPattern->InitPixMap(8, 8, surfaceWindow);
-               // This complex procedure is to reproduce the checker board dithered pattern used by windows
+               const int patternSize = 8;
+               pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow, wMain.GetID());
+               // This complex procedure is to reproduce the checkerboard dithered pattern used by windows
                // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half
                // way between the chrome colour and the chrome highlight colour making a nice transition
                // between the window chrome and the content area. And it works in low colour depths.
-               PRectangle rcPattern(0, 0, 8, 8);
-               if (vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff)) {
-                       pixmapSelPattern->FillRectangle(rcPattern, vs.selbar.allocated);
-                       pixmapSelPattern->PenColour(vs.selbarlight.allocated);
-                       for (int stripe = 0; stripe < 8; stripe++) {
-                               pixmapSelPattern->MoveTo(0, stripe * 2);
-                               pixmapSelPattern->LineTo(8, stripe * 2 - 8);
-                       }
-               } else {
+               PRectangle rcPattern(0, 0, patternSize, patternSize);
+
+               // Initialize default colours based on the chrome colour scheme.  Typically the highlight is white.
+               ColourAllocated colourFMFill = vs.selbar.allocated;
+               ColourAllocated colourFMStripes = vs.selbarlight.allocated;
+
+               if (!(vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff))) {
                        // User has chosen an unusual chrome colour scheme so just use the highlight edge colour.
-                       pixmapSelPattern->FillRectangle(rcPattern, vs.selbarlight.allocated);
+                       // (Typically, the highlight colour is white.)
+                       colourFMFill = vs.selbarlight.allocated;
+               }
+
+               if (vs.foldmarginColourSet) {
+                       // override default fold margin colour
+                       colourFMFill = vs.foldmarginColour.allocated;
+               }
+               if (vs.foldmarginHighlightColourSet) {
+                       // override default fold margin highlight colour
+                       colourFMStripes = vs.foldmarginHighlightColour.allocated;
+               }
+
+               pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
+               pixmapSelPattern->PenColour(colourFMStripes);
+               for (int stripe = 0; stripe < patternSize; stripe++) {
+                       // Alternating 1 pixel stripes is same as checkerboard.
+                       pixmapSelPattern->MoveTo(0, stripe * 2);
+                       pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
                }
        }
+
        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);
+               pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID());
+               pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID());
                PRectangle rcIG(0, 0, 1, vs.lineHeight);
                pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated);
                pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated);
@@ -2055,12 +2296,26 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 
        if (bufferedDraw) {
                if (!pixmapLine->Initialised()) {
+                       PRectangle rcClient = GetClientRectangle();
                        pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(),
-                                             surfaceWindow);
+                                              surfaceWindow, wMain.GetID());
                        pixmapSelMargin->InitPixMap(vs.fixedColumnWidth,
-                                                  rcClient.Height(), surfaceWindow);
+                                                   rcClient.Height(), surfaceWindow, wMain.GetID());
                }
        }
+}
+
+void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
+       //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
+       //      paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
+
+       RefreshStyleData();
+
+       RefreshPixMaps(surfaceWindow);
+
+       PRectangle rcClient = GetClientRectangle();
+       //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d)   %d\n",
+       //      rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
 
        surfaceWindow->SetPalette(&palette, true);
        pixmapLine->SetPalette(&palette, !hasFocus);
@@ -2090,6 +2345,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 
        PaintSelMargin(surfaceWindow, rcArea);
 
+       if (WrapLines()) {
+               // The wrapping process has changed the height of some lines so abandon this
+               // paint for a complete repaint.
+               if (AbandonPaint()) {
+                       return;
+               }
+       }
+
        PRectangle rcRightMargin = rcClient;
        rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
        if (rcArea.Intersects(rcRightMargin)) {
@@ -2119,6 +2382,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        surface = pixmapLine;
                }
                surface->SetUnicodeMode(IsUnicodeMode());
+               surface->SetDBCSMode(CodePage());
 
                int visibleLine = topLine + screenLinePaintFirst;
 
@@ -2140,7 +2404,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                //double durCopy = 0.0;
                //ElapsedTime etWhole;
                int lineDocPrevious = -1;       // Used to avoid laying out one document line multiple times
-               LineLayout *ll = 0;
+               AutoLineLayout ll(llc, 0);
                while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) {
 
                        int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -2153,8 +2417,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        // and determine the x position at which each character starts.
                        //ElapsedTime et;
                        if (lineDoc != lineDocPrevious) {
-                               llc.Dispose(ll);
-                               ll = RetrieveLineLayout(lineDoc);
+                               ll.Set(RetrieveLineLayout(lineDoc));
                                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                                lineDocPrevious = lineDoc;
                        }
@@ -2170,6 +2433,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                        ll->containsCaret = false;
                                }
 
+                               GetHotSpotRange(ll->hsStart, ll->hsEnd);
+
                                PRectangle rcLine = rcClient;
                                rcLine.top = ypos;
                                rcLine.bottom = ypos + vs.lineHeight;
@@ -2177,7 +2442,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
                                // Highlight the current braces if any
                                ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
-                                       highlightGuideColumn * vs.spaceWidth);
+                                                      highlightGuideColumn * vs.spaceWidth);
 
                                // Draw the line
                                DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
@@ -2187,26 +2452,68 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                ll->RestoreBracesHighlight(rangeLine, braces);
 
                                bool expanded = cs.GetExpanded(lineDoc);
-                               if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) {
-                                       if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+                               if ((foldFlags & SC_FOLDFLAG_BOX) == 0) {
+                                       // Paint the line above the fold
+                                       if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
+                                               ||
+                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
+                                               if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+                                                       PRectangle rcFoldLine = rcLine;
+                                                       rcFoldLine.bottom = rcFoldLine.top + 1;
+                                                       surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+                                               }
+                                       }
+                                       // Paint the line below the fold
+                                       if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
+                                               ||
+                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
+                                               if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+                                                       PRectangle rcFoldLine = rcLine;
+                                                       rcFoldLine.top = rcFoldLine.bottom - 1;
+                                                       surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+                                               }
+                                       }
+                               } else {
+                                       int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
+                                       int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
+                                       int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK);
+                                       int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars);
+                                       // Draw line above fold
+                                       if ((FoldLevelPrev < FoldLevelCurr)
+                                               ||
+                                               (FoldLevelFlags & SC_FOLDLEVELBOXHEADERFLAG
+                                                &&
+                                                (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELBOXFOOTERFLAG) == 0)) {
                                                PRectangle rcFoldLine = rcLine;
                                                rcFoldLine.bottom = rcFoldLine.top + 1;
+                                               rcFoldLine.left += xStart + FoldLevelCurr * vs.spaceWidth * indentationStep - 1;
                                                surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
                                        }
-                               }
-                               if ( (expanded && (foldFlags & 8)) || (!expanded && (foldFlags & 16)) ) {
-                                       if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+
+                                       // Line below the fold (or below a contracted fold)
+                                       if (FoldLevelFlags & SC_FOLDLEVELBOXFOOTERFLAG
+                                               ||
+                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
                                                PRectangle rcFoldLine = rcLine;
                                                rcFoldLine.top = rcFoldLine.bottom - 1;
+                                               rcFoldLine.left += xStart + (FoldLevelCurr) * vs.spaceWidth * indentationStep - 1;
                                                surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
                                        }
+
+                                       PRectangle rcBoxLine = rcLine;
+                                       // Draw vertical line for every fold level
+                                       for (int i = 0; i <= FoldLevelCurr; i++) {
+                                               rcBoxLine.left = xStart + i * vs.spaceWidth * indentationStep - 1;
+                                               rcBoxLine.right = rcBoxLine.left + 1;
+                                               surface->FillRectangle(rcBoxLine, vs.styles[STYLE_DEFAULT].fore.allocated);
+                                       }
                                }
 
                                // Draw the Caret
                                if (lineDoc == lineCaret) {
                                        int offset = Platform::Minimum(posCaret - rangeLine.start, ll->maxLineLength);
                                        if ((offset >= ll->LineStart(subLine)) &&
-                                               ((offset < ll->LineStart(subLine+1)) || offset == ll->numCharsInLine)) {
+                                               ((offset < ll->LineStart(subLine + 1)) || offset == ll->numCharsInLine)) {
                                                int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;
                                                int widthOverstrikeCaret;
                                                if (posCaret == pdoc->Length()) {   // At end of document
@@ -2244,7 +2551,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                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);
                                }
                                //durCopy += et.Duration(true);
@@ -2258,7 +2565,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        visibleLine++;
                        //gdk_flush();
                }
-               llc.Dispose(ll);
                //if (durPaint < 0.00000001)
                //      durPaint = 0.00000001;
 
@@ -2307,10 +2613,10 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
        if (!pfr)
                return 0;
 
-       AutoSurface surface(pfr->hdc, IsUnicodeMode());
+       AutoSurface surface(pfr->hdc, this);
        if (!surface)
                return 0;
-       AutoSurface surfaceMeasure(pfr->hdcTarget, IsUnicodeMode());
+       AutoSurface surfaceMeasure(pfr->hdcTarget, this);
        if (!surfaceMeasure) {
                return 0;
        }
@@ -2364,8 +2670,8 @@ long Editor::FormatRange(bool draw, RangeToFormat *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,
-                                                    "99999" lineNumberPrintSpace, 5 + strlen(lineNumberPrintSpace));
+               lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font,
+                                 "99999" lineNumberPrintSpace, 5 + strlen(lineNumberPrintSpace));
                vsPrint.ms[lineNumberIndex].width = lineNumberWidth;
        }
 
@@ -2373,12 +2679,12 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
        int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1;
        if (linePrintLast < linePrintStart)
                linePrintLast = linePrintStart;
-       int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax - 1);
+       int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax);
        if (linePrintLast > linePrintMax)
                linePrintLast = linePrintMax;
        //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n",
-       //      linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight,
-       //      surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font));
+       //      linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight,
+       //      surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font));
        int endPosPrint = pdoc->Length();
        if (linePrintLast < pdoc->LinesTotal())
                endPosPrint = pdoc->LineStart(linePrintLast + 1);
@@ -2388,61 +2694,101 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
 
        int xStart = vsPrint.fixedColumnWidth + pfr->rc.left + lineNumberWidth;
        int ypos = pfr->rc.top;
-       int line = linePrintStart;
-
-       if (draw) {     // Otherwise just measuring
 
-               while (line <= linePrintLast && ypos < pfr->rc.bottom) {
-
-                       // When printing, the hdc and hdcTarget may be the same, so
-                       // changing the state of surfaceMeasure may change the underlying
-                       // state of surface. Therefore, any cached state is discarded before
-                       // using each surface.
-                       surfaceMeasure->FlushCachedState();
+       int lineDoc = linePrintStart;
+
+       int nPrintPos = pfr->chrg.cpMin;
+       int visibleLine = 0;
+       int widthPrint = pfr->rc.Width() - lineNumberWidth;
+       if (printWrapState == eWrapNone)
+               widthPrint = LineLayout::wrapWidthInfinite;
+
+       while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) {
+
+               // When printing, the hdc and hdcTarget may be the same, so
+               // changing the state of surfaceMeasure may change the underlying
+               // state of surface. Therefore, any cached state is discarded before
+               // using each surface.
+               surfaceMeasure->FlushCachedState();
+
+               // Copy this line and its styles from the document into local arrays
+               // and determine the x position at which each character starts.
+               LineLayout ll(8000);
+               LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
+
+               ll.selStart = -1;
+               ll.selEnd = -1;
+               ll.containsCaret = false;
+
+               PRectangle rcLine;
+               rcLine.left = pfr->rc.left + lineNumberWidth;
+               rcLine.top = ypos;
+               rcLine.right = pfr->rc.right - 1;
+               rcLine.bottom = ypos + vsPrint.lineHeight;
+
+               // When document line is wrapped over multiple display lines, find where
+               // to start printing from to ensure a particular position is on the first
+               // line of the page.
+               if (visibleLine == 0) {
+                       int startWithinLine = nPrintPos - pdoc->LineStart(lineDoc);
+                       for (int iwl = 0; iwl < ll.lines - 1; iwl++) {
+                               if (ll.LineStart(iwl) <= startWithinLine && ll.LineStart(iwl + 1) >= startWithinLine) {
+                                       visibleLine = -iwl;
+                               }
+                       }
 
-                       // Copy this line and its styles from the document into local arrays
-                       // and determine the x position at which each character starts.
-                       LineLayout ll(8000);
-                       LayoutLine(line, surfaceMeasure, vsPrint, &ll);
-                       ll.selStart = -1;
-                       ll.selEnd = -1;
-                       ll.containsCaret = false;
-
-                       PRectangle rcLine;
-                       rcLine.left = pfr->rc.left + lineNumberWidth;
-                       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));
-                               surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
-                                                 ypos + vsPrint.maxAscent, number, strlen(number),
-                                                 vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
-                                                 vsPrint.styles[STYLE_LINENUMBER].back.allocated);
+                       if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) {
+                               visibleLine = -(ll.lines - 1);
                        }
+               }
 
-                       // Draw the line
+               if (draw && lineNumberWidth &&
+                       (ypos + vsPrint.lineHeight <= pfr->rc.bottom) &&
+                       (visibleLine >= 0)) {
+                       char number[100];
+                       sprintf(number, "%d" lineNumberPrintSpace, lineDoc + 1);
+                       PRectangle rcNumber = rcLine;
+                       rcNumber.right = rcNumber.left + lineNumberWidth;
+                       // Right justify
+                       rcNumber.left -= surfaceMeasure->WidthText(
+                                            vsPrint.styles[STYLE_LINENUMBER].font, number, strlen(number));
                        surface->FlushCachedState();
-                       DrawLine(surface, vsPrint, line, line, xStart, rcLine, &ll);
-
-                       ypos += vsPrint.lineHeight;
-                       line++;
+                       surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font,
+                                               ypos + vsPrint.maxAscent, number, strlen(number),
+                                               vsPrint.styles[STYLE_LINENUMBER].fore.allocated,
+                                               vsPrint.styles[STYLE_LINENUMBER].back.allocated);
+               }
+
+               // Draw the line
+               surface->FlushCachedState();
+
+               for (int iwl = 0; iwl < ll.lines; iwl++) {
+                       if (ypos + vsPrint.lineHeight <= pfr->rc.bottom) {
+                               if (visibleLine >= 0) {
+                                       if (draw) {
+                                               rcLine.top = ypos;
+                                               rcLine.bottom = ypos + vsPrint.lineHeight;
+                                               DrawLine(surface, vsPrint, lineDoc, visibleLine, xStart, rcLine, &ll, iwl);
+                                       }
+                                       ypos += vsPrint.lineHeight;
+                               }
+                               visibleLine++;
+                               if (iwl == ll.lines - 1)
+                                       nPrintPos = pdoc->LineStart(lineDoc + 1);
+                               else
+                                       nPrintPos += ll.LineStart(iwl + 1) - ll.LineStart(iwl);
+                       }
                }
+
+               ++lineDoc;
        }
 
-       return endPosPrint;
+       return nPrintPos;
 }
 
 int Editor::TextWidth(int style, const char *text) {
        RefreshStyleData();
-       AutoSurface surface(IsUnicodeMode());
+       AutoSurface surface(this);
        if (surface) {
                return surface->WidthText(vs.styles[style].font, text, strlen(text));
        } else {
@@ -2451,8 +2797,7 @@ int Editor::TextWidth(int style, const char *text) {
 }
 
 // Empty method is overridden on GTK+ to show / hide scrollbars
-void Editor::ReconfigureScrollBars() {
-}
+void Editor::ReconfigureScrollBars() {}
 
 void Editor::SetScrollBars() {
        RefreshStyleData();
@@ -2499,9 +2844,9 @@ void Editor::AddChar(char ch) {
 void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
        bool wasSelection = currentPos != anchor;
        ClearSelection();
-       if (inOverstrike && !wasSelection) {
-               if (currentPos < (pdoc->Length() - 1)) {
-                       if ((pdoc->CharAt(currentPos) != '\r') && (pdoc->CharAt(currentPos) != '\n')) {
+       if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
+               if (currentPos < (pdoc->Length())) {
+                       if (!IsEOLChar(pdoc->CharAt(currentPos))) {
                                pdoc->DelChar(currentPos);
                        }
                }
@@ -2516,7 +2861,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 
        if (treatAsDBCS) {
                NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
-                       static_cast<unsigned char>(s[1]));
+                          static_cast<unsigned char>(s[1]));
        } else {
                int byte = static_cast<unsigned char>(s[0]);
                if ((byte < 0xC0) || (1 == len)) {
@@ -2542,7 +2887,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
                                if (((byte2 & 0xC0) == 0x80) && ((byte3 & 0xC0) == 0x80)) {
                                        // Three-byte-character lead byte followed by two trail bytes.
                                        byte = (((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) |
-                                               (byte3 & 0x3F));
+                                               (byte3 & 0x3F));
                                }
                                // A three-byte-character lead-byte not followed by two trail-bytes
                                // represents itself.
@@ -2553,30 +2898,32 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 }
 
 void Editor::ClearSelection() {
-       if (selType == selRectangle) {
-               pdoc->BeginUndoAction();
-               int lineStart = pdoc->LineFromPosition(SelectionStart());
-               int lineEnd = pdoc->LineFromPosition(SelectionEnd());
-               int startPos = SelectionStart();
-               for (int line = lineEnd; line >= lineStart; line--) {
-                       startPos = SelectionStart(line);
-                       unsigned int chars = SelectionEnd(line) - startPos;
+       if (!SelectionContainsProtected()) {
+               if (selType == selRectangle) {
+                       pdoc->BeginUndoAction();
+                       int lineStart = pdoc->LineFromPosition(SelectionStart());
+                       int lineEnd = pdoc->LineFromPosition(SelectionEnd());
+                       int startPos = SelectionStart();
+                       for (int line = lineEnd; line >= lineStart; line--) {
+                               startPos = SelectionStart(line);
+                               unsigned int chars = SelectionEnd(line) - startPos;
+                               if (0 != chars) {
+                                       pdoc->DeleteChars(startPos, chars);
+                               }
+                       }
+                       SetEmptySelection(startPos);
+                       pdoc->EndUndoAction();
+                       selType = selStream;
+               } else {
+                       int startPos = SelectionStart();
+                       unsigned int chars = SelectionEnd() - startPos;
+                       SetEmptySelection(startPos);
                        if (0 != chars) {
+                               pdoc->BeginUndoAction();
                                pdoc->DeleteChars(startPos, chars);
+                               pdoc->EndUndoAction();
                        }
                }
-               SetEmptySelection(startPos);
-               pdoc->EndUndoAction();
-               selType = selStream;
-       } else {
-               int startPos = SelectionStart();
-               unsigned int chars = SelectionEnd() - startPos;
-               SetEmptySelection(startPos);
-               if (0 != chars) {
-                       pdoc->BeginUndoAction();
-                       pdoc->DeleteChars(startPos, chars);
-                       pdoc->EndUndoAction();
-               }
        }
 }
 
@@ -2603,14 +2950,14 @@ void Editor::ClearDocumentStyle() {
 }
 
 void Editor::Cut() {
-       if (!pdoc->IsReadOnly()) {
+       if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) {
                Copy();
                ClearSelection();
        }
 }
 
 void Editor::PasteRectangular(int pos, const char *ptr, int len) {
-       if (pdoc->IsReadOnly()) {
+       if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
                return;
        }
        currentPos = pos;
@@ -2619,7 +2966,7 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) {
        bool prevCr = false;
        pdoc->BeginUndoAction();
        for (int i = 0; i < len; i++) {
-               if ((ptr[i] == '\r') || (ptr[i] == '\n')) {
+               if (IsEOLChar(ptr[i])) {
                        if ((ptr[i] == '\r') || (!prevCr))
                                line++;
                        if (line >= pdoc->LinesTotal()) {
@@ -2648,12 +2995,14 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) {
 }
 
 bool Editor::CanPaste() {
-       return !pdoc->IsReadOnly();
+       return !pdoc->IsReadOnly() && !SelectionContainsProtected();
 }
 
 void Editor::Clear() {
        if (currentPos == anchor) {
-               DelChar();
+               if (!RangeContainsProtected(currentPos, currentPos + 1)) {
+                       DelChar();
+               }
        } else {
                ClearSelection();
        }
@@ -2683,29 +3032,33 @@ void Editor::Redo() {
 }
 
 void Editor::DelChar() {
-       pdoc->DelChar(currentPos);
+       if (!RangeContainsProtected(currentPos, currentPos + 1)) {
+               pdoc->DelChar(currentPos);
+       }
        // Avoid blinking during rapid typing:
        ShowCaretAtCurrentPosition();
 }
 
 void Editor::DelCharBack(bool allowLineStartDeletion) {
        if (currentPos == anchor) {
-               int lineCurrentPos = pdoc->LineFromPosition(currentPos);
-               if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
-                       if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
-                               pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) {
-                               pdoc->BeginUndoAction();
-                               int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-                               int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars);
-                               if (indentation % indentationStep == 0) {
-                                       pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+               if (!RangeContainsProtected(currentPos - 1, currentPos)) {
+                       int lineCurrentPos = pdoc->LineFromPosition(currentPos);
+                       if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
+                               if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+                                       pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) {
+                                       pdoc->BeginUndoAction();
+                                       int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+                                       int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars);
+                                       if (indentation % indentationStep == 0) {
+                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+                                       } else {
+                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+                                       }
+                                       SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+                                       pdoc->EndUndoAction();
                                } else {
-                                       pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+                                       pdoc->DelCharBack(currentPos);
                                }
-                               SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-                               pdoc->EndUndoAction();
-                       } else {
-                               pdoc->DelCharBack(currentPos);
                        }
                }
        } else {
@@ -2764,6 +3117,24 @@ void Editor::NotifyDoubleClick(Point, bool) {
        NotifyParent(scn);
 }
 
+void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) {
+       SCNotification scn;
+       scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK;
+       scn.position = position;
+       scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+                       (alt ? SCI_ALT : 0);
+       NotifyParent(scn);
+}
+
+void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) {
+       SCNotification scn;
+       scn.nmhdr.code = SCN_HOTSPOTCLICK;
+       scn.position = position;
+       scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+                       (alt ? SCI_ALT : 0);
+       NotifyParent(scn);
+}
+
 void Editor::NotifyUpdateUI() {
        SCNotification scn;
        scn.nmhdr.code = SCN_UPDATEUI;
@@ -2841,23 +3212,22 @@ void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
 
 void Editor::CheckModificationForWrap(DocModification mh) {
        if ((mh.modificationType & SC_MOD_INSERTTEXT) ||
-               (mh.modificationType & SC_MOD_DELETETEXT)) {
+               (mh.modificationType & SC_MOD_DELETETEXT)) {
                llc.Invalidate(LineLayout::llCheckTextAndStyle);
                if (wrapState != eWrapNone) {
                        int lineDoc = pdoc->LineFromPosition(mh.position);
                        if (mh.linesAdded == 0) {
-                               AutoSurface surface(IsUnicodeMode());
-                               LineLayout *ll = RetrieveLineLayout(lineDoc);
+                               AutoSurface surface(this);
+                               AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
                                if (surface && ll) {
                                        LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                                        if (cs.GetHeight(lineDoc) != ll->lines) {
-                                               NeedWrapping(lineDoc-1);
+                                               NeedWrapping(lineDoc - 1);
                                                Redraw();
                                        }
                                } else {
                                        NeedWrapping(lineDoc);
                                }
-                               llc.Dispose(ll);
                        } else {
                                NeedWrapping(lineDoc);
                        }
@@ -3004,6 +3374,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_REPLACESEL:
        case SCI_ADDTEXT:
        case SCI_INSERTTEXT:
+       case SCI_APPENDTEXT:
        case SCI_CLEARALL:
        case SCI_SELECTALL:
        case SCI_GOTOLINE:
@@ -3013,8 +3384,12 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_SEARCHPREV:
        case SCI_LINEDOWN:
        case SCI_LINEDOWNEXTEND:
+       case SCI_PARADOWN:
+       case SCI_PARADOWNEXTEND:
        case SCI_LINEUP:
        case SCI_LINEUPEXTEND:
+       case SCI_PARAUP:
+       case SCI_PARAUPEXTEND:
        case SCI_CHARLEFT:
        case SCI_CHARLEFTEXTEND:
        case SCI_CHARRIGHT:
@@ -3031,6 +3406,10 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_HOMEEXTEND:
        case SCI_LINEEND:
        case SCI_LINEENDEXTEND:
+       case SCI_HOMEWRAP:
+       case SCI_HOMEWRAPEXTEND:
+       case SCI_LINEENDWRAP:
+       case SCI_LINEENDWRAPEXTEND:
        case SCI_DOCUMENTSTART:
        case SCI_DOCUMENTSTARTEXTEND:
        case SCI_DOCUMENTEND:
@@ -3047,6 +3426,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_FORMFEED:
        case SCI_VCHOME:
        case SCI_VCHOMEEXTEND:
+       case SCI_VCHOMEWRAP:
+       case SCI_VCHOMEWRAPEXTEND:
        case SCI_DELWORDLEFT:
        case SCI_DELWORDRIGHT:
        case SCI_DELLINELEFT:
@@ -3054,6 +3435,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_LINECUT:
        case SCI_LINEDELETE:
        case SCI_LINETRANSPOSE:
+       case SCI_LINEDUPLICATE:
        case SCI_LOWERCASE:
        case SCI_UPPERCASE:
        case SCI_LINESCROLLDOWN:
@@ -3070,7 +3452,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long
        case SCI_NEWLINE:
        default:
                //              printf("Filtered out %ld of macro recording\n", iMessage);
-               return;
+               return ;
        }
 
        // Send notification
@@ -3154,6 +3536,17 @@ void Editor::LineTranspose() {
        }
 }
 
+void Editor::LineDuplicate() {
+       int line = pdoc->LineFromPosition(currentPos);
+       int start = pdoc->LineStart(line);
+       int end = pdoc->LineEnd(line);
+       char *thisLine = CopyRange(start, end);
+       const char *eol = StringFromEOLMode(pdoc->eolMode);
+       pdoc->InsertString(end, eol);
+       pdoc->InsertString(end + strlen(eol), thisLine, end - start);
+       delete []thisLine;
+}
+
 void Editor::CancelModes() {}
 
 void Editor::NewLine() {
@@ -3178,7 +3571,7 @@ void Editor::NewLine() {
 void Editor::CursorUpOrDown(int direction, bool extend) {
        Point pt = LocationFromPosition(currentPos);
        int posNew = PositionFromLocation(
-               Point(lastXChosen, pt.y + direction * vs.lineHeight));
+                        Point(lastXChosen, pt.y + direction * vs.lineHeight));
        if (direction < 0) {
                // Line wrapping may lead to a location on the same line, so
                // seek back if that is the case.
@@ -3196,29 +3589,28 @@ void Editor::CursorUpOrDown(int direction, bool extend) {
 int Editor::StartEndDisplayLine(int pos, bool start) {
        RefreshStyleData();
        int line = pdoc->LineFromPosition(pos);
-       AutoSurface surface(IsUnicodeMode());
-       LineLayout *ll = RetrieveLineLayout(line);
+       AutoSurface surface(this);
+       AutoLineLayout ll(llc, RetrieveLineLayout(line));
        int posRet = INVALID_POSITION;
        if (surface && ll) {
                unsigned int posLineStart = pdoc->LineStart(line);
                LayoutLine(line, surface, vs, ll, wrapWidth);
                int posInLine = pos - posLineStart;
                if (posInLine <= ll->maxLineLength) {
-                       for (int subLine=0; subLine<ll->lines; subLine++) {
-                               if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine+1))) {
+                       for (int subLine = 0; subLine < ll->lines; subLine++) {
+                               if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) {
                                        if (start) {
                                                posRet = ll->LineStart(subLine) + posLineStart;
                                        } else {
                                                if (subLine == ll->lines - 1)
-                                                       posRet = ll->LineStart(subLine+1) + posLineStart;
+                                                       posRet = ll->LineStart(subLine + 1) + posLineStart;
                                                else
-                                                       posRet = ll->LineStart(subLine+1) + posLineStart - 1;
+                                                       posRet = ll->LineStart(subLine + 1) + posLineStart - 1;
                                        }
                                }
                        }
                }
        }
-       llc.Dispose(ll);
        if (posRet == INVALID_POSITION) {
                return pos;
        } else {
@@ -3234,6 +3626,12 @@ int Editor::KeyCommand(unsigned int iMessage) {
        case SCI_LINEDOWNEXTEND:
                CursorUpOrDown(1, true);
                break;
+       case SCI_PARADOWN:
+               MovePositionTo(pdoc->ParaDown(currentPos));
+               break;
+       case SCI_PARADOWNEXTEND:
+               MovePositionTo(pdoc->ParaDown(currentPos), true);
+               break;
        case SCI_LINESCROLLDOWN:
                ScrollTo(topLine + 1);
                MoveCaretInsideView(false);
@@ -3244,6 +3642,12 @@ int Editor::KeyCommand(unsigned int iMessage) {
        case SCI_LINEUPEXTEND:
                CursorUpOrDown(-1, true);
                break;
+       case SCI_PARAUP:
+               MovePositionTo(pdoc->ParaUp(currentPos));
+               break;
+       case SCI_PARAUPEXTEND:
+               MovePositionTo(pdoc->ParaUp(currentPos), true);
+               break;
        case SCI_LINESCROLLUP:
                ScrollTo(topLine - 1);
                MoveCaretInsideView(false);
@@ -3304,6 +3708,38 @@ int Editor::KeyCommand(unsigned int iMessage) {
                MovePositionTo(pdoc->LineEndPosition(currentPos), true);
                SetLastXChosen();
                break;
+       case SCI_HOMEWRAP: {
+                       int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if (currentPos <= homePos)
+                               homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+                       MovePositionTo(homePos);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_HOMEWRAPEXTEND: {
+                       int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if (currentPos <= homePos)
+                               homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+                       MovePositionTo(homePos, true);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_LINEENDWRAP: {
+                       int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
+                       if (currentPos >= endPos)
+                               endPos = pdoc->LineEndPosition(currentPos);
+                       MovePositionTo(endPos);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_LINEENDWRAPEXTEND: {
+                       int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
+                       if (currentPos >= endPos)
+                               endPos = pdoc->LineEndPosition(currentPos);
+                       MovePositionTo(endPos, true);
+                       SetLastXChosen();
+               }
+               break;
        case SCI_DOCUMENTSTART:
                MovePositionTo(0);
                SetLastXChosen();
@@ -3321,10 +3757,10 @@ int Editor::KeyCommand(unsigned int iMessage) {
                SetLastXChosen();
                break;
        case SCI_PAGEUP:
-               PageMove( -1);
+               PageMove(-1);
                break;
        case SCI_PAGEUPEXTEND:
-               PageMove( -1, true);
+               PageMove(-1, true);
                break;
        case SCI_PAGEDOWN:
                PageMove(1);
@@ -3338,7 +3774,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
                ShowCaretAtCurrentPosition();
                NotifyUpdateUI();
                break;
-       case SCI_CANCEL:                // Cancel any modes - handled in subclass
+       case SCI_CANCEL:                // Cancel any modes - handled in subclass
                // Also unselect text
                CancelModes();
                break;
@@ -3376,6 +3812,26 @@ int Editor::KeyCommand(unsigned int iMessage) {
                MovePositionTo(pdoc->VCHomePosition(currentPos), true);
                SetLastXChosen();
                break;
+       case SCI_VCHOMEWRAP: {
+                       int homePos = pdoc->VCHomePosition(currentPos);
+                       int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+                               homePos = viewLineStart;
+
+                       MovePositionTo(homePos);
+                       SetLastXChosen();
+               }
+               break;
+       case SCI_VCHOMEWRAPEXTEND: {
+                       int homePos = pdoc->VCHomePosition(currentPos);
+                       int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
+                       if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+                               homePos = viewLineStart;
+
+                       MovePositionTo(homePos, true);
+                       SetLastXChosen();
+               }
+               break;
        case SCI_ZOOMIN:
                if (vs.zoomLevel < 20) {
                        vs.zoomLevel++;
@@ -3438,6 +3894,9 @@ int Editor::KeyCommand(unsigned int iMessage) {
        case SCI_LINETRANSPOSE:
                LineTranspose();
                break;
+       case SCI_LINEDUPLICATE:
+               LineDuplicate();
+               break;
        case SCI_LOWERCASE:
                ChangeCaseOfSelection(false);
                break;
@@ -3462,22 +3921,22 @@ int Editor::KeyCommand(unsigned int iMessage) {
                break;
        case SCI_HOMEDISPLAY:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, true), -1));
+                                  StartEndDisplayLine(currentPos, true), -1));
                SetLastXChosen();
                break;
        case SCI_HOMEDISPLAYEXTEND:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, true), -1), true);
+                                  StartEndDisplayLine(currentPos, true), -1), true);
                SetLastXChosen();
                break;
        case SCI_LINEENDDISPLAY:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, false), 1));
+                                  StartEndDisplayLine(currentPos, false), 1));
                SetLastXChosen();
                break;
        case SCI_LINEENDDISPLAYEXTEND:
                MovePositionTo(MovePositionSoVisible(
-                       StartEndDisplayLine(currentPos, false), 1), true);
+                                  StartEndDisplayLine(currentPos, false), 1), true);
                SetLastXChosen();
                break;
        }
@@ -3592,8 +4051,8 @@ void Editor::Indent(bool forwards) {
  * @return The position of the found text, -1 if not found.
  */
 long Editor::FindText(
-    uptr_t wParam,     ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
-    ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP.
+    uptr_t wParam,             ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
+    ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
     sptr_t lParam) {                   ///< @c TextToFind structure: The text to search for in the given range.
 
        TextToFind *ft = reinterpret_cast<TextToFind *>(lParam);
@@ -3603,6 +4062,7 @@ long Editor::FindText(
                                 (wParam & SCFIND_WHOLEWORD) != 0,
                                 (wParam & SCFIND_WORDSTART) != 0,
                                 (wParam & SCFIND_REGEXP) != 0,
+                                (wParam & SCFIND_POSIX) != 0,
                                 &lengthFound);
        if (pos != -1) {
                ft->chrgText.cpMin = pos;
@@ -3632,8 +4092,8 @@ void Editor::SearchAnchor() {
  * @return The position of the found text, -1 if not found.
  */
 long Editor::SearchText(
-    unsigned int iMessage,     ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV.
-    uptr_t wParam,     ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
+    unsigned int iMessage,             ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV.
+    uptr_t wParam,             ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
     ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP.
     sptr_t lParam) {                   ///< The text to search for.
 
@@ -3646,6 +4106,7 @@ long Editor::SearchText(
                                     (wParam & SCFIND_WHOLEWORD) != 0,
                                     (wParam & SCFIND_WORDSTART) != 0,
                                     (wParam & SCFIND_REGEXP) != 0,
+                                    (wParam & SCFIND_POSIX) != 0,
                                     &lengthFound);
        } else {
                pos = pdoc->FindText(searchAnchor, 0, txt,
@@ -3653,6 +4114,7 @@ long Editor::SearchText(
                                     (wParam & SCFIND_WHOLEWORD) != 0,
                                     (wParam & SCFIND_WORDSTART) != 0,
                                     (wParam & SCFIND_REGEXP) != 0,
+                                    (wParam & SCFIND_POSIX) != 0,
                                     &lengthFound);
        }
 
@@ -3674,6 +4136,7 @@ long Editor::SearchInTarget(const char *text, int length) {
                                 (searchFlags & SCFIND_WHOLEWORD) != 0,
                                 (searchFlags & SCFIND_WORDSTART) != 0,
                                 (searchFlags & SCFIND_REGEXP) != 0,
+                                (searchFlags & SCFIND_POSIX) != 0,
                                 &lengthFound);
        if (pos != -1) {
                targetStart = pos;
@@ -3943,7 +4406,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                SetEmptySelection(newPos);
                bool doubleClick = false;
                // Stop mouse button bounce changing selection type
-               if (curTime != lastClickTime) {
+               if (!Platform::MouseButtonBounce() || curTime != lastClickTime) {
                        if (selectionType == selChar) {
                                selectionType = selWord;
                                doubleClick = true;
@@ -3967,13 +4430,15 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                        lineAnchor = LineFromLocation(pt);
                        SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
                        //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
-               }
-               else {
+               } else {
                        SetEmptySelection(currentPos);
                }
                //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos);
-               if (doubleClick)
+               if (doubleClick) {
                        NotifyDoubleClick(pt, shift);
+                       if (PositionIsHotspot(newPos))
+                               NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt);
+               }
        } else {        // Single click
                if (inSelMargin) {
                        selType = selStream;
@@ -4003,6 +4468,9 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                        SetMouseCapture(true);
                        selectionType = selLine;
                } else {
+                       if (PositionIsHotspot(newPos)) {
+                               NotifyHotSpotClicked(newPos, shift, ctrl, alt);
+                       }
                        if (!shift) {
                                inDragDrop = PointInSelection(pt);
                        }
@@ -4029,6 +4497,53 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
        ShowCaretAtCurrentPosition();
 }
 
+bool Editor::PositionIsHotspot(int position) {
+       return vs.styles[pdoc->StyleAt(position)].hotspot;
+}
+
+bool Editor::PointIsHotspot(Point pt) {
+       int pos = PositionFromLocation(pt);
+       return PositionIsHotspot(pos);
+}
+
+void Editor::SetHotSpotRange(Point *pt) {
+       if (pt) {
+               int pos = PositionFromLocation(*pt);
+
+               // If we don't limit this to word characters then the
+               // range can encompass more than the run range and then
+               // the underline will not be drawn properly.
+               int hsStart_ = pdoc->ExtendStyleRange(pos, -1);
+               int hsEnd_ = pdoc->ExtendStyleRange(pos, 1);
+
+               // Only invalidate the range if the hotspot range has changed...
+               if (hsStart_ != hsStart || hsEnd_ != hsEnd) {
+                       if (hsStart != -1) {
+                               InvalidateRange(hsStart, hsEnd);
+                       }
+                       hsStart = hsStart_;
+                       hsEnd = hsEnd_;
+                       InvalidateRange(hsStart, hsEnd);
+               }
+       } else {
+               if (hsStart != -1) {
+                       int hsStart_ = hsStart;
+                       int hsEnd_ = hsEnd;
+                       hsStart = -1;
+                       hsEnd = -1;
+                       InvalidateRange(hsStart_, hsEnd_);
+               } else {
+                       hsStart = -1;
+                       hsEnd = -1;
+               }
+       }
+}
+
+void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) {
+       hsStart_ = hsStart;
+       hsEnd_ = hsEnd;
+}
+
 void Editor::ButtonMove(Point pt) {
        if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) {
                DwellEnd(true);
@@ -4072,6 +4587,9 @@ void Editor::ButtonMove(Point pt) {
                PRectangle rcClient = GetClientRectangle();
                if (pt.y > rcClient.bottom) {
                        int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
+                       if (lineMove < 0) {
+                               lineMove = cs.DisplayFromDoc(pdoc->LinesTotal() - 1);
+                       }
                        ScrollTo(lineMove - LinesOnScreen() + 5);
                        Redraw();
                } else if (pt.y < rcClient.top) {
@@ -4081,6 +4599,9 @@ void Editor::ButtonMove(Point pt) {
                }
                EnsureCaretVisible(false, false, true);
 
+               if (hsStart != -1 && !PositionIsHotspot(movePos))
+                       SetHotSpotRange(NULL);
+
        } else {
                if (vs.fixedColumnWidth > 0) {  // There is a margin
                        if (PointInSelMargin(pt)) {
@@ -4089,10 +4610,15 @@ void Editor::ButtonMove(Point pt) {
                        }
                }
                // Display regular (drag) cursor over selection
-               if (PointInSelection(pt))
+               if (PointInSelection(pt)) {
                        DisplayCursor(Window::cursorArrow);
-               else
+               } else if (PointIsHotspot(pt)) {
+                       DisplayCursor(Window::cursorHand);
+                       SetHotSpotRange(&pt);
+               } else {
                        DisplayCursor(Window::cursorText);
+                       SetHotSpotRange(NULL);
+               }
        }
 
 }
@@ -4104,6 +4630,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
                        DisplayCursor(Window::cursorReverseArrow);
                } else {
                        DisplayCursor(Window::cursorText);
+                       SetHotSpotRange(NULL);
                }
                xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
                ptMouseLast = pt;
@@ -4117,7 +4644,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
                                if (drag.len) {
                                        if (ctrl) {
                                                if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-                                               SetSelection(newPos, newPos + drag.len);
+                                                       SetSelection(newPos, newPos + drag.len);
                                                }
                                        } else if (newPos < selStart) {
                                                pdoc->DeleteChars(selStart, drag.len);
@@ -4169,8 +4696,8 @@ void Editor::Tick() {
                }
        }
        if ((dwellDelay < SC_TIME_FOREVER) &&
-               (ticksToDwell > 0) &&
-               (!HaveMouseCapture())) {
+               (ticksToDwell > 0) &&
+               (!HaveMouseCapture())) {
                ticksToDwell -= timer.tickSize;
                if (ticksToDwell <= 0) {
                        dwelling = true;
@@ -4185,6 +4712,7 @@ void Editor::SetFocusState(bool focusState) {
        if (hasFocus) {
                ShowCaretAtCurrentPosition();
        } else {
+               CancelModes();
                DropCaret();
        }
 }
@@ -4329,6 +4857,13 @@ void Editor::SetDocPointer(Document *document) {
                pdoc = document;
        }
        pdoc->AddRef();
+
+       // Ensure all positions within document
+       currentPos = 0;
+       anchor = 0;
+       targetStart = 0;
+       targetEnd = 0;
+
        // Reset the contraction state to fully shown.
        cs.Clear();
        cs.InsertLines(0, pdoc->LinesTotal() - 1);
@@ -4337,7 +4872,10 @@ void Editor::SetDocPointer(Document *document) {
 
        pdoc->AddWatcher(this, 0);
        Redraw();
-       SetScrollBars();
+       // Removed because of reentrance problems of GTK+ 2.x
+       // where changing a scroll bar position causes synchronous
+       // painting before lexer and styling state is set up.
+       //SetScrollBars();
 }
 
 // Recursively expand a fold, making lines visible except where they have an unexpanded parent
@@ -4407,7 +4945,7 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
                                SetVerticalScrollPos();
                                Redraw();
                        } else if ((lineDisplay > topLine + LinesOnScreen() - 1) ||
-                                          ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) {
+                                  ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) {
                                SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, 0, MaxScrollPos()));
                                SetVerticalScrollPos();
                                Redraw();
@@ -4444,6 +4982,13 @@ bool Editor::IsUnicodeMode() const {
        return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage);
 }
 
+int Editor::CodePage() const {
+       if (pdoc)
+               return pdoc->dbcsCodePage;
+       else
+               return 0;
+}
+
 static bool ValidMargin(unsigned long wParam) {
        return wParam < ViewStyle::margins;
 }
@@ -4461,8 +5006,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        switch (iMessage) {
 
-       case SCI_GETTEXT:
-               {
+       case SCI_GETTEXT: {
                        if (lParam == 0)
                                return 0;
                        if (wParam == 0)
@@ -4475,8 +5019,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        return iChar;
                }
 
-       case SCI_SETTEXT:
-               {
+       case SCI_SETTEXT: {
                        if (lParam == 0)
                                return 0;
                        pdoc->DeleteChars(0, pdoc->Length());
@@ -4593,7 +5136,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                //      return -1;
                return pdoc->LineStart(wParam);
 
-       // Replacement of the old Scintilla interpretation of EM_LINELENGTH
+               // Replacement of the old Scintilla interpretation of EM_LINELENGTH
        case SCI_LINELENGTH:
                if ((static_cast<int>(wParam) < 0) ||
                        (static_cast<int>(wParam) > pdoc->LineFromPosition(pdoc->Length())))
@@ -4627,6 +5170,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETTARGETEND:
                return targetEnd;
 
+       case SCI_TARGETFROMSELECTION:
+               if (currentPos < anchor) {
+                       targetStart = currentPos;
+                       targetEnd = anchor;
+               } else {
+                       targetStart = anchor;
+                       targetEnd = currentPos;
+               }
+               break;
+
        case SCI_REPLACETARGET:
                PLATFORM_ASSERT(lParam);
                return ReplaceTarget(false, CharPtrFromSPtr(lParam), wParam);
@@ -4653,12 +5206,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_SETXOFFSET:
                xOffset = wParam;
+               SetHorizontalScrollPos();
                Redraw();
                break;
 
        case SCI_GETXOFFSET:
                return xOffset;
 
+       case SCI_CHOOSECARETX:
+               SetLastXChosen();
+               break;
+
        case SCI_SCROLLCARET:
                EnsureCaretVisible();
                break;
@@ -4763,6 +5321,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        return 0;
                }
 
+       case SCI_APPENDTEXT:
+               pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam);
+               return 0;
+
        case SCI_CLEARALL:
                ClearAll();
                return 0;
@@ -4848,6 +5410,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETPRINTCOLOURMODE:
                return printColourMode;
 
+       case SCI_SETPRINTWRAPMODE:
+               printWrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone;
+               break;
+
+       case SCI_GETPRINTWRAPMODE:
+               return printWrapState;
+
        case SCI_GETSTYLEAT:
                if (static_cast<short>(wParam) >= pdoc->Length())
                        return 0;
@@ -4948,7 +5517,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                pdoc->SetStyleFor(wParam, static_cast<char>(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, CharPtrFromSPtr(lParam));
@@ -4961,6 +5530,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETBUFFEREDDRAW:
                return bufferedDraw;
 
+       case SCI_GETTWOPHASEDRAW:
+               return twoPhaseDraw;
+
+       case SCI_SETTWOPHASEDRAW:
+               twoPhaseDraw = wParam != 0;
+               InvalidateStyleRedraw();
+               break;
+
        case SCI_SETTABWIDTH:
                if (wParam > 0)
                        pdoc->tabInChars = wParam;
@@ -5052,8 +5629,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETSCROLLWIDTH:
                return scrollWidth;
 
+       case SCI_LINESJOIN:
+               LinesJoin();
+               break;
+
+       case SCI_LINESSPLIT:
+               LinesSplit(wParam);
+               break;
+
        case SCI_TEXTWIDTH:
-               PLATFORM_ASSERT((wParam >= 0) && (wParam <= STYLE_MAX));
+               PLATFORM_ASSERT(wParam <= STYLE_MAX);
                PLATFORM_ASSERT(lParam);
                return TextWidth(wParam, CharPtrFromSPtr(lParam));
 
@@ -5061,7 +5646,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return vs.lineHeight;
 
        case SCI_SETENDATLASTLINE:
-               PLATFORM_ASSERT((wParam == 0) || (wParam ==1));
+               PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
                if (endAtLastLine != (wParam != 0)) {
                        endAtLastLine = wParam != 0;
                        SetScrollBars();
@@ -5085,6 +5670,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETHSCROLLBAR:
                return horizontalScrollBarVisible;
 
+       case SCI_SETVSCROLLBAR:
+               if (verticalScrollBarVisible != (wParam != 0)) {
+                       verticalScrollBarVisible = wParam != 0;
+                       SetScrollBars();
+                       ReconfigureScrollBars();
+               }
+               break;
+
+       case SCI_GETVSCROLLBAR:
+               return verticalScrollBarVisible;
+
        case SCI_SETINDENTATIONGUIDES:
                vs.viewIndentationGuides = wParam != 0;
                Redraw();
@@ -5174,6 +5770,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                }
                return -1;
 
+       case SCI_MARKERDEFINEPIXMAP:
+               if (wParam <= MARKER_MAX) {
+                       vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam));
+               };
+               InvalidateStyleData();
+               RedrawSelMargin();
+               break;
+
        case SCI_SETMARGINTYPEN:
                if (ValidMargin(wParam)) {
                        vs.ms[wParam].symbol = (lParam == SC_MARGIN_SYMBOL);
@@ -5305,6 +5909,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        InvalidateStyleRedraw();
                }
                break;
+       case SCI_STYLESETHOTSPOT:
+               if (wParam <= STYLE_MAX) {
+                       vs.styles[wParam].hotspot = lParam != 0;
+                       InvalidateStyleRedraw();
+               }
+               break;
 
        case SCI_STYLERESETDEFAULT:
                vs.ResetDefaultStyle();
@@ -5412,10 +6022,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_SEARCHPREV:
                return SearchText(iMessage, wParam, lParam);
 
-       case SCI_SETCARETPOLICY:        // Deprecated
+#ifdef INCLUDE_DEPRECATED_FEATURES
+       case SCI_SETCARETPOLICY:        // Deprecated
                caretXPolicy = caretYPolicy = wParam;
                caretXSlop = caretYSlop = lParam;
                break;
+#endif
 
        case SCI_SETXCARETPOLICY:
                caretXPolicy = wParam;
@@ -5468,8 +6080,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return vs.caretcolour.desired.AsLong();
 
        case SCI_SETCARETWIDTH:
-               if (wParam <= 1)
-                       vs.caretWidth = 1;
+               if (wParam <= 0)
+                       vs.caretWidth = 0;
                else if (wParam >= 3)
                        vs.caretWidth = 3;
                else
@@ -5516,8 +6128,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_LINEDOWN:
        case SCI_LINEDOWNEXTEND:
+       case SCI_PARADOWN:
+       case SCI_PARADOWNEXTEND:
        case SCI_LINEUP:
        case SCI_LINEUPEXTEND:
+       case SCI_PARAUP:
+       case SCI_PARAUPEXTEND:
        case SCI_CHARLEFT:
        case SCI_CHARLEFTEXTEND:
        case SCI_CHARRIGHT:
@@ -5530,6 +6146,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_HOMEEXTEND:
        case SCI_LINEEND:
        case SCI_LINEENDEXTEND:
+       case SCI_HOMEWRAP:
+       case SCI_HOMEWRAPEXTEND:
+       case SCI_LINEENDWRAP:
+       case SCI_LINEENDWRAPEXTEND:
        case SCI_DOCUMENTSTART:
        case SCI_DOCUMENTSTARTEXTEND:
        case SCI_DOCUMENTEND:
@@ -5547,6 +6167,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_FORMFEED:
        case SCI_VCHOME:
        case SCI_VCHOMEEXTEND:
+       case SCI_VCHOMEWRAP:
+       case SCI_VCHOMEWRAPEXTEND:
        case SCI_ZOOMIN:
        case SCI_ZOOMOUT:
        case SCI_DELWORDLEFT:
@@ -5556,6 +6178,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_LINECUT:
        case SCI_LINEDELETE:
        case SCI_LINETRANSPOSE:
+       case SCI_LINEDUPLICATE:
        case SCI_LOWERCASE:
        case SCI_UPPERCASE:
        case SCI_LINESCROLLDOWN:
@@ -5629,12 +6252,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return reinterpret_cast<sptr_t>(pdoc);
 
        case SCI_SETDOCPOINTER:
+               CancelModes();
                SetDocPointer(reinterpret_cast<Document *>(lParam));
                return 0;
 
        case SCI_CREATEDOCUMENT: {
                        Document *doc = new Document();
-                       doc->AddRef();
+                       if (doc) {
+                               doc->AddRef();
+                       }
                        return reinterpret_cast<sptr_t>(doc);
                }
 
@@ -5716,6 +6342,35 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                MoveCaretInsideView();
                break;
 
+       case SCI_SETFOLDMARGINCOLOUR:
+               vs.foldmarginColourSet = wParam != 0;
+               vs.foldmarginColour.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETFOLDMARGINHICOLOUR:
+               vs.foldmarginHighlightColourSet = wParam != 0;
+               vs.foldmarginHighlightColour.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETHOTSPOTACTIVEFORE:
+               vs.hotspotForegroundSet = wParam != 0;
+               vs.hotspotForeground.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETHOTSPOTACTIVEBACK:
+               vs.hotspotBackgroundSet = wParam != 0;
+               vs.hotspotBackground.desired = ColourDesired(lParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETHOTSPOTACTIVEUNDERLINE:
+               vs.hotspotUnderline = wParam != 0;
+               InvalidateStyleRedraw();
+               break;
+
        default:
                return DefWndProc(iMessage, wParam, lParam);
        }
index 800630bbb045a11f90f6841b243864c8a4637b28..2cc7930c47d17e27cba1b0b25a5ce437d055be51 100644 (file)
@@ -2,7 +2,7 @@
 /** @file Editor.h
  ** Defines the main editor class.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef EDITOR_H
@@ -58,6 +58,10 @@ public:
        int *positions;
        char bracePreviousStyles[2];
 
+       // Hotspot support
+       int hsStart;
+       int hsEnd;
+
        // Wrapped line support
        int widthLine;
        int lines;
@@ -131,38 +135,6 @@ public:
        }
 };
 
-/**
- * A smart pointer class to ensure Surfaces are set up and deleted correctly.
- */
-class AutoSurface {
-private:
-       Surface *surf;
-public:
-       AutoSurface(bool unicodeMode) {
-               surf = Surface::Allocate();
-               if (surf) {
-                       surf->Init();
-                       surf->SetUnicodeMode(unicodeMode);
-               }
-       }
-       AutoSurface(SurfaceID sid, bool unicodeMode) {
-               surf = Surface::Allocate();
-               if (surf) {
-                       surf->Init(sid);
-                       surf->SetUnicodeMode(unicodeMode);
-               }
-       }
-       ~AutoSurface() {
-               delete surf;
-       }
-       Surface *operator->() const {
-               return surf;
-       }
-       operator Surface *() const {
-               return surf;
-       }
-};
-
 /**
  */
 class Editor : public DocWatcher {
@@ -184,6 +156,7 @@ protected:  // ScintillaBase subclass needs access to much of Editor
 
        int printMagnification;
        int printColourMode;
+       int printWrapState;
        int cursorMode;
        int controlCharSymbol;
 
@@ -196,11 +169,15 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
         * the screen. This avoids flashing but is about 30% slower. */
        bool bufferedDraw;
+       /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
+       * and then the foreground. This avoids chopping off characters that overlap the next run. */
+       bool twoPhaseDraw;
 
        int xOffset;            ///< Horizontal scrolled amount in pixels
        int xCaretMargin;       ///< Ensure this many pixels visible on both sides of caret
        bool horizontalScrollBarVisible;
        int scrollWidth;
+       bool verticalScrollBarVisible;
        bool endAtLastLine;
 
        Surface *pixmapLine;
@@ -275,6 +252,10 @@ protected: // ScintillaBase subclass needs access to much of Editor
        int foldFlags;
        ContractionState cs;
 
+       // Hotspot support
+       int hsStart;
+       int hsEnd;
+
        // Wrapping support
        enum { eWrapNone, eWrapWord } wrapState;
        int wrapWidth;
@@ -321,12 +302,14 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        void SetSelection(int currentPos_, int anchor_);
        void SetSelection(int currentPos_);
        void SetEmptySelection(int currentPos_);
+       bool RangeContainsProtected(int start, int end) const;
+       bool SelectionContainsProtected() const;
        int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
        int MovePositionTo(int newPos, bool extend=false, bool ensureVisible=true);
        int MovePositionSoVisible(int pos, int moveDir);
        void SetLastXChosen();
 
-       void ScrollTo(int line);
+       void ScrollTo(int line, bool moveThumb=true);
        virtual void ScrollText(int linesToMove);
        void HorizontalScrollTo(int xPos);
        void MoveCaretInsideView(bool ensureVisible=true);
@@ -338,14 +321,22 @@ protected:        // ScintillaBase subclass needs access to much of Editor
 
        void NeedWrapping(int docLineStartWrapping=0);
        bool WrapLines();
+       void LinesJoin();
+       void LinesSplit(int pixelWidth);
 
        int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault);
        void PaintSelMargin(Surface *surface, PRectangle &rc);
        LineLayout *RetrieveLineLayout(int lineNumber);
        void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
                int width=LineLayout::wrapWidthInfinite);
+       ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
+       void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
+       void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
+               int line, int lineEnd, int xStart, int subLine, int subLineStart,
+               bool overrideBackground, ColourAllocated background);
        void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
                PRectangle rcLine, LineLayout *ll, int subLine=0);
+       void RefreshPixMaps(Surface *surfaceWindow);
        void Paint(Surface *surfaceWindow, PRectangle rcArea);
        long FormatRange(bool draw, RangeToFormat *pfr);
        int TextWidth(int style, const char *text);
@@ -385,6 +376,8 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        void NotifySavePoint(bool isSavePoint);
        void NotifyModifyAttempt();
        virtual void NotifyDoubleClick(Point pt, bool shift);
+       void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
+       void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
        void NotifyUpdateUI();
        void NotifyPainted();
        bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
@@ -403,6 +396,7 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        void PageMove(int direction, bool extend=false);
        void ChangeCaseOfSelection(bool makeUpperCase);
        void LineTranspose();
+       void LineDuplicate();
        virtual void CancelModes();
        void NewLine();
        void CursorUpOrDown(int direction, bool extend=false);
@@ -456,6 +450,13 @@ protected: // ScintillaBase subclass needs access to much of Editor
        void EnsureLineVisible(int lineDoc, bool enforcePolicy);
        int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
 
+       bool PositionIsHotspot(int position);
+       bool PointIsHotspot(Point pt);
+       void SetHotSpotRange(Point *pt);
+       void GetHotSpotRange(int& hsStart, int& hsEnd);
+
+       int CodePage() const;
+
        virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
 
 public:
@@ -465,6 +466,45 @@ public:
        virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
        // Public so scintilla_set_id can use it.
        int ctrlID;
+       friend class AutoSurface;
+};
+
+/**
+ * A smart pointer class to ensure Surfaces are set up and deleted correctly.
+ */
+class AutoSurface {
+private:
+       Surface *surf;
+public:
+       AutoSurface(Editor *ed) : surf(0) {
+               if (ed->wMain.GetID()) {
+                       surf = Surface::Allocate();
+                       if (surf) {
+                               surf->Init(ed->wMain.GetID());
+                               surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
+                               surf->SetDBCSMode(ed->CodePage());
+                       }
+               }
+       }
+       AutoSurface(SurfaceID sid, Editor *ed) : surf(0) {
+               if (ed->wMain.GetID()) {
+                       surf = Surface::Allocate();
+                       if (surf) {
+                               surf->Init(sid, ed->wMain.GetID());
+                               surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
+                               surf->SetDBCSMode(ed->CodePage());
+                       }
+               }
+       }
+       ~AutoSurface() {
+               delete surf;
+       }
+       Surface *operator->() const {
+               return surf;
+       }
+       operator Surface *() const {
+               return surf;
+       }
 };
 
 #endif
index c91e6c6cccb8c50ca003e1d95d2fd233eae37abc..12249e5f3c70e903529811febb5d30773b31c82c 100644 (file)
@@ -1,5 +1,5 @@
 // Scintilla source code edit control
-/** @file KeyMap.cxx 
+/** @file KeyMap.cxx
  ** Defines a mapping between keystrokes and commands.
  **/
 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
@@ -13,7 +13,7 @@
 
 KeyMap::KeyMap() : kmap(0), len(0), alloc(0) {
        for (int i = 0; MapDefault[i].key; i++) {
-               AssignCmdKey(MapDefault[i].key, 
+               AssignCmdKey(MapDefault[i].key,
                        MapDefault[i].modifiers,
                        MapDefault[i].msg);
        }
@@ -66,9 +66,13 @@ const KeyToCommand KeyMap::MapDefault[] = {
     {SCK_DOWN,         SCI_NORM,       SCI_LINEDOWN},
     {SCK_DOWN,         SCI_SHIFT,      SCI_LINEDOWNEXTEND},
     {SCK_DOWN,         SCI_CTRL,       SCI_LINESCROLLDOWN},
+    {SCK_DOWN,         SCI_ALT,                SCI_PARADOWN},
+    {SCK_DOWN,         SCI_ASHIFT,     SCI_PARADOWNEXTEND},
     {SCK_UP,                   SCI_NORM,       SCI_LINEUP},
     {SCK_UP,                   SCI_SHIFT,      SCI_LINEUPEXTEND},
     {SCK_UP,                   SCI_CTRL,       SCI_LINESCROLLUP},
+    {SCK_UP,                   SCI_ALT,                SCI_PARAUP},
+    {SCK_UP,                   SCI_ASHIFT,     SCI_PARAUPEXTEND},
     {SCK_LEFT,         SCI_NORM,       SCI_CHARLEFT},
     {SCK_LEFT,         SCI_SHIFT,      SCI_CHARLEFTEXTEND},
     {SCK_LEFT,         SCI_CTRL,       SCI_WORDLEFT},
@@ -109,7 +113,7 @@ const KeyToCommand KeyMap::MapDefault[] = {
     {SCK_BACK,         SCI_SHIFT,      SCI_DELETEBACK},
     {SCK_BACK,         SCI_CTRL,       SCI_DELWORDLEFT},
     {SCK_BACK,                 SCI_ALT,        SCI_UNDO},
-    {SCK_BACK,         SCI_CSHIFT,     SCI_DELLINELEFT},    
+    {SCK_BACK,         SCI_CSHIFT,     SCI_DELLINELEFT},
     {'Z',                      SCI_CTRL,       SCI_UNDO},
     {'Y',                      SCI_CTRL,       SCI_REDO},
     {'X',                      SCI_CTRL,       SCI_CUT},
@@ -127,6 +131,7 @@ const KeyToCommand KeyMap::MapDefault[] = {
     {'L',                      SCI_CTRL,       SCI_LINECUT},
     {'L',                      SCI_CSHIFT,     SCI_LINEDELETE},
     {'T',                      SCI_CTRL,       SCI_LINETRANSPOSE},
+    {'D',                      SCI_CTRL,       SCI_LINEDUPLICATE},
     {'U',                      SCI_CTRL,       SCI_LOWERCASE},
     {'U',                      SCI_CSHIFT,     SCI_UPPERCASE},
     {0,0,0},
index 8a03aa8ac4fbb42e7eb46b1793bfabccb2912682..73ecddf50dc26797a50998d7c8ce9847b155d1d2 100644 (file)
@@ -25,10 +25,10 @@ int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
 LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
        const char *languageName_, LexerFunction fnFolder_,
        const char * const wordListDescriptions_[]) :
-       language(language_), 
-       fnLexer(fnLexer_), 
-       fnFolder(fnFolder_), 
-       wordListDescriptions(wordListDescriptions_), 
+       language(language_),
+       fnLexer(fnLexer_),
+       fnFolder(fnFolder_),
+       wordListDescriptions(wordListDescriptions_),
        languageName(languageName_) {
        next = base;
        base = this;
@@ -62,7 +62,7 @@ const char * LexerModule::GetWordListDescription(int index) const {
                return wordListDescriptions[index];
        }
 }
+
 const LexerModule *LexerModule::Find(int language) {
        const LexerModule *lm = base;
        while (lm) {
@@ -142,15 +142,20 @@ int Scintilla_LinkLexers() {
 //++Autogenerated -- run src/LexGen.py to regenerate
 //**\(\tLINK_LEXER(\*);\n\)
        LINK_LEXER(lmAda);
+       LINK_LEXER(lmAsm);
        LINK_LEXER(lmAVE);
        LINK_LEXER(lmBaan);
        LINK_LEXER(lmBullant);
        LINK_LEXER(lmConf);
        LINK_LEXER(lmCPP);
+       LINK_LEXER(lmCPPNoCase);
        LINK_LEXER(lmTCL);
        LINK_LEXER(lmNncrontab);
+       LINK_LEXER(lmCss);
        LINK_LEXER(lmEiffel);
        LINK_LEXER(lmEiffelkw);
+       LINK_LEXER(lmFortran);
+       LINK_LEXER(lmF77);
        LINK_LEXER(lmHTML);
        LINK_LEXER(lmXML);
        LINK_LEXER(lmASP);
@@ -166,6 +171,7 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmLatex);
        LINK_LEXER(lmPascal);
        LINK_LEXER(lmPerl);
+       LINK_LEXER(lmPOV);
        LINK_LEXER(lmPython);
        LINK_LEXER(lmRuby);
        LINK_LEXER(lmSQL);
index dfd15f02f1866327e4b0fcc38b9ee47e8dc3043d..900aea317cfedb83d63b87269714b81326185bd0 100644 (file)
 // SciTE - Scintilla based Text Editor
 /** @file LexAVE.cxx
  ** Lexer for Avenue.
+ **
+  ** Written by Alexey Yutkin <yutkin@geol.msu.ru>.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <stdio.h>
 #include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
 
 #include "Platform.h"
 
 #include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-static void ColouriseAveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+static inline bool IsEnumChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch)|| ch == '_');
+}
+static inline bool IsANumberChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' );
+}
+
+inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+inline bool isAveOperator(char ch) {
+       if (isalnum(ch))
+               return false;
+       // '.' left out as it is used to make up numbers
+       if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+               ch == '(' || ch == ')' || ch == '=' ||
+               ch == '{' || ch == '}' ||
+               ch == '[' || ch == ']' || ch == ';' ||
+               ch == '<' || ch == '>' || ch == ',' ||
+               ch == '.'  )
+               return true;
+       return false;
+}
+
+static void ColouriseAveDoc(
+       unsigned int startPos,
+       int length,
+       int initStyle,
+       WordList *keywordlists[],
        Accessor &styler) {
 
        WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2];
+       WordList &keywords4 = *keywordlists[3];
+       WordList &keywords5 = *keywordlists[4];
+       WordList &keywords6 = *keywordlists[5];
+
+       // Do not leak onto next line
+       if (initStyle == SCE_AVE_STRINGEOL) {
+               initStyle = SCE_AVE_DEFAULT;
+       }
 
-       styler.StartAt(startPos);
+       StyleContext sc(startPos, length, initStyle, styler);
 
-       bool fold = styler.GetPropertyInt("fold") != 0;
-       int lineCurrent = styler.GetLine(startPos);
-       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
-       int levelCurrent = levelPrev;
+       for (; sc.More(); sc.Forward()) {
+               if (sc.atLineEnd) {
+                       // Update the line state, so it can be seen by next line
+                       int currentLine = styler.GetLine(sc.currentPos);
+                       styler.SetLineState(currentLine, 0);
+               }
+               if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) {
+                       // Prevent SCE_AVE_STRINGEOL from leaking back to previous line
+                       sc.SetState(SCE_AVE_STRING);
+               }
 
-       int state = initStyle;
-       if (state == SCE_AVE_STRINGEOL) // Does not leak onto next line
-               state = SCE_AVE_DEFAULT;
-       char chNext = styler[startPos];
-       unsigned int lengthDoc = startPos + length;
-       int visibleChars = 0;
-       styler.StartSegment(startPos);
 
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
-               chNext = styler.SafeGetCharAt(i + 1);
-               if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-                       // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-                       // Avoid triggering two times on Dos/Win
-                       // End of line
-                       if (state == SCE_AVE_STRINGEOL) {
-                               styler.ColourTo(i, state);
-                               state = SCE_AVE_DEFAULT;
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_AVE_OPERATOR) {
+                       sc.SetState(SCE_AVE_DEFAULT);
+               } else if (sc.state == SCE_AVE_NUMBER) {
+                       if (!IsANumberChar(sc.ch)) {
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-                       if (fold) {
-                               int lev = levelPrev;
-                               if (visibleChars == 0)
-                                       lev |= SC_FOLDLEVELWHITEFLAG;
-                               if ((levelCurrent > levelPrev) && (visibleChars > 0))
-                                       lev |= SC_FOLDLEVELHEADERFLAG;
-                               styler.SetLevel(lineCurrent, lev);
-                               lineCurrent++;
-                               levelPrev = levelCurrent;
+               } else if (sc.state == SCE_AVE_ENUM) {
+                       if (!IsEnumChar(sc.ch)) {
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-                       visibleChars = 0;
-               }
-               if (!isspace(ch))
-                       visibleChars++;
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       i += 1;
-                       continue;
-               }
-
-               if (state == SCE_AVE_DEFAULT) {
-                       if (iswordstart(ch) || (ch == '.') )  {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_IDENTIFIER;
-                       } else if (ch == '\'') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_COMMENT;
-                       } else if (ch == '\"') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_STRING;
-                       } else if (ch == '#') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_ENUM;
-                       } else if (isoperator(ch) ) {
-                               styler.ColourTo(i-1, state);
-                               styler.ColourTo(i, SCE_AVE_OPERATOR);
+               } else if (sc.state == SCE_AVE_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+                               char s[100];
+                               //sc.GetCurrent(s, sizeof(s));
+                               sc.GetCurrentLowered(s, sizeof(s));
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD2);
+                               } else if (keywords3.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD3);
+                               } else if (keywords4.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD4);
+                               } else if (keywords5.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD5);
+                               } else if (keywords6.InList(s)) {
+                                       sc.ChangeState(SCE_AVE_WORD6);
+                               }
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-               }
-               else if (state == SCE_AVE_COMMENT) {
-                       if (ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_DEFAULT;
+               } else if (sc.state == SCE_AVE_COMMENT) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_AVE_DEFAULT);
                        }
-               }
-               else if (state == SCE_AVE_ENUM) {
-                       if (isoperator(ch)  || ch == ' ' || ch == '\'' || ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_AVE_DEFAULT;
+               } else if (sc.state == SCE_AVE_STRING) {
+                        if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_AVE_DEFAULT);
+                       } else if (sc.atLineEnd) {
+                               sc.ChangeState(SCE_AVE_STRINGEOL);
+                               sc.ForwardSetState(SCE_AVE_DEFAULT);
                        }
                }
-               else if (state == SCE_AVE_STRING) {
-                       if (ch == '\"') {
-                               if (chNext == '\"') {
-                                       i++;
-                                       ch = chNext;
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               } else
-                               {
-                                       styler.ColourTo(i, state);
-                                       state = SCE_AVE_DEFAULT;
-                               }
-                       } else if (chNext == '\r' || chNext == '\n') {
-                               styler.ColourTo(i-1, SCE_AVE_STRINGEOL);
-                               state = SCE_AVE_STRINGEOL;
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_AVE_DEFAULT) {
+                       if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_AVE_NUMBER);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_AVE_IDENTIFIER);
+                       } else if (sc.Match('\"')) {
+                               sc.SetState(SCE_AVE_STRING);
+                       } else if (sc.Match('\'')) {
+                               sc.SetState(SCE_AVE_COMMENT);
+                               sc.Forward();
+                       } else if (isAveOperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_AVE_OPERATOR);
+                       } else if (sc.Match('#')) {
+                               sc.SetState(SCE_AVE_ENUM);
+                               sc.Forward();
                        }
                }
-               if ((state == SCE_AVE_IDENTIFIER)) {
-                       if (!iswordchar(ch) || ch == '.' ) {
-                               char s[100];
-                               unsigned int start = styler.GetStartSegment();
-                               unsigned int end = i - 1;
-                               for (unsigned int ii = 0; ii < end - start + 1 && ii < 30; ii++)        {
-                                       s[ii] = static_cast<char>(tolower(styler[start + ii]));
-                                       s[ii + 1] = '\0';
-                               }
-
-                               char chAttr = SCE_AVE_IDENTIFIER;
-
-                               if (isdigit(s[0]))
-                                       chAttr = SCE_AVE_NUMBER;
-                               else {
-                                       if ((strcmp(s, "for") == 0) || (strcmp(s, "if") == 0) || (strcmp(s, "while") == 0))
-                                       {
-                                               levelCurrent +=1;
-                                               chAttr = SCE_AVE_STATEMENT;
-                                       }
-
-                                       if (strcmp(s, "end") == 0)
-                                       {
-                                               levelCurrent -=1;
-                                               chAttr = SCE_AVE_STATEMENT;
-                                       }
+       }
+       sc.Complete();
+}
 
-                                       if ( (strcmp(s, "then") == 0) ||  (strcmp(s, "else") == 0)       || (strcmp(s, "break") == 0) ||
-                                               (strcmp(s, "each") == 0) ||
-                                               (strcmp(s, "exit") == 0) ||  (strcmp(s, "continue") == 0) || (strcmp(s, "return") == 0) ||
-                                               (strcmp(s, "by") == 0)   ||  (strcmp(s, "in") == 0)          || (strcmp(s, "elseif") == 0))
-                                       {
-                                               chAttr = SCE_AVE_STATEMENT;
-                                       }
+static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+                       Accessor &styler) {
+       unsigned int lengthDoc = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = static_cast<char>(tolower(styler[startPos]));
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       int styleNext = styler.StyleAt(startPos);
+       char s[10];
 
-                                       if ((strcmp(s, "av") == 0) || (strcmp(s, "self") == 0))
-                                       {
-                                               chAttr = SCE_AVE_KEYWORD;
+       for (unsigned int i = startPos; i < lengthDoc; i++) {
+               char ch = static_cast<char>(tolower(chNext));
+               chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
+               int style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (style == SCE_AVE_WORD) {
+                       if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') {
+                               for (unsigned int j = 0; j < 6; j++) {
+                                       if (!iswordchar(styler[i + j])) {
+                                               break;
                                        }
+                                       s[j] = static_cast<char>(tolower(styler[i + j]));
+                                       s[j + 1] = '\0';
+                               }
 
-                                       if (keywords.InList(s))
-                                       {
-                                               chAttr = SCE_AVE_WORD;
-                                       }
+                               if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
+                                       levelCurrent++;
                                }
-                               styler.ColourTo(end, chAttr);
-                               state = SCE_AVE_DEFAULT;
-
-                               if (ch == '\'') {
-                                       state = SCE_AVE_COMMENT;
-                               } else if (ch == '\"') {
-                                       state = SCE_AVE_STRING;
-                               } else if (isoperator(ch)) {
-                                       styler.ColourTo(i, SCE_AVE_OPERATOR);
+                               if ((strcmp(s, "end") == 0)) {
+                                       levelCurrent--;
                                }
                        }
+               } else if (style == SCE_AVE_OPERATOR) {
+                       if (ch == '{' || ch == '(') {
+                               levelCurrent++;
+                       } else if (ch == '}' || ch == ')') {
+                               levelCurrent--;
+                       }
                }
 
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact) {
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       }
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       }
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch)) {
+                       visibleChars++;
+               }
        }
-       styler.ColourTo(lengthDoc - 1, state);
-
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
-       if (fold) {
-               int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
-               styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 
-       }
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave");
+LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc);
+
index 0d8fb9d5dd7148fd42b792ca6927e3dd4595684e..263f7da4564910053ca7f3259afe693cf2193f32 100644 (file)
-// SciTE - Scintilla based Text Editor
-// LexAda.cxx - lexer for Ada95
-// by Tahir Karaca <tahir@bigfoot.de>
+// Scintilla source code edit control
+/** @file LexAda.cxx
+ ** Lexer for Ada 95
+ **/
+// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
 // The License.txt file describes the conditions under which this software may be distributed.
 
-#include <stdlib.h> 
-#include <string.h> 
-#include <ctype.h> 
-#include <stdio.h> 
-#include <stdarg.h> 
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
 
 #include "Platform.h"
 
-#include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
+#include "PropSet.h"
 #include "KeyWords.h"
-#include "Scintilla.h"
 #include "SciLexer.h"
+#include "SString.h"
+
+/*
+ * Interface
+ */
+
+static void ColouriseDocument(
+    unsigned int startPos,
+    int length,
+    int initStyle,
+    WordList *keywordlists[],
+    Accessor &styler);
+
+static const char * const adaWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
+
+/*
+ * Implementation
+ */
+
+// Functions that have apostropheStartsAttribute as a parameter set it according to whether
+// an apostrophe encountered after processing the current token will start an attribute or
+// a character literal.
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+
+static inline bool IsDelimiterCharacter(int ch);
+static inline bool IsNumberStartCharacter(int ch);
+static inline bool IsNumberCharacter(int ch);
+static inline bool IsSeparatorOrDelimiterCharacter(int ch);
+static bool IsValidIdentifier(const SString& identifier);
+static bool IsValidNumber(const SString& number);
+static inline bool IsWordStartCharacter(int ch);
+static inline bool IsWordCharacter(int ch);
 
-inline void classifyWordAda(unsigned int start, unsigned int end,
-       WordList &keywords, Accessor &styler) {
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
 
-       static const unsigned KEWORD_LEN_MAX = 30;
+       sc.SetState(SCE_ADA_CHARACTER);
 
-       char wordLower[KEWORD_LEN_MAX + 1];
-       unsigned i;
-       for(i = 0; ( i < KEWORD_LEN_MAX ) && ( i < end - start + 1 ); i++) {
-               wordLower[i] = static_cast<char>(tolower(styler[start + i]));           
+       // Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
+       // is handled correctly)
+       sc.Forward();
+       sc.Forward();
+
+       ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
+}
+
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
+       while (!sc.atLineEnd && !sc.Match(chEnd)) {
+               sc.Forward();
        }
-       wordLower[i] = '\0';
-               
-//     int levelChange = 0;
-       char chAttr = SCE_ADA_IDENTIFIER;
-       if (keywords.InList(wordLower)) {
-               chAttr = SCE_ADA_WORD;
 
-// Folding doesn't work this way since the semantics of some keywords depends
-// on the current context.
-// E.g. - "cond1 and THEN cond2" <-> "if ... THEN ..."         
-//      - "procedure X IS ... end X;" <-> "procedure X IS new Y;"
-//             if (strcmp(wordLower, "is") == 0 || strcmp(wordLower, "then") == 0)
-//                     levelChange=1;
-//             else if (strcmp(wordLower, "end") == 0)
-//                     levelChange=-1;
+       if (!sc.atLineEnd) {
+               sc.ForwardSetState(SCE_ADA_DEFAULT);
+       } else {
+               sc.ChangeState(stateEOL);
        }
-       styler.ColourTo(end, chAttr);
-       
-//     return levelChange;
 }
 
+static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+       // Apostrophe meaning is not changed, but the parameter is present for uniformity
 
-static inline bool isAdaOperator(char ch) {
-       
-       if (ch == '&' || ch == '\'' || ch == '(' || ch == ')' ||
-               ch == '*' || ch == '+' || ch == ',' || ch == '-' ||
-               ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
-               ch == '<' || ch == '=' || ch == '>')
-               return true;
-       return false;
-}
-
-
-inline void styleTokenBegin(char beginChar, unsigned int pos, int &state,
-       Accessor &styler) {
-               
-       if (isalpha(beginChar)) {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_IDENTIFIER;
-       } else if (isdigit(beginChar)) {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_NUMBER;
-       } else if (beginChar == '-' && styler.SafeGetCharAt(pos + 1) == '-') {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_COMMENT;
-       } else if (beginChar == '\"') {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_STRING;
-       } else if (beginChar == '\'' && styler.SafeGetCharAt(pos + 2) == '\'') {
-               styler.ColourTo(pos-1, state);
-               state = SCE_ADA_CHARACTER;
-       } else if (isAdaOperator(beginChar)) {
-               styler.ColourTo(pos-1, state);
-               styler.ColourTo(pos, SCE_ADA_OPERATOR);
-       }
-}
-
-
-static void ColouriseAdaDoc(unsigned int startPos, int length, int initStyle,
-       WordList *keywordlists[], Accessor &styler) {
-       
+       sc.SetState(SCE_ADA_COMMENTLINE);
+
+       while (!sc.atLineEnd) {
+               sc.Forward();
+       }
+}
+
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = sc.Match (')');
+       sc.SetState(SCE_ADA_DELIMITER);
+       sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = false;
+
+       sc.SetState(SCE_ADA_LABEL);
+
+       // Skip "<<"
+       sc.Forward();
+       sc.Forward();
+
+       SString identifier;
+
+       while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+               identifier += static_cast<char>(tolower(sc.ch));
+               sc.Forward();
+       }
+
+       // Skip ">>"
+       if (sc.Match('>', '>')) {
+               sc.Forward();
+               sc.Forward();
+       } else {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+       }
+
+       // If the name is an invalid identifier or a keyword, then make it invalid label
+       if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+       }
+
+       sc.SetState(SCE_ADA_DEFAULT);
+
+}
+
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
+
+       SString number;
+       sc.SetState(SCE_ADA_NUMBER);
+
+       // Get all characters up to a delimiter or a separator, including points, but excluding
+       // double points (ranges).
+       while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
+               number += static_cast<char>(sc.ch);
+               sc.Forward();
+       }
+
+       // Special case: exponent with sign
+       if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+               (sc.ch == '+' || sc.ch == '-')) {
+               number += static_cast<char>(sc.ch);
+               sc.Forward ();
+
+               while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+                       number += static_cast<char>(sc.ch);
+                       sc.Forward();
+               }
+       }
+
+       if (!IsValidNumber(number)) {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+       }
+
+       sc.SetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
+
+       sc.SetState(SCE_ADA_STRING);
+       sc.Forward();
+
+       ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
+}
+
+static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+       // Apostrophe meaning is not changed, but the parameter is present for uniformity
+       sc.SetState(SCE_ADA_DEFAULT);
+       sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+       apostropheStartsAttribute = true;
+       sc.SetState(SCE_ADA_IDENTIFIER);
+
+       SString word;
+
+       while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+               word += static_cast<char>(tolower(sc.ch));
+               sc.Forward();
+       }
+
+       if (!IsValidIdentifier(word)) {
+               sc.ChangeState(SCE_ADA_ILLEGAL);
+
+       } else if (keywords.InList(word.c_str())) {
+               sc.ChangeState(SCE_ADA_WORD);
+
+               if (word != "all") {
+                       apostropheStartsAttribute = false;
+               }
+       }
+
+       sc.SetState(SCE_ADA_DEFAULT);
+}
+
+//
+// ColouriseDocument
+//
+
+static void ColouriseDocument(
+    unsigned int startPos,
+    int length,
+    int initStyle,
+    WordList *keywordlists[],
+    Accessor &styler) {
        WordList &keywords = *keywordlists[0];
-       
-       styler.StartAt(startPos);
-       
-//     bool fold = styler.GetPropertyInt("fold");
-//     int lineCurrent = styler.GetLine(startPos);
-//     int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
-//     int levelCurrent = levelPrev;
-
-       int state = initStyle;
-       if (state == SCE_ADA_STRINGEOL) // Does not leak onto next line
-               state = SCE_ADA_DEFAULT;
-       char chNext = styler[startPos];
-       const unsigned int lengthDoc = startPos + length;
-       //int visibleChars = 0;
-       styler.StartSegment(startPos);
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
-               chNext = styler.SafeGetCharAt(i + 1);
-
-               if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-                       // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-                       // Avoid triggering two times on Dos/Win
-                       if (state == SCE_ADA_STRINGEOL) {
-                               styler.ColourTo(i, state);
-                               state = SCE_ADA_DEFAULT;
-                       }
-//                     if (fold) {
-//                             int lev = levelPrev;
-//                             if (visibleChars == 0)
-//                                     lev |= SC_FOLDLEVELWHITEFLAG;
-//                             if ((levelCurrent > levelPrev) && (visibleChars > 0))
-//                                     lev |= SC_FOLDLEVELHEADERFLAG;
-//                             styler.SetLevel(lineCurrent, lev);
-//                             lineCurrent++;
-//                             levelPrev = levelCurrent;
-//                     }
-                       //visibleChars = 0;
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       int lineCurrent = styler.GetLine(startPos);
+       bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
+
+       while (sc.More()) {
+               if (sc.atLineEnd) {
+                       // Go to the next line
+                       sc.Forward();
+                       lineCurrent++;
+
+                       // Remember the line state for future incremental lexing
+                       styler.SetLineState(lineCurrent, apostropheStartsAttribute);
+
+                       // Don't continue any styles on the next line
+                       sc.SetState(SCE_ADA_DEFAULT);
                }
-               //if (!isspacechar(ch))
-               //      visibleChars++;
 
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       i += 1;
-                       continue;
+               // Comments
+               if (sc.Match('-', '-')) {
+                       ColouriseComment(sc, apostropheStartsAttribute);
+
+               // Strings
+               } else if (sc.Match('"')) {
+                       ColouriseString(sc, apostropheStartsAttribute);
+
+               // Characters
+               } else if (sc.Match('\'') && !apostropheStartsAttribute) {
+                       ColouriseCharacter(sc, apostropheStartsAttribute);
+
+               // Labels
+               } else if (sc.Match('<', '<')) {
+                       ColouriseLabel(sc, keywords, apostropheStartsAttribute);
+
+               // Whitespace
+               } else if (isspace(sc.ch)) {
+                       ColouriseWhiteSpace(sc, apostropheStartsAttribute);
+
+               // Delimiters
+               } else if (IsDelimiterCharacter(sc.ch)) {
+                       ColouriseDelimiter(sc, apostropheStartsAttribute);
+
+               // Numbers
+               } else if (isdigit(sc.ch) || sc.ch == '#') {
+                       ColouriseNumber(sc, apostropheStartsAttribute);
+
+               // Keywords or identifiers
+               } else {
+                       ColouriseWord(sc, keywords, apostropheStartsAttribute);
+               }
+       }
+
+       sc.Complete();
+}
+
+static inline bool IsDelimiterCharacter(int ch) {
+       switch (ch) {
+       case '&':
+       case '\'':
+       case '(':
+       case ')':
+       case '*':
+       case '+':
+       case ',':
+       case '-':
+       case '.':
+       case '/':
+       case ':':
+       case ';':
+       case '<':
+       case '=':
+       case '>':
+       case '|':
+               return true;
+       default:
+               return false;
+       }
+}
+
+static inline bool IsNumberCharacter(int ch) {
+       return IsNumberStartCharacter(ch) ||
+              ch == '_' ||
+              ch == '.' ||
+              ch == '#' ||
+              (ch >= 'a' && ch <= 'f') ||
+              (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool IsNumberStartCharacter(int ch) {
+       return isdigit(ch) != 0;
+}
+
+static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
+       return isspace(ch) || IsDelimiterCharacter(ch);
+}
+
+static bool IsValidIdentifier(const SString& identifier) {
+       // First character can't be '_', so initialize the flag to true
+       bool lastWasUnderscore = true;
+
+       int length = identifier.length();
+
+       // Zero-length identifiers are not valid (these can occur inside labels)
+       if (length == 0) {
+               return false;
+       }
+
+       // Check for valid character at the start
+       if (!IsWordStartCharacter(identifier[0])) {
+               return false;
+       }
+
+       // Check for only valid characters and no double underscores
+       for (int i = 0; i < length; i++) {
+               if (!IsWordCharacter(identifier[i]) ||
+                       (identifier[i] == '_' && lastWasUnderscore)) {
+                       return false;
                }
+               lastWasUnderscore = identifier[i] == '_';
+       }
+
+       // Check for underscore at the end
+       if (lastWasUnderscore == true) {
+               return false;
+       }
 
-               if (state == SCE_ADA_DEFAULT) {
-                       styleTokenBegin(ch, i, state, styler);
-               } else if (state == SCE_ADA_IDENTIFIER) {
-                       if (!iswordchar(ch)) {
-                               classifyWordAda(styler.GetStartSegment(),
-                                                               i - 1,
-                                                               keywords,
-                                                               styler);
-                               state = SCE_ADA_DEFAULT;
-                               styleTokenBegin(ch, i, state, styler);
+       // All checks passed
+       return true;
+}
+
+static bool IsValidNumber(const SString& number) {
+       int hashPos = number.search("#");
+       bool seenDot = false;
+
+       int i = 0;
+       int length = number.length();
+
+       if (length == 0)
+               return false; // Just in case
+
+       // Decimal number
+       if (hashPos == -1) {
+               bool canBeSpecial = false;
+
+               for (; i < length; i++) {
+                       if (number[i] == '_') {
+                               if (!canBeSpecial) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                       } else if (number[i] == '.') {
+                               if (!canBeSpecial || seenDot) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                               seenDot = true;
+                       } else if (isdigit(number[i])) {
+                               canBeSpecial = true;
+                       } else {
+                               break;
                        }
-               } else if (state == SCE_ADA_COMMENT) {
-                       if (ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, state);
-                               state = SCE_ADA_DEFAULT;
+               }
+
+               if (!canBeSpecial)
+                       return false;
+       } else {
+               // Based number
+               bool canBeSpecial = false;
+               int base = 0;
+
+               // Parse base
+               for (; i < length; i++) {
+                       int ch = number[i];
+                       if (ch == '_') {
+                               if (!canBeSpecial)
+                                       return false;
+                               canBeSpecial = false;
+                       } else if (isdigit (ch)) {
+                               base = base * 10 + (ch - '0');
+                               if (base > 16)
+                                       return false;
+                               canBeSpecial = true;
+                       } else if (ch == '#' && canBeSpecial) {
+                               break;
+                       } else {
+                               return false;
                        }
-               } else if (state == SCE_ADA_STRING) {
-                       if (ch == '"' ) {
-                               if( chNext == '"' ) {
-                                       i++;
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               } else {                                        
-                                       styler.ColourTo(i, state);
-                                       state = SCE_ADA_DEFAULT;
+               }
+
+               if (base < 2)
+                       return false;
+               if (i == length)
+                       return false;
+
+               i++; // Skip over '#'
+
+               // Parse number
+               canBeSpecial = false;
+
+               for (; i < length; i++) {
+                       int ch = tolower(number[i]);
+
+                       if (ch == '_') {
+                               if (!canBeSpecial) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+
+                       } else if (ch == '.') {
+                               if (!canBeSpecial || seenDot) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                               seenDot = true;
+
+                       } else if (isdigit (ch)) {
+                               if (ch - '0' >= base) {
+                                       return false;
+                               }
+                               canBeSpecial = true;
+
+                       } else if (ch >= 'a' && ch <= 'f') {
+                               if (ch - 'a' + 10 >= base) {
+                                       return false;
                                }
-                       } else if (chNext == '\r' || chNext == '\n') {
-                               styler.ColourTo(i-1, SCE_ADA_STRINGEOL);
-                               state = SCE_ADA_STRINGEOL;
+                               canBeSpecial = true;
+
+                       } else if (ch == '#' && canBeSpecial) {
+                               break;
+
+                       } else {
+                               return false;
                        }
-               } else if (state == SCE_ADA_CHARACTER) {
-                       if (ch == '\r' || ch == '\n') {
-                               styler.ColourTo(i-1, SCE_ADA_STRINGEOL);
-                               state = SCE_ADA_STRINGEOL;
-                       } else if (ch == '\'' && styler.SafeGetCharAt(i - 2) == '\'') {
-                               styler.ColourTo(i, state);
-                               state = SCE_ADA_DEFAULT;
+               }
+
+               if (i == length) {
+                       return false;
+               }
+
+               i++;
+       }
+
+       // Exponent (optional)
+       if (i < length) {
+               if (number[i] != 'e' && number[i] != 'E')
+                       return false;
+
+               i++; // Move past 'E'
+
+               if (i == length) {
+                       return false;
+               }
+
+               if (number[i] == '+')
+                       i++;
+               else if (number[i] == '-') {
+                       if (seenDot) {
+                               i++;
+                       } else {
+                               return false; // Integer literals should not have negative exponents
                        }
-               } else if (state == SCE_ADA_NUMBER) {
-                       if ( !( isdigit(ch) || ch == '.' || ch == '_' || ch == '#'
-                                   || ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D'
-                                       || ch == 'E' || ch == 'F'
-                                       || ch == 'a' || ch == 'b' || ch == 'c' || ch == 'd'
-                                       || ch == 'e' || ch == 'f' ) ) {
-                               styler.ColourTo(i-1, SCE_ADA_NUMBER);
-                               state = SCE_ADA_DEFAULT;
-                               styleTokenBegin(ch, i, state, styler);
+               }
+
+               if (i == length) {
+                       return false;
+               }
+
+               bool canBeSpecial = false;
+
+               for (; i < length; i++) {
+                       if (number[i] == '_') {
+                               if (!canBeSpecial) {
+                                       return false;
+                               }
+                               canBeSpecial = false;
+                       } else if (isdigit(number[i])) {
+                               canBeSpecial = true;
+                       } else {
+                               return false;
                        }
                }
 
+               if (!canBeSpecial)
+                       return false;
        }
-       styler.ColourTo(lengthDoc - 1, state);
 
-//     // Fill in the real level of the next line, keeping the current flags as they will be filled in later
-//     if (fold) {
-//             int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
-//             styler.SetLevel(lineCurrent, levelPrev | flagsNext);
-//     }
+       // if i == length, number was parsed successfully.
+       return i == length;
+}
+
+static inline bool IsWordCharacter(int ch) {
+       return IsWordStartCharacter(ch) || isdigit(ch);
 }
 
-LexerModule lmAda(SCLEX_ADA, ColouriseAdaDoc, "ada");
+static inline bool IsWordStartCharacter(int ch) {
+       return isalpha(ch) || ch == '_';
+}
diff --git a/src/stc/scintilla/src/LexAsm.cxx b/src/stc/scintilla/src/LexAsm.cxx
new file mode 100644 (file)
index 0000000..1eecf9b
--- /dev/null
@@ -0,0 +1,142 @@
+// Scintilla source code edit control
+/** @file LexAsm.cxx
+ ** Lexer for Assembler, just for the Masm Syntax
+ ** Written by The Black Horus
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');
+}
+
+static inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+}
+
+inline bool isAsmOperator(char ch) {
+       if (isalnum(ch))
+               return false;
+       // '.' left out as it is used to make up numbers
+       if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+               ch == '(' || ch == ')' || ch == '=' ||
+               ch == '[' || ch == ']' || ch == '<' ||
+               ch == '>' || ch == ',' ||
+               ch == '.' || ch == '%' || ch == ':')
+               return true;
+       return false;
+}
+
+static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+
+       WordList &cpuInstruction = *keywordlists[0];
+       WordList &mathInstruction = *keywordlists[1];
+       WordList &registers = *keywordlists[2];
+       WordList &directive = *keywordlists[3];
+       WordList &directiveOperand = *keywordlists[4];
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       for (; sc.More(); sc.Forward())
+       {
+               // Handle line continuation generically.
+               if (sc.ch == '\\') {
+                       if (sc.Match("\\\n")) {
+                               sc.Forward();
+                               continue;
+                       }
+                       if (sc.Match("\\\r\n")) {
+                               sc.Forward();
+                               sc.Forward();
+                               continue;
+                       }
+               }
+
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_ASM_OPERATOR) {
+                       sc.SetState(SCE_ASM_DEFAULT);
+               }else if (sc.state == SCE_ASM_NUMBER) {
+                       if (!IsAWordChar(sc.ch)) {
+                               sc.SetState(SCE_ASM_DEFAULT);
+                       }
+               } else if (sc.state == SCE_ASM_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) ) {
+                       char s[100];
+                       sc.GetCurrentLowered(s, sizeof(s));
+
+                       if (cpuInstruction.InList(s)) {
+                               sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
+                       } else if (mathInstruction.InList(s)) {
+                               sc.ChangeState(SCE_ASM_MATHINSTRUCTION);
+                       } else if (registers.InList(s)) {
+                               sc.ChangeState(SCE_ASM_REGISTER);
+                       }  else if (directive.InList(s)) {
+                               sc.ChangeState(SCE_ASM_DIRECTIVE);
+                       } else if (directiveOperand.InList(s)) {
+                               sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
+                       }
+                       sc.SetState(SCE_ASM_DEFAULT);
+                       }
+               }
+               else if (sc.state == SCE_ASM_COMMENT ) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_ASM_DEFAULT);
+                       }
+               } else if (sc.state == SCE_ASM_STRING) {
+                       if (sc.ch == '\\') {
+                               if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+                                       sc.Forward();
+                               }
+                       } else if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_ASM_DEFAULT);
+                       } else if (sc.atLineEnd) {
+                               sc.ForwardSetState(SCE_ASM_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               else if (sc.state == SCE_ASM_DEFAULT) {
+                       if (sc.ch == ';'){
+                               sc.SetState(SCE_ASM_COMMENT);
+                       } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+                               sc.SetState(SCE_ASM_NUMBER);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_ASM_IDENTIFIER);
+                       } else if (sc.Match('\"')) {
+                               sc.SetState(SCE_ASM_STRING);
+                       }
+               }
+
+       }
+       sc.Complete();
+}
+
+static const char * const asmWordListDesc[] = {
+       "CPU instructions",
+       "FPU instructions",
+       "Registers",
+       "Directives",
+       "Directive operands",
+       0
+};
+
+LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);
+
index 1f76ffcf00189795df47952d5b0b377664fa308e..902f89c1e481b34037dec8d71cac87aeb559e046 100644 (file)
@@ -30,18 +30,6 @@ static int classifyWordBullant(unsigned int start, unsigned int end, WordList &k
        else {
                if (keywords.InList(s)) {
                        chAttr = SCE_C_WORD;
-/*                     if (strcmp(s, "end method") == 0 ||
-                               strcmp(s, "end case") == 0 ||
-                               strcmp(s, "end class") == 0 ||
-                               strcmp(s, "end debug") == 0 ||
-                               strcmp(s, "end test") == 0 ||
-                               strcmp(s, "end if") == 0 ||
-                               strcmp(s, "end lock") == 0 ||
-                               strcmp(s, "end transaction") == 0 ||
-                               strcmp(s, "end trap") == 0 ||
-                               strcmp(s, "end until") == 0 ||
-                               strcmp(s, "end while") == 0)
-                               lev = -1;*/
                        if (strcmp(s, "end") == 0)
                                lev = -1;
                        else if (strcmp(s, "method") == 0 ||
@@ -80,7 +68,6 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
        char chNext = styler[startPos];
        unsigned int lengthDoc = startPos + length;
        int visibleChars = 0;
-       // int blockChange = 0;
        styler.StartSegment(startPos);
        int endFoundThisLine = 0;
        for (unsigned int i = startPos; i < lengthDoc; i++) {
@@ -230,4 +217,9 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
        }
 }
 
-LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant");
+static const char * const bullantWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc);
index 39f458da7397171b0148ce2bed11c2b6c72d13e6..661b968cd75c3138b798bea9c369027e73a08367 100644 (file)
@@ -20,6 +20,9 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#define KEYWORD_BOXHEADER 1
+#define KEYWORD_FOLDCONTRACTED 2
+
 static bool IsOKBeforeRE(const int ch) {
        return (ch == '(') || (ch == '=') || (ch == ',');
 }
@@ -34,17 +37,17 @@ static inline bool IsAWordStart(const int ch) {
 
 static inline bool IsADoxygenChar(const int ch) {
        return (islower(ch) || ch == '$' || ch == '@' ||
-                   ch == '\\' || ch == '&' || ch == '<' ||
-                       ch == '>' || ch == '#' || ch == '{' ||
-                       ch == '}' || ch == '[' || ch == ']');
+               ch == '\\' || ch == '&' || ch == '<' ||
+               ch == '>' || ch == '#' || ch == '{' ||
+               ch == '}' || ch == '[' || ch == ']');
 }
 
 static inline bool IsStateComment(const int state) {
        return ((state == SCE_C_COMMENT) ||
-                     (state == SCE_C_COMMENTLINE) ||
-                     (state == SCE_C_COMMENTDOC) ||
-                     (state == SCE_C_COMMENTDOCKEYWORD) ||
-                     (state == SCE_C_COMMENTDOCKEYWORDERROR));
+               (state == SCE_C_COMMENTLINE) ||
+               (state == SCE_C_COMMENTDOC) ||
+               (state == SCE_C_COMMENTDOCKEYWORD) ||
+               (state == SCE_C_COMMENTDOCKEYWORDERROR));
 }
 
 static inline bool IsStateString(const int state) {
@@ -52,7 +55,7 @@ static inline bool IsStateString(const int state) {
 }
 
 static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
+                            Accessor &styler, bool caseSensitive) {
 
        WordList &keywords = *keywordlists[0];
        WordList &keywords2 = *keywordlists[1];
@@ -71,7 +74,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
        StyleContext sc(startPos, length, initStyle, styler);
 
        for (; sc.More(); sc.Forward()) {
-       
+
                if (sc.atLineStart && (sc.state == SCE_C_STRING)) {
                        // Prevent SCE_C_STRINGEOL from leaking back to previous line
                        sc.SetState(SCE_C_STRING);
@@ -98,7 +101,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                } else if (sc.state == SCE_C_IDENTIFIER) {
                        if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
                                char s[100];
-                               sc.GetCurrent(s, sizeof(s));
+                               if (caseSensitive) {
+                                       sc.GetCurrent(s, sizeof(s));
+                               } else {
+                                       sc.GetCurrentLowered(s, sizeof(s));
+                               }
                                if (keywords.InList(s)) {
                                        lastWordWasUUID = strcmp(s, "uuid") == 0;
                                        sc.ChangeState(SCE_C_WORD);
@@ -141,8 +148,12 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                sc.ForwardSetState(SCE_C_DEFAULT);
                        } else if (!IsADoxygenChar(sc.ch)) {
                                char s[100];
-                               sc.GetCurrent(s, sizeof(s));
-                               if (!isspace(sc.ch) || !keywords3.InList(s+1)) {
+                               if (caseSensitive) {
+                                       sc.GetCurrent(s, sizeof(s));
+                               } else {
+                                       sc.GetCurrentLowered(s, sizeof(s));
+                               }
+                               if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
                                        sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
                                }
                                sc.SetState(SCE_C_COMMENTDOC);
@@ -237,7 +248,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                // Skip whitespace between # and preprocessor word
                                do {
                                        sc.Forward();
-                               } while ((sc.ch == ' ') && (sc.ch == '\t') && sc.More());
+                               } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
                                if (sc.atLineEnd) {
                                        sc.SetState(SCE_C_DEFAULT);
                                }
@@ -245,9 +256,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                sc.SetState(SCE_C_OPERATOR);
                        }
                }
-               
+
                if (sc.atLineEnd) {
-                       // Reset states to begining of colourise so no surprises 
+                       // Reset states to begining of colourise so no surprises
                        // if different sets of lines lexed.
                        chPrevNonWhite = ' ';
                        visibleChars = 0;
@@ -262,13 +273,234 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 }
 
 static bool IsStreamCommentStyle(int style) {
-       return style == SCE_C_COMMENT || 
-               style == SCE_C_COMMENTDOC ||
-               style == SCE_C_COMMENTDOCKEYWORD ||
-               style == SCE_C_COMMENTDOCKEYWORDERROR;
+       return style == SCE_C_COMMENT ||
+              style == SCE_C_COMMENTDOC ||
+              style == SCE_C_COMMENTDOCKEYWORD ||
+              style == SCE_C_COMMENTDOCKEYWORDERROR;
 }
 
-static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+static bool matchKeyword(unsigned int start, WordList &keywords, Accessor &styler, int keywordtype) {
+       bool FoundKeyword = false;
+
+       for (unsigned int i = 0;
+               strlen(keywords[i]) > 0 && !FoundKeyword;
+               i++) {
+               if (atoi(keywords[i]) == keywordtype) {
+                       FoundKeyword = styler.Match(start, ((char *)keywords[i]) + 2);
+               }
+       }
+       return FoundKeyword;
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+       unsigned int Pos = styler.LineStart(line);
+       while (styler.GetLine(Pos) == line) {
+               int PosStyle = styler.StyleAt(Pos);
+
+               if (    !IsStreamCommentStyle(PosStyle)
+                       &&
+                       PosStyle != SCE_C_COMMENTLINEDOC
+                       &&
+                       PosStyle != SCE_C_COMMENTLINE
+                       &&
+                       !IsASpace(styler.SafeGetCharAt(Pos))
+                  )
+                       return false;
+               Pos++;
+       }
+
+       return true;
+}
+
+static void FoldBoxCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                          Accessor &styler) {
+
+       WordList &keywords4 = *keywordlists[3];
+
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       bool firstLine = true;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       int levelPrevPrev;
+       int levelFlags = 0;
+       int levelUnindent = 0;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+
+       if (lineCurrent == 0) {
+               levelPrevPrev = levelPrev;
+       } else {
+               levelPrevPrev = styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK;
+       }
+
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+               if (foldComment && IsStreamCommentStyle(style)) {
+                       if (!IsStreamCommentStyle(stylePrev)) {
+                               levelCurrent++;
+                       } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+                               // Comments don't end at end of line and the next character may be unstyled.
+                               levelCurrent--;
+                       }
+               }
+
+               if (foldComment && (style == SCE_C_COMMENTLINE)) {
+                       if ((ch == '/') && (chNext == '/')) {
+                               char chNext2 = styler.SafeGetCharAt(i + 2);
+                               if (chNext2 == '{') {
+                                       levelCurrent++;
+                               } else if (chNext2 == '}') {
+                                       levelCurrent--;
+                               }
+                       }
+               }
+
+               if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+                       if (ch == '#') {
+                               unsigned int j = i + 1;
+                               while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+                                       j++;
+                               }
+
+                               if (styler.Match(j, "region") || styler.Match(j, "if")) {
+                                       levelCurrent++;
+                               } else if (styler.Match(j, "end")) {
+                                       levelCurrent--;
+                               }
+                       }
+               }
+
+               if (style == SCE_C_OPERATOR
+                       ||
+                       style == SCE_C_COMMENT
+                       ||
+                       style == SCE_C_COMMENTLINE) {
+
+                       if (ch == '{') {
+                               levelCurrent++;
+                               // Special handling if line has closing brace followed by opening brace.
+                               if (levelCurrent == levelPrev) {
+                                       if (firstLine)
+                                               levelUnindent = 1;
+                                       else
+                                               levelUnindent = -1;
+                               }
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+
+               /* Check for fold header keyword at beginning of word */
+               if ((style == SCE_C_WORD || style == SCE_C_COMMENT || style == SCE_C_COMMENTLINE)
+                       &&
+                       (style != stylePrev)) {
+                       if (matchKeyword(i, keywords4, styler, KEYWORD_BOXHEADER)) {
+                               int line;
+                               /* Loop backwards all empty or comment lines */
+                               for (line = lineCurrent - 1;
+                                       line >= 0
+                                       &&
+                                       levelCurrent == (styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK)
+                                       &&
+                                       (styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0
+                                       &&
+                                       IsCommentLine(line, styler);
+                                       line--) {
+                                       /* just loop backwards */;
+                               }
+
+                               line++;
+                               /* Set Box header flag (if the previous line has no footer line) */
+                               if ((styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0) {
+                                       if (line == lineCurrent) {
+                                               /* in current line */
+                                               levelFlags |= SC_FOLDLEVELBOXHEADERFLAG;
+                                       } else {
+                                               /* at top of all preceding comment lines */
+                                               styler.SetLevel(line, styler.LevelAt(line)
+                                                               | SC_FOLDLEVELBOXHEADERFLAG);
+                                       }
+                               }
+                       }
+               }
+
+               if (matchKeyword(i, keywords4, styler, KEYWORD_FOLDCONTRACTED)) {
+                       levelFlags |= SC_FOLDLEVELCONTRACTED;
+               }
+
+               if (atEOL) {
+                       int lev;
+                       // Compute level correction for special case: '} else {'
+                       if (levelUnindent < 0) {
+                               levelPrev += levelUnindent;
+                       } else {
+                               levelCurrent += levelUnindent;
+                       }
+
+                       lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       // Produce additional footer line (e.g. after closed if)
+                       if (visibleChars == 0
+                               &&
+                               (levelPrev < levelPrevPrev))
+                               lev |= SC_FOLDLEVELBOXFOOTERFLAG;
+                       // Produce footer line at line before (special handling for '} else {'
+                       if (levelPrev < levelPrevPrev) {
+                               styler.SetLevel(lineCurrent - 1,
+                                               styler.LevelAt(lineCurrent - 1) | SC_FOLDLEVELBOXFOOTERFLAG);
+                       }
+                       // Mark the fold header (the line that is always visible)
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       // Show a footer line at end of fold
+                       if (levelCurrent < levelPrev)
+                               lev |= SC_FOLDLEVELBOXFOOTERFLAG;
+                       /* Show a footer line at the end of each procedure (level == SC_FOLDLEVELBASE) */
+                       if ((levelPrev == SC_FOLDLEVELBASE)
+                               &&
+                               (levelPrevPrev > SC_FOLDLEVELBASE)
+                               &&
+                               (visibleChars == 0)) {
+                               lev |= SC_FOLDLEVELBOXFOOTERFLAG;
+                       }
+
+                       lev |= levelFlags;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+
+                       lineCurrent++;
+                       levelPrevPrev = levelPrev;
+                       levelPrev = levelCurrent;
+                       levelUnindent = 0;
+                       visibleChars = 0;
+                       levelFlags = 0;
+                       firstLine = false;
+               }
+
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static void FoldNoBoxCppDoc(unsigned int startPos, int length, int initStyle,
                             Accessor &styler) {
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
        bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
@@ -308,8 +540,8 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordLis
                }
                if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
                        if (ch == '#') {
-                               unsigned int j=i+1;
-                               while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+                               unsigned int j = i + 1;
+                               while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
                                        j++;
                                }
                                if (styler.Match(j, "region") || styler.Match(j, "if")) {
@@ -347,12 +579,37 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordLis
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
+static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                       Accessor &styler) {
+
+       int foldFlags = styler.GetPropertyInt("fold.flags") ;
+       bool foldBox = ((foldFlags & SC_FOLDFLAG_BOX) == SC_FOLDFLAG_BOX);
+
+       if (foldBox) {
+               FoldBoxCppDoc(startPos, length, initStyle, keywordlists, styler);
+       } else {
+               FoldNoBoxCppDoc(startPos, length, initStyle, styler);
+       }
+}
+
 static const char * const cppWordLists[] = {
-       "Primary keywords and identifiers",
-       "Secondary keywords and identifiers",
-       "Documentation comment keywords",
-       0,
-};
-
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmTCL(SCLEX_TCL, ColouriseCppDoc, "tcl", FoldCppDoc, cppWordLists);
+            "Primary keywords and identifiers",
+            "Secondary keywords and identifiers",
+            "Documentation comment keywords",
+            "Fold header keywords",
+            0,
+        };
+
+static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                     Accessor &styler) {
+       ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                       Accessor &styler) {
+       ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+LexerModule lmTCL(SCLEX_TCL, ColouriseCppDocSensitive, "tcl", FoldCppDoc, cppWordLists);
diff --git a/src/stc/scintilla/src/LexCSS.cxx b/src/stc/scintilla/src/LexCSS.cxx
new file mode 100644 (file)
index 0000000..b89f7ea
--- /dev/null
@@ -0,0 +1,260 @@
+// Scintilla source code edit control
+/** @file LexCSS.cxx
+ ** Lexer for Cascade Style Sheets
+ ** Written by Jakub Vrána
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static inline bool IsAWordChar(const unsigned int ch) {
+       return (isalnum(ch) || ch == '-' || ch == '_' || ch >= 161); // _ is not in fact correct CSS word-character
+}
+
+inline bool IsCssOperator(const char ch) {
+       if (!isalnum(ch) && (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' || ch == '.' || ch == '#' || ch == '!' || ch == '@'))
+               return true;
+       return false;
+}
+
+static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+       WordList &keywords = *keywordlists[0];
+       WordList &pseudoClasses = *keywordlists[1];
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       int lastState = -1; // before operator
+       int lastStateC = -1; // before comment
+       int op = ' '; // last operator
+
+       for (; sc.More(); sc.Forward()) {
+               if (sc.state == SCE_CSS_COMMENT && sc.Match('*', '/')) {
+                       if (lastStateC == -1) {
+                               // backtrack to get last state
+                               unsigned int i = startPos;
+                               for (; i > 0; i--) {
+                                       if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
+                                               if (lastStateC == SCE_CSS_OPERATOR) {
+                                                       op = styler.SafeGetCharAt(i-1);
+                                                       while (--i) {
+                                                               lastState = styler.StyleAt(i-1);
+                                                               if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
+                                                                       break;
+                                                       }
+                                                       if (i == 0)
+                                                               lastState = SCE_CSS_DEFAULT;
+                                               }
+                                               break;
+                                       }
+                               }
+                               if (i == 0)
+                                       lastStateC = SCE_CSS_DEFAULT;
+                       }
+                       sc.Forward();
+                       sc.ForwardSetState(lastStateC);
+               }
+
+               if (sc.state == SCE_CSS_COMMENT)
+                       continue;
+
+               if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) {
+                       if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
+                               continue;
+                       unsigned int i = sc.currentPos;
+                       while (i && styler[i-1] == '\\')
+                               i--;
+                       if ((sc.currentPos - i) % 2 == 1)
+                               continue;
+                       sc.ForwardSetState(SCE_CSS_VALUE);
+               }
+
+               if (sc.state == SCE_CSS_OPERATOR) {
+                       if (op == ' ') {
+                               unsigned int i = startPos;
+                               op = styler.SafeGetCharAt(i-1);
+                               while (--i) {
+                                       lastState = styler.StyleAt(i-1);
+                                       if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
+                                               break;
+                               }
+                       }
+                       switch (op) {
+                       case '@':
+                               if (lastState == SCE_CSS_DEFAULT)
+                                       sc.SetState(SCE_CSS_DIRECTIVE);
+                               break;
+                       case '{':
+                               if (lastState == SCE_CSS_DIRECTIVE)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               else if (lastState == SCE_CSS_TAG)
+                                       sc.SetState(SCE_CSS_IDENTIFIER);
+                               break;
+                       case '}':
+                               if (lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT || lastState == SCE_CSS_IDENTIFIER)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               break;
+                       case ':':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID)
+                                       sc.SetState(SCE_CSS_PSEUDOCLASS);
+                               else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
+                                       sc.SetState(SCE_CSS_VALUE);
+                               break;
+                       case '.':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+                                       sc.SetState(SCE_CSS_CLASS);
+                               break;
+                       case '#':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+                                       sc.SetState(SCE_CSS_ID);
+                               break;
+                       case ',':
+                               if (lastState == SCE_CSS_TAG)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               break;
+                       case ';':
+                               if (lastState == SCE_CSS_DIRECTIVE)
+                                       sc.SetState(SCE_CSS_DEFAULT);
+                               else if (lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT)
+                                       sc.SetState(SCE_CSS_IDENTIFIER);
+                               break;
+                       case '!':
+                               if (lastState == SCE_CSS_VALUE)
+                                       sc.SetState(SCE_CSS_IMPORTANT);
+                               break;
+                       }
+               }
+
+               if (IsAWordChar(sc.ch)) {
+                       if (sc.state == SCE_CSS_DEFAULT)
+                               sc.SetState(SCE_CSS_TAG);
+                       continue;
+               }
+
+               if (IsAWordChar(sc.chPrev) && (
+                       sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_UNKNOWN_IDENTIFIER
+                       || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
+                       || sc.state == SCE_CSS_IMPORTANT
+               )) {
+                       char s[100];
+                       sc.GetCurrentLowered(s, sizeof(s));
+                       char *s2 = s;
+                       while (*s2 && !IsAWordChar(*s2))
+                               s2++;
+                       switch (sc.state) {
+                       case SCE_CSS_IDENTIFIER:
+                               if (!keywords.InList(s2))
+                                       sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
+                               break;
+                       case SCE_CSS_UNKNOWN_IDENTIFIER:
+                               if (keywords.InList(s2))
+                                       sc.ChangeState(SCE_CSS_IDENTIFIER);
+                               break;
+                       case SCE_CSS_PSEUDOCLASS:
+                               if (!pseudoClasses.InList(s2))
+                                       sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
+                               break;
+                       case SCE_CSS_UNKNOWN_PSEUDOCLASS:
+                               if (pseudoClasses.InList(s2))
+                                       sc.ChangeState(SCE_CSS_PSEUDOCLASS);
+                               break;
+                       case SCE_CSS_IMPORTANT:
+                               if (strcmp(s2, "important") != 0)
+                                       sc.ChangeState(SCE_CSS_VALUE);
+                               break;
+                       }
+               }
+
+               if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS || sc.state == SCE_CSS_ID))
+                       sc.SetState(SCE_CSS_TAG);
+
+               if (sc.Match('/', '*')) {
+                       lastStateC = sc.state;
+                       sc.SetState(SCE_CSS_COMMENT);
+                       sc.Forward();
+               } else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
+                       sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
+               } else if (IsCssOperator(static_cast<char>(sc.ch))
+                       && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
+                       && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
+               ) {
+                       if (sc.state != SCE_CSS_OPERATOR)
+                               lastState = sc.state;
+                       sc.SetState(SCE_CSS_OPERATOR);
+                       op = sc.ch;
+               }
+       }
+
+       sc.Complete();
+}
+
+static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT);
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int style = styler.StyleAt(i);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment) {
+                       if (!inComment && (style == SCE_CSS_COMMENT))
+                               levelCurrent++;
+                       else if (inComment && (style != SCE_CSS_COMMENT))
+                               levelCurrent--;
+                       inComment = (style == SCE_CSS_COMMENT);
+               }
+               if (style == SCE_CSS_OPERATOR) {
+                       if (ch == '{') {
+                               levelCurrent++;
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const cssWordListDesc[] = {
+       "Keywords",
+       "Pseudo classes",
+       0
+};
+
+LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);
index c8441f41ec6e2dccc99f9e19fdfa24ce6cbe1962..c33cdb5ce68edcf8ebc85dd7f7307edceac73508 100644 (file)
@@ -175,4 +175,10 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
        delete []buffer;
 }
 
-LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf");
+static const char * const confWordListDesc[] = {
+       "Directives",
+       "Parameters",
+       0
+};
+
+LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
index 37729cbfdd73c682a055420854dc65b1731a89c9..d139bb4f144778f532d7b2c89389191954c80c3d 100644 (file)
@@ -62,7 +62,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
                                        state = SCE_NNCRONTAB_TASK;
                                        styler.ColourTo(i,SCE_NNCRONTAB_TASK);
                                }
-                                 else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' || 
+                                 else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
                                                                                 styler.SafeGetCharAt(i+1) == '\t')) {
                                        // signals the start of an extended comment...
                                        state = SCE_NNCRONTAB_COMMENT;
@@ -208,4 +208,11 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
        delete []buffer;
 }
 
-LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab");
+static const char * const cronWordListDesc[] = {
+       "Section keywords and Forth words",
+       "nnCrontab keywords",
+       "Modifiers",
+       0
+};
+
+LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);
index a0bf26a5ea2e46955cc66273588f133097c69b8d..974efd9a72e1d9a3a5071fb4315b2c92e296ee68 100644 (file)
@@ -28,7 +28,7 @@ static inline bool isEiffelOperator(unsigned int ch) {
                ch == '{' || ch == '}' || ch == '~' ||
                ch == '[' || ch == ']' || ch == ';' ||
                ch == '<' || ch == '>' || ch == ',' ||
-               ch == '.' || ch == '^' || ch == '%' || ch == ':' || 
+               ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
                ch == '!' || ch == '@' || ch == '?';
 }
 
@@ -187,19 +187,19 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init
                        s[j] = '\0';
 
                        if (
-                               (strcmp(s, "check") == 0) || 
-                               (strcmp(s, "debug") == 0) || 
-                               (strcmp(s, "deferred") == 0) || 
-                               (strcmp(s, "do") == 0) || 
+                               (strcmp(s, "check") == 0) ||
+                               (strcmp(s, "debug") == 0) ||
+                               (strcmp(s, "deferred") == 0) ||
+                               (strcmp(s, "do") == 0) ||
                                (strcmp(s, "from") == 0) ||
                                (strcmp(s, "if") == 0) ||
-                               (strcmp(s, "inspect") == 0) || 
+                               (strcmp(s, "inspect") == 0) ||
                                (strcmp(s, "once") == 0)
                        )
                                levelCurrent++;
                        if (!lastDeferred && (strcmp(s, "class") == 0))
                                levelCurrent++;
-                       if (strcmp(s, "end") == 0) 
+                       if (strcmp(s, "end") == 0)
                                levelCurrent--;
                        lastDeferred = strcmp(s, "deferred") == 0;
                }
@@ -226,5 +226,10 @@ static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* init
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent);
-LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords);
+static const char * const eiffelWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc);
+LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc);
diff --git a/src/stc/scintilla/src/LexFortran.cxx b/src/stc/scintilla/src/LexFortran.cxx
new file mode 100644 (file)
index 0000000..e2109a0
--- /dev/null
@@ -0,0 +1,310 @@
+// Scintilla source code edit control
+/** @file LexFortran.cxx
+ ** Lexer for Fortran.
+ ** Writen by Chuan-jian Shen, Last changed Nov. 2002
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
+}
+
+static inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch));
+}
+
+inline bool IsABlank(unsigned int ch) {
+    return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
+}
+static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler, bool isFixFormat) {
+
+       WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2];
+
+       int posLineStart = 0, prevState = 0;
+       int endPos = startPos + length;
+
+       // backtrack to the beginning of the document, this may be slow for big documents.
+       // initStyle = SCE_F_DEFAULT;
+       // StyleContext sc(0, startPos+length, initStyle, styler);
+
+       // backtrack to the nearest keyword
+       while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) {
+               startPos--;
+       }
+       startPos = styler.LineStart(styler.GetLine(startPos));
+       initStyle = styler.StyleAt(startPos - 1);
+       StyleContext sc(startPos, endPos-startPos, initStyle, styler);
+
+       for (; sc.More(); sc.Forward()) {
+
+               // remember the position of the line
+               if (sc.atLineStart) {
+                       posLineStart = sc.currentPos;
+                       sc.SetState(SCE_F_DEFAULT);
+               }
+
+               // Handle line continuation generically.
+               if (sc.ch == '&') {
+                       char chTemp = ' ';
+                       int j = 1;
+                       while (IsABlank(chTemp) && j<132) {
+                               chTemp = static_cast<char>(sc.GetRelative(j));
+                               j ++;
+                       }
+                       if (chTemp == '!') {
+                               sc.SetState(SCE_F_CONTINUATION);
+                               if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT);
+                       } else if (chTemp == '\r' || chTemp == '\n') {
+                               int currentState = sc.state;
+                               sc.SetState(SCE_F_CONTINUATION);
+                               if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       while (IsASpace(sc.ch) && sc.More()) sc.Forward();
+                                       if (sc.ch == '&') {
+                                               sc.SetState(SCE_F_CONTINUATION);
+                                               sc.Forward();
+                                       }
+                                       sc.SetState(currentState);
+                               }
+                       }
+                       continue;
+               }
+
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_F_OPERATOR) {
+                       sc.SetState(SCE_F_DEFAULT);
+               } else if (sc.state == SCE_F_NUMBER) {
+                       if (!IsAWordChar(sc.ch)) {
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) || (sc.ch == '%')) {
+                               char s[100];
+                               sc.GetCurrentLowered(s, sizeof(s));
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_F_WORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_F_WORD2);
+                               } else if (keywords3.InList(s)) {
+                                       sc.ChangeState(SCE_F_WORD3);
+                               }
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_COMMENT) {
+                       if (sc.ch == '\r' || sc.ch == '\n') {
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_STRING1) {
+                       prevState = sc.state;
+                       if (sc.ch == '\'') {
+                               if (sc.chNext == '\'') {
+                                       sc.Forward();
+                               } else {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       prevState = SCE_F_DEFAULT;
+                               }
+                       } else if (sc.atLineEnd) {
+                               if (isFixFormat) {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       posLineStart = sc.currentPos;
+                               } else {
+                                       sc.ChangeState(SCE_F_STRINGEOL);
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                               }
+                       }
+               } else if (sc.state == SCE_F_STRING2) {
+                       prevState = sc.state;
+                       if (sc.atLineEnd) {
+                               if (isFixFormat) {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       posLineStart = sc.currentPos;
+                               } else {
+                                       sc.ChangeState(SCE_F_STRINGEOL);
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                               }
+                       } else if (sc.ch == '\"') {
+                               if (sc.chNext == '\"') {
+                                       sc.Forward();
+                               } else {
+                                       sc.ForwardSetState(SCE_F_DEFAULT);
+                                       prevState = SCE_F_DEFAULT;
+                               }
+                       }
+               } else if (sc.state == SCE_F_OPERATOR2) {
+                       if (sc.ch == '.') {
+                               sc.ForwardSetState(SCE_F_DEFAULT);
+                       }
+               } else if (sc.state == SCE_F_CONTINUATION) {
+                       sc.SetState(SCE_F_DEFAULT);
+               } else if (sc.state == SCE_F_LABEL) {
+                       if (sc.currentPos >= static_cast<unsigned int>(posLineStart+5)) {
+                               sc.SetState(SCE_F_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_F_DEFAULT) {
+                       int toLineStart = sc.currentPos - posLineStart;
+                       if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
+                               if (sc.atLineStart && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') {
+                                       sc.SetState(SCE_F_COMMENT);
+                               } else if (toLineStart > 72) {
+                                       sc.SetState(SCE_F_COMMENT);
+                               } else if (toLineStart < 5 && !IsASpace(sc.ch)) {
+                                       sc.SetState(SCE_F_LABEL);
+                               } else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) {
+                                       sc.SetState(SCE_F_CONTINUATION);
+                                       sc.ForwardSetState(prevState);
+                               }
+                       } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_F_NUMBER);
+                       } else if (sc.ch == '.' && isalpha(sc.chNext)) {
+                               sc.SetState(SCE_F_OPERATOR2);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_F_IDENTIFIER);
+                       } else if (sc.ch == '!') {
+                               sc.SetState(SCE_F_COMMENT);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_F_STRING2);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_F_STRING1);
+                       } else if (isoperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_F_OPERATOR);
+                       }
+               }
+       }
+       sc.Complete();
+}
+
+// The folding depends on the mercy of the programer.
+static int classifyFoldPointFortran(const char* s, const char* prevWord) {
+       int lev = 0;
+       if (strcmp(prevWord, "end") == 0) return lev;
+       if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
+               return -1;
+       if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
+           || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
+           || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
+           || strcmp(s, "forall") == 0 || strcmp(s, "function") == 0
+           || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0
+           || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0
+           || strcmp(s, "then") == 0 || strcmp(s, "where") == 0) {
+               lev = 1;
+       } else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0
+           || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
+           || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
+           || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
+           || strcmp(s, "endif") == 0
+           || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0
+           || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0
+           || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0
+           || strcmp(s, "endwhere") == 0 || strcmp(s, "procedure") == 0 ) {
+               lev = -1;
+       }
+       return lev;
+}
+static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+       //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       // Do not know how to fold the comment at the moment.
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+
+       int lastStart = 0;
+       char prevWord[32] = "";
+
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+               if (stylePrev == SCE_F_DEFAULT && style == SCE_F_WORD)
+               {
+                       // Store last word start point.
+                       lastStart = i;
+               }
+
+               if (style == SCE_F_WORD) {
+                       if(iswordchar(ch) && !iswordchar(chNext)) {
+                               char s[32];
+                               unsigned int j;
+                               for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
+                                       s[j] = static_cast<char>(tolower(styler[lastStart + j]));
+                               }
+                               s[j] = '\0';
+                               levelCurrent += classifyFoldPointFortran(s, prevWord);
+                               strcpy(prevWord, s);
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+                       strcpy(prevWord, "");
+               }
+
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const FortranWordLists[] = {
+       "Primary keywords and identifiers",
+       "Intrinsic functions",
+       "Extended and user defined functions",
+       0,
+};
+
+static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+       ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+       ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
+}
+
+
+LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDoc, FortranWordLists);
+LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDoc, FortranWordLists);
index 545bbfd553317abf95674c83caf0fe4e1bd4de0f..345b15edcb3b1c6c6a931d7340e8aae2fc996a1a 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LexHTML.cxx
  ** Lexer for HTML.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -197,16 +197,30 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
 }
 
 static int classifyTagHTML(unsigned int start, unsigned int end,
-                           WordList &keywords, Accessor &styler) {
-       char s[30 + 1];
+                           WordList &keywords, Accessor &styler, bool &tagDontFold,
+                          bool caseSensitive) {
+       char s[30 + 2];
        // Copy after the '<'
        unsigned int i = 0;
        for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
                char ch = styler[cPos];
-               if ((ch != '<') && (ch != '/'))
-                       s[i++] = static_cast<char>(tolower(ch));
+               if ((ch != '<') && (ch != '/')) {
+                       s[i++] = caseSensitive ? ch : static_cast<char>(tolower(ch));
+               }
        }
+
+       //The following is only a quick hack, to see if this whole thing would work
+       //we first need the tagname with a trailing space...
+       s[i] = ' ';
+       s[i+1] = '\0';
+
+       //...to find it in the list of no-container-tags
+       // (There are many more. We will need a keywordlist in the property file for this)
+       tagDontFold = (NULL != strstr("meta link img area br hr input ",s));
+
+       //now we can remove the trailing space
        s[i] = '\0';
+
        bool isScript = false;
        char chAttr = SCE_H_TAGUNKNOWN;
        if (s[0] == '!') {
@@ -368,6 +382,14 @@ static inline bool issgmlwordchar(char ch) {
        return isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[';
 }
 
+static inline bool IsPhpWordStart(const unsigned char ch) {
+       return isalpha(ch) || (ch == '_') || (ch >= 0x7f);
+}
+
+static inline bool IsPhpWordChar(char ch) {
+       return isdigit(ch) || IsPhpWordStart(ch);
+}
+
 static bool InTagState(int state) {
        return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
               state == SCE_H_SCRIPT ||
@@ -433,6 +455,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
        bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag
        bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag
+       bool tagDontFold = false; //some HTML tags should not be folded
        script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name
        script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name
        int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
@@ -440,8 +463,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        script_type scriptLanguage = ScriptOfState(state);
 
        const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
-       const bool fold = foldHTML && styler.GetPropertyInt("fold");
+       const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
+       const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
        const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
 
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
        int levelCurrent = levelPrev;
@@ -481,7 +506,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        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 ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
+                               //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
+                               //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
                                        if ((ch == '{') || (ch == '}')) {
                                                levelCurrent += (ch == '{') ? 1 : -1;
                                        }
@@ -600,9 +627,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        else
                                inScriptType = eNonHtmlPreProc;
                        // fold whole script
-                       levelCurrent++;
-                       if (scriptLanguage == eScriptXML)
-                               levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
+                       if (foldHTMLPreprocessor){
+                               levelCurrent++;
+                               if (scriptLanguage == eScriptXML)
+                                       levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
+                       }
                        // should be better
                        ch = styler.SafeGetCharAt(i);
                        continue;
@@ -640,7 +669,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        scriptLanguage = eScriptVBS;
                        styler.ColourTo(i, SCE_H_ASP);
                        // fold whole script
-                       levelCurrent++;
+                       if (foldHTMLPreprocessor)
+                               levelCurrent++;
                        // should be better
                        ch = styler.SafeGetCharAt(i);
                        continue;
@@ -665,8 +695,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                state = SCE_H_SGML_COMMAND; // wait for a pending command
                        }
                        // fold whole tag (-- when closing the tag)
-
-                       levelCurrent++;
+                       if (foldHTMLPreprocessor)
+                               levelCurrent++;
                        continue;
                }
 
@@ -723,7 +753,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                inScriptType = eHtml;
                        scriptLanguage = eScriptNone;
                        // unfold all scripting languages
-                       levelCurrent--;
+                       if (foldHTMLPreprocessor)
+                               levelCurrent--;
                        continue;
                }
                /////////////////////////////////////
@@ -904,7 +935,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        break;
                case SCE_H_TAGUNKNOWN:
                        if (!ishtmlwordchar(ch) && !((ch == '/') && (chPrev == '<')) && ch != '[') {
-                               int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler);
+                               int eClass = classifyTagHTML(styler.GetStartSegment(),
+                                       i - 1, keywords, styler, tagDontFold, caseSensitive);
                                if (eClass == SCE_H_SCRIPT) {
                                        if (!tagClosing) {
                                                inScriptType = eNonHtmlScript;
@@ -923,10 +955,12 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                state = SCE_H_DEFAULT;
                                        }
                                        tagOpened = false;
-                                       if (tagClosing) {
-                                               levelCurrent--;
-                                       } else {
-                                               levelCurrent++;
+                                       if (!tagDontFold){
+                                               if (tagClosing) {
+                                                       levelCurrent--;
+                                               } else {
+                                                       levelCurrent++;
+                                               }
                                        }
                                        tagClosing = false;
                                } else if (ch == '/' && chNext == '>') {
@@ -969,10 +1003,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                state = SCE_H_DEFAULT;
                                        }
                                        tagOpened = false;
-                                       if (tagClosing)
-                                               levelCurrent--;
-                                       else
-                                               levelCurrent++;
+                                       if (!tagDontFold){
+                                               if (tagClosing){
+                                                       levelCurrent--;
+                                               } else {
+                                                       levelCurrent++;
+                                               }
+                                       }
                                        tagClosing = false;
                                } else if (ch == '=') {
                                        styler.ColourTo(i, SCE_H_OTHER);
@@ -992,10 +1029,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                        state = SCE_H_DEFAULT;
                                }
                                tagOpened = false;
-                               if (tagClosing)
-                                       levelCurrent--;
-                               else
-                                       levelCurrent++;
+                               if (!tagDontFold){
+                                       if (tagClosing){
+                                               levelCurrent--;
+                                       } else {
+                                               levelCurrent++;
+                                       }
+                               }
                                tagClosing = false;
                        } else if (ch == '\"') {
                                styler.ColourTo(i - 1, StateToPrint);
@@ -1044,10 +1084,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        break;
                case SCE_H_VALUE:
                        if (!ishtmlwordchar(ch)) {
-                               if (ch == '\"') {
+                               if (ch == '\"' && chPrev == '=') {
                                        // Should really test for being first character
                                        state = SCE_H_DOUBLESTRING;
-                               } else if (ch == '\'') {
+                               } else if (ch == '\'' && chPrev == '=') {
                                        state = SCE_H_SINGLESTRING;
                                } else {
                                        if (IsNumber(styler.GetStartSegment(), styler)) {
@@ -1063,10 +1103,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                        state = SCE_H_DEFAULT;
                                                }
                                                tagOpened = false;
-                                               if (tagClosing)
-                                                       levelCurrent--;
-                                               else
-                                                       levelCurrent++;
+                                               if (!tagDontFold){
+                                                       if (tagClosing){
+                                                               levelCurrent--;
+                                                       } else {
+                                                               levelCurrent++;
+                                                       }
+                                               }
                                                tagClosing = false;
                                        } else {
                                                state = SCE_H_OTHER;
@@ -1397,7 +1440,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        break;
                        ///////////// start - PHP state handling
                case SCE_HPHP_WORD:
-                       if (!iswordstart(ch)) {
+                       if (!iswordchar(ch)) {
                                classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
                                if (ch == '/' && chNext == '*') {
                                        i++;
@@ -1411,7 +1454,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                        state = SCE_HPHP_HSTRING;
                                } else if (ch == '\'') {
                                        state = SCE_HPHP_SIMPLESTRING;
-                               } else if (ch == '$') {
+                               } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                        state = SCE_HPHP_VARIABLE;
                                } else if (isoperator(ch)) {
                                        state = SCE_HPHP_OPERATOR;
@@ -1430,7 +1473,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        break;
                case SCE_HPHP_VARIABLE:
-                       if (!iswordstart(ch)) {
+                       if (!IsPhpWordChar(ch)) {
                                styler.ColourTo(i - 1, SCE_HPHP_VARIABLE);
                                if (isoperator(ch))
                                        state = SCE_HPHP_OPERATOR;
@@ -1454,7 +1497,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        if (ch == '\\') {
                                // skip the next char
                                i++;
-                       } else if (ch == '$') {
+                       } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                styler.ColourTo(i - 1, StateToPrint);
                                state = SCE_HPHP_HSTRING_VARIABLE;
                        } else if (ch == '\"') {
@@ -1472,7 +1515,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        break;
                case SCE_HPHP_HSTRING_VARIABLE:
-                       if (!iswordstart(ch)) {
+                       if (!IsPhpWordChar(ch)) {
                                styler.ColourTo(i - 1, StateToPrint);
                                i--; // strange but it works
                                state = SCE_HPHP_HSTRING;
@@ -1497,7 +1540,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                state = SCE_HPHP_HSTRING;
                        } else if (ch == '\'') {
                                state = SCE_HPHP_SIMPLESTRING;
-                       } else if (ch == '$') {
+                       } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                state = SCE_HPHP_VARIABLE;
                        } else if (isoperator(ch)) {
                                state = SCE_HPHP_OPERATOR;
@@ -1553,7 +1596,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        }
 
        StateToPrint = statePrintForState(state, inScriptType);
-       styler.ColourTo(lengthDoc - 1, StateToPrint);
+               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) {
@@ -1701,9 +1744,9 @@ static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) {
                        sc.SetState(SCE_H_ENTITY);
                }
        } else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) {
-               if (sc.ch == '\"') {
+               if (sc.ch == '\"' && sc.chPrev == '=') {
                        sc.SetState(SCE_H_DOUBLESTRING);
-               } else if (sc.ch == '\'') {
+               } else if (sc.ch == '\'' && sc.chPrev == '=') {
                        sc.SetState(SCE_H_SINGLESTRING);
                } else if (IsADigit(sc.ch)) {
                        sc.SetState(SCE_H_NUMBER);
@@ -1780,7 +1823,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
 
        // Handle some PHP script
        if (sc.state == SCE_HPHP_WORD) {
-               if (!IsAWordStart(sc.ch)) {
+               if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_DEFAULT);
                }
        } else if (sc.state == SCE_HPHP_COMMENTLINE) {
@@ -1802,7 +1845,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
                        sc.ForwardSetState(SCE_HPHP_DEFAULT);
                }
        } else if (sc.state == SCE_HPHP_VARIABLE) {
-               if (!IsAWordStart(sc.ch)) {
+               if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_DEFAULT);
                }
        } else if (sc.state == SCE_HPHP_OPERATOR) {
@@ -1822,7 +1865,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
                }
        }
        if (sc.state == SCE_HPHP_DEFAULT) {
-               if (IsAWordStart(sc.ch)) {
+               if (IsPhpWordStart(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_WORD);
                } else if (sc.ch == '#') {
                        sc.SetState(SCE_HPHP_COMMENTLINE);
@@ -1836,7 +1879,7 @@ static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
                        sc.SetState(SCE_HPHP_HSTRING);
                } else if (sc.ch == '\'') {
                        sc.SetState(SCE_HPHP_SIMPLESTRING);
-               } else if (sc.ch == '$') {
+               } else if (sc.ch == '$' && IsPhpWordStart(static_cast<char>(sc.chNext))) {
                        sc.SetState(SCE_HPHP_VARIABLE);
                } else if (isoperator(static_cast<char>(sc.ch))) {
                        sc.SetState(SCE_HPHP_OPERATOR);
index cb150ff76deb3ac0eaf435785eced7fe939c81ff..9cd5433c89630299cb796c5b1c9b464464483b62 100644 (file)
@@ -98,7 +98,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                        if (isLispwordstart(ch)) {
                                styler.ColourTo(i - 1, state);
                                state = SCE_LISP_IDENTIFIER;
-                       } 
+                       }
                        else if (ch == ';') {
                                styler.ColourTo(i - 1, state);
                                state = SCE_LISP_COMMENT;
@@ -107,7 +107,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                                styler.ColourTo(i - 1, state);
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
                        }
-                       
+
                        else if (ch == '\"') {
                                        state = SCE_LISP_STRING;
                        }
@@ -115,12 +115,12 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                        if (!isLispwordstart(ch)) {
                                classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler);
                                state = SCE_LISP_DEFAULT;
-                       } /*else*/ 
+                       } /*else*/
                        if (isLispoperator(ch) || ch=='\'') {
                                styler.ColourTo(i - 1, state);
                                styler.ColourTo(i, SCE_LISP_OPERATOR);
                        }
-                       
+
                } else {
                        if (state == SCE_LISP_COMMENT) {
                                if (atEOL) {
@@ -192,4 +192,9 @@ static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */,
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc);
+static const char * const lispWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);
index fc9607e25d24300256ea201cd1bf598f47151378..159bc1585d14f4347fd258c3114944a873613bb8 100644 (file)
@@ -23,8 +23,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#define SCE_LUA_LAST_STYLE     SCE_LUA_WORD6
-
 static inline bool IsAWordChar(const int ch) {
        return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
 }
@@ -61,14 +59,16 @@ static void ColouriseLuaDoc(
        WordList &keywords5 = *keywordlists[4];
        WordList &keywords6 = *keywordlists[5];
 
-       // Must initialize the literal string nesting level, if we are inside such a string.
+       int currentLine = styler.GetLine(startPos);
+       // Initialize the literal string [[ ... ]] nesting level, if we are inside such a string.
        int literalStringLevel = 0;
        if (initStyle == SCE_LUA_LITERALSTRING) {
-               literalStringLevel = 1;
+               literalStringLevel = styler.GetLineState(currentLine - 1);
        }
-       // We use states above the last one to indicate nesting level of literal strings
-       if (initStyle > SCE_LUA_LAST_STYLE) {
-               literalStringLevel = initStyle - SCE_LUA_LAST_STYLE + 1;
+       // Initialize the block comment --[[ ... ]] nesting level, if we are inside such a comment
+       int blockCommentLevel = 0;
+       if (initStyle == SCE_LUA_COMMENT) {
+               blockCommentLevel = styler.GetLineState(currentLine - 1);
        }
 
        // Do not leak onto next line
@@ -78,9 +78,28 @@ static void ColouriseLuaDoc(
 
        StyleContext sc(startPos, length, initStyle, styler);
        if (startPos == 0 && sc.ch == '#') {
+               // shbang line: # is a comment only if first char of the script
                sc.SetState(SCE_LUA_COMMENTLINE);
        }
        for (; sc.More(); sc.Forward()) {
+               if (sc.atLineEnd) {
+                       // Update the line state, so it can be seen by next line
+                       currentLine = styler.GetLine(sc.currentPos);
+                       switch (sc.state) {
+                       case SCE_LUA_LITERALSTRING:
+                               // Inside a literal string, we set the line state
+                               styler.SetLineState(currentLine, literalStringLevel);
+                               break;
+                       case SCE_LUA_COMMENT:   // Block comment
+                               // Inside a block comment, we set the line state
+                               styler.SetLineState(currentLine, blockCommentLevel);
+                               break;
+                       default:
+                               // Reset the line state
+                               styler.SetLineState(currentLine, 0);
+                               break;
+                       }
+               }
                if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) {
                        // Prevent SCE_LUA_STRINGEOL from leaking back to previous line
                        sc.SetState(SCE_LUA_STRING);
@@ -88,7 +107,7 @@ static void ColouriseLuaDoc(
 
                // Handle string line continuation
                if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) &&
-                               sc.ch == '\\') {
+                       sc.ch == '\\') {
                        if (sc.chNext == '\n' || sc.chNext == '\r') {
                                sc.Forward();
                                if (sc.ch == '\r' && sc.chNext == '\n') {
@@ -154,22 +173,31 @@ static void ColouriseLuaDoc(
                                sc.ChangeState(SCE_LUA_STRINGEOL);
                                sc.ForwardSetState(SCE_LUA_DEFAULT);
                        }
-               } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state > SCE_LUA_LAST_STYLE) {
+               } else if (sc.state == SCE_LUA_LITERALSTRING) {
                        if (sc.Match('[', '[')) {
                                literalStringLevel++;
-                               sc.SetState(SCE_LUA_LAST_STYLE + literalStringLevel - 1);
+                               sc.Forward();
+                               sc.SetState(SCE_LUA_LITERALSTRING);
                        } else if (sc.Match(']', ']') && literalStringLevel > 0) {
                                literalStringLevel--;
                                sc.Forward();
                                if (literalStringLevel == 0) {
                                        sc.ForwardSetState(SCE_LUA_DEFAULT);
-                               } else if (literalStringLevel == 1) {
-                                       sc.ForwardSetState(SCE_LUA_LITERALSTRING);
-                               } else {
-                                       sc.ForwardSetState(SCE_LUA_LAST_STYLE + literalStringLevel - 1);
+                               }
+                       }
+               } else if (sc.state == SCE_LUA_COMMENT) {       // Lua 5.0's block comment
+                       if (sc.Match('[', '[')) {
+                               blockCommentLevel++;
+                               sc.Forward();
+                       } else if (sc.Match(']', ']') && blockCommentLevel > 0) {
+                               blockCommentLevel--;
+                               sc.Forward();
+                               if (blockCommentLevel == 0) {
+                                       sc.ForwardSetState(SCE_LUA_DEFAULT);
                                }
                        }
                }
+
                // Determine if a new state should be entered.
                if (sc.state == SCE_LUA_DEFAULT) {
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
@@ -184,12 +212,16 @@ static void ColouriseLuaDoc(
                                literalStringLevel = 1;
                                sc.SetState(SCE_LUA_LITERALSTRING);
                                sc.Forward();
+                       } else if (sc.Match("--[[")) {  // Lua 5.0's block comment
+                               blockCommentLevel = 1;
+                               sc.SetState(SCE_LUA_COMMENT);
+                               sc.Forward(3);
                        } else if (sc.Match('-', '-')) {
                                sc.SetState(SCE_LUA_COMMENTLINE);
                                sc.Forward();
-                       } else if (sc.Match('$') && sc.atLineStart) {
+                       } else if (sc.atLineStart && sc.Match('$')) {
                                sc.SetState(SCE_LUA_PREPROCESSOR);      // Obsolete since Lua 4.0, but still in old code
-                       }  else if (isLuaOperator(static_cast<char>(sc.ch))) {
+                       } else if (isLuaOperator(static_cast<char>(sc.ch))) {
                                sc.SetState(SCE_LUA_OPERATOR);
                        }
                }
@@ -197,7 +229,6 @@ static void ColouriseLuaDoc(
        sc.Complete();
 }
 
-
 static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
                        Accessor &styler) {
        unsigned int lengthDoc = startPos + length;
@@ -266,4 +297,14 @@ static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, W
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc);
+static const char * const luaWordListDesc[] = {
+       "Keywords",
+       "Basic functions",
+       "String & math functions",
+       "I/O & system facilities",
+       "XXX",
+       "XXX",
+       0
+};
+
+LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc);
index f75d15c7ab99379b7185898a8a9f13afe7a94b72..5f4dff3b8e4661d83ceeb034ae2b457677bcca24 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LexMatlab.cxx
  ** Lexer for Matlab.
  ** Written by José Fonseca
- **/ 
+ **/
 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
@@ -165,4 +165,9 @@ static void FoldMatlabDoc(unsigned int startPos, int length, int,
        }
 }
 
-LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc);
+static const char * const matlabWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
index babb3a0d3771da2336bbc61dc70633f21ae11815..6d537c9b6c2294e3200158f56738a9e2e35b58df 100644 (file)
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+static bool Is0To9(char ch) {
+       return (ch >= '0') && (ch <= '9');
+}
+
+static bool Is1To9(char ch) {
+       return (ch >= '1') && (ch <= '9');
+}
+
 static inline bool AtEOL(Accessor &styler, unsigned int i) {
        return (styler[i] == '\n') ||
                ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
@@ -85,7 +93,7 @@ static void ColouriseBatchLine(
                while (offset < lengthLine) {
                        if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
                                styler.ColourTo(startLine + offset - 1, state);
-                               if (isdigit(lineBuffer[offset + 1])) {
+                               if (Is0To9(lineBuffer[offset + 1])) {
                                        styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
                                        offset += 2;
                                } else if (lineBuffer[offset + 1] == '%' &&
@@ -164,13 +172,17 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
                styler.ColourTo(endLine, SCE_DIFF_HEADER);
        } else if (0 == strncmp(lineBuffer, "+++ ", 3)) {
                styler.ColourTo(endLine, SCE_DIFF_HEADER);
-       } else if (0 == strncmp(lineBuffer, "***", 3)) {
+       } else if (0 == strncmp(lineBuffer, "====", 4)) {  // For p4's diff
+               styler.ColourTo(endLine, SCE_DIFF_HEADER);
+       } else if (0 == strncmp(lineBuffer, "***", 3)) {
+               styler.ColourTo(endLine, SCE_DIFF_HEADER);
+       } else if (0 == strncmp(lineBuffer, "? ", 2)) {    // For difflib
                styler.ColourTo(endLine, SCE_DIFF_HEADER);
        } else if (lineBuffer[0] == '@') {
                styler.ColourTo(endLine, SCE_DIFF_POSITION);
-       } else if (lineBuffer[0] == '-') {
+       } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') {
                styler.ColourTo(endLine, SCE_DIFF_DELETED);
-       } else if (lineBuffer[0] == '+') {
+       } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
                styler.ColourTo(endLine, SCE_DIFF_ADDED);
        } else if (lineBuffer[0] != ' ') {
                styler.ColourTo(endLine, SCE_DIFF_COMMENT);
@@ -264,7 +276,7 @@ static void ColouriseMakeLine(
     Accessor &styler) {
 
        unsigned int i = 0;
-        unsigned int lastNonSpace = 0;
+       int lastNonSpace = -1;
        unsigned int state = SCE_MAKE_DEFAULT;
        bool bSpecial = false;
        // Skip initial spaces
@@ -291,13 +303,15 @@ static void ColouriseMakeLine(
                        if (lineBuffer[i] == ':') {
                                // We should check that no colouring was made since the beginning of the line,
                                // to avoid colouring stuff like /OUT:file
-                               styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
+                               if (lastNonSpace >= 0)
+                                       styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
                                styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
                                styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
                                bSpecial = true;        // Only react to the first ':' of the line
                                state = SCE_MAKE_DEFAULT;
                        } else if (lineBuffer[i] == '=') {
-                               styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
+                               if (lastNonSpace >= 0)
+                                       styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
                                styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
                                styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
                                bSpecial = true;        // Only react to the first '=' of the line
@@ -337,12 +351,17 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[
        }
 }
 
+static bool strstart(char *haystack, char *needle) {
+       return strncmp(haystack, needle, strlen(needle)) == 0;
+}
+
 static void ColouriseErrorListLine(
     char *lineBuffer,
     unsigned int lengthLine,
     //         unsigned int startLine,
     unsigned int endPos,
     Accessor &styler) {
+       const int unRecognized = 99;
        if (lineBuffer[0] == '>') {
                // Command or return status
                styler.ColourTo(endPos, SCE_ERR_CMD);
@@ -359,10 +378,19 @@ static void ColouriseErrorListLine(
                styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION);
        } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
                styler.ColourTo(endPos, SCE_ERR_PYTHON);
-       } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) {
+       } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
+               styler.ColourTo(endPos, SCE_ERR_PHP);
+       } else if ((strstart(lineBuffer, "Error ") ||
+               strstart(lineBuffer, "Warning ")) &&
+               strstr(lineBuffer, " at (") &&
+               strstr(lineBuffer, ") : ") &&
+               (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
+               // Intel Fortran Compiler error/warning message
+               styler.ColourTo(endPos, SCE_ERR_IFC);
+       } else if (strstart(lineBuffer, "Error ")) {
                // Borland error message
                styler.ColourTo(endPos, SCE_ERR_BORLAND);
-       } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) {
+       } else if (strstart(lineBuffer, "Warning ")) {
                // Borland warning message
                styler.ColourTo(endPos, SCE_ERR_BORLAND);
        } else if (strstr(lineBuffer, "at line " ) &&
@@ -374,54 +402,87 @@ static void ColouriseErrorListLine(
        } else if (strstr(lineBuffer, " at " ) &&
                   (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
                   strstr(lineBuffer, " line ") &&
-                  (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine))) {
+                  (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
+                          (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
                // perl error message
                styler.ColourTo(endPos, SCE_ERR_PERL);
        } else if ((memcmp(lineBuffer, "   at ", 6) == 0) &&
                strstr(lineBuffer, ":line ")) {
                // A .NET traceback
                styler.ColourTo(endPos, SCE_ERR_NET);
+       } else if (strstart(lineBuffer, "Line ") &&
+               strstr(lineBuffer, ", file ")) {
+               // Essential Lahey Fortran error message
+               styler.ColourTo(endPos, SCE_ERR_ELF);
        } else {
-               // Look for <filename>:<line>:message
-               // Look for <filename>(line)message
-               // Look for <filename>(line,pos)message
+               // Look for GCC <filename>:<line>:message
+               // Look for Microsoft <filename>(line) :message
+               // Look for Microsoft <filename>(line,pos)message
+               // Look for CTags \tmessage
                int state = 0;
                for (unsigned int i = 0; i < lengthLine; i++) {
-                       if ((state == 0) && (lineBuffer[i] == ':') && isdigit(lineBuffer[i + 1])) {
-                               state = 1;
-                       } else if ((state == 0) && (lineBuffer[i] == '(')) {
-                               state = 10;
-                       } else if ((state == 0) && (lineBuffer[i] == '\t')) {
-                               state = 20;
-                       } else if ((state == 1) && isdigit(lineBuffer[i])) {
-                               state = 2;
-                       } else if ((state == 2) && (lineBuffer[i] == ':')) {
-                               state = 3;
-                               break;
-                       } else if ((state == 2) && !isdigit(lineBuffer[i])) {
-                               state = 99;
-                       } else if ((state == 10) && isdigit(lineBuffer[i])) {
-                               state = 11;
-                       } else if ((state == 11) && (lineBuffer[i] == ',')) {
-                               state = 14;
-                       } else if ((state == 11) && (lineBuffer[i] == ')')) {
-                               state = 12;
-                       } else if ((state == 12) && (lineBuffer[i] == ':')) {
-                               state = 13;
-                       } else if ((state == 14) && (lineBuffer[i] == ')')) {
-                               state = 15;
-                               break;
-                       } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) {
-                               state = 99;
-                       } else if ((state == 20) && (lineBuffer[i-1] == '\t') && 
-                               ((lineBuffer[i] == '/' && lineBuffer[i+1] == '^') || isdigit(lineBuffer[i]))) {
-                               state = 24;
-                               break;
-                       } else if ((state == 20) && ((lineBuffer[i] == '/') && (lineBuffer[i+1] == '^'))) {
-                               state = 21;
+                       char ch = lineBuffer[i];
+                       char chNext = ' ';
+                       if ((i+1) < lengthLine)
+                               chNext = lineBuffer[i+1];
+                       if (state == 0) {
+                               if (ch == ':') {
+                                       // May be GCC
+                                       if ((chNext != '\\') && (chNext != '/')) {
+                                               // This check is not completely accurate as may be on
+                                               // GTK+ with a file name that includes ':'.
+                                               state = 1;
+                                       }
+                               } else if ((ch == '(') && Is1To9(chNext)) {
+                                       // May be Microsoft
+                                       // Check againt '0' often removes phone numbers
+                                       state = 10;
+                               } else if (ch == '\t') {
+                                       // May be CTags
+                                       state = 20;
+                               }
+                       } else if (state == 1) {
+                               state = Is1To9(ch) ? 2 : unRecognized;
+                       } else if (state == 2) {
+                               if (ch == ':') {
+                                       state = 3;      // :9.*: is GCC
+                                       break;
+                               } else if (!Is0To9(ch)) {
+                                       state = unRecognized;
+                               }
+                       } else if (state == 10) {
+                               state = Is0To9(ch) ? 11 : unRecognized;
+                       } else if (state == 11) {
+                               if (ch == ',') {
+                                       state = 14;
+                               } else if (ch == ')') {
+                                       state = 12;
+                               } else if ((ch != ' ') && !Is0To9(ch)) {
+                                       state = unRecognized;
+                               }
+                       } else if (state == 12) {
+                               if ((ch == ' ') && (chNext == ':'))
+                                       state = 13;
+                               else
+                                       state = unRecognized;
+                       } else if (state == 14) {
+                               if (ch == ')') {
+                                       state = 15;
+                                       break;
+                               } else if ((ch != ' ') && !Is0To9(ch)) {
+                                       state = unRecognized;
+                               }
+                       } else if (state == 20) {
+                               if ((lineBuffer[i-1] == '\t') &&
+                                       ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) {
+                                       state = 24;
+                                       break;
+                               } else if ((ch == '/') && (lineBuffer[i+1] == '^')) {
+                                       state = 21;
+                               }
                        } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) {
                                state = 22;
-                               break;          
+                               break;
                        }
                }
                if (state == 3) {
@@ -429,7 +490,7 @@ static void ColouriseErrorListLine(
                } else if ((state == 13) || (state == 14) || (state == 15)) {
                        styler.ColourTo(endPos, SCE_ERR_MS);
                } else if (((state == 22) || (state == 24)) && (lineBuffer[0] != '\t')) {
-                       styler.ColourTo(endPos, SCE_ERR_CTAG);  
+                       styler.ColourTo(endPos, SCE_ERR_CTAG);
                } else {
                        styler.ColourTo(endPos, SCE_ERR_DEFAULT);
                }
@@ -553,12 +614,21 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
                        }
                }
        }
-       styler.ColourTo(lengthDoc, state);
+       styler.ColourTo(lengthDoc-1, state);
 }
 
-LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch");
-LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff");
-LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props");
-LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile");
-LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist");
-LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex");
+static const char * const batchWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+static const char * const emptyWordListDesc[] = {
+       0
+};
+
+LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
+LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", 0, emptyWordListDesc);
+LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", 0, emptyWordListDesc);
+LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
+LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
+LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
diff --git a/src/stc/scintilla/src/LexPOV.cxx b/src/stc/scintilla/src/LexPOV.cxx
new file mode 100644 (file)
index 0000000..1e44450
--- /dev/null
@@ -0,0 +1,222 @@
+// Scintilla source code edit control
+/** @file LexPOV.cxx
+ ** Lexer for POV-Ray, based on lexer for C++.
+ **/
+// Copyright 2003 by Steven te Brinke <steven.t.b@zonnet.nl>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#define KEYWORD_BOXHEADER 1
+#define KEYWORD_FOLDCONTRACTED 2
+
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
+}
+
+static inline bool IsAWordStart(const int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsStateComment(const int state) {
+       return ((state == SCE_POV_COMMENT) ||
+               (state == SCE_POV_COMMENTLINE) ||
+               (state == SCE_POV_COMMENTDOC));
+}
+
+static inline bool IsStateString(const int state) {
+       return ((state == SCE_POV_STRING));
+}
+
+static void ColourisePOVDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler) {
+
+       WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+
+       // Do not leak onto next line
+       /*if (initStyle == SCE_POV_STRINGEOL)
+               initStyle = SCE_POV_DEFAULT;*/
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       bool caseSensitive = styler.GetPropertyInt("pov.case.sensitive", 1) != 0;
+
+       for (; sc.More(); sc.Forward()) {
+
+               /*if (sc.atLineStart && (sc.state == SCE_POV_STRING)) {
+                       // Prevent SCE_POV_STRINGEOL from leaking back to previous line
+                       sc.SetState(SCE_POV_STRING);
+               }*/
+
+               // Handle line continuation generically.
+               if (sc.ch == '\\') {
+                       if (sc.chNext == '\n' || sc.chNext == '\r') {
+                               sc.Forward();
+                               if (sc.ch == '\r' && sc.chNext == '\n') {
+                                       sc.Forward();
+                               }
+                               continue;
+                       }
+               }
+
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_POV_OPERATOR || sc.state == SCE_POV_BRACE) {
+                       sc.SetState(SCE_POV_DEFAULT);
+               } else if (sc.state == SCE_POV_NUMBER) {
+                       if (!IsADigit(sc.ch) || sc.ch != '.') {
+                               sc.SetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+                               char s[100];
+                               if (caseSensitive) {
+                                       sc.GetCurrent(s, sizeof(s));
+                               } else {
+                                       sc.GetCurrentLowered(s, sizeof(s));
+                               }
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_POV_WORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_POV_WORD2);
+                               }
+                               sc.SetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_COMMENT) {
+                       if (sc.Match('*', '/')) {
+                               sc.Forward();
+                               sc.ForwardSetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_COMMENTDOC) {
+                       if (sc.Match('*', '/')) {
+                               sc.Forward();
+                               sc.ForwardSetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_COMMENTLINE) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_POV_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POV_STRING) {
+                       if (sc.ch == '\\') {
+                               if (sc.chNext == '\"' || sc.chNext == '\\') {
+                                       sc.Forward();
+                               }
+                       } else if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_POV_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_POV_DEFAULT) {
+                       if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_POV_NUMBER);
+                       } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
+                               sc.SetState(SCE_POV_IDENTIFIER);
+                       } else if (sc.Match('/', '*')) {
+                               sc.SetState(SCE_POV_COMMENT);
+                               sc.Forward();   // Eat the * so it isn't used for the end of the comment
+                       } else if (sc.Match('/', '/')) {
+                               sc.SetState(SCE_POV_COMMENTLINE);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_POV_STRING);
+                               //} else if (isoperator(static_cast<char>(sc.ch))) {
+                       } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
+                               sc.SetState(SCE_POV_OPERATOR);
+                       } else if (sc.ch == '{' || sc.ch == '}') {
+                               sc.SetState(SCE_POV_BRACE);
+                       }
+               }
+
+       }
+       sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+       return style == SCE_POV_COMMENT ||
+              style == SCE_POV_COMMENTDOC;
+}
+
+static void FoldNoBoxPOVDoc(unsigned int startPos, int length, int initStyle,
+                            Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment && IsStreamCommentStyle(style)) {
+                       if (!IsStreamCommentStyle(stylePrev)) {
+                               levelCurrent++;
+                       } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+                               // Comments don't end at end of line and the next character may be unstyled.
+                               levelCurrent--;
+                       }
+               }
+               if (style == SCE_POV_BRACE) {
+                       if (ch == '{') {
+                               levelCurrent++;
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static void FoldPOVDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+       FoldNoBoxPOVDoc(startPos, length, initStyle, styler);
+}
+
+static const char * const POVWordLists[] = {
+            "Primary keywords and identifiers",
+            "Secondary keywords and identifiers",
+            0,
+        };
+
+static void ColourisePOVDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                     Accessor &styler) {
+       ColourisePOVDoc(startPos, length, initStyle, keywordlists, styler);
+}
+
+LexerModule lmPOV(SCLEX_POV, ColourisePOVDocSensitive, "pov", FoldPOVDoc, POVWordLists);
index 37e5e995fb4164ee2009cf553edfbf47e34c6361..c3bea6773df0f57a15b27e6fc1c52f391a3a21aa 100644 (file)
@@ -34,7 +34,7 @@ static void getRange(unsigned int start,
 }
 
 static bool IsStreamCommentStyle(int style) {
-       return style == SCE_C_COMMENT || 
+       return style == SCE_C_COMMENT ||
                style == SCE_C_COMMENTDOC ||
                style == SCE_C_COMMENTDOCKEYWORD ||
                style == SCE_C_COMMENTDOCKEYWORDERROR;
@@ -50,7 +50,7 @@ static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &
 
        WordList& keywords = *keywordlists[0];
        WordList& classwords = *keywordlists[1];
-       
+
        char s[100];
        getRange(start, end, styler, s, sizeof(s));
 
@@ -119,7 +119,7 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle,
        styler.StartSegment(startPos);
        for (unsigned int i = startPos; i < lengthDoc; i++) {
                char ch = chNext;
-               
+
                chNext = styler.SafeGetCharAt(i + 1);
 
                if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
@@ -329,7 +329,7 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
                        levelPrev = levelCurrent;
                        visibleChars = 0;
                }
-               
+
                if (!isspacechar(ch))
                        visibleChars++;
        }
@@ -339,4 +339,10 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc);
+static const char * const pascalWordListDesc[] = {
+       "Keywords",
+       "Classwords",
+       0
+};
+
+LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc);
index 1715009c9d0d064a08f2bbd095e614d8e86902e5..211c3b8751e83e47db835eb76ec4c0f9fc53e5c7 100644 (file)
@@ -659,9 +659,64 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
        styler.ColourTo(lengthDoc - 1, state);
 }
 
+static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
+                            Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+       int levelCurrent = levelPrev;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment && (style == SCE_PL_COMMENTLINE)) {
+                       if ((ch == '/') && (chNext == '/')) {
+                               char chNext2 = styler.SafeGetCharAt(i + 2);
+                               if (chNext2 == '{') {
+                                       levelCurrent++;
+                               } else if (chNext2 == '}') {
+                                       levelCurrent--;
+                               }
+                       }
+               }
+               if (style == SCE_C_OPERATOR) {
+                       if (ch == '{') {
+                               levelCurrent++;
+                       } else if (ch == '}') {
+                               levelCurrent--;
+                       }
+               }
+               if (atEOL) {
+                       int lev = levelPrev;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
 static const char * const perlWordListDesc[] = {
-       "Perl keywords",
+       "Keywords",
        0
 };
 
-LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", 0, perlWordListDesc);
+LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc);
index bfaa08f0e9daba30327b4f269832a9c0abdc5085..47974d1bced8911196416eb131c7334c0563e14f 100644 (file)
@@ -1,7 +1,7 @@
 // Scintilla source code edit control
 /** @file LexPython.cxx
  ** Lexer for Python.
- **/ 
+ **/
 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
@@ -42,7 +42,7 @@ static bool IsPyStringStart(int ch, int chNext, int chNext2) {
 }
 
 /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
-static int GetPyStringState(Accessor &styler, int i, int *nextIndex) {
+static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex) {
        char ch = styler.SafeGetCharAt(i);
        char chNext = styler.SafeGetCharAt(i + 1);
 
@@ -99,7 +99,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
        int lineCurrent = styler.GetLine(startPos);
        if (startPos > 0) {
                if (lineCurrent > 0) {
-                       startPos = styler.LineStart(lineCurrent - 1);
+                       lineCurrent--;
+                       startPos = styler.LineStart(lineCurrent);
                        if (startPos == 0)
                                initStyle = SCE_P_DEFAULT;
                        else
@@ -139,6 +140,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        } else if (whingeLevel == 4) {
                                chFlags = (spaceFlags & wsTab) ? chBad : chGood;
                        }
+                       sc.SetState(sc.state);
                        styler.SetFlags(chFlags, static_cast<char>(sc.state));
                }
 
@@ -148,7 +150,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                (sc.state == SCE_P_TRIPLEDOUBLE)) {
                                // Perform colourisation of white space and triple quoted strings at end of each line to allow
                                // tab marking to work inside white space and triple quoted strings
-                               sc.ForwardSetState(sc.state);
+                               sc.SetState(sc.state);
                        }
                        lineCurrent++;
                        styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
@@ -160,6 +162,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                break;
                }
 
+               bool needEOLCheck = false;
+
                // Check for a state end
                if (sc.state == SCE_P_OPERATOR) {
                        kwLast = kwOther;
@@ -212,8 +216,10 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                sc.Forward();
                        } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        }
                } else if (sc.state == SCE_P_TRIPLE) {
                        if (sc.ch == '\\') {
@@ -222,6 +228,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                sc.Forward();
                                sc.Forward();
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        }
                } else if (sc.state == SCE_P_TRIPLEDOUBLE) {
                        if (sc.ch == '\\') {
@@ -230,9 +237,18 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                sc.Forward();
                                sc.Forward();
                                sc.ForwardSetState(SCE_P_DEFAULT);
+                               needEOLCheck = true;
                        }
                }
 
+               // State exit code may have moved on to end of line
+               if (needEOLCheck && sc.atLineEnd) {
+                       lineCurrent++;
+                       styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
+                       if (!sc.More())
+                               break;
+               }
+
                // Check for a new state starting character
                if (sc.state == SCE_P_DEFAULT) {
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
@@ -247,7 +263,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        } else if (sc.ch == '#') {
                                sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
                        } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2))) {
-                               int nextIndex = 0;
+                               unsigned int nextIndex = 0;
                                sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
                                while (nextIndex > (sc.currentPos + 1)) {
                                        sc.Forward();
@@ -357,34 +373,40 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
                        lev = lev + 1;
                }
 
-               // Skip past any blank lines for next indent level info; we skip also comments
-               // starting in column 0 which effectively folds them into surrounding code rather
+               // Skip past any blank lines for next indent level info; we skip also
+               // comments (all comments, not just those starting in column 0)
+               // which effectively folds them into surrounding code rather
                // than screwing up folding.
-               const int saveIndentNext = indentNext;
+
                while (!quote &&
                        (lineNext < docLines) &&
                        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
-                        (lineNext <= docLines && styler[styler.LineStart(lineNext)] == '#'))) {
+                        (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
 
                        lineNext++;
                        indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
                }
 
-               // Next compute max indent level of current line and next non-blank line.
-               // This is the level to which we set all the intervening blank or comment lines.
-               const int skip_level = Platform::Maximum(indentCurrentLevel,
-                                      indentNext & SC_FOLDLEVELNUMBERMASK);
+               const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+               const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
 
                // Now set all the indent levels on the lines we skipped
-               int skipLine = lineCurrent + 1;
-               int skipIndentNext = saveIndentNext;
-               while (skipLine < lineNext) {
-                       int skipLineLevel = skip_level;
-                       if (skipIndentNext & SC_FOLDLEVELWHITEFLAG)
-                               skipLineLevel = SC_FOLDLEVELWHITEFLAG | skipLineLevel;
-                       styler.SetLevel(skipLine, skipLineLevel);
-                       skipLine++;
-                       skipIndentNext = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+               // Do this from end to start.  Once we encounter one line
+               // which is indented more than the line after the end of
+               // the comment-block, use the level of the block before
+
+               int skipLine = lineNext;
+               int skipLevel = levelAfterComments;
+
+               while (--skipLine > lineCurrent) {
+                       int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+                       if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+                               skipLevel = levelBeforeComments;
+
+                       int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+                       styler.SetLevel(skipLine, skipLevel | whiteFlag);
                }
 
                // Set fold header on non-quote/non-comment line
@@ -409,9 +431,9 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 }
 
 static const char * const pythonWordListDesc[] = {
-       "Python keywords",
+       "Keywords",
        0
 };
 
-LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, 
+LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
                                         pythonWordListDesc);
index 35804e7107a3d4eccbc37771746af94dc5fdbdc0..43a874968d5f6c18aedccdff15ad9740a5326e20 100644 (file)
@@ -221,7 +221,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                        } else if (isoperator(ch)) {
                                styler.ColourTo(i - 1, state);
                                styler.ColourTo(i, SCE_P_OPERATOR);
-                       } 
+                       }
                        } else if (state == SCE_P_WORD) {
                        if (!iswordchar(ch)) {
                                ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
@@ -351,5 +351,10 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
                }
        }
 }
-                                                  
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc);
+
+static const char * const rubyWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
index 5af86d9f4acbbf0b3f1b1796e222a7e1beae81b1..0520c00ed6fcefb48dd7e6ce0ba71cfaae0b5788 100644 (file)
@@ -155,4 +155,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length,
        styler.ColourTo(lengthDoc - 1, state);
 }
 
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql");
+static const char * const sqlWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
index bd1248e044be8c76e90b559e821ceba9109ed6d1..72fdb9c3cf86c4699fb6f812614f2728f9f32261 100644 (file)
@@ -37,7 +37,7 @@ static inline bool IsAWordStart(const int ch) {
 }
 
 static inline bool IsADateCharacter(const int ch) {
-       return (ch < 0x80) && 
+       return (ch < 0x80) &&
                (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
 }
 
@@ -49,7 +49,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
        styler.StartAt(startPos);
 
        int visibleChars = 0;
-                                  
+
        StyleContext sc(startPos, length, initStyle, styler);
 
        for (; sc.More(); sc.Forward()) {
@@ -83,7 +83,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                                sc.SetState(SCE_B_DEFAULT);
                        }
                } else if (sc.state == SCE_B_STRING) {
-                       // VB doubles quotes to preserve them, so just end this string 
+                       // VB doubles quotes to preserve them, so just end this string
                        // state now as a following quote will start again
                        if (sc.ch == '\"') {
                                if (tolower(sc.chNext) == 'c') {
@@ -104,7 +104,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                                sc.ForwardSetState(SCE_B_DEFAULT);
                        }
                }
-               
+
                if (sc.state == SCE_B_DEFAULT) {
                        if (sc.ch == '\'') {
                                sc.SetState(SCE_B_COMMENT);
@@ -116,7 +116,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                        } else if (sc.ch == '#') {
                                int n = 1;
                                int chSeek = ' ';
-                               while (chSeek == ' ' || chSeek == '\t') {
+                               while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
                                        chSeek = sc.GetRelative(n);
                                        n++;
                                }
@@ -137,7 +137,7 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                                sc.SetState(SCE_B_OPERATOR);
                        }
                }
-               
+
                if (sc.atLineEnd) {
                        visibleChars = 0;
                }
@@ -200,6 +200,11 @@ static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyl
        ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
 }
 
-LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc);
-LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc);
+static const char * const vbWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
+LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);
 
index 009ea4ea50e869a30542dd1e6b1fa3278c522822..ec9c86f74f2f8c208fc03dd86b79895a2a8446b1 100644 (file)
@@ -2,14 +2,37 @@
 /** @file LineMarker.cxx
  ** Defines the look of a line marker in the margin .
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#include <string.h>
+
 #include "Platform.h"
 
 #include "Scintilla.h"
+#include "XPM.h"
 #include "LineMarker.h"
 
+void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
+       pal.WantFind(fore, want);
+       pal.WantFind(back, want);
+       if (pxpm) {
+               pxpm->RefreshColourPalette(pal, want);
+       }
+}
+
+void LineMarker::SetXPM(const char *textForm) {
+       delete pxpm;
+       pxpm = new XPM(textForm);
+       markType = SC_MARK_PIXMAP;
+}
+
+void LineMarker::SetXPM(const char * const *linesForm) {
+       delete pxpm;
+       pxpm = new XPM(linesForm);
+       markType = SC_MARK_PIXMAP;
+}
+
 static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
        PRectangle rc;
        rc.left = centreX - armSize;
@@ -41,6 +64,10 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
 }
 
 void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
+       if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
+               pxpm->Draw(surface, rcWhole);
+               return;
+       }
        // Restrict most shapes a bit
        PRectangle rc = rcWhole;
        rc.top++;
@@ -122,121 +149,121 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
                rcSmall.right = rc.right - 1;
                rcSmall.bottom = rc.bottom - 2;
                surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
-               
+
        } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
                // An invisible marker so don't draw anything
-               
+
        } else if (markType == SC_MARK_VLINE) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
        } else if (markType == SC_MARK_LCORNER) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rc.top + dimOn2);
                surface->LineTo(rc.right - 2, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_TCORNER) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rcWhole.bottom);
                surface->MoveTo(centreX, rc.top + dimOn2);
                surface->LineTo(rc.right - 2, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_LCORNERCURVE) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rc.top + dimOn2-3);
                surface->LineTo(centreX+3, rc.top + dimOn2);
                surface->LineTo(rc.right - 1, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_TCORNERCURVE) {
                surface->PenColour(back.allocated);
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rc.top + dimOn2-3);
                surface->LineTo(centreX+3, rc.top + dimOn2);
                surface->LineTo(rc.right - 1, rc.top + dimOn2);
-               
+
        } else if (markType == SC_MARK_BOXPLUS) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
        } else if (markType == SC_MARK_BOXPLUSCONNECTED) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType == SC_MARK_BOXMINUS) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
        } else if (markType == SC_MARK_BOXMINUSCONNECTED) {
                surface->PenColour(back.allocated);
                DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType == SC_MARK_CIRCLEPLUS) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
        } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType == SC_MARK_CIRCLEMINUS) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
        } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
                DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
                surface->PenColour(back.allocated);
                DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
-               
+
                surface->MoveTo(centreX, centreY + blobSize);
                surface->LineTo(centreX, rcWhole.bottom);
-               
+
                surface->MoveTo(centreX, rcWhole.top);
                surface->LineTo(centreX, centreY - blobSize);
-               
+
        } else if (markType >= SC_MARK_CHARACTER) {
                char character[1];
                character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
                int width = surface->WidthText(fontForCharacter, character, 1);
                rc.left += (rc.Width() - width) / 2;
                rc.right = rc.left + width;
-               surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, 
+               surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
                        character, 1, fore.allocated, back.allocated);
 
        } else if (markType == SC_MARK_DOTDOTDOT) {
index 7897aa7759355665b7f2992d6d34f964064e274b..ef5924f7511e1207fce82854915880125fef8125 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LineMarker.h
  ** Defines the look of a line marker in the margin .
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef LINEMARKER_H
@@ -15,11 +15,35 @@ public:
        int markType;
        ColourPair fore;
        ColourPair back;
+       XPM *pxpm;
        LineMarker() {
                markType = SC_MARK_CIRCLE;
                fore = ColourDesired(0,0,0);
                back = ColourDesired(0xff,0xff,0xff);
+               pxpm = NULL;
        }
+       LineMarker(const LineMarker &) {
+               // Defined to avoid pxpm being blindly copied, not as real copy constructor
+               markType = SC_MARK_CIRCLE;
+               fore = ColourDesired(0,0,0);
+               back = ColourDesired(0xff,0xff,0xff);
+               pxpm = NULL;
+       }
+       ~LineMarker() {
+               delete pxpm;
+       }
+       LineMarker &operator=(const LineMarker &) {
+               // Defined to avoid pxpm being blindly copied, not as real assignment operator
+               markType = SC_MARK_CIRCLE;
+               fore = ColourDesired(0,0,0);
+               back = ColourDesired(0xff,0xff,0xff);
+               delete pxpm;
+               pxpm = NULL;
+               return *this;
+       }
+       void RefreshColourPalette(Palette &pal, bool want);
+       void SetXPM(const char *textForm);
+       void SetXPM(const char * const *linesForm);
        void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
 };
 
index b527c385ce15f54beff0d2fb63a006dc2e0b2896..18544aef23c87b54b8e09c91b7edffa1944895b6 100644 (file)
@@ -2,14 +2,14 @@
 /** @file PropSet.cxx
  ** A Java style properties file module.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 // Maintain a dictionary of properties
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
+//#include <ctype.h>
 #include <stdio.h>
 
 #include "Platform.h"
@@ -30,6 +30,10 @@ static inline bool IsLetter(char ch) {
        return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
 }
 
+inline bool IsASpace(unsigned int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
 int CompareCaseInsensitive(const char *a, const char *b) {
        while (*a && *b) {
                if (*a != *b) {
@@ -98,13 +102,13 @@ void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
                lenVal = static_cast<int>(strlen(val));
        unsigned int hash = HashString(key, lenKey);
        for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-               if ((hash == p->hash) && 
-                       ((strlen(p->key) == static_cast<unsigned int>(lenKey)) && 
+               if ((hash == p->hash) &&
+                       ((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
                                (0 == strncmp(p->key, key, lenKey)))) {
                        // Replace current value
                        delete [](p->val);
                        p->val = StringDup(val, lenVal);
-                       return ;
+                       return;
                }
        }
        // Not found
@@ -119,7 +123,7 @@ void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
 }
 
 void PropSet::Set(const char *keyVal) {
-       while (isspace(*keyVal))
+       while (IsASpace(*keyVal))
                keyVal++;
        const char *endVal = keyVal;
        while (*endVal && (*endVal != '\n'))
@@ -181,7 +185,8 @@ SString PropSet::GetExpanded(const char *key) {
 SString PropSet::Expand(const char *withVars) {
        char *base = StringDup(withVars);
        char *cpvar = strstr(base, "$(");
-       while (cpvar) {
+       int maxExpands = 1000;  // Avoid infinite expansion of recursive definitions
+       while (cpvar && (maxExpands > 0)) {
                char *cpendvar = strchr(cpvar, ')');
                if (cpendvar) {
                        int lenvar = cpendvar - cpvar - 2;      // Subtract the $()
@@ -197,6 +202,7 @@ SString PropSet::Expand(const char *withVars) {
                        base = newbase;
                }
                cpvar = strstr(base, "$(");
+               maxExpands--;
        }
        SString sret = base;
        delete []base;
@@ -257,7 +263,7 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {
                                if (keyfile == NULL)
                                        keyfile = orgkeyfile;
 
-                               for (; ; ) {
+                               for (;;) {
                                        char *del = strchr(keyfile, ';');
                                        if (del == NULL)
                                                del = keyfile + strlen(keyfile);
@@ -300,7 +306,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) {
 SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
        char *base = StringDup(GetWild(keybase, filename).c_str());
        char *cpvar = strstr(base, "$(");
-       while (cpvar) {
+       int maxExpands = 1000;  // Avoid infinite expansion of recursive definitions
+       while (cpvar && (maxExpands > 0)) {
                char *cpendvar = strchr(cpvar, ')');
                if (cpendvar) {
                        int lenvar = cpendvar - cpvar - 2;      // Subtract the $()
@@ -316,6 +323,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
                        base = newbase;
                }
                cpvar = strstr(base, "$(");
+               maxExpands--;
        }
        SString sret = base;
        delete []base;
@@ -328,9 +336,9 @@ void PropSet::Clear() {
                while (p) {
                        Property *pNext = p->next;
                        p->hash = 0;
-                       delete p->key;
+                       delete []p->key;
                        p->key = 0;
-                       delete p->val;
+                       delete []p->val;
                        p->val = 0;
                        delete p;
                        p = pNext;
@@ -626,7 +634,7 @@ static unsigned int LengthWord(const char *word, char otherSeparator) {
        if (endWord > word) {
                endWord--;      // Back from the '(', ':', or '\0'
                // Move backwards over any spaces
-               while ((endWord > word) && (isspace(*endWord))) {
+               while ((endWord > word) && (IsASpace(*endWord))) {
                        endWord--;
                }
        }
@@ -669,13 +677,13 @@ char *WordList::GetNearestWords(
                        if (!cond) {
                                // Find first match
                                while ((pivot > start) &&
-                                       (0 == CompareNCaseInsensitive(wordStart, 
+                                       (0 == CompareNCaseInsensitive(wordStart,
                                                wordsNoCase[pivot-1], searchLen))) {
                                        --pivot;
                                }
                                // Grab each match
                                while ((pivot <= end) &&
-                                       (0 == CompareNCaseInsensitive(wordStart, 
+                                       (0 == CompareNCaseInsensitive(wordStart,
                                                wordsNoCase[pivot], searchLen))) {
                                        wordlen = LengthWord(wordsNoCase[pivot], otherSeparator) + 1;
                                        wordsNear.append(wordsNoCase[pivot], wordlen, ' ');
@@ -695,14 +703,14 @@ char *WordList::GetNearestWords(
                        if (!cond) {
                                // Find first match
                                while ((pivot > start) &&
-                                       (0 == strncmp(wordStart, 
-                                               words[pivot-1], searchLen))) { 
+                                       (0 == strncmp(wordStart,
+                                               words[pivot-1], searchLen))) {
                                        --pivot;
                                }
                                // Grab each match
                                while ((pivot <= end) &&
-                                       (0 == strncmp(wordStart, 
-                                               words[pivot], searchLen))) { 
+                                       (0 == strncmp(wordStart,
+                                               words[pivot], searchLen))) {
                                        wordlen = LengthWord(words[pivot], otherSeparator) + 1;
                                        wordsNear.append(words[pivot], wordlen, ' ');
                                        ++pivot;
index f176bbf19e02107aac4100a5fc1492f5d4596343..656570a24b9b2309c765f7756eb1e07e8f4b0faa 100644 (file)
  *      Dept. of Computer Science
  *      York University
  *
- * Original code available from http://www.cs.yorku.ca/~oz/ 
+ * Original code available from http://www.cs.yorku.ca/~oz/
  * Translation to C++ by Neil Hodgson neilh@scintilla.org
  * Removed all use of register.
  * Converted to modern function prototypes.
- * Put all global/static variables into an object so this code can be 
+ * Put all global/static variables into an object so this code can be
  * used from multiple threads etc.
  *
  * These routines are the PUBLIC DOMAIN equivalents of regex
  * Modification history:
  *
  * $Log$
- * Revision 1.5  2002/09/11 00:55:27  RD
- * Update to Scintilla 1.48
+ * Revision 1.6  2003/04/19 19:59:49  RD
+ * Updated Scintilla to 1.52 (on the trunk this time too)
+ *
+ * Revision 1.9  2003/03/21 10:36:08  nyamatongwe
+ * Detect patterns too long in regular expression search.
+ *
+ * Revision 1.8  2003/03/04 10:53:59  nyamatongwe
+ * Patch from Jakub to optionally implement more POSIX compatible regular
+ * expressions. \(..\) changes to (..)
+ * Fixes problem where find previous would not find earlier matches on same
+ * line.
+ *
+ * Revision 1.8  2003/03/03 20:12:56  vrana
+ * Added posix syntax.
+ *
+ * Revision 1.7  2002/09/28 00:33:28  nyamatongwe
+ * Fixed problem with character ranges caused by expansion to 8 bits.
  *
  * Revision 1.6  2001/04/29 13:32:10  nyamatongwe
  * Addition of new target methods - versions of ReplaceTarget that take counted
  *
  * Revision 1.2  88/08/28  15:36:04  oz
  * Use a complement bitmap to represent NCL.
- * This removes the need to have seperate 
- * code in the PMatch case block - it is 
+ * This removes the need to have seperate
+ * code in the PMatch case block - it is
  * just CCL code now.
- * 
+ *
  * Use the actual CCL code in the CLO
  * section of PMatch. No need for a recursive
  * PMatch call.
- * 
+ *
  * Use a bitmap table to set char bits in an
  * 8-bit chunk.
- * 
+ *
  * Interfaces:
  *      RESearch::Compile:        compile a regular expression into a NFA.
  *
  *                     void re_fail(msg, op)
  *                     char *msg;
  *                     char op;
- *  
+ *
  * Regular Expressions:
  *
  *      [1]     char    matches itself, unless it is a special
  *
  *      [3]     \       matches the character following it, except
  *                     when followed by a left or right round bracket,
- *                     a digit 1 to 9 or a left or right angle bracket. 
+ *                     a digit 1 to 9 or a left or right angle bracket.
  *                     (see [7], [8] and [9])
- *                     It is used as an escape character for all 
+ *                     It is used as an escape character for all
  *                     other meta-characters, and itself. When used
  *                     in a set ([4]), it is treated as an ordinary
  *                     character.
  *
  *      [4]     [set]   matches one of the characters in the set.
  *                      If the first character in the set is "^",
- *                      it matches a character NOT in the set, i.e. 
- *                     complements the set. A shorthand S-E is 
- *                     used to specify a set of characters S upto 
- *                     E, inclusive. The special characters "]" and 
- *                     "-" have no special meaning if they appear 
+ *                      it matches a character NOT in the set, i.e.
+ *                     complements the set. A shorthand S-E is
+ *                     used to specify a set of characters S upto
+ *                     E, inclusive. The special characters "]" and
+ *                     "-" have no special meaning if they appear
  *                     as the first chars in the set.
  *                      examples:        match:
  *
  * Notes:
  *
  *     This implementation uses a bit-set representation for character
- *     classes for speed and compactness. Each character is represented 
- *     by one bit in a 128-bit block. Thus, CCL always takes a 
+ *     classes for speed and compactness. Each character is represented
+ *     by one bit in a 128-bit block. Thus, CCL always takes a
  *     constant 16 bytes in the internal nfa, and RESearch::Execute does a single
  *     bit comparison to locate the character in the set.
  *
  *     compile:        CHR f CHR o CLO CHR o END CLO ANY END END
  *     matches:        fo foo fooo foobar fobar foxx ...
  *
- *     pattern:        fo[ob]a[rz]     
+ *     pattern:        fo[ob]a[rz]
  *     compile:        CHR f CHR o CCL bitset CHR a CCL bitset END
  *     matches:        fobar fooar fobaz fooaz
  *
 const char bitarr[] = {1,2,4,8,16,32,64,'\200'};
 
 #define badpat(x)      (*nfa = END, x)
+
 RESearch::RESearch() {
        Init();
 }
@@ -332,10 +347,11 @@ const char escapeValue(char ch) {
        return 0;
 }
 
-const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
+const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) {
        char *mp=nfa;          /* nfa pointer       */
        char *lp;              /* saved pointer..   */
        char *sp=nfa;          /* another one..     */
+    char *mpMax = mp + MAXNFA - BITBLK - 10;
 
        int tagi = 0;          /* tag stack index   */
        int tagc = 1;          /* actual tag count  */
@@ -343,7 +359,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
        int n;
        char mask;              /* xor mask -CCL/NCL */
        int c1, c2;
-               
+
        if (!pat || !length)
                if (sta)
                        return 0;
@@ -353,6 +369,8 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
 
        const char *p=pat;               /* pattern pointer   */
        for (int i=0; i<length; i++, p++) {
+               if (mp > mpMax)
+                       return badpat("Pattern too long");
                lp = mp;
                switch(*p) {
 
@@ -383,7 +401,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
 
                        i++;
                        if (*++p == '^') {
-                               mask = '\377';  
+                               mask = '\377';
                                i++;
                                p++;
                        } else
@@ -427,7 +445,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
 
                        for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
                                *mp++ = static_cast<char>(mask ^ bittab[n]);
-       
+
                        break;
 
                case '*':               /* match 0 or more.. */
@@ -467,25 +485,6 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
                        i++;
                        switch(*++p) {
 
-                       case '(':
-                               if (tagc < MAXTAG) {
-                                       tagstk[++tagi] = tagc;
-                                       *mp++ = BOT;
-                                       *mp++ = static_cast<char>(tagc++);
-                               }
-                               else
-                                       return badpat("Too many \\(\\) pairs");
-                               break;
-                       case ')':
-                               if (*sp == BOT)
-                                       return badpat("Null pattern inside \\(\\)");
-                               if (tagi > 0) {
-                                       *mp++ = static_cast<char>(EOT);
-                                       *mp++ = static_cast<char>(tagstk[tagi--]);
-                               }
-                               else
-                                       return badpat("Unmatched \\)");
-                               break;
                        case '<':
                                *mp++ = BOW;
                                break;
@@ -524,13 +523,49 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
                                *mp++ = escapeValue(*p);
                                break;
                        default:
-                               *mp++ = CHR;
-                               *mp++ = *p;
+                               if (!posix && *p == '(') {
+                                       if (tagc < MAXTAG) {
+                                               tagstk[++tagi] = tagc;
+                                               *mp++ = BOT;
+                                               *mp++ = static_cast<char>(tagc++);
+                                       }
+                                       else
+                                               return badpat("Too many \\(\\) pairs");
+                               } else if (!posix && *p == ')') {
+                                       if (*sp == BOT)
+                                               return badpat("Null pattern inside \\(\\)");
+                                       if (tagi > 0) {
+                                               *mp++ = static_cast<char>(EOT);
+                                               *mp++ = static_cast<char>(tagstk[tagi--]);
+                                       }
+                                       else
+                                               return badpat("Unmatched \\)");
+                               } else {
+                                       *mp++ = CHR;
+                                       *mp++ = *p;
+                               }
                        }
                        break;
 
                default :               /* an ordinary char  */
-                       if (caseSensitive) {
+                       if (posix && *p == '(') {
+                               if (tagc < MAXTAG) {
+                                       tagstk[++tagi] = tagc;
+                                       *mp++ = BOT;
+                                       *mp++ = static_cast<char>(tagc++);
+                               }
+                               else
+                                       return badpat("Too many () pairs");
+                       } else if (posix && *p == ')') {
+                               if (*sp == BOT)
+                                       return badpat("Null pattern inside ()");
+                               if (tagi > 0) {
+                                       *mp++ = static_cast<char>(EOT);
+                                       *mp++ = static_cast<char>(tagstk[tagi--]);
+                               }
+                               else
+                                       return badpat("Unmatched )");
+                       } else if (caseSensitive) {
                                *mp++ = CHR;
                                *mp++ = *p;
                        } else {
@@ -545,7 +580,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
                sp = lp;
        }
        if (tagi > 0)
-               return badpat("Unmatched \\(");
+               return badpat((posix ? "Unmatched (" : "Unmatched \\("));
        *mp = END;
        sta = OKP;
        return 0;
@@ -555,7 +590,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
  * RESearch::Execute:
  *     execute nfa to find a match.
  *
- *     special cases: (nfa[0]) 
+ *     special cases: (nfa[0])
  *             BOL
  *                     Match only once, starting from the
  *                     beginning.
@@ -580,7 +615,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
 
        bol = lp;
        failure = 0;
-       
+
        Clear();
 
        switch(*ap) {
@@ -621,7 +656,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
        return 1;
 }
 
-/* 
+/*
  * PMatch: internal routine for the hard part
  *
  *     This code is partly snarfed from an early grep written by
@@ -647,7 +682,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
  *
  *     At the end of a successful match, bopat[n] and eopat[n]
  *     are set to the beginning and end of subpatterns matched
- *     by tagged expressions (n = 1 to 9).     
+ *     by tagged expressions (n = 1 to 9).
  *
  */
 
@@ -658,23 +693,23 @@ extern void re_fail(char *,char);
  * and EOW. the reason for not using ctype macros is that we can
  * let the user add into our own table. see RESearch::ModifyWord. This table
  * is not in the bitset form, since we may wish to extend it in the
- * future for other character classifications. 
+ * future for other character classifications.
  *
  *     TRUE for 0-9 A-Z a-z _
  */
 static char chrtyp[MAXCHR] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
-       0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+       0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 0, 0, 0, 0, 0
        };
 
@@ -688,7 +723,7 @@ static char chrtyp[MAXCHR] = {
 
 #define ANYSKIP        2       /* [CLO] ANY END ...         */
 #define CHRSKIP        3       /* [CLO] CHR chr END ...     */
-#define CCLSKIP 18     /* [CLO] CCL 16bytes END ... */
+#define CCLSKIP 34     /* [CLO] CCL 32bytes END ... */
 
 int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
        int op, c, n;
@@ -796,10 +831,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
  *     the compact bitset representation for the default table]
  */
 
-static char deftab[16] = {     
-       0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207',  
-       '\376', '\377', '\377', 007 
-}; 
+static char deftab[16] = {
+       0, 0, 0, 0, 0, 0, '\377', 003, '\376', '\377', '\377', '\207',
+       '\376', '\377', '\377', 007
+};
 
 void RESearch::ModifyWord(char *s) {
        int i;
@@ -846,7 +881,7 @@ int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) {
                                pin = c - '0';
                                break;
                        }
-                       
+
                default:
                        *dst++ = c;
                        continue;
index 28238bfb7c03ad20138bf54084ab5c5dbeb853ee..d676e0f3181b072260ba48b188c60a9c0c553ba7 100644 (file)
  * The following defines are not meant to be changeable.
  * They are for readability only.
  */
-#define MAXCHR 128
+#define MAXCHR 256
 #define CHRBIT 8
 #define BITBLK MAXCHR/CHRBIT
 
 class CharacterIndexer {
-public: 
+public:
        virtual char CharAt(int index)=0;
 };
 
@@ -32,7 +32,7 @@ public:
        bool GrabMatches(CharacterIndexer &ci);
        void ChSet(char c);
        void ChSetWithCase(char c, bool caseSensitive);
-       const char *Compile(const char *pat, int length, bool caseSensitive);
+       const char *Compile(const char *pat, int length, bool caseSensitive, bool posix);
        int Execute(CharacterIndexer &ci, int lp, int endp);
        void ModifyWord(char *s);
        int Substitute(CharacterIndexer &ci, char *src, char *dst);
index c8edb513bc3fdca89e6ef43f7341ee4a73f5ed13..9c3235d580f08e6c44edd76705e99dbb2f5bf124 100644 (file)
  */
 class SVector {
        enum { allocSize = 4000 };
-       
+
        int *v;                         ///< The vector
        unsigned int size;      ///< Number of elements allocated
        unsigned int len;       ///< Number of elements used in vector
        bool allocFailure;      ///< A memory allocation call has failed
-       
+
        /** Internally allocate more elements than the user wants
         * to avoid thrashing the memory allocator. */
        void SizeTo(int newSize) {
                if (newSize < allocSize)
                        newSize += allocSize;
-               else 
+               else
                        newSize = (newSize * 3) / 2;
                int* newv = new int[newSize];
                if (!newv) {
@@ -44,7 +44,7 @@ class SVector {
                delete []v;
                v = newv;
        }
-       
+
 public:
        SVector() {
                allocFailure = false;
index ab6e9a19b45e6c2620d041ca6fe04cd73770b262..ea2e2d1d6db9eef8e3a48ccc347a2ea13c6b3aa1 100644 (file)
@@ -2,7 +2,7 @@
 /** @file ScintillaBase.cxx
  ** An enhanced subclass of Editor with calltips, autocomplete and context menu.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -26,6 +26,7 @@
 #include "CallTip.h"
 #include "KeyMap.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
 #include "ViewStyle.h"
@@ -211,7 +212,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                        return;
                }
        }
-       ac.Start(wMain, idAutoComplete, currentPos, lenEntered);
+       ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode());
 
        PRectangle rcClient = GetClientRectangle();
        Point pt = LocationFromPosition(currentPos - lenEntered);
@@ -224,7 +225,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                pt = LocationFromPosition(currentPos);
        }
        PRectangle rcac;
-       rcac.left = pt.x - 5;
+       rcac.left = pt.x - ac.lb->CaretFromEdge();
        if (pt.y >= rcClient.bottom - heightLB &&  // Wont fit below.
                pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above.
                rcac.top = pt.y - heightLB;
@@ -237,19 +238,19 @@ 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[STYLE_DEFAULT].font);
-       ac.lb.SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth);
-       ac.lb.SetDoubleClickAction(AutoCompleteDoubleClick, this);
+       ac.lb->SetPositionRelative(rcac, wMain);
+       ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
+       ac.lb->SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth);
+       ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
 
        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.GetDesiredRect();
+       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.left = pt.x - ac.lb->CaretFromEdge();
        rcList.right = rcList.left + widthLB;
        if (((pt.y + vs.lineHeight) >= (rcClient.bottom - heightAlloced)) &&  // Wont fit below.
                ((pt.y + vs.lineHeight / 2) >= (rcClient.bottom + rcClient.top) / 2)) { // and there is more room above.
@@ -258,7 +259,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                rcList.top = pt.y + vs.lineHeight;
        }
        rcList.bottom = rcList.top + heightAlloced;
-       ac.lb.SetPositionRelative(rcList, wMain);
+       ac.lb->SetPositionRelative(rcList, wMain);
        ac.Show();
        if (lenEntered != 0) {
                AutoCompleteMoveToCurrentWord();
@@ -304,10 +305,11 @@ void ScintillaBase::AutoCompleteCharacterDeleted() {
 }
 
 void ScintillaBase::AutoCompleteCompleted() {
-       int item = ac.lb.GetSelection();
+       int item = ac.lb->GetSelection();
        char selected[1000];
+       selected[0] = '\0';
        if (item != -1) {
-               ac.lb.GetValue(item, selected, sizeof(selected));
+               ac.lb->GetValue(item, selected, sizeof(selected));
        }
        ac.Cancel();
 
@@ -343,6 +345,36 @@ void ScintillaBase::AutoCompleteCompleted() {
        pdoc->EndUndoAction();
 }
 
+void ScintillaBase::CallTipShow(Point pt, const char *defn) {
+       AutoCompleteCancel();
+       pt.y += vs.lineHeight;
+       PRectangle rc = ct.CallTipStart(currentPos, pt,
+                                                                       defn,
+                                                                       vs.styles[STYLE_DEFAULT].fontName,
+                                                                       vs.styles[STYLE_DEFAULT].sizeZoomed,
+                                                                       IsUnicodeMode(),
+                                                                       wMain);
+       // If the call-tip window would be out of the client
+       // space, adjust so it displays above the text.
+       PRectangle rcClient = GetClientRectangle();
+       if (rc.bottom > rcClient.bottom) {
+               int offset = vs.lineHeight + rc.Height();
+               rc.top -= offset;
+               rc.bottom -= offset;
+       }
+       // Now display the window.
+       CreateCallTipWindow(rc);
+       ct.wCallTip.SetPositionRelative(rc, wMain);
+       ct.wCallTip.Show();
+}
+
+void ScintillaBase::CallTipClick() {
+       SCNotification scn;
+       scn.nmhdr.code = SCN_CALLTIPCLICK;
+       scn.position = ct.clickPlace;
+       NotifyParent(scn);
+}
+
 void ScintillaBase::ContextMenu(Point pt) {
        if (displayPopupMenu) {
                bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
@@ -509,30 +541,24 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
        case SCI_AUTOCGETDROPRESTOFWORD:
                return ac.dropRestOfWord;
 
-       case SCI_CALLTIPSHOW: {
-                       AutoCompleteCancel();
-                       if (!ct.wCallTip.Created()) {
-                               Point pt = LocationFromPosition(wParam);
-                               pt.y += vs.lineHeight;
-                               PRectangle rc = ct.CallTipStart(currentPos, pt,
-                                                               reinterpret_cast<char *>(lParam),
-                                                               vs.styles[STYLE_DEFAULT].fontName,
-                                                               vs.styles[STYLE_DEFAULT].sizeZoomed,
-                                                                                               IsUnicodeMode());
-                               // If the call-tip window would be out of the client
-                               // space, adjust so it displays above the text.
-                               PRectangle rcClient = GetClientRectangle();
-                               if (rc.bottom > rcClient.bottom) {
-                                       int offset = vs.lineHeight + rc.Height();
-                                       rc.top -= offset;
-                                       rc.bottom -= offset;
-                               }
-                               // Now display the window.
-                               CreateCallTipWindow(rc);
-                               ct.wCallTip.SetPositionRelative(rc, wMain);
-                               ct.wCallTip.Show();
-                       }
-               }
+       case SCI_REGISTERIMAGE:
+               ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
+               break;
+
+       case SCI_CLEARREGISTEREDIMAGES:
+               ac.lb->ClearRegisteredImages();
+               break;
+
+       case SCI_AUTOCSETTYPESEPARATOR:
+               ac.SetTypesep(static_cast<char>(wParam));
+               break;
+
+       case SCI_AUTOCGETTYPESEPARATOR:
+               return ac.GetTypesep();
+
+       case SCI_CALLTIPSHOW:
+               CallTipShow(LocationFromPosition(wParam),
+                       reinterpret_cast<const char *>(lParam));
                break;
 
        case SCI_CALLTIPCANCEL:
@@ -554,6 +580,16 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
                InvalidateStyleRedraw();
                break;
 
+       case SCI_CALLTIPSETFORE:
+               ct.colourUnSel = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_CALLTIPSETFOREHLT:
+               ct.colourSel = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
        case SCI_USEPOPUP:
                displayPopupMenu = wParam != 0;
                break;
index e68aeb60841415ac4fb29da25d89b17a29eb0d92..bf0b92d57da6acee322f33c3b9f2c058a5ba1366 100644 (file)
@@ -43,7 +43,7 @@ protected:
        int lexLanguage;
        const LexerModule *lexCurrent;
        PropSet props;
-       enum {numWordLists=6};
+       enum {numWordLists=9};
        WordList *keyWordLists[numWordLists+1];
        void SetLexer(uptr_t wParam);
        void SetLexerLanguage(const char *languageName);
@@ -71,6 +71,8 @@ protected:
        void AutoCompleteMoveToCurrentWord();
        static void AutoCompleteDoubleClick(void* p);
 
+       void CallTipClick();
+       void CallTipShow(Point pt, const char *defn);
        virtual void CreateCallTipWindow(PRectangle rc) = 0;
 
        virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0;
index 2ee09f57d27745227b286be46e27675c7dfa81a1..40a8dba6a456b8a63433b9dd0796208f415e63bd 100644 (file)
@@ -16,13 +16,13 @@ Style::Style() {
        aliasOfDefaultFont = true;
        Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
              Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
-             false, false, false, false, caseMixed, true, true);
+             false, false, false, false, caseMixed, true, true, false);
 }
 
 Style::Style(const Style &source) {
        Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
              0, 0, 0,
-             false, false, false, false, caseMixed, true, true);
+             false, false, false, false, caseMixed, true, true, false);
        fore.desired = source.fore.desired;
        back.desired = source.back.desired;
        characterSet = source.characterSet;
@@ -34,6 +34,7 @@ Style::Style(const Style &source) {
        caseForce = source.caseForce;
        visible = source.visible;
        changeable = source.changeable;
+       hotspot = source.hotspot;
 }
 
 Style::~Style() {
@@ -49,7 +50,7 @@ Style &Style::operator=(const Style &source) {
                return * this;
        Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
              0, 0, SC_CHARSET_DEFAULT,
-             false, false, false, false, caseMixed, true, true);
+             false, false, false, false, caseMixed, true, true, false);
        fore.desired = source.fore.desired;
        back.desired = source.back.desired;
        characterSet = source.characterSet;
@@ -66,9 +67,9 @@ Style &Style::operator=(const Style &source) {
 
 void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
                   const char *fontName_, int characterSet_,
-                  bool bold_, bool italic_, bool eolFilled_, 
-                  bool underline_, ecaseForced caseForce_, 
-                 bool visible_, bool changeable_) {
+                  bool bold_, bool italic_, bool eolFilled_,
+                  bool underline_, ecaseForced caseForce_,
+                 bool visible_, bool changeable_, bool hotspot_) {
        fore.desired = fore_;
        back.desired = back_;
        characterSet = characterSet_;
@@ -81,6 +82,7 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
        caseForce = caseForce_;
        visible = visible_;
        changeable = changeable_;
+       hotspot = hotspot_;
        if (aliasOfDefaultFont)
                font.SetID(0);
        else
@@ -100,8 +102,9 @@ void Style::ClearTo(const Style &source) {
                source.eolFilled,
                source.underline,
                source.caseForce,
-               source.visible, 
-               source.changeable);
+               source.visible,
+               source.changeable,
+               source.hotspot);
 }
 
 bool Style::EquivalentFontTo(const Style *other) const {
index 63259b1a93b9edf6bfc41ea9995b81eebef5a75a..2f1e57586089f7dc1d6289caabe4d40cf7591861 100644 (file)
@@ -26,6 +26,7 @@ public:
        ecaseForced caseForce;
        bool visible;
        bool changeable;
+       bool hotspot;
 
        Font font;
        int sizeZoomed;
@@ -43,13 +44,13 @@ public:
        void Clear(ColourDesired fore_, ColourDesired back_,
                   int size_,
                   const char *fontName_, int characterSet_,
-                  bool bold_, bool italic_, bool eolFilled_, 
-                  bool underline_, ecaseForced caseForce_, 
-                  bool visible_, bool changeable_);
+                  bool bold_, bool italic_, bool eolFilled_,
+                  bool underline_, ecaseForced caseForce_,
+                  bool visible_, bool changeable_, bool hotspot_);
        void ClearTo(const Style &source);
        bool EquivalentFontTo(const Style *other) const;
        void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0);
-       bool IsProtected() { return !(changeable && visible);} ;
+       bool IsProtected() const { return !(changeable && visible);};
 };
 
 #endif
index bdae28196f57314bf3d420c157f54ca57ece689d..64fc7a048e0be5cc7d11a2e0dd679ec9d2a6ac5c 100644 (file)
@@ -29,7 +29,7 @@ static void getRange(unsigned int start,
        s[i] = '\0';
 }
 
-void StyleContext::GetCurrent(char *s, int len) {
+void StyleContext::GetCurrent(char *s, unsigned int len) {
        getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len);
 }
 
@@ -46,6 +46,6 @@ static void getRangeLowered(unsigned int start,
        s[i] = '\0';
 }
 
-void StyleContext::GetCurrentLowered(char *s, int len) {
+void StyleContext::GetCurrentLowered(char *s, unsigned int len) {
        getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
 }
index 4c9352916da7925aa4f3c7f4c968576cbeefdd4c..f2f8305c940b1dbc8e06c7d8dc5eea8c7f4b9b22 100644 (file)
@@ -2,21 +2,35 @@
 /** @file StyleContext.cxx
  ** Lexer infrastructure.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 // This file is in the public domain.
 
 // All languages handled so far can treat all characters >= 0x80 as one class
 // which just continues the current token or starts an identifier if in default.
-// DBCS treated specially as the second character can be < 0x80 and hence 
+// DBCS treated specially as the second character can be < 0x80 and hence
 // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
 class StyleContext {
        Accessor &styler;
-       int endPos;
+       unsigned int endPos;
        StyleContext& operator=(const StyleContext&) {
                return *this;
        }
+       void GetNextChar(unsigned int pos) {
+               chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
+               if (styler.IsLeadByte(static_cast<char>(chNext))) {
+                       chNext = chNext << 8;
+                       chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+               }
+               // End of line?
+               // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
+               // or on LF alone (Unix). Avoid triggering two times on Dos/Win.
+               atLineEnd = (ch == '\r' && chNext != '\n') ||
+                                       (ch == '\n') ||
+                                       (currentPos >= endPos);
+       }
+
 public:
-       int currentPos;
+       unsigned int currentPos;
        bool atLineStart;
        bool atLineEnd;
        int state;
@@ -24,32 +38,27 @@ public:
        int ch;
        int chNext;
 
-       StyleContext(unsigned int startPos, int length,
-                        int initStyle, Accessor &styler_, char chMask=31) : 
+       StyleContext(unsigned int startPos, unsigned int length,
+                        int initStyle, Accessor &styler_, char chMask=31) :
                styler(styler_),
                endPos(startPos + length),
-               currentPos(startPos), 
+               currentPos(startPos),
                atLineStart(true),
                atLineEnd(false),
-               state(initStyle), 
+               state(initStyle),
                chPrev(0),
-               ch(0), 
+               ch(0),
                chNext(0) {
                styler.StartAt(startPos, chMask);
                styler.StartSegment(startPos);
-               int pos = currentPos;
+               unsigned int pos = currentPos;
                ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
                if (styler.IsLeadByte(static_cast<char>(ch))) {
                        pos++;
                        ch = ch << 8;
                        ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
                }
-               chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
-               if (styler.IsLeadByte(static_cast<char>(chNext))) {
-                       chNext = chNext << 8;
-                       chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
-               }
-               atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos);
+               GetNextChar(pos);
        }
        void Complete() {
                styler.ColourTo(currentPos - 1, state);
@@ -60,21 +69,12 @@ public:
        void Forward() {
                if (currentPos < endPos) {
                        atLineStart = atLineEnd;
-                       // A lot of this is repeated from the constructor - TODO: merge code
                        chPrev = ch;
                        currentPos++;
                        if (ch >= 0x100)
                                currentPos++;
                        ch = chNext;
-                       chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+1));
-                       if (styler.IsLeadByte(static_cast<char>(chNext))) {
-                               chNext = chNext << 8;
-                               chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + 2));
-                       }
-                       // 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
-                       atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos);
+                       GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
                } else {
                        atLineStart = false;
                        chPrev = ' ';
@@ -83,6 +83,11 @@ public:
                        atLineEnd = true;
                }
        }
+       void Forward(int nb) {
+               for (int i = 0; i < nb; i++) {
+                       Forward();
+               }
+       }
        void ChangeState(int state_) {
                state = state_;
        }
@@ -136,8 +141,8 @@ public:
                return true;
        }
        // Non-inline
-       void GetCurrent(char *s, int len);
-       void GetCurrentLowered(char *s, int len);
+       void GetCurrent(char *s, unsigned int len);
+       void GetCurrentLowered(char *s, unsigned int len);
 };
 
 inline bool IsASpace(unsigned int ch) {
index 12e1406aa440db3930e2e8d1ae8f51f36b4b8bcc..eb8e54f2f8b3759d6acafc41111a1c47e6b0a231 100644 (file)
@@ -2,7 +2,7 @@
 /** @file ViewStyle.cxx
  ** Store information on how the document is to be viewed.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <string.h>
@@ -11,6 +11,7 @@
 
 #include "Scintilla.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
 #include "ViewStyle.h"
@@ -72,6 +73,18 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
        selbackset = source.selbackset;
        selbackground.desired = source.selbackground.desired;
        selbackground2.desired = source.selbackground2.desired;
+
+       foldmarginColourSet = source.foldmarginColourSet;
+       foldmarginColour.desired = source.foldmarginColour.desired;
+       foldmarginHighlightColourSet = source.foldmarginHighlightColourSet;
+       foldmarginHighlightColour.desired = source.foldmarginHighlightColour.desired;
+
+       hotspotForegroundSet = source.hotspotForegroundSet;
+       hotspotForeground.desired = source.hotspotForeground.desired;
+       hotspotBackgroundSet = source.hotspotBackgroundSet;
+       hotspotBackground.desired = source.hotspotBackground.desired;
+       hotspotUnderline = source.hotspotUnderline;
+
        whitespaceForegroundSet = source.whitespaceForegroundSet;
        whitespaceForeground.desired = source.whitespaceForeground.desired;
        whitespaceBackgroundSet = source.whitespaceBackgroundSet;
@@ -124,6 +137,12 @@ void ViewStyle::Init() {
        selbackset = true;
        selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0);
        selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0);
+
+       foldmarginColourSet = false;
+       foldmarginColour.desired = ColourDesired(0xff, 0, 0);
+       foldmarginHighlightColourSet = false;
+       foldmarginHighlightColour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+
        whitespaceForegroundSet = false;
        whitespaceForeground.desired = ColourDesired(0, 0, 0);
        whitespaceBackgroundSet = false;
@@ -138,6 +157,13 @@ void ViewStyle::Init() {
        edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0);
        edgeState = EDGE_NONE;
        caretWidth = 1;
+       someStylesProtected = false;
+
+       hotspotForegroundSet = false;
+       hotspotForeground.desired = ColourDesired(0, 0, 0xff);
+       hotspotBackgroundSet = false;
+       hotspotBackground.desired = ColourDesired(0xff, 0xff, 0xff);
+       hotspotUnderline = true;
 
        leftMarginWidth = 1;
        rightMarginWidth = 1;
@@ -148,9 +174,7 @@ void ViewStyle::Init() {
        ms[1].width = 16;
        ms[1].mask = ~SC_MASK_FOLDERS;
        ms[2].symbol = true;
-       ms[2].width = 14;       // Nice width for arrows
-       ms[2].mask = SC_MASK_FOLDERS;
-       ms[2].width = 0;        // Nice width for arrows
+       ms[2].width = 0;
        ms[2].mask = 0;
        fixedColumnWidth = leftMarginWidth;
        symbolMargin = false;
@@ -178,12 +202,15 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
                pal.WantFind(indicators[i].fore, want);
        }
        for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) {
-               pal.WantFind(markers[i].fore, want);
-               pal.WantFind(markers[i].back, want);
+               markers[i].RefreshColourPalette(pal, want);
        }
        pal.WantFind(selforeground, want);
        pal.WantFind(selbackground, want);
        pal.WantFind(selbackground2, want);
+
+       pal.WantFind(foldmarginColour, want);
+       pal.WantFind(foldmarginHighlightColour, want);
+
        pal.WantFind(whitespaceForeground, want);
        pal.WantFind(whitespaceBackground, want);
        pal.WantFind(selbar, want);
@@ -191,6 +218,8 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(caretcolour, want);
        pal.WantFind(caretLineBackground, want);
        pal.WantFind(edgecolour, want);
+       pal.WantFind(hotspotForeground, want);
+       pal.WantFind(hotspotBackground, want);
 }
 
 void ViewStyle::Refresh(Surface &surface) {
@@ -199,6 +228,7 @@ void ViewStyle::Refresh(Surface &surface) {
        styles[STYLE_DEFAULT].Realise(surface, zoomLevel);
        maxAscent = styles[STYLE_DEFAULT].ascent;
        maxDescent = styles[STYLE_DEFAULT].descent;
+       someStylesProtected = false;
        for (unsigned int i=0;i<(sizeof(styles)/sizeof(styles[0]));i++) {
                if (i != STYLE_DEFAULT) {
                        styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT]);
@@ -207,6 +237,9 @@ void ViewStyle::Refresh(Surface &surface) {
                        if (maxDescent < styles[i].descent)
                                maxDescent = styles[i].descent;
                }
+               if (styles[i].IsProtected()) {
+                       someStylesProtected = true;
+               }
        }
 
        lineHeight = maxAscent + maxDescent;
@@ -225,11 +258,11 @@ void ViewStyle::Refresh(Surface &surface) {
 }
 
 void ViewStyle::ResetDefaultStyle() {
-       styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), 
+       styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
                ColourDesired(0xff,0xff,0xff),
                Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
                SC_CHARSET_DEFAULT,
-               false, false, false, false, Style::caseMixed, true, true);
+               false, false, false, false, Style::caseMixed, true, true, false);
 }
 
 void ViewStyle::ClearStyles() {
@@ -245,3 +278,7 @@ void ViewStyle::ClearStyles() {
 void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
        styles[styleIndex].fontName = fontNames.Save(name);
 }
+
+bool ViewStyle::ProtectionActive() const {
+    return someStylesProtected;
+}
index 887170eaac1ee17685c9a17dc174965f9a6c4db6..ff38efef2eb5ca328d52bbf274d5942080963930 100644 (file)
@@ -59,6 +59,15 @@ public:
        ColourPair whitespaceBackground;
        ColourPair selbar;
        ColourPair selbarlight;
+       bool foldmarginColourSet;
+       ColourPair foldmarginColour;
+       bool foldmarginHighlightColourSet;
+       ColourPair foldmarginHighlightColour;
+       bool hotspotForegroundSet;
+       ColourPair hotspotForeground;
+       bool hotspotBackgroundSet;
+       ColourPair hotspotBackground;
+       bool hotspotUnderline;
        /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin
        enum { margins=3 };
        int leftMarginWidth;    ///< Spacing margin on left of text
@@ -78,7 +87,8 @@ public:
        ColourPair edgecolour;
        int edgeState;
        int caretWidth;
-       
+       bool someStylesProtected;
+
        ViewStyle();
        ViewStyle(const ViewStyle &source);
        ~ViewStyle();
@@ -88,6 +98,7 @@ public:
        void ResetDefaultStyle();
        void ClearStyles();
        void SetStyleFontName(int styleIndex, const char *name);
+       bool ProtectionActive() const;
 };
 
 #endif
index ce42534e7bffa52b588207e0dcd4ef38854102eb..d70ddf5c3472752facb5f2b4144f67f517e5f0f5 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h> 
+#include <ctype.h>
 #include <stdio.h>
 
 #include "Platform.h"
@@ -24,7 +24,7 @@ bool WindowAccessor::InternalIsLeadByte(char ch) {
        if (SC_CP_UTF8 == codePage)
                // For lexing, all characters >= 0x80 are treated the
                // same so none is considered a lead byte.
-               return false;   
+               return false;
        else
                return Platform::IsDBCSLeadByte(codePage, ch);
 }
@@ -71,10 +71,10 @@ int WindowAccessor::LevelAt(int line) {
        return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0);
 }
 
-int WindowAccessor::Length() { 
-       if (lenDoc == -1) 
+int WindowAccessor::Length() {
+       if (lenDoc == -1)
                lenDoc = Platform::SendScintilla(id, SCI_GETTEXTLENGTH, 0, 0);
-       return lenDoc; 
+       return lenDoc;
 }
 
 int WindowAccessor::GetLineState(int line) {
@@ -125,7 +125,7 @@ void WindowAccessor::Flush() {
        startPos = extremePosition;
        lenDoc = -1;
        if (validLen > 0) {
-               Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen, 
+               Platform::SendScintillaPointer(id, SCI_SETSTYLINGEX, validLen,
                        styleBuf);
                validLen = 0;
        }
@@ -134,12 +134,12 @@ void WindowAccessor::Flush() {
 int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
        int end = Length();
        int spaceFlags = 0;
-       
-       // Determines the indentation level of the current line and also checks for consistent 
+
+       // Determines the indentation level of the current line and also checks for consistent
        // indentation compared to the previous line.
-       // Indentation is judged consistent when the indentation whitespace of each line lines 
+       // Indentation is judged consistent when the indentation whitespace of each line lines
        // the same or the indentation of one line is a prefix of the other.
-       
+
        int pos = LineStart(line);
        char ch = (*this)[pos];
        int indent = 0;
@@ -166,7 +166,7 @@ int WindowAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsC
                }
                ch = (*this)[++pos];
        }
-       
+
        *flags = spaceFlags;
        indent += SC_FOLDLEVELBASE;
        // if completely empty line or the start of a comment...
diff --git a/src/stc/scintilla/src/XPM.cxx b/src/stc/scintilla/src/XPM.cxx
new file mode 100644 (file)
index 0000000..c4e4f88
--- /dev/null
@@ -0,0 +1,297 @@
+// Scintilla source code edit control
+/** @file XPM.cxx
+ ** Define a class that holds data in the X Pixmap (XPM) format,
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "Platform.h"
+
+#include "XPM.h"
+
+static const char *NextField(const char *s) {
+       while (*s && *s != ' ') {
+               s++;
+       }
+       while (*s && *s == ' ') {
+               s++;
+       }
+       return s;
+}
+
+// Data lines in XPM can be terminated either with NUL or "
+static size_t MeasureLength(const char *s) {
+       size_t i = 0;
+       while (s[i] && (s[i] != '\"'))
+               i++;
+       return i;
+}
+
+ColourAllocated XPM::ColourFromCode(int ch) {
+       return colourCodeTable[ch]->allocated;
+#ifdef SLOW
+       for (int i=0;i<nColours;i++) {
+               if (codes[i] == ch) {
+                       return colours[i].allocated;
+               }
+       }
+       return colours[0].allocated;
+#endif
+}
+
+void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
+       if ((code != codeTransparent) && (startX != x)) {
+               PRectangle rc(startX, y, x, y+1);
+               surface->FillRectangle(rc, ColourFromCode(code));
+       }
+}
+
+XPM::XPM(const char *textForm) :
+       data(0),        codes(0), colours(0), lines(0) {
+       Init(textForm);
+}
+
+XPM::XPM(const char * const *linesForm) :
+       data(0),        codes(0), colours(0), lines(0) {
+       Init(linesForm);
+}
+
+XPM::~XPM() {
+       Clear();
+}
+
+void XPM::Init(const char *textForm) {
+       Clear();
+       // Test done is two parts to avoid possibility of overstepping the memory
+       // if memcmp implemented strangely. Must be 4 bytes at least at destination.
+       if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
+               // Build the lines form out of the text form
+               const char **linesForm = LinesFormFromTextForm(textForm);
+               Init(linesForm);
+               delete []linesForm;
+       } else {
+               // It is really in line form
+               Init(reinterpret_cast<const char * const *>(textForm));
+       }
+}
+
+void XPM::Init(const char * const *linesForm) {
+       Clear();
+       height = 1;
+       width = 1;
+       nColours = 1;
+       data = NULL;
+       codeTransparent = ' ';
+       codes = NULL;
+       colours = NULL;
+       lines = NULL;
+       if (!linesForm)
+               return;
+
+       const char *line0 = linesForm[0];
+       width = atoi(line0);
+       line0 = NextField(line0);
+       height = atoi(line0);
+       line0 = NextField(line0);
+       nColours = atoi(line0);
+       codes = new char[nColours];
+       colours = new ColourPair[nColours];
+
+       int strings = 1+height+nColours;
+       lines = new char *[strings];
+       int allocation = 0;
+       for (int i=0; i<strings; i++) {
+               allocation += MeasureLength(linesForm[i]) + 1;
+       }
+       data = new char[allocation];
+       char *nextBit = data;
+       for (int j=0; j<strings; j++) {
+               lines[j] = nextBit;
+               size_t len = MeasureLength(linesForm[j]);
+               memcpy(nextBit, linesForm[j], len);
+               nextBit += len;
+               *nextBit++ = '\0';
+       }
+
+       for (int code=0;code<256; code++) {
+               colourCodeTable[code] = 0;
+       }
+
+       for (int c=0; c<nColours; c++) {
+               const char *colourDef = linesForm[c+1];
+               codes[c] = colourDef[0];
+               colourDef += 4;
+               if (*colourDef == '#') {
+                       colours[c].desired.Set(colourDef);
+               } else {
+                       colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
+                       codeTransparent = codes[c];
+               }
+               colourCodeTable[static_cast<unsigned char>(codes[c])] = &(colours[c]);
+       }
+}
+
+void XPM::Clear() {
+       delete []data;
+       data = 0;
+       delete []codes;
+       codes = 0;
+       delete []colours;
+       colours = 0;
+       delete []lines;
+       lines = 0;
+}
+
+void XPM::RefreshColourPalette(Palette &pal, bool want) {
+       if (!data || !codes || !colours || !lines) {
+               return;
+       }
+       for (int i=0;i<nColours;i++) {
+               pal.WantFind(colours[i], want);
+       }
+}
+
+void XPM::CopyDesiredColours() {
+       if (!data || !codes || !colours || !lines) {
+               return;
+       }
+       for (int i=0;i<nColours;i++) {
+               colours[i].Copy();
+       }
+}
+
+void XPM::Draw(Surface *surface, PRectangle &rc) {
+       if (!data || !codes || !colours || !lines) {
+               return;
+       }
+       // Centre the pixmap
+       int startY = rc.top + (rc.Height() - height) / 2;
+       int startX = rc.left + (rc.Width() - width) / 2;
+       for (int y=0;y<height;y++) {
+               int prevCode = 0;
+               int xStartRun = 0;
+               for (int x=0; x<width; x++) {
+                       int code = lines[y+nColours+1][x];
+                       if (code != prevCode) {
+                               FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x);
+                               xStartRun = x;
+                               prevCode = code;
+                       }
+               }
+               FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width);
+       }
+}
+
+const char **XPM::LinesFormFromTextForm(const char *textForm) {
+       // Build the lines form out of the text form
+       const char **linesForm = 0;
+       int countQuotes = 0;
+       int strings=1;
+       for (int j=0; countQuotes < (2*strings); j++) {
+               if (textForm[j] == '\"') {
+                       if (countQuotes == 0) {
+                               const char *line0 = textForm + j + 1;
+                               // Skip width
+                               line0 = NextField(line0);
+                               // Add 1 line for each pixel of height
+                               strings += atoi(line0);
+                               line0 = NextField(line0);
+                               // Add 1 line for each colour
+                               strings += atoi(line0);
+                               linesForm = new const char *[strings];
+                       }
+                       if (linesForm && ((countQuotes & 1) == 0)) {
+                               linesForm[countQuotes / 2] = textForm + j + 1;
+                       }
+                       countQuotes++;
+               }
+       }
+       return linesForm;
+}
+
+// In future, may want to minimize search time by sorting and using a binary search.
+
+XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
+}
+
+XPMSet::~XPMSet() {
+       Clear();
+}
+
+void XPMSet::Clear() {
+       for (int i=0;i<maximum;i++) {
+               delete set[i];
+       }
+       delete []set;
+       set = 0;
+       len = 0;
+       maximum = 0;
+       height = -1;
+       width = -1;
+}
+
+void XPMSet::Add(int id, const char *textForm) {
+       // Invalidate cached dimensions
+       height = -1;
+       width = -1;
+
+       // Replace if this id already present
+       for (int i=0;i<maximum;i++) {
+               if (set[i]->GetId() == id) {
+                       set[i]->Init(textForm);
+                       return;
+               }
+       }
+
+       // No present, so add to end
+       XPM *pxpm = new XPM(textForm);
+       if (pxpm) {
+               pxpm->SetId(id);
+               pxpm->CopyDesiredColours();
+               if (len == maximum) {
+                       int lenNew = len + 100;
+                       XPM **setNew = new XPM *[lenNew];
+                       for (int i=0; i<maximum; i++) {
+                               setNew[i] = set[i];
+                       }
+                       delete []set;
+                       set = setNew;
+               }
+               set[maximum] = pxpm;
+               maximum++;
+       }
+}
+
+XPM *XPMSet::Get(int id) {
+       for (int i=0;i<maximum;i++) {
+               if (set[i]->GetId() == id) {
+                       return set[i];
+               }
+       }
+       return 0;
+}
+
+int XPMSet::GetHeight() {
+       if (height < 0) {
+               for (int i=0; i<maximum; i++) {
+                       if (height < set[i]->GetHeight()) {
+                               height = set[i]->GetHeight();
+                       }
+               }
+       }
+       return (height > 0) ? height : 0;
+}
+
+int XPMSet::GetWidth() {
+       if (width < 0) {
+               for (int i=0; i<maximum; i++) {
+                       if (width < set[i]->GetWidth()) {
+                               width = set[i]->GetWidth();
+                       }
+               }
+       }
+       return (width > 0) ? width : 0;
+}
diff --git a/src/stc/scintilla/src/XPM.h b/src/stc/scintilla/src/XPM.h
new file mode 100644 (file)
index 0000000..948e557
--- /dev/null
@@ -0,0 +1,67 @@
+// Scintilla source code edit control
+/** @file XPM.h
+ ** Define a class that holds data in the X Pixmap (XPM) format,
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef XPM_H
+#define XPM_H
+
+/**
+ * Hold a pixmap in XPM format.
+ */
+class XPM {
+       int id;         // Assigned by container
+       int height;
+       int width;
+       int nColours;
+       char *data;
+       char codeTransparent;
+       char *codes;
+       ColourPair *colours;
+       ColourAllocated ColourFromCode(int ch);
+       void FillRun(Surface *surface, int code, int startX, int y, int x);
+       char **lines;
+       ColourPair *colourCodeTable[256];
+public:
+       XPM(const char *textForm);
+       XPM(const char * const *linesForm);
+       ~XPM();
+       void Init(const char *textForm);
+       void Init(const char * const *linesForm);
+       void Clear();
+       // Similar to same named method in ViewStyle:
+       void RefreshColourPalette(Palette &pal, bool want);
+       // No palette used, so just copy the desired colours to the allocated colours:
+       void CopyDesiredColours();
+       // Decompose image into runs and use FillRectangle for each run:
+       void Draw(Surface *surface, PRectangle &rc);
+       char **InLinesForm() { return lines; }
+       void SetId(int id_) { id = id_; }
+       int GetId() { return id; }
+       int GetHeight() { return height; }
+       int GetWidth() { return width; }
+       static const char **LinesFormFromTextForm(const char *textForm);
+};
+
+/**
+ * A collection of pixmaps indexed by integer id.
+ */
+class XPMSet {
+       XPM **set;
+       int len;
+       int maximum;
+       int height;
+       int width;
+public:
+       XPMSet();
+       ~XPMSet();
+       void Clear();
+       void Add(int id, const char *textForm);
+       XPM *Get(int id);
+       int GetHeight();
+       int GetWidth();
+};
+
+#endif
index 17cf6ee40604404f5468ea286be7eb5b62927cb6..c4a9d0c4e13027df6e96c10123eb1b6b193c0c6c 100644 (file)
 #include "wx/stc/stc.h"
 #include "ScintillaWX.h"
 
+#include <wx/wx.h>
 #include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
 
 
 //----------------------------------------------------------------------
@@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG )
 DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER )
 DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP )
 DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+
 
 
 BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
@@ -201,7 +208,7 @@ int wxStyledTextCtrl::GetLength() {
 
 // Returns the character byte at the position.
 int wxStyledTextCtrl::GetCharAt(int pos) {
-                       return (unsigned char)SendMsg(2007, pos, 0);
+         return (unsigned char)SendMsg(2007, pos, 0);
 }
 
 // Returns the position of the caret.
@@ -216,7 +223,7 @@ int wxStyledTextCtrl::GetAnchor() {
 
 // Returns the style byte at the position.
 int wxStyledTextCtrl::GetStyleAt(int pos) {
-                       return (unsigned char)SendMsg(2010, pos, 0);
+         return (unsigned char)SendMsg(2010, pos, 0);
 }
 
 // Redoes the next action on the undo history.
@@ -243,21 +250,21 @@ void wxStyledTextCtrl::SetSavePoint() {
 
 // Retrieve a buffer of cells.
 wxMemoryBuffer wxStyledTextCtrl::GetStyledText(int startPos, int endPos) {
-                          wxMemoryBuffer buf;
-                          if (endPos < startPos) {
-                              int temp = startPos;
-                              startPos = endPos;
-                              endPos = temp;
-                          }
-                          int len = endPos - startPos;
-                          if (!len) return buf;
-                          TextRange tr;
-                          tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
-                          tr.chrg.cpMin = startPos;
-                          tr.chrg.cpMax = endPos;
-                          len = SendMsg(2015, 0, (long)&tr);
-                          buf.UngetWriteBuf(len);
-                          return buf;
+        wxMemoryBuffer buf;
+        if (endPos < startPos) {
+            int temp = startPos;
+            startPos = endPos;
+            endPos = temp;
+        }
+        int len = endPos - startPos;
+        if (!len) return buf;
+        TextRange tr;
+        tr.lpstrText = (char*)buf.GetWriteBuf(len*2+1);
+        tr.chrg.cpMin = startPos;
+        tr.chrg.cpMax = endPos;
+        len = SendMsg(2015, 0, (long)&tr);
+        buf.UngetWriteBuf(len);
+        return buf;
 }
 
 // Are there any redoable actions in the undo history?
@@ -293,7 +300,7 @@ void wxStyledTextCtrl::SetViewWhiteSpace(int viewWS) {
 
 // Find the position from a point within the window.
 int wxStyledTextCtrl::PositionFromPoint(wxPoint pt) {
-                              return SendMsg(2022, pt.x, pt.y);
+        return SendMsg(2022, pt.x, pt.y);
 }
 
 // Find the position from a point within the window but return
@@ -321,20 +328,20 @@ void wxStyledTextCtrl::SetAnchor(int posAnchor) {
 // Retrieve the text of the line containing the caret.
 // Returns the index of the caret on the line.
 wxString wxStyledTextCtrl::GetCurLine(int* linePos) {
-                       int len = LineLength(GetCurrentLine());
-                       if (!len) {
-                           if (linePos)  *linePos = 0;
-                           return wxEmptyString;
-                       }
+        int len = LineLength(GetCurrentLine());
+        if (!len) {
+            if (linePos)  *linePos = 0;
+            return wxEmptyString;
+        }
 
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
+        wxMemoryBuffer mbuf(len+1);
+        char* buf = (char*)mbuf.GetWriteBuf(len+1);
 
-                       int pos = SendMsg(2027, len+1, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       if (linePos)  *linePos = pos;
-                       return stc2wx(buf);
+        int pos = SendMsg(2027, len+1, (long)buf);
+        mbuf.UngetWriteBuf(len);
+        mbuf.AppendByte(0);
+        if (linePos)  *linePos = pos;
+        return stc2wx(buf);
 }
 
 // Retrieve the position of the last correctly styled character.
@@ -399,20 +406,20 @@ void wxStyledTextCtrl::SetCodePage(int codePage) {
     wxASSERT_MSG(codePage != wxSTC_CP_UTF8,
                  wxT("wxSTC_CP_UTF8 may not be used when wxUSE_UNICODE is off."));
 #endif
-                 SendMsg(2037, codePage);
+    SendMsg(2037, codePage);
 }
 
 // Set the symbol used for a particular marker number,
 // and optionally the fore and background colours.
 void wxStyledTextCtrl::MarkerDefine(int markerNumber, int markerSymbol,
-                            const wxColour& foreground,
-                            const wxColour& background) {
+                const wxColour& foreground,
+                const wxColour& background) {
 
-                            SendMsg(2040, markerNumber, markerSymbol);
-                            if (foreground.Ok())
-                                MarkerSetForeground(markerNumber, foreground);
-                            if (background.Ok())
-                                MarkerSetBackground(markerNumber, background);
+                SendMsg(2040, markerNumber, markerSymbol);
+                if (foreground.Ok())
+                    MarkerSetForeground(markerNumber, foreground);
+                if (background.Ok())
+                    MarkerSetBackground(markerNumber, background);
 }
 
 // Set the foreground colour used for a particular marker number.
@@ -455,6 +462,21 @@ int wxStyledTextCtrl::MarkerPrevious(int lineStart, int markerMask) {
     return SendMsg(2048, lineStart, markerMask);
 }
 
+// Define a marker from a bitmap
+void wxStyledTextCtrl::MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(2049, markerNumber, (long)buff);
+        delete [] buff;
+        
+}
+
 // Set a margin to be either numeric or symbolic.
 void wxStyledTextCtrl::SetMarginType(int margin, int marginType) {
     SendMsg(2240, margin, marginType);
@@ -555,6 +577,11 @@ void wxStyledTextCtrl::StyleSetCharacterSet(int style, int characterSet) {
     SendMsg(2066, style, characterSet);
 }
 
+// Set a style to be a hotspot or not.
+void wxStyledTextCtrl::StyleSetHotSpot(int style, bool hotspot) {
+    SendMsg(2409, style, hotspot);
+}
+
 // Set the foreground colour of the selection and whether to use this setting.
 void wxStyledTextCtrl::SetSelForeground(bool useSetting, const wxColour& fore) {
     SendMsg(2067, useSetting, wxColourAsLong(fore));
@@ -572,12 +599,12 @@ void wxStyledTextCtrl::SetCaretForeground(const wxColour& fore) {
 
 // When key+modifier combination km is pressed perform msg.
 void wxStyledTextCtrl::CmdKeyAssign(int key, int modifiers, int cmd) {
-                          SendMsg(2070, MAKELONG(key, modifiers), cmd);
+         SendMsg(2070, MAKELONG(key, modifiers), cmd);
 }
 
 // When key+modifier combination km do nothing.
 void wxStyledTextCtrl::CmdKeyClear(int key, int modifiers) {
-                          SendMsg(2071, MAKELONG(key, modifiers));
+         SendMsg(2071, MAKELONG(key, modifiers));
 }
 
 // Drop all key mappings.
@@ -587,7 +614,7 @@ void wxStyledTextCtrl::CmdKeyClearAll() {
 
 // Set the styles for a segment of the document.
 void wxStyledTextCtrl::SetStyleBytes(int length, char* styleBytes) {
-                          SendMsg(2073, length, (long)styleBytes);
+        SendMsg(2073, length, (long)styleBytes);
 }
 
 // Set a style to be visible or not.
@@ -818,6 +845,37 @@ bool wxStyledTextCtrl::AutoCompGetDropRestOfWord() {
     return SendMsg(2271, 0, 0) != 0;
 }
 
+// Register an image for use in autocompletion lists.
+void wxStyledTextCtrl::RegisterImage(int type, const wxBitmap& bmp) {
+        // convert bmp to a xpm in a string
+        wxMemoryOutputStream strm;
+        wxImage img = bmp.ConvertToImage();
+        img.SaveFile(strm, wxBITMAP_TYPE_XPM);
+        size_t len = strm.GetSize();
+        char* buff = new char[len+1];
+        strm.CopyTo(buff, len);
+        buff[len] = 0;
+        SendMsg(2405, type, (long)buff);
+        delete [] buff;
+     
+}
+
+// Clear all the registered images.
+void wxStyledTextCtrl::ClearRegisteredImages() {
+    SendMsg(2408, 0, 0);
+}
+
+// Retrieve the auto-completion list type-separator character.
+int wxStyledTextCtrl::AutoCompGetTypeSeparator() {
+    return SendMsg(2285, 0, 0);
+}
+
+// Change the type-separator character in the string setting up an auto-completion list.
+// Default is '?' but can be changed if items contain '?'.
+void wxStyledTextCtrl::AutoCompSetTypeSeparator(int separatorCharacter) {
+    SendMsg(2286, separatorCharacter, 0);
+}
+
 // Set the number of spaces used for one level of indentation.
 void wxStyledTextCtrl::SetIndent(int indentSize) {
     SendMsg(2122, indentSize, 0);
@@ -958,64 +1016,64 @@ int wxStyledTextCtrl::GetPrintColourMode() {
 
 // Find some text in the document.
 int wxStyledTextCtrl::FindText(int minPos, int maxPos,
-                            const wxString& text,
-                            int flags) {
-                     TextToFind  ft;
-                     ft.chrg.cpMin = minPos;
-                     ft.chrg.cpMax = maxPos;
-                     wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                     ft.lpstrText = (char*)(const char*)buf;
+               const wxString& text,
+               int flags) {
+            TextToFind  ft;
+            ft.chrg.cpMin = minPos;
+            ft.chrg.cpMax = maxPos;
+            wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+            ft.lpstrText = (char*)(const char*)buf;
 
-                     return SendMsg(2150, flags, (long)&ft);
+            return SendMsg(2150, flags, (long)&ft);
 }
 
 // On Windows, will draw the document into a display context such as a printer.
  int wxStyledTextCtrl::FormatRange(bool   doDraw,
-                                int    startPos,
-                                int    endPos,
-                                wxDC*  draw,
-                                wxDC*  target,  // Why does it use two? Can they be the same?
-                                wxRect renderRect,
-                                wxRect pageRect) {
-                            RangeToFormat fr;
-
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            fr.hdc = draw;
-                            fr.hdcTarget = target;
-                            fr.rc.top = renderRect.GetTop();
-                            fr.rc.left = renderRect.GetLeft();
-                            fr.rc.right = renderRect.GetRight();
-                            fr.rc.bottom = renderRect.GetBottom();
-                            fr.rcPage.top = pageRect.GetTop();
-                            fr.rcPage.left = pageRect.GetLeft();
-                            fr.rcPage.right = pageRect.GetRight();
-                            fr.rcPage.bottom = pageRect.GetBottom();
-                            fr.chrg.cpMin = startPos;
-                            fr.chrg.cpMax = endPos;
-
-                            return SendMsg(2151, doDraw, (long)&fr);
-}
-
-// Retrieve the line at the top of the display.
+                int    startPos,
+                int    endPos,
+                wxDC*  draw,
+                wxDC*  target,  // Why does it use two? Can they be the same?
+                wxRect renderRect,
+                wxRect pageRect) {
+             RangeToFormat fr;
+
+             if (endPos < startPos) {
+                 int temp = startPos;
+                 startPos = endPos;
+                 endPos = temp;
+             }
+             fr.hdc = draw;
+             fr.hdcTarget = target;
+             fr.rc.top = renderRect.GetTop();
+             fr.rc.left = renderRect.GetLeft();
+             fr.rc.right = renderRect.GetRight();
+             fr.rc.bottom = renderRect.GetBottom();
+             fr.rcPage.top = pageRect.GetTop();
+             fr.rcPage.left = pageRect.GetLeft();
+             fr.rcPage.right = pageRect.GetRight();
+             fr.rcPage.bottom = pageRect.GetBottom();
+             fr.chrg.cpMin = startPos;
+             fr.chrg.cpMax = endPos;
+
+             return SendMsg(2151, doDraw, (long)&fr);
+}
+
+// Retrieve the display line at the top of the display.
 int wxStyledTextCtrl::GetFirstVisibleLine() {
     return SendMsg(2152, 0, 0);
 }
 
 // Retrieve the contents of a line.
 wxString wxStyledTextCtrl::GetLine(int line) {
-                       int len = LineLength(line);
-                       if (!len) return wxEmptyString;
+         int len = LineLength(line);
+         if (!len) return wxEmptyString;
 
-                       wxMemoryBuffer mbuf(len+1);
-                       char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                       SendMsg(2153, line, (long)buf);
-                       mbuf.UngetWriteBuf(len);
-                       mbuf.AppendByte(0);
-                       return stc2wx(buf);
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(2153, line, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Returns the number of lines in the document. There is always at least one.
@@ -1055,40 +1113,40 @@ void wxStyledTextCtrl::SetSelection(int start, int end) {
 
 // Retrieve the selected text.
 wxString wxStyledTextCtrl::GetSelectedText() {
-                            int   start;
-                            int   end;
+         int   start;
+         int   end;
 
-                            GetSelection(&start, &end);
-                            int   len  = end - start;
-                            if (!len) return wxEmptyString;
+         GetSelection(&start, &end);
+         int   len  = end - start;
+         if (!len) return wxEmptyString;
 
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                            SendMsg(2161, 0, (long)buf);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(2161, 0, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Retrieve a range of text.
 wxString wxStyledTextCtrl::GetTextRange(int startPos, int endPos) {
-                            if (endPos < startPos) {
-                                int temp = startPos;
-                                startPos = endPos;
-                                endPos = temp;
-                            }
-                            int   len  = endPos - startPos;
-                            if (!len) return wxEmptyString;
-                            wxMemoryBuffer mbuf(len+1);
-                            char* buf = (char*)mbuf.GetWriteBuf(len);
-                            TextRange tr;
-                            tr.lpstrText = buf;
-                            tr.chrg.cpMin = startPos;
-                            tr.chrg.cpMax = endPos;
-                            SendMsg(2162, 0, (long)&tr);
-                            mbuf.UngetWriteBuf(len);
-                            mbuf.AppendByte(0);
-                            return stc2wx(buf);
+         if (endPos < startPos) {
+             int temp = startPos;
+             startPos = endPos;
+             endPos = temp;
+         }
+         int   len  = endPos - startPos;
+         if (!len) return wxEmptyString;
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len);
+         TextRange tr;
+         tr.lpstrText = buf;
+         tr.chrg.cpMin = startPos;
+         tr.chrg.cpMax = endPos;
+         SendMsg(2162, 0, (long)&tr);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Draw the selection in normal style or with selection highlighted.
@@ -1173,13 +1231,13 @@ void wxStyledTextCtrl::SetText(const wxString& text) {
 
 // Retrieve all the text in the document.
 wxString wxStyledTextCtrl::GetText() {
-                        int len  = GetTextLength();
-                        wxMemoryBuffer mbuf(len+1);   // leave room for the null...
-                        char* buf = (char*)mbuf.GetWriteBuf(len+1);
-                        SendMsg(2182, len+1, (long)buf);
-                        mbuf.UngetWriteBuf(len);
-                        mbuf.AppendByte(0);
-                        return stc2wx(buf);
+         int len  = GetTextLength();
+         wxMemoryBuffer mbuf(len+1);   // leave room for the null...
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(2182, len+1, (long)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
 }
 
 // Retrieve the number of characters in the document.
@@ -1233,9 +1291,9 @@ int wxStyledTextCtrl::GetTargetEnd() {
 // Text is counted so it can contain nulls.
 // Returns the length of the replacement text.
 
-                       int wxStyledTextCtrl::ReplaceTarget(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(2194, strlen(buf), (long)(const char*)buf);
+     int wxStyledTextCtrl::ReplaceTarget(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(2194, strlen(buf), (long)(const char*)buf);
 }
 
 // Replace the target text with the argument text after \d processing.
@@ -1245,18 +1303,18 @@ int wxStyledTextCtrl::GetTargetEnd() {
 // Returns the length of the replacement text including any change
 // caused by processing the \d patterns.
 
-                       int wxStyledTextCtrl::ReplaceTargetRE(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(2195, strlen(buf), (long)(const char*)buf);
+     int wxStyledTextCtrl::ReplaceTargetRE(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(2195, strlen(buf), (long)(const char*)buf);
 }
 
 // Search for a counted string in the target and set the target to the found
 // range. Text is counted so it can contain nulls.
 // Returns length of range or -1 for failure in which case target is not moved.
 
-                       int wxStyledTextCtrl::SearchInTarget(const wxString& text) {
-                           wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
-                           return SendMsg(2197, strlen(buf), (long)(const char*)buf);
+     int wxStyledTextCtrl::SearchInTarget(const wxString& text) {
+         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
+         return SendMsg(2197, strlen(buf), (long)(const char*)buf);
 }
 
 // Set the search flags used by SearchInTarget.
@@ -1299,6 +1357,16 @@ void wxStyledTextCtrl::CallTipSetBackground(const wxColour& back) {
     SendMsg(2205, wxColourAsLong(back), 0);
 }
 
+// Set the foreground colour for the call tip.
+void wxStyledTextCtrl::CallTipSetForeground(const wxColour& fore) {
+    SendMsg(2206, wxColourAsLong(fore), 0);
+}
+
+// Set the foreground colour for the highlighted part of the call tip.
+void wxStyledTextCtrl::CallTipSetForegroundHighlight(const wxColour& fore) {
+    SendMsg(2207, wxColourAsLong(fore), 0);
+}
+
 // Find the display line of a document line taking hidden lines into account.
 int wxStyledTextCtrl::VisibleFromDocLine(int line) {
     return SendMsg(2220, line, 0);
@@ -1366,7 +1434,7 @@ void wxStyledTextCtrl::EnsureVisible(int line) {
     SendMsg(2232, line, 0);
 }
 
-// Set some debugging options for folding.
+// Set some style options for folding.
 void wxStyledTextCtrl::SetFoldFlags(int flags) {
     SendMsg(2233, flags, 0);
 }
@@ -1472,6 +1540,61 @@ int wxStyledTextCtrl::TextHeight(int line) {
     return SendMsg(2279, line, 0);
 }
 
+// Show or hide the vertical scroll bar.
+void wxStyledTextCtrl::SetUseVerticalScrollBar(bool show) {
+    SendMsg(2280, show, 0);
+}
+
+// Is the vertical scroll bar visible?
+bool wxStyledTextCtrl::GetUseVerticalScrollBar() {
+    return SendMsg(2281, 0, 0) != 0;
+}
+
+// Append a string to the end of the document without changing the selection.
+void wxStyledTextCtrl::AppendText(int length, const wxString& text) {
+    SendMsg(2282, length, (long)(const char*)wx2stc(text));
+}
+
+// Is drawing done in two phases with backgrounds drawn before foregrounds?
+bool wxStyledTextCtrl::GetTwoPhaseDraw() {
+    return SendMsg(2283, 0, 0) != 0;
+}
+
+// In twoPhaseDraw mode, drawing is performed in two phases, first the background
+// and then the foreground. This avoids chopping off characters that overlap the next run.
+void wxStyledTextCtrl::SetTwoPhaseDraw(bool twoPhase) {
+    SendMsg(2284, twoPhase, 0);
+}
+
+// Make the target range start and end be the same as the selection range start and end.
+void wxStyledTextCtrl::TargetFromSelection() {
+    SendMsg(2287, 0, 0);
+}
+
+// Join the lines in the target.
+void wxStyledTextCtrl::LinesJoin() {
+    SendMsg(2288, 0, 0);
+}
+
+// Split the lines in the target into lines that are less wide than pixelWidth
+// where possible.
+void wxStyledTextCtrl::LinesSplit(int pixelWidth) {
+    SendMsg(2289, pixelWidth, 0);
+}
+
+// Set the colours used as a chequerboard pattern in the fold margin
+void wxStyledTextCtrl::SetFoldMarginColour(bool useSetting, const wxColour& back) {
+    SendMsg(2290, useSetting, wxColourAsLong(back));
+}
+void wxStyledTextCtrl::SetFoldMarginHiColour(bool useSetting, const wxColour& fore) {
+    SendMsg(2291, useSetting, wxColourAsLong(fore));
+}
+
+// Duplicate the current line.
+void wxStyledTextCtrl::LineDuplicate() {
+    SendMsg(2404, 0, 0);
+}
+
 // Move caret to first position on display line.
 void wxStyledTextCtrl::HomeDisplay() {
     SendMsg(2345, 0, 0);
@@ -1531,12 +1654,12 @@ void wxStyledTextCtrl::SetViewEOL(bool visible) {
 
 // Retrieve a pointer to the document object.
 void* wxStyledTextCtrl::GetDocPointer() {
-                           return (void*)SendMsg(2357);
+         return (void*)SendMsg(2357);
 }
 
 // Change the document object used.
 void wxStyledTextCtrl::SetDocPointer(void* docPointer) {
-                           SendMsg(2358, 0, (long)docPointer);
+         SendMsg(2358, 0, (long)docPointer);
 }
 
 // Set which document modification events are sent to the container.
@@ -1624,17 +1747,17 @@ int wxStyledTextCtrl::GetZoom() {
 // Create a new document object.
 // Starts with reference count of 1 and not selected into editor.
 void* wxStyledTextCtrl::CreateDocument() {
-                           return (void*)SendMsg(2375);
+         return (void*)SendMsg(2375);
 }
 
 // Extend life of document.
 void wxStyledTextCtrl::AddRefDocument(void* docPointer) {
-                           SendMsg(2376, 0, (long)docPointer);
+         SendMsg(2376, 0, (long)docPointer);
 }
 
 // Release a reference to the document, deleting document if it fades to black.
 void wxStyledTextCtrl::ReleaseDocument(void* docPointer) {
-                           SendMsg(2377, 0, (long)docPointer);
+         SendMsg(2377, 0, (long)docPointer);
 }
 
 // Get which document modification events are sent to the container.
@@ -1739,6 +1862,11 @@ int wxStyledTextCtrl::GetXOffset() {
     return SendMsg(2398, 0, 0);
 }
 
+// Set the last x chosen value to be the caret x position
+void wxStyledTextCtrl::ChooseCaretX() {
+    SendMsg(2399, 0, 0);
+}
+
 // Set the way the caret is kept visible when going sideway.
 // The exclusion zone is given in pixels.
 void wxStyledTextCtrl::SetXCaretPolicy(int caretPolicy, int caretSlop) {
@@ -1751,6 +1879,31 @@ void wxStyledTextCtrl::SetYCaretPolicy(int caretPolicy, int caretSlop) {
     SendMsg(2403, caretPolicy, caretSlop);
 }
 
+// Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).
+void wxStyledTextCtrl::SetPrintWrapMode(int mode) {
+    SendMsg(2406, mode, 0);
+}
+
+// Is printing line wrapped.
+int wxStyledTextCtrl::GetPrintWrapMode() {
+    return SendMsg(2407, 0, 0);
+}
+
+// Set a fore colour for active hotspots.
+void wxStyledTextCtrl::SetHotspotActiveForeground(bool useSetting, const wxColour& fore) {
+    SendMsg(2410, useSetting, wxColourAsLong(fore));
+}
+
+// Set a back colour for active hotspots.
+void wxStyledTextCtrl::SetHotspotActiveBackground(bool useSetting, const wxColour& back) {
+    SendMsg(2411, useSetting, wxColourAsLong(back));
+}
+
+// Enable / Disable underlining active hotspots.
+void wxStyledTextCtrl::SetHotspotActiveUnderline(bool underline) {
+    SendMsg(2412, underline, 0);
+}
+
 // Start notifying the container of all key presses and commands.
 void wxStyledTextCtrl::StartRecord() {
     SendMsg(3001, 0, 0);
@@ -1928,9 +2081,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) {
 
 void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) {
     wxPaintDC dc(this);
-    wxRegion  region = GetUpdateRegion();
-
-    m_swx->DoPaint(&dc, region.GetBox());
+    m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
 }
 
 void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
@@ -2196,6 +2347,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
         evt.SetEventType(wxEVT_STC_ZOOM);
         break;
 
+    case SCN_HOTSPOTCLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK);
+        break;
+
+    case SCN_HOTSPOTDOUBLECLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK);
+        break;
+
+    case SCN_CALLTIPCLICK:
+        evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
+        break;
+
     default:
         return;
     }
index 0ab9afdc5e1390ed9d460243356de8630e84ac50..66434747989357d29e48838b585aff223876d947 100644 (file)
 #include "wx/stc/stc.h"
 #include "ScintillaWX.h"
 
+#include <wx/wx.h>
 #include <wx/tokenzr.h>
+#include <wx/mstream.h>
+#include <wx/image.h>
 
 
 //----------------------------------------------------------------------
@@ -82,6 +85,10 @@ DEFINE_EVENT_TYPE( wxEVT_STC_START_DRAG )
 DEFINE_EVENT_TYPE( wxEVT_STC_DRAG_OVER )
 DEFINE_EVENT_TYPE( wxEVT_STC_DO_DROP )
 DEFINE_EVENT_TYPE( wxEVT_STC_ZOOM )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+
 
 
 BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
@@ -306,9 +313,7 @@ void wxStyledTextCtrl::ScrollToColumn(int column) {
 
 void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) {
     wxPaintDC dc(this);
-    wxRegion  region = GetUpdateRegion();
-
-    m_swx->DoPaint(&dc, region.GetBox());
+    m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
 }
 
 void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
@@ -574,6 +579,18 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
         evt.SetEventType(wxEVT_STC_ZOOM);
         break;
 
+    case SCN_HOTSPOTCLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK);
+        break;
+
+    case SCN_HOTSPOTDOUBLECLICK:
+        evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK);
+        break;
+
+    case SCN_CALLTIPCLICK:
+        evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
+        break;
+
     default:
         return;
     }
index 7a54289b2c8147c1bce9f594b24087a0ea7ee3c9..baeaf0d437f4b2d890740316668fe2e6ad9504f4 100644 (file)
@@ -225,11 +225,11 @@ private:
     void NotifyChange();
     void NotifyParent(SCNotification* scn);
 
-
-private:
     DECLARE_EVENT_TABLE()
     DECLARE_CLASS(wxStyledTextCtrl)
 
+protected:
+
     ScintillaWX*        m_swx;
     wxStopWatch         m_stopWatch;
     wxScrollBar*        m_vScrollBar;
@@ -348,6 +348,8 @@ private:
 #endif
 };
 
+
+
 #ifndef SWIG
 BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CHANGE,                  1650)
@@ -373,6 +375,9 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DRAG_OVER,               1670)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_DO_DROP,                 1671)
     DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_ZOOM,                    1672)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_CLICK,           1673)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_HOTSPOT_DCLICK,          1674)
+    DECLARE_LOCAL_EVENT_TYPE(wxEVT_STC_CALLTIP_CLICK,           1675)
 END_DECLARE_EVENT_TYPES()
 #else
     enum {
@@ -399,6 +404,9 @@ END_DECLARE_EVENT_TYPES()
         wxEVT_STC_DRAG_OVER,
         wxEVT_STC_DO_DROP,
         wxEVT_STC_ZOOM,
+        wxEVT_STC_HOTSPOT_CLICK,
+        wxEVT_STC_HOTSPOT_DCLICK,
+        wxEVT_STC_CALLTIP_CLICK
     };
 #endif
 
@@ -430,6 +438,10 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&);
 #define EVT_STC_DRAG_OVER(id, fn)               DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DRAG_OVER,             id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_DO_DROP(id, fn)                 DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_DO_DROP,               id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_STC_ZOOM(id, fn)                    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_ZOOM,                  id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_CLICK(id, fn)           DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK,         id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_HOTSPOT_DCLICK(id, fn)          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK,        id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+#define EVT_STC_CALLTIP_CLICK(id, fn))          DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK          id, -1, (wxObjectEventFunction) (wxEventFunction) (wxStyledTextEventFunction) & fn, (wxObject *) NULL ),
+
 #endif
 
 //----------------------------------------------------------------------