]> git.saurik.com Git - wxWidgets.git/commitdiff
Apply patch (plus some additional changes) upgrading Scintilla to version 2.03. ...
authorRobin Dunn <robin@alldunn.com>
Tue, 30 Mar 2010 03:50:06 +0000 (03:50 +0000)
committerRobin Dunn <robin@alldunn.com>
Tue, 30 Mar 2010 03:50:06 +0000 (03:50 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63792 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

125 files changed:
Makefile.in
build/bakefiles/scintilla.bkl
build/msw/makefile.bcc
build/msw/makefile.gcc
build/msw/makefile.vc
build/msw/makefile.wat
build/msw/wx_vc7_wxscintilla.vcproj
build/msw/wx_vc8_wxscintilla.vcproj
build/msw/wx_vc9_wxscintilla.vcproj
build/msw/wx_wxscintilla.dsp
include/wx/stc/stc.h
interface/wx/stc/stc.h
samples/stc/edit.cpp
samples/stc/edit.h
src/common/wincmn.cpp
src/stc/Makefile.in
src/stc/PlatWX.cpp
src/stc/ScintillaWX.cpp
src/stc/ScintillaWX.h
src/stc/gen_iface.py
src/stc/scintilla/README.txt
src/stc/scintilla/include/KeyWords.h
src/stc/scintilla/include/Platform.h
src/stc/scintilla/include/PropSet.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/Array.cpp [new file with mode: 0644]
src/stc/scintilla/src/Array.h [new file with mode: 0644]
src/stc/scintilla/src/AutoComplete.cxx
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/CharClassify.cxx
src/stc/scintilla/src/CharClassify.h
src/stc/scintilla/src/Document.cxx
src/stc/scintilla/src/Document.h
src/stc/scintilla/src/DocumentAccessor.h
src/stc/scintilla/src/Editor.cxx
src/stc/scintilla/src/Editor.h
src/stc/scintilla/src/ExternalLexer.cxx
src/stc/scintilla/src/ExternalLexer.h
src/stc/scintilla/src/FontQuality.h [new file with mode: 0644]
src/stc/scintilla/src/Indicator.cxx
src/stc/scintilla/src/Indicator.h
src/stc/scintilla/src/KeyWords.cxx
src/stc/scintilla/src/LexAU3.cxx
src/stc/scintilla/src/LexAbaqus.cxx
src/stc/scintilla/src/LexAda.cxx
src/stc/scintilla/src/LexAsm.cxx
src/stc/scintilla/src/LexBash.cxx
src/stc/scintilla/src/LexCOBOL.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexCPP.cxx
src/stc/scintilla/src/LexCSS.cxx
src/stc/scintilla/src/LexCaml.cxx
src/stc/scintilla/src/LexCmake.cxx
src/stc/scintilla/src/LexD.cxx
src/stc/scintilla/src/LexErlang.cxx
src/stc/scintilla/src/LexForth.cxx
src/stc/scintilla/src/LexFortran.cxx
src/stc/scintilla/src/LexGen.py [new file with mode: 0644]
src/stc/scintilla/src/LexHTML.cxx
src/stc/scintilla/src/LexHaskell.cxx
src/stc/scintilla/src/LexInno.cxx
src/stc/scintilla/src/LexLisp.cxx
src/stc/scintilla/src/LexLua.cxx
src/stc/scintilla/src/LexMPT.cxx
src/stc/scintilla/src/LexMagik.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexMarkdown.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexMatlab.cxx
src/stc/scintilla/src/LexMySQL.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexNimrod.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexNsis.cxx
src/stc/scintilla/src/LexOthers.cxx
src/stc/scintilla/src/LexPascal.cxx
src/stc/scintilla/src/LexPerl.cxx
src/stc/scintilla/src/LexPowerPro.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexPowerShell.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexProgress.cxx
src/stc/scintilla/src/LexPython.cxx
src/stc/scintilla/src/LexRuby.cxx
src/stc/scintilla/src/LexSML.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexSQL.cxx
src/stc/scintilla/src/LexSorcus.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexSpice.cxx
src/stc/scintilla/src/LexTACL.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexTADS3.cxx
src/stc/scintilla/src/LexTAL.cxx [new file with mode: 0644]
src/stc/scintilla/src/LexTeX.cxx
src/stc/scintilla/src/LexVB.cxx
src/stc/scintilla/src/LexVerilog.cxx
src/stc/scintilla/src/LexYAML.cxx
src/stc/scintilla/src/LineMarker.cxx
src/stc/scintilla/src/LineMarker.h
src/stc/scintilla/src/Partitioning.h
src/stc/scintilla/src/PerLine.cxx [new file with mode: 0644]
src/stc/scintilla/src/PerLine.h [new file with mode: 0644]
src/stc/scintilla/src/PositionCache.cxx
src/stc/scintilla/src/PositionCache.h
src/stc/scintilla/src/PropSet.cxx
src/stc/scintilla/src/PropSetSimple.h [new file with mode: 0644]
src/stc/scintilla/src/RESearch.cxx
src/stc/scintilla/src/RESearch.h
src/stc/scintilla/src/RunStyles.cxx
src/stc/scintilla/src/RunStyles.h
src/stc/scintilla/src/SVector.h
src/stc/scintilla/src/ScintillaBase.cxx
src/stc/scintilla/src/ScintillaBase.h
src/stc/scintilla/src/Selection.cxx [new file with mode: 0644]
src/stc/scintilla/src/Selection.h [new file with mode: 0644]
src/stc/scintilla/src/SplitVector.h
src/stc/scintilla/src/Style.cxx
src/stc/scintilla/src/Style.h
src/stc/scintilla/src/StyleContext.h
src/stc/scintilla/src/UniConversion.cxx
src/stc/scintilla/src/ViewStyle.cxx
src/stc/scintilla/src/ViewStyle.h
src/stc/scintilla/src/WindowAccessor.cxx
src/stc/scintilla/src/XPM.h
src/stc/stc.cpp
src/stc/stc.cpp.in
src/stc/stc.h.in

index f6de013fdc2511037d3fc55ea906ab2d9c31d928..c7bf50e85477264be2fc999d66d7f56a2287ad81 100644 (file)
@@ -246,6 +246,7 @@ WXSCINTILLA_OBJECTS =  \
        wxscintilla_LexCSS.o \
        wxscintilla_LexCaml.o \
        wxscintilla_LexCsound.o \
+       wxscintilla_LexCOBOL.o \
        wxscintilla_LexConf.o \
        wxscintilla_LexCrontab.o \
        wxscintilla_LexD.o \
@@ -264,11 +265,14 @@ WXSCINTILLA_OBJECTS =  \
        wxscintilla_LexLisp.o \
        wxscintilla_LexLout.o \
        wxscintilla_LexLua.o \
+       wxscintilla_LexMagik.o \
        wxscintilla_LexMMIXAL.o \
        wxscintilla_LexMPT.o \
        wxscintilla_LexMSSQL.o \
        wxscintilla_LexMatlab.o \
        wxscintilla_LexMetapost.o \
+       wxscintilla_LexMySQL.o \
+       wxscintilla_LexNimrod.o \
        wxscintilla_LexNsis.o \
        wxscintilla_LexOpal.o \
        wxscintilla_LexOthers.o \
@@ -279,16 +283,22 @@ WXSCINTILLA_OBJECTS =  \
        wxscintilla_LexPS.o \
        wxscintilla_LexPascal.o \
        wxscintilla_LexPerl.o \
+       wxscintilla_LexPowerPro.o \
+       wxscintilla_LexPowerShell.o \
        wxscintilla_LexPython.o \
        wxscintilla_LexR.o \
        wxscintilla_LexRebol.o \
        wxscintilla_LexRuby.o \
        wxscintilla_LexSQL.o \
+       wxscintilla_LexSML.o \
        wxscintilla_LexSmalltalk.o \
        wxscintilla_LexTADS3.o \
        wxscintilla_LexScriptol.o \
        wxscintilla_LexSpecman.o \
+       wxscintilla_LexSorcus.o \
        wxscintilla_LexSpice.o \
+       wxscintilla_LexTAL.o \
+       wxscintilla_LexTACL.o \
        wxscintilla_LexTCL.o \
        wxscintilla_LexTeX.o \
        wxscintilla_LexVB.o \
@@ -296,17 +306,21 @@ WXSCINTILLA_OBJECTS =  \
        wxscintilla_LexVerilog.o \
        wxscintilla_LexYAML.o \
        wxscintilla_LineMarker.o \
+       wxscintilla_PerLine.o \
        wxscintilla_PositionCache.o \
        wxscintilla_PropSet.o \
        wxscintilla_RESearch.o \
        wxscintilla_RunStyles.o \
+       wxscintilla_Selection.o \
        wxscintilla_ScintillaBase.o \
        wxscintilla_Style.o \
        wxscintilla_StyleContext.o \
        wxscintilla_UniConversion.o \
        wxscintilla_ViewStyle.o \
        wxscintilla_WindowAccessor.o \
-       wxscintilla_XPM.o
+       wxscintilla_XPM.o \
+       wxscintilla_LexMarkdown.o \
+       wxscintilla_Array.o
 PLUGINS_INST_DIR = $(libdir)/wx/$(PLUGIN_VERSION0)
 ALL_BASE_HEADERS =  \
        wx/afterstd.h \
@@ -14501,6 +14515,9 @@ wxscintilla_LexCaml.o: $(srcdir)/src/stc/scintilla/src/LexCaml.cxx
 wxscintilla_LexCsound.o: $(srcdir)/src/stc/scintilla/src/LexCsound.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexCsound.cxx
 
+wxscintilla_LexCOBOL.o: $(srcdir)/src/stc/scintilla/src/LexCOBOL.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexCOBOL.cxx
+
 wxscintilla_LexConf.o: $(srcdir)/src/stc/scintilla/src/LexConf.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexConf.cxx
 
@@ -14555,6 +14572,9 @@ wxscintilla_LexLout.o: $(srcdir)/src/stc/scintilla/src/LexLout.cxx
 wxscintilla_LexLua.o: $(srcdir)/src/stc/scintilla/src/LexLua.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexLua.cxx
 
+wxscintilla_LexMagik.o: $(srcdir)/src/stc/scintilla/src/LexMagik.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexMagik.cxx
+
 wxscintilla_LexMMIXAL.o: $(srcdir)/src/stc/scintilla/src/LexMMIXAL.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexMMIXAL.cxx
 
@@ -14570,6 +14590,12 @@ wxscintilla_LexMatlab.o: $(srcdir)/src/stc/scintilla/src/LexMatlab.cxx
 wxscintilla_LexMetapost.o: $(srcdir)/src/stc/scintilla/src/LexMetapost.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexMetapost.cxx
 
+wxscintilla_LexMySQL.o: $(srcdir)/src/stc/scintilla/src/LexMySQL.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexMySQL.cxx
+
+wxscintilla_LexNimrod.o: $(srcdir)/src/stc/scintilla/src/LexNimrod.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexNimrod.cxx
+
 wxscintilla_LexNsis.o: $(srcdir)/src/stc/scintilla/src/LexNsis.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexNsis.cxx
 
@@ -14600,6 +14626,12 @@ wxscintilla_LexPascal.o: $(srcdir)/src/stc/scintilla/src/LexPascal.cxx
 wxscintilla_LexPerl.o: $(srcdir)/src/stc/scintilla/src/LexPerl.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexPerl.cxx
 
+wxscintilla_LexPowerPro.o: $(srcdir)/src/stc/scintilla/src/LexPowerPro.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexPowerPro.cxx
+
+wxscintilla_LexPowerShell.o: $(srcdir)/src/stc/scintilla/src/LexPowerShell.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexPowerShell.cxx
+
 wxscintilla_LexPython.o: $(srcdir)/src/stc/scintilla/src/LexPython.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexPython.cxx
 
@@ -14615,6 +14647,9 @@ wxscintilla_LexRuby.o: $(srcdir)/src/stc/scintilla/src/LexRuby.cxx
 wxscintilla_LexSQL.o: $(srcdir)/src/stc/scintilla/src/LexSQL.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexSQL.cxx
 
+wxscintilla_LexSML.o: $(srcdir)/src/stc/scintilla/src/LexSML.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexSML.cxx
+
 wxscintilla_LexSmalltalk.o: $(srcdir)/src/stc/scintilla/src/LexSmalltalk.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexSmalltalk.cxx
 
@@ -14627,9 +14662,18 @@ wxscintilla_LexScriptol.o: $(srcdir)/src/stc/scintilla/src/LexScriptol.cxx
 wxscintilla_LexSpecman.o: $(srcdir)/src/stc/scintilla/src/LexSpecman.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexSpecman.cxx
 
+wxscintilla_LexSorcus.o: $(srcdir)/src/stc/scintilla/src/LexSorcus.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexSorcus.cxx
+
 wxscintilla_LexSpice.o: $(srcdir)/src/stc/scintilla/src/LexSpice.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexSpice.cxx
 
+wxscintilla_LexTAL.o: $(srcdir)/src/stc/scintilla/src/LexTAL.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexTAL.cxx
+
+wxscintilla_LexTACL.o: $(srcdir)/src/stc/scintilla/src/LexTACL.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexTACL.cxx
+
 wxscintilla_LexTCL.o: $(srcdir)/src/stc/scintilla/src/LexTCL.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexTCL.cxx
 
@@ -14651,6 +14695,9 @@ wxscintilla_LexYAML.o: $(srcdir)/src/stc/scintilla/src/LexYAML.cxx
 wxscintilla_LineMarker.o: $(srcdir)/src/stc/scintilla/src/LineMarker.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LineMarker.cxx
 
+wxscintilla_PerLine.o: $(srcdir)/src/stc/scintilla/src/PerLine.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/PerLine.cxx
+
 wxscintilla_PositionCache.o: $(srcdir)/src/stc/scintilla/src/PositionCache.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/PositionCache.cxx
 
@@ -14663,6 +14710,9 @@ wxscintilla_RESearch.o: $(srcdir)/src/stc/scintilla/src/RESearch.cxx
 wxscintilla_RunStyles.o: $(srcdir)/src/stc/scintilla/src/RunStyles.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/RunStyles.cxx
 
+wxscintilla_Selection.o: $(srcdir)/src/stc/scintilla/src/Selection.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/Selection.cxx
+
 wxscintilla_ScintillaBase.o: $(srcdir)/src/stc/scintilla/src/ScintillaBase.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/ScintillaBase.cxx
 
@@ -14684,6 +14734,12 @@ wxscintilla_WindowAccessor.o: $(srcdir)/src/stc/scintilla/src/WindowAccessor.cxx
 wxscintilla_XPM.o: $(srcdir)/src/stc/scintilla/src/XPM.cxx
        $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/XPM.cxx
 
+wxscintilla_LexMarkdown.o: $(srcdir)/src/stc/scintilla/src/LexMarkdown.cxx
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/LexMarkdown.cxx
+
+wxscintilla_Array.o: $(srcdir)/src/stc/scintilla/src/Array.cpp
+       $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/Array.cpp
+
 monodll_any.o: $(srcdir)/src/common/any.cpp $(MONODLL_ODEP)
        $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/any.cpp
 
index 45d244e1d60bd53ef9a957dcef6d8e44488a5f76..d79cb7aab7e03897f30b1addc4c610aa8c697a4a 100644 (file)
@@ -69,6 +69,7 @@
             src/stc/scintilla/src/LexCSS.cxx
             src/stc/scintilla/src/LexCaml.cxx
             src/stc/scintilla/src/LexCsound.cxx
+            src/stc/scintilla/src/LexCOBOL.cxx
             src/stc/scintilla/src/LexConf.cxx
             src/stc/scintilla/src/LexCrontab.cxx
             src/stc/scintilla/src/LexD.cxx
             src/stc/scintilla/src/LexLisp.cxx
             src/stc/scintilla/src/LexLout.cxx
             src/stc/scintilla/src/LexLua.cxx
+            src/stc/scintilla/src/LexMagik.cxx
             src/stc/scintilla/src/LexMMIXAL.cxx
             src/stc/scintilla/src/LexMPT.cxx
             src/stc/scintilla/src/LexMSSQL.cxx
             src/stc/scintilla/src/LexMatlab.cxx
             src/stc/scintilla/src/LexMetapost.cxx
+            src/stc/scintilla/src/LexMySQL.cxx
+            src/stc/scintilla/src/LexNimrod.cxx
             src/stc/scintilla/src/LexNsis.cxx
             src/stc/scintilla/src/LexOpal.cxx
             src/stc/scintilla/src/LexOthers.cxx
             src/stc/scintilla/src/LexPS.cxx
             src/stc/scintilla/src/LexPascal.cxx
             src/stc/scintilla/src/LexPerl.cxx
+            src/stc/scintilla/src/LexPowerPro.cxx
+            src/stc/scintilla/src/LexPowerShell.cxx
             src/stc/scintilla/src/LexPython.cxx
             src/stc/scintilla/src/LexR.cxx
             src/stc/scintilla/src/LexRebol.cxx
             src/stc/scintilla/src/LexRuby.cxx
             src/stc/scintilla/src/LexSQL.cxx
+            src/stc/scintilla/src/LexSML.cxx
             src/stc/scintilla/src/LexSmalltalk.cxx
             src/stc/scintilla/src/LexTADS3.cxx
             src/stc/scintilla/src/LexScriptol.cxx
             src/stc/scintilla/src/LexSpecman.cxx
+            src/stc/scintilla/src/LexSorcus.cxx
             src/stc/scintilla/src/LexSpice.cxx
+            src/stc/scintilla/src/LexTAL.cxx
+            src/stc/scintilla/src/LexTACL.cxx
             src/stc/scintilla/src/LexTCL.cxx
             src/stc/scintilla/src/LexTeX.cxx
             src/stc/scintilla/src/LexVB.cxx
             src/stc/scintilla/src/LexVerilog.cxx
             src/stc/scintilla/src/LexYAML.cxx
             src/stc/scintilla/src/LineMarker.cxx
+            src/stc/scintilla/src/PerLine.cxx
             src/stc/scintilla/src/PositionCache.cxx
             src/stc/scintilla/src/PropSet.cxx
             src/stc/scintilla/src/RESearch.cxx
             src/stc/scintilla/src/RunStyles.cxx
+            src/stc/scintilla/src/Selection.cxx
             src/stc/scintilla/src/ScintillaBase.cxx
             src/stc/scintilla/src/Style.cxx
             src/stc/scintilla/src/StyleContext.cxx
             src/stc/scintilla/src/ViewStyle.cxx
             src/stc/scintilla/src/WindowAccessor.cxx
             src/stc/scintilla/src/XPM.cxx
+            src/stc/scintilla/src/LexMarkdown.cxx
+           src/stc/scintilla/src/Array.cpp
         </sources>
     </lib>
 
index 5e1184ba3a3ec69e240d93055e87e2fe10911c5f..d03bfbc61f2ea8cd19ca49d890a03f5154a4fb63 100644 (file)
@@ -227,6 +227,7 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexCSS.obj \\r
        $(OBJS)\wxscintilla_LexCaml.obj \\r
        $(OBJS)\wxscintilla_LexCsound.obj \\r
+       $(OBJS)\wxscintilla_LexCOBOL.obj \\r
        $(OBJS)\wxscintilla_LexConf.obj \\r
        $(OBJS)\wxscintilla_LexCrontab.obj \\r
        $(OBJS)\wxscintilla_LexD.obj \\r
@@ -245,11 +246,14 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexLisp.obj \\r
        $(OBJS)\wxscintilla_LexLout.obj \\r
        $(OBJS)\wxscintilla_LexLua.obj \\r
+       $(OBJS)\wxscintilla_LexMagik.obj \\r
        $(OBJS)\wxscintilla_LexMMIXAL.obj \\r
        $(OBJS)\wxscintilla_LexMPT.obj \\r
        $(OBJS)\wxscintilla_LexMSSQL.obj \\r
        $(OBJS)\wxscintilla_LexMatlab.obj \\r
        $(OBJS)\wxscintilla_LexMetapost.obj \\r
+       $(OBJS)\wxscintilla_LexMySQL.obj \\r
+       $(OBJS)\wxscintilla_LexNimrod.obj \\r
        $(OBJS)\wxscintilla_LexNsis.obj \\r
        $(OBJS)\wxscintilla_LexOpal.obj \\r
        $(OBJS)\wxscintilla_LexOthers.obj \\r
@@ -260,16 +264,22 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexPS.obj \\r
        $(OBJS)\wxscintilla_LexPascal.obj \\r
        $(OBJS)\wxscintilla_LexPerl.obj \\r
+       $(OBJS)\wxscintilla_LexPowerPro.obj \\r
+       $(OBJS)\wxscintilla_LexPowerShell.obj \\r
        $(OBJS)\wxscintilla_LexPython.obj \\r
        $(OBJS)\wxscintilla_LexR.obj \\r
        $(OBJS)\wxscintilla_LexRebol.obj \\r
        $(OBJS)\wxscintilla_LexRuby.obj \\r
        $(OBJS)\wxscintilla_LexSQL.obj \\r
+       $(OBJS)\wxscintilla_LexSML.obj \\r
        $(OBJS)\wxscintilla_LexSmalltalk.obj \\r
        $(OBJS)\wxscintilla_LexTADS3.obj \\r
        $(OBJS)\wxscintilla_LexScriptol.obj \\r
        $(OBJS)\wxscintilla_LexSpecman.obj \\r
+       $(OBJS)\wxscintilla_LexSorcus.obj \\r
        $(OBJS)\wxscintilla_LexSpice.obj \\r
+       $(OBJS)\wxscintilla_LexTAL.obj \\r
+       $(OBJS)\wxscintilla_LexTACL.obj \\r
        $(OBJS)\wxscintilla_LexTCL.obj \\r
        $(OBJS)\wxscintilla_LexTeX.obj \\r
        $(OBJS)\wxscintilla_LexVB.obj \\r
@@ -277,17 +287,21 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexVerilog.obj \\r
        $(OBJS)\wxscintilla_LexYAML.obj \\r
        $(OBJS)\wxscintilla_LineMarker.obj \\r
+       $(OBJS)\wxscintilla_PerLine.obj \\r
        $(OBJS)\wxscintilla_PositionCache.obj \\r
        $(OBJS)\wxscintilla_PropSet.obj \\r
        $(OBJS)\wxscintilla_RESearch.obj \\r
        $(OBJS)\wxscintilla_RunStyles.obj \\r
+       $(OBJS)\wxscintilla_Selection.obj \\r
        $(OBJS)\wxscintilla_ScintillaBase.obj \\r
        $(OBJS)\wxscintilla_Style.obj \\r
        $(OBJS)\wxscintilla_StyleContext.obj \\r
        $(OBJS)\wxscintilla_UniConversion.obj \\r
        $(OBJS)\wxscintilla_ViewStyle.obj \\r
        $(OBJS)\wxscintilla_WindowAccessor.obj \\r
-       $(OBJS)\wxscintilla_XPM.obj\r
+       $(OBJS)\wxscintilla_XPM.obj \\r
+       $(OBJS)\wxscintilla_LexMarkdown.obj \\r
+       $(OBJS)\wxscintilla_Array.obj\r
 MONODLL_CFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \\r
        $(__OPTIMIZEFLAG) $(__THREADSFLAG) -D__WXMSW__ $(__WXUNIV_DEFINE_p) \\r
        $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \\r
@@ -5434,6 +5448,9 @@ $(OBJS)\wxscintilla_LexCaml.obj: ..\..\src\stc\scintilla\src\LexCaml.cxx
 $(OBJS)\wxscintilla_LexCsound.obj: ..\..\src\stc\scintilla\src\LexCsound.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexCsound.cxx\r
 \r
+$(OBJS)\wxscintilla_LexCOBOL.obj: ..\..\src\stc\scintilla\src\LexCOBOL.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexCOBOL.cxx\r
+\r
 $(OBJS)\wxscintilla_LexConf.obj: ..\..\src\stc\scintilla\src\LexConf.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexConf.cxx\r
 \r
@@ -5488,6 +5505,9 @@ $(OBJS)\wxscintilla_LexLout.obj: ..\..\src\stc\scintilla\src\LexLout.cxx
 $(OBJS)\wxscintilla_LexLua.obj: ..\..\src\stc\scintilla\src\LexLua.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexLua.cxx\r
 \r
+$(OBJS)\wxscintilla_LexMagik.obj: ..\..\src\stc\scintilla\src\LexMagik.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMagik.cxx\r
+\r
 $(OBJS)\wxscintilla_LexMMIXAL.obj: ..\..\src\stc\scintilla\src\LexMMIXAL.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMMIXAL.cxx\r
 \r
@@ -5503,6 +5523,12 @@ $(OBJS)\wxscintilla_LexMatlab.obj: ..\..\src\stc\scintilla\src\LexMatlab.cxx
 $(OBJS)\wxscintilla_LexMetapost.obj: ..\..\src\stc\scintilla\src\LexMetapost.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMetapost.cxx\r
 \r
+$(OBJS)\wxscintilla_LexMySQL.obj: ..\..\src\stc\scintilla\src\LexMySQL.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMySQL.cxx\r
+\r
+$(OBJS)\wxscintilla_LexNimrod.obj: ..\..\src\stc\scintilla\src\LexNimrod.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexNimrod.cxx\r
+\r
 $(OBJS)\wxscintilla_LexNsis.obj: ..\..\src\stc\scintilla\src\LexNsis.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexNsis.cxx\r
 \r
@@ -5533,6 +5559,12 @@ $(OBJS)\wxscintilla_LexPascal.obj: ..\..\src\stc\scintilla\src\LexPascal.cxx
 $(OBJS)\wxscintilla_LexPerl.obj: ..\..\src\stc\scintilla\src\LexPerl.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPerl.cxx\r
 \r
+$(OBJS)\wxscintilla_LexPowerPro.obj: ..\..\src\stc\scintilla\src\LexPowerPro.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPowerPro.cxx\r
+\r
+$(OBJS)\wxscintilla_LexPowerShell.obj: ..\..\src\stc\scintilla\src\LexPowerShell.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPowerShell.cxx\r
+\r
 $(OBJS)\wxscintilla_LexPython.obj: ..\..\src\stc\scintilla\src\LexPython.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPython.cxx\r
 \r
@@ -5548,6 +5580,9 @@ $(OBJS)\wxscintilla_LexRuby.obj: ..\..\src\stc\scintilla\src\LexRuby.cxx
 $(OBJS)\wxscintilla_LexSQL.obj: ..\..\src\stc\scintilla\src\LexSQL.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSQL.cxx\r
 \r
+$(OBJS)\wxscintilla_LexSML.obj: ..\..\src\stc\scintilla\src\LexSML.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSML.cxx\r
+\r
 $(OBJS)\wxscintilla_LexSmalltalk.obj: ..\..\src\stc\scintilla\src\LexSmalltalk.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSmalltalk.cxx\r
 \r
@@ -5560,9 +5595,18 @@ $(OBJS)\wxscintilla_LexScriptol.obj: ..\..\src\stc\scintilla\src\LexScriptol.cxx
 $(OBJS)\wxscintilla_LexSpecman.obj: ..\..\src\stc\scintilla\src\LexSpecman.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSpecman.cxx\r
 \r
+$(OBJS)\wxscintilla_LexSorcus.obj: ..\..\src\stc\scintilla\src\LexSorcus.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSorcus.cxx\r
+\r
 $(OBJS)\wxscintilla_LexSpice.obj: ..\..\src\stc\scintilla\src\LexSpice.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSpice.cxx\r
 \r
+$(OBJS)\wxscintilla_LexTAL.obj: ..\..\src\stc\scintilla\src\LexTAL.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexTAL.cxx\r
+\r
+$(OBJS)\wxscintilla_LexTACL.obj: ..\..\src\stc\scintilla\src\LexTACL.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexTACL.cxx\r
+\r
 $(OBJS)\wxscintilla_LexTCL.obj: ..\..\src\stc\scintilla\src\LexTCL.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexTCL.cxx\r
 \r
@@ -5584,6 +5628,9 @@ $(OBJS)\wxscintilla_LexYAML.obj: ..\..\src\stc\scintilla\src\LexYAML.cxx
 $(OBJS)\wxscintilla_LineMarker.obj: ..\..\src\stc\scintilla\src\LineMarker.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LineMarker.cxx\r
 \r
+$(OBJS)\wxscintilla_PerLine.obj: ..\..\src\stc\scintilla\src\PerLine.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\PerLine.cxx\r
+\r
 $(OBJS)\wxscintilla_PositionCache.obj: ..\..\src\stc\scintilla\src\PositionCache.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\PositionCache.cxx\r
 \r
@@ -5596,6 +5643,9 @@ $(OBJS)\wxscintilla_RESearch.obj: ..\..\src\stc\scintilla\src\RESearch.cxx
 $(OBJS)\wxscintilla_RunStyles.obj: ..\..\src\stc\scintilla\src\RunStyles.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\RunStyles.cxx\r
 \r
+$(OBJS)\wxscintilla_Selection.obj: ..\..\src\stc\scintilla\src\Selection.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\Selection.cxx\r
+\r
 $(OBJS)\wxscintilla_ScintillaBase.obj: ..\..\src\stc\scintilla\src\ScintillaBase.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\ScintillaBase.cxx\r
 \r
@@ -5617,6 +5667,12 @@ $(OBJS)\wxscintilla_WindowAccessor.obj: ..\..\src\stc\scintilla\src\WindowAccess
 $(OBJS)\wxscintilla_XPM.obj: ..\..\src\stc\scintilla\src\XPM.cxx\r
        $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\XPM.cxx\r
 \r
+$(OBJS)\wxscintilla_LexMarkdown.obj: ..\..\src\stc\scintilla\src\LexMarkdown.cxx\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMarkdown.cxx\r
+\r
+$(OBJS)\wxscintilla_Array.obj: ..\..\src\stc\scintilla\src\Array.cpp\r
+       $(CXX) -q -c -P -o$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\Array.cpp\r
+\r
 $(OBJS)\monodll_dummy.obj: ..\..\src\common\dummy.cpp\r
        $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) -H ..\..\src\common\dummy.cpp\r
 \r
index 671f5020960d8ff2018269dbd4756e4190baff2b..02f15af326c82cf3b6f06c90895c5896c019ef06 100644 (file)
@@ -214,6 +214,7 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexCSS.o \\r
        $(OBJS)\wxscintilla_LexCaml.o \\r
        $(OBJS)\wxscintilla_LexCsound.o \\r
+       $(OBJS)\wxscintilla_LexCOBOL.o \\r
        $(OBJS)\wxscintilla_LexConf.o \\r
        $(OBJS)\wxscintilla_LexCrontab.o \\r
        $(OBJS)\wxscintilla_LexD.o \\r
@@ -232,11 +233,14 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexLisp.o \\r
        $(OBJS)\wxscintilla_LexLout.o \\r
        $(OBJS)\wxscintilla_LexLua.o \\r
+       $(OBJS)\wxscintilla_LexMagik.o \\r
        $(OBJS)\wxscintilla_LexMMIXAL.o \\r
        $(OBJS)\wxscintilla_LexMPT.o \\r
        $(OBJS)\wxscintilla_LexMSSQL.o \\r
        $(OBJS)\wxscintilla_LexMatlab.o \\r
        $(OBJS)\wxscintilla_LexMetapost.o \\r
+       $(OBJS)\wxscintilla_LexMySQL.o \\r
+       $(OBJS)\wxscintilla_LexNimrod.o \\r
        $(OBJS)\wxscintilla_LexNsis.o \\r
        $(OBJS)\wxscintilla_LexOpal.o \\r
        $(OBJS)\wxscintilla_LexOthers.o \\r
@@ -247,16 +251,22 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexPS.o \\r
        $(OBJS)\wxscintilla_LexPascal.o \\r
        $(OBJS)\wxscintilla_LexPerl.o \\r
+       $(OBJS)\wxscintilla_LexPowerPro.o \\r
+       $(OBJS)\wxscintilla_LexPowerShell.o \\r
        $(OBJS)\wxscintilla_LexPython.o \\r
        $(OBJS)\wxscintilla_LexR.o \\r
        $(OBJS)\wxscintilla_LexRebol.o \\r
        $(OBJS)\wxscintilla_LexRuby.o \\r
        $(OBJS)\wxscintilla_LexSQL.o \\r
+       $(OBJS)\wxscintilla_LexSML.o \\r
        $(OBJS)\wxscintilla_LexSmalltalk.o \\r
        $(OBJS)\wxscintilla_LexTADS3.o \\r
        $(OBJS)\wxscintilla_LexScriptol.o \\r
        $(OBJS)\wxscintilla_LexSpecman.o \\r
+       $(OBJS)\wxscintilla_LexSorcus.o \\r
        $(OBJS)\wxscintilla_LexSpice.o \\r
+       $(OBJS)\wxscintilla_LexTAL.o \\r
+       $(OBJS)\wxscintilla_LexTACL.o \\r
        $(OBJS)\wxscintilla_LexTCL.o \\r
        $(OBJS)\wxscintilla_LexTeX.o \\r
        $(OBJS)\wxscintilla_LexVB.o \\r
@@ -264,17 +274,21 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexVerilog.o \\r
        $(OBJS)\wxscintilla_LexYAML.o \\r
        $(OBJS)\wxscintilla_LineMarker.o \\r
+       $(OBJS)\wxscintilla_PerLine.o \\r
        $(OBJS)\wxscintilla_PositionCache.o \\r
        $(OBJS)\wxscintilla_PropSet.o \\r
        $(OBJS)\wxscintilla_RESearch.o \\r
        $(OBJS)\wxscintilla_RunStyles.o \\r
+       $(OBJS)\wxscintilla_Selection.o \\r
        $(OBJS)\wxscintilla_ScintillaBase.o \\r
        $(OBJS)\wxscintilla_Style.o \\r
        $(OBJS)\wxscintilla_StyleContext.o \\r
        $(OBJS)\wxscintilla_UniConversion.o \\r
        $(OBJS)\wxscintilla_ViewStyle.o \\r
        $(OBJS)\wxscintilla_WindowAccessor.o \\r
-       $(OBJS)\wxscintilla_XPM.o\r
+       $(OBJS)\wxscintilla_XPM.o \\r
+       $(OBJS)\wxscintilla_LexMarkdown.o \\r
+       $(OBJS)\wxscintilla_Array.o\r
 MONODLL_CFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) $(GCCFLAGS) \\r
        -DHAVE_W32API_H -D__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) \\r
        $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \\r
@@ -5600,6 +5614,9 @@ $(OBJS)\wxscintilla_LexCaml.o: ../../src/stc/scintilla/src/LexCaml.cxx
 $(OBJS)\wxscintilla_LexCsound.o: ../../src/stc/scintilla/src/LexCsound.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexCOBOL.o: ../../src/stc/scintilla/src/LexCOBOL.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexConf.o: ../../src/stc/scintilla/src/LexConf.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5654,6 +5671,9 @@ $(OBJS)\wxscintilla_LexLout.o: ../../src/stc/scintilla/src/LexLout.cxx
 $(OBJS)\wxscintilla_LexLua.o: ../../src/stc/scintilla/src/LexLua.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexMagik.o: ../../src/stc/scintilla/src/LexMagik.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexMMIXAL.o: ../../src/stc/scintilla/src/LexMMIXAL.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5669,6 +5689,12 @@ $(OBJS)\wxscintilla_LexMatlab.o: ../../src/stc/scintilla/src/LexMatlab.cxx
 $(OBJS)\wxscintilla_LexMetapost.o: ../../src/stc/scintilla/src/LexMetapost.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexMySQL.o: ../../src/stc/scintilla/src/LexMySQL.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
+$(OBJS)\wxscintilla_LexNimrod.o: ../../src/stc/scintilla/src/LexNimrod.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexNsis.o: ../../src/stc/scintilla/src/LexNsis.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5699,6 +5725,12 @@ $(OBJS)\wxscintilla_LexPascal.o: ../../src/stc/scintilla/src/LexPascal.cxx
 $(OBJS)\wxscintilla_LexPerl.o: ../../src/stc/scintilla/src/LexPerl.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexPowerPro.o: ../../src/stc/scintilla/src/LexPowerPro.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
+$(OBJS)\wxscintilla_LexPowerShell.o: ../../src/stc/scintilla/src/LexPowerShell.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexPython.o: ../../src/stc/scintilla/src/LexPython.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5714,6 +5746,9 @@ $(OBJS)\wxscintilla_LexRuby.o: ../../src/stc/scintilla/src/LexRuby.cxx
 $(OBJS)\wxscintilla_LexSQL.o: ../../src/stc/scintilla/src/LexSQL.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexSML.o: ../../src/stc/scintilla/src/LexSML.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexSmalltalk.o: ../../src/stc/scintilla/src/LexSmalltalk.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5726,9 +5761,18 @@ $(OBJS)\wxscintilla_LexScriptol.o: ../../src/stc/scintilla/src/LexScriptol.cxx
 $(OBJS)\wxscintilla_LexSpecman.o: ../../src/stc/scintilla/src/LexSpecman.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexSorcus.o: ../../src/stc/scintilla/src/LexSorcus.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexSpice.o: ../../src/stc/scintilla/src/LexSpice.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexTAL.o: ../../src/stc/scintilla/src/LexTAL.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
+$(OBJS)\wxscintilla_LexTACL.o: ../../src/stc/scintilla/src/LexTACL.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_LexTCL.o: ../../src/stc/scintilla/src/LexTCL.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5750,6 +5794,9 @@ $(OBJS)\wxscintilla_LexYAML.o: ../../src/stc/scintilla/src/LexYAML.cxx
 $(OBJS)\wxscintilla_LineMarker.o: ../../src/stc/scintilla/src/LineMarker.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_PerLine.o: ../../src/stc/scintilla/src/PerLine.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_PositionCache.o: ../../src/stc/scintilla/src/PositionCache.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5762,6 +5809,9 @@ $(OBJS)\wxscintilla_RESearch.o: ../../src/stc/scintilla/src/RESearch.cxx
 $(OBJS)\wxscintilla_RunStyles.o: ../../src/stc/scintilla/src/RunStyles.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_Selection.o: ../../src/stc/scintilla/src/Selection.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\wxscintilla_ScintillaBase.o: ../../src/stc/scintilla/src/ScintillaBase.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
@@ -5783,6 +5833,12 @@ $(OBJS)\wxscintilla_WindowAccessor.o: ../../src/stc/scintilla/src/WindowAccessor
 $(OBJS)\wxscintilla_XPM.o: ../../src/stc/scintilla/src/XPM.cxx\r
        $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
 \r
+$(OBJS)\wxscintilla_LexMarkdown.o: ../../src/stc/scintilla/src/LexMarkdown.cxx\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
+$(OBJS)\wxscintilla_Array.o: ../../src/stc/scintilla/src/Array.cpp\r
+       $(CXX) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(CPPDEPS) $<\r
+\r
 $(OBJS)\monodll_dummy.o: ../../src/common/dummy.cpp\r
        $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<\r
 \r
index d1da00996b9d223c21c21ac6214c71957c670534..17e5c2b8559ffd414a6dca60b3cadc04c19b62da 100644 (file)
@@ -227,6 +227,7 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexCSS.obj \\r
        $(OBJS)\wxscintilla_LexCaml.obj \\r
        $(OBJS)\wxscintilla_LexCsound.obj \\r
+       $(OBJS)\wxscintilla_LexCOBOL.obj \\r
        $(OBJS)\wxscintilla_LexConf.obj \\r
        $(OBJS)\wxscintilla_LexCrontab.obj \\r
        $(OBJS)\wxscintilla_LexD.obj \\r
@@ -245,11 +246,14 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexLisp.obj \\r
        $(OBJS)\wxscintilla_LexLout.obj \\r
        $(OBJS)\wxscintilla_LexLua.obj \\r
+       $(OBJS)\wxscintilla_LexMagik.obj \\r
        $(OBJS)\wxscintilla_LexMMIXAL.obj \\r
        $(OBJS)\wxscintilla_LexMPT.obj \\r
        $(OBJS)\wxscintilla_LexMSSQL.obj \\r
        $(OBJS)\wxscintilla_LexMatlab.obj \\r
        $(OBJS)\wxscintilla_LexMetapost.obj \\r
+       $(OBJS)\wxscintilla_LexMySQL.obj \\r
+       $(OBJS)\wxscintilla_LexNimrod.obj \\r
        $(OBJS)\wxscintilla_LexNsis.obj \\r
        $(OBJS)\wxscintilla_LexOpal.obj \\r
        $(OBJS)\wxscintilla_LexOthers.obj \\r
@@ -260,16 +264,22 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexPS.obj \\r
        $(OBJS)\wxscintilla_LexPascal.obj \\r
        $(OBJS)\wxscintilla_LexPerl.obj \\r
+       $(OBJS)\wxscintilla_LexPowerPro.obj \\r
+       $(OBJS)\wxscintilla_LexPowerShell.obj \\r
        $(OBJS)\wxscintilla_LexPython.obj \\r
        $(OBJS)\wxscintilla_LexR.obj \\r
        $(OBJS)\wxscintilla_LexRebol.obj \\r
        $(OBJS)\wxscintilla_LexRuby.obj \\r
        $(OBJS)\wxscintilla_LexSQL.obj \\r
+       $(OBJS)\wxscintilla_LexSML.obj \\r
        $(OBJS)\wxscintilla_LexSmalltalk.obj \\r
        $(OBJS)\wxscintilla_LexTADS3.obj \\r
        $(OBJS)\wxscintilla_LexScriptol.obj \\r
        $(OBJS)\wxscintilla_LexSpecman.obj \\r
+       $(OBJS)\wxscintilla_LexSorcus.obj \\r
        $(OBJS)\wxscintilla_LexSpice.obj \\r
+       $(OBJS)\wxscintilla_LexTAL.obj \\r
+       $(OBJS)\wxscintilla_LexTACL.obj \\r
        $(OBJS)\wxscintilla_LexTCL.obj \\r
        $(OBJS)\wxscintilla_LexTeX.obj \\r
        $(OBJS)\wxscintilla_LexVB.obj \\r
@@ -277,17 +287,21 @@ WXSCINTILLA_OBJECTS =  \
        $(OBJS)\wxscintilla_LexVerilog.obj \\r
        $(OBJS)\wxscintilla_LexYAML.obj \\r
        $(OBJS)\wxscintilla_LineMarker.obj \\r
+       $(OBJS)\wxscintilla_PerLine.obj \\r
        $(OBJS)\wxscintilla_PositionCache.obj \\r
        $(OBJS)\wxscintilla_PropSet.obj \\r
        $(OBJS)\wxscintilla_RESearch.obj \\r
        $(OBJS)\wxscintilla_RunStyles.obj \\r
+       $(OBJS)\wxscintilla_Selection.obj \\r
        $(OBJS)\wxscintilla_ScintillaBase.obj \\r
        $(OBJS)\wxscintilla_Style.obj \\r
        $(OBJS)\wxscintilla_StyleContext.obj \\r
        $(OBJS)\wxscintilla_UniConversion.obj \\r
        $(OBJS)\wxscintilla_ViewStyle.obj \\r
        $(OBJS)\wxscintilla_WindowAccessor.obj \\r
-       $(OBJS)\wxscintilla_XPM.obj\r
+       $(OBJS)\wxscintilla_XPM.obj \\r
+       $(OBJS)\wxscintilla_LexMarkdown.obj \\r
+       $(OBJS)\wxscintilla_Array.obj\r
 MONODLL_CFLAGS = /M$(__RUNTIME_LIBS_116)$(__DEBUGRUNTIME) /DWIN32 \\r
        $(__DEBUGINFO) \\r
        /Fd$(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_vc$(VENDORTAG).pdb \\r
@@ -6031,6 +6045,9 @@ $(OBJS)\wxscintilla_LexCaml.obj: ..\..\src\stc\scintilla\src\LexCaml.cxx
 $(OBJS)\wxscintilla_LexCsound.obj: ..\..\src\stc\scintilla\src\LexCsound.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexCsound.cxx\r
 \r
+$(OBJS)\wxscintilla_LexCOBOL.obj: ..\..\src\stc\scintilla\src\LexCOBOL.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexCOBOL.cxx\r
+\r
 $(OBJS)\wxscintilla_LexConf.obj: ..\..\src\stc\scintilla\src\LexConf.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexConf.cxx\r
 \r
@@ -6085,6 +6102,9 @@ $(OBJS)\wxscintilla_LexLout.obj: ..\..\src\stc\scintilla\src\LexLout.cxx
 $(OBJS)\wxscintilla_LexLua.obj: ..\..\src\stc\scintilla\src\LexLua.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexLua.cxx\r
 \r
+$(OBJS)\wxscintilla_LexMagik.obj: ..\..\src\stc\scintilla\src\LexMagik.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMagik.cxx\r
+\r
 $(OBJS)\wxscintilla_LexMMIXAL.obj: ..\..\src\stc\scintilla\src\LexMMIXAL.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMMIXAL.cxx\r
 \r
@@ -6100,6 +6120,12 @@ $(OBJS)\wxscintilla_LexMatlab.obj: ..\..\src\stc\scintilla\src\LexMatlab.cxx
 $(OBJS)\wxscintilla_LexMetapost.obj: ..\..\src\stc\scintilla\src\LexMetapost.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMetapost.cxx\r
 \r
+$(OBJS)\wxscintilla_LexMySQL.obj: ..\..\src\stc\scintilla\src\LexMySQL.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMySQL.cxx\r
+\r
+$(OBJS)\wxscintilla_LexNimrod.obj: ..\..\src\stc\scintilla\src\LexNimrod.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexNimrod.cxx\r
+\r
 $(OBJS)\wxscintilla_LexNsis.obj: ..\..\src\stc\scintilla\src\LexNsis.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexNsis.cxx\r
 \r
@@ -6130,6 +6156,12 @@ $(OBJS)\wxscintilla_LexPascal.obj: ..\..\src\stc\scintilla\src\LexPascal.cxx
 $(OBJS)\wxscintilla_LexPerl.obj: ..\..\src\stc\scintilla\src\LexPerl.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPerl.cxx\r
 \r
+$(OBJS)\wxscintilla_LexPowerPro.obj: ..\..\src\stc\scintilla\src\LexPowerPro.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPowerPro.cxx\r
+\r
+$(OBJS)\wxscintilla_LexPowerShell.obj: ..\..\src\stc\scintilla\src\LexPowerShell.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPowerShell.cxx\r
+\r
 $(OBJS)\wxscintilla_LexPython.obj: ..\..\src\stc\scintilla\src\LexPython.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexPython.cxx\r
 \r
@@ -6145,6 +6177,9 @@ $(OBJS)\wxscintilla_LexRuby.obj: ..\..\src\stc\scintilla\src\LexRuby.cxx
 $(OBJS)\wxscintilla_LexSQL.obj: ..\..\src\stc\scintilla\src\LexSQL.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSQL.cxx\r
 \r
+$(OBJS)\wxscintilla_LexSML.obj: ..\..\src\stc\scintilla\src\LexSML.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSML.cxx\r
+\r
 $(OBJS)\wxscintilla_LexSmalltalk.obj: ..\..\src\stc\scintilla\src\LexSmalltalk.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSmalltalk.cxx\r
 \r
@@ -6157,9 +6192,18 @@ $(OBJS)\wxscintilla_LexScriptol.obj: ..\..\src\stc\scintilla\src\LexScriptol.cxx
 $(OBJS)\wxscintilla_LexSpecman.obj: ..\..\src\stc\scintilla\src\LexSpecman.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSpecman.cxx\r
 \r
+$(OBJS)\wxscintilla_LexSorcus.obj: ..\..\src\stc\scintilla\src\LexSorcus.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSorcus.cxx\r
+\r
 $(OBJS)\wxscintilla_LexSpice.obj: ..\..\src\stc\scintilla\src\LexSpice.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexSpice.cxx\r
 \r
+$(OBJS)\wxscintilla_LexTAL.obj: ..\..\src\stc\scintilla\src\LexTAL.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexTAL.cxx\r
+\r
+$(OBJS)\wxscintilla_LexTACL.obj: ..\..\src\stc\scintilla\src\LexTACL.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexTACL.cxx\r
+\r
 $(OBJS)\wxscintilla_LexTCL.obj: ..\..\src\stc\scintilla\src\LexTCL.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexTCL.cxx\r
 \r
@@ -6181,6 +6225,9 @@ $(OBJS)\wxscintilla_LexYAML.obj: ..\..\src\stc\scintilla\src\LexYAML.cxx
 $(OBJS)\wxscintilla_LineMarker.obj: ..\..\src\stc\scintilla\src\LineMarker.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LineMarker.cxx\r
 \r
+$(OBJS)\wxscintilla_PerLine.obj: ..\..\src\stc\scintilla\src\PerLine.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\PerLine.cxx\r
+\r
 $(OBJS)\wxscintilla_PositionCache.obj: ..\..\src\stc\scintilla\src\PositionCache.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\PositionCache.cxx\r
 \r
@@ -6193,6 +6240,9 @@ $(OBJS)\wxscintilla_RESearch.obj: ..\..\src\stc\scintilla\src\RESearch.cxx
 $(OBJS)\wxscintilla_RunStyles.obj: ..\..\src\stc\scintilla\src\RunStyles.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\RunStyles.cxx\r
 \r
+$(OBJS)\wxscintilla_Selection.obj: ..\..\src\stc\scintilla\src\Selection.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\Selection.cxx\r
+\r
 $(OBJS)\wxscintilla_ScintillaBase.obj: ..\..\src\stc\scintilla\src\ScintillaBase.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\ScintillaBase.cxx\r
 \r
@@ -6214,6 +6264,12 @@ $(OBJS)\wxscintilla_WindowAccessor.obj: ..\..\src\stc\scintilla\src\WindowAccess
 $(OBJS)\wxscintilla_XPM.obj: ..\..\src\stc\scintilla\src\XPM.cxx\r
        $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\XPM.cxx\r
 \r
+$(OBJS)\wxscintilla_LexMarkdown.obj: ..\..\src\stc\scintilla\src\LexMarkdown.cxx\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\LexMarkdown.cxx\r
+\r
+$(OBJS)\wxscintilla_Array.obj: ..\..\src\stc\scintilla\src\Array.cpp\r
+       $(CXX) /c /nologo /TP /Fo$@ $(WXSCINTILLA_CXXFLAGS) ..\..\src\stc\scintilla\src\Array.cpp\r
+\r
 $(OBJS)\monodll_dummy.obj: ..\..\src\common\dummy.cpp\r
        $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp\r
 \r
index 61cc8599a4360acfc39336d934de4547740aa776..497fae7286d67cb25fdcb3c9ce1d97f0d1e6c1bf 100644 (file)
@@ -3430,6 +3430,7 @@ WXSCINTILLA_OBJECTS =  &
        $(OBJS)\wxscintilla_LexCSS.obj &\r
        $(OBJS)\wxscintilla_LexCaml.obj &\r
        $(OBJS)\wxscintilla_LexCsound.obj &\r
+       $(OBJS)\wxscintilla_LexCOBOL.obj &\r
        $(OBJS)\wxscintilla_LexConf.obj &\r
        $(OBJS)\wxscintilla_LexCrontab.obj &\r
        $(OBJS)\wxscintilla_LexD.obj &\r
@@ -3448,11 +3449,14 @@ WXSCINTILLA_OBJECTS =  &
        $(OBJS)\wxscintilla_LexLisp.obj &\r
        $(OBJS)\wxscintilla_LexLout.obj &\r
        $(OBJS)\wxscintilla_LexLua.obj &\r
+       $(OBJS)\wxscintilla_LexMagik.obj &\r
        $(OBJS)\wxscintilla_LexMMIXAL.obj &\r
        $(OBJS)\wxscintilla_LexMPT.obj &\r
        $(OBJS)\wxscintilla_LexMSSQL.obj &\r
        $(OBJS)\wxscintilla_LexMatlab.obj &\r
        $(OBJS)\wxscintilla_LexMetapost.obj &\r
+       $(OBJS)\wxscintilla_LexMySQL.obj &\r
+       $(OBJS)\wxscintilla_LexNimrod.obj &\r
        $(OBJS)\wxscintilla_LexNsis.obj &\r
        $(OBJS)\wxscintilla_LexOpal.obj &\r
        $(OBJS)\wxscintilla_LexOthers.obj &\r
@@ -3463,16 +3467,22 @@ WXSCINTILLA_OBJECTS =  &
        $(OBJS)\wxscintilla_LexPS.obj &\r
        $(OBJS)\wxscintilla_LexPascal.obj &\r
        $(OBJS)\wxscintilla_LexPerl.obj &\r
+       $(OBJS)\wxscintilla_LexPowerPro.obj &\r
+       $(OBJS)\wxscintilla_LexPowerShell.obj &\r
        $(OBJS)\wxscintilla_LexPython.obj &\r
        $(OBJS)\wxscintilla_LexR.obj &\r
        $(OBJS)\wxscintilla_LexRebol.obj &\r
        $(OBJS)\wxscintilla_LexRuby.obj &\r
        $(OBJS)\wxscintilla_LexSQL.obj &\r
+       $(OBJS)\wxscintilla_LexSML.obj &\r
        $(OBJS)\wxscintilla_LexSmalltalk.obj &\r
        $(OBJS)\wxscintilla_LexTADS3.obj &\r
        $(OBJS)\wxscintilla_LexScriptol.obj &\r
        $(OBJS)\wxscintilla_LexSpecman.obj &\r
+       $(OBJS)\wxscintilla_LexSorcus.obj &\r
        $(OBJS)\wxscintilla_LexSpice.obj &\r
+       $(OBJS)\wxscintilla_LexTAL.obj &\r
+       $(OBJS)\wxscintilla_LexTACL.obj &\r
        $(OBJS)\wxscintilla_LexTCL.obj &\r
        $(OBJS)\wxscintilla_LexTeX.obj &\r
        $(OBJS)\wxscintilla_LexVB.obj &\r
@@ -3480,17 +3490,21 @@ WXSCINTILLA_OBJECTS =  &
        $(OBJS)\wxscintilla_LexVerilog.obj &\r
        $(OBJS)\wxscintilla_LexYAML.obj &\r
        $(OBJS)\wxscintilla_LineMarker.obj &\r
+       $(OBJS)\wxscintilla_PerLine.obj &\r
        $(OBJS)\wxscintilla_PositionCache.obj &\r
        $(OBJS)\wxscintilla_PropSet.obj &\r
        $(OBJS)\wxscintilla_RESearch.obj &\r
        $(OBJS)\wxscintilla_RunStyles.obj &\r
+       $(OBJS)\wxscintilla_Selection.obj &\r
        $(OBJS)\wxscintilla_ScintillaBase.obj &\r
        $(OBJS)\wxscintilla_Style.obj &\r
        $(OBJS)\wxscintilla_StyleContext.obj &\r
        $(OBJS)\wxscintilla_UniConversion.obj &\r
        $(OBJS)\wxscintilla_ViewStyle.obj &\r
        $(OBJS)\wxscintilla_WindowAccessor.obj &\r
-       $(OBJS)\wxscintilla_XPM.obj\r
+       $(OBJS)\wxscintilla_XPM.obj &\r
+       $(OBJS)\wxscintilla_LexMarkdown.obj &\r
+       $(OBJS)\wxscintilla_Array.obj\r
 MONODLL_CFLAGS = -bd $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) &\r
        $(__RUNTIME_LIBS) -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) &\r
        $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) &\r
@@ -5859,6 +5873,9 @@ $(OBJS)\wxscintilla_LexCaml.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexCa
 $(OBJS)\wxscintilla_LexCsound.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexCsound.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexCOBOL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexCOBOL.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexConf.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexConf.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -5913,6 +5930,9 @@ $(OBJS)\wxscintilla_LexLout.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexLo
 $(OBJS)\wxscintilla_LexLua.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexLua.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexMagik.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexMagik.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexMMIXAL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexMMIXAL.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -5928,6 +5948,12 @@ $(OBJS)\wxscintilla_LexMatlab.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\Lex
 $(OBJS)\wxscintilla_LexMetapost.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexMetapost.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexMySQL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexMySQL.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
+$(OBJS)\wxscintilla_LexNimrod.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexNimrod.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexNsis.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexNsis.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -5958,6 +5984,12 @@ $(OBJS)\wxscintilla_LexPascal.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\Lex
 $(OBJS)\wxscintilla_LexPerl.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexPerl.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexPowerPro.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexPowerPro.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
+$(OBJS)\wxscintilla_LexPowerShell.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexPowerShell.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexPython.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexPython.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -5973,6 +6005,9 @@ $(OBJS)\wxscintilla_LexRuby.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexRu
 $(OBJS)\wxscintilla_LexSQL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexSQL.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexSML.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexSML.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexSmalltalk.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexSmalltalk.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -5985,9 +6020,18 @@ $(OBJS)\wxscintilla_LexScriptol.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\L
 $(OBJS)\wxscintilla_LexSpecman.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexSpecman.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexSorcus.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexSorcus.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexSpice.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexSpice.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexTAL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexTAL.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
+$(OBJS)\wxscintilla_LexTACL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexTACL.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_LexTCL.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexTCL.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -6009,6 +6053,9 @@ $(OBJS)\wxscintilla_LexYAML.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexYA
 $(OBJS)\wxscintilla_LineMarker.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LineMarker.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_PerLine.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\PerLine.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_PositionCache.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\PositionCache.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -6021,6 +6068,9 @@ $(OBJS)\wxscintilla_RESearch.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\RESe
 $(OBJS)\wxscintilla_RunStyles.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\RunStyles.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_Selection.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\Selection.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\wxscintilla_ScintillaBase.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\ScintillaBase.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
@@ -6042,6 +6092,12 @@ $(OBJS)\wxscintilla_WindowAccessor.obj :  .AUTODEPEND ..\..\src\stc\scintilla\sr
 $(OBJS)\wxscintilla_XPM.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\XPM.cxx\r
        $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
 \r
+$(OBJS)\wxscintilla_LexMarkdown.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\LexMarkdown.cxx\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
+$(OBJS)\wxscintilla_Array.obj :  .AUTODEPEND ..\..\src\stc\scintilla\src\Array.cpp\r
+       $(CXX) -bt=nt -zq -fo=$^@ $(WXSCINTILLA_CXXFLAGS) $<\r
+\r
 $(OBJS)\monodll_dummy.obj :  .AUTODEPEND ..\..\src\common\dummy.cpp\r
        $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $<\r
 \r
index df4e33ceb7a24c318c1af39322dc53bc130b759f..0928dab780fde8b07c079a425c6c352a2dcf3aa9 100644 (file)
                        Name="Source Files"\r
                        Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\Array.cpp">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\AutoComplete.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexCLW.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexCOBOL.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexCPP.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMSSQL.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMagik.cxx">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMarkdown.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMatlab.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMetapost.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMySQL.cxx">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexNimrod.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexNsis.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexPerl.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexPowerPro.cxx">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexPowerShell.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexProgress.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexRuby.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexSML.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSQL.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSmalltalk.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexSorcus.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSpecman.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSpice.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexTACL.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexTADS3.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexTAL.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexTCL.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LineMarker.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\PerLine.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\PositionCache.cxx">\r
                        </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\ScintillaBase.cxx">\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\Selection.cxx">\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\Style.cxx">\r
                        </File>\r
index e6e782866e82bb28654091b740b9c3ad5b640fc6..50e3b123a244adae6a0a65395b148554b6dafdbe 100644 (file)
                        Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
                        >\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\Array.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\AutoComplete.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexCLW.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexCOBOL.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexCPP.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMSSQL.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMagik.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMarkdown.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMatlab.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMetapost.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMySQL.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexNimrod.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexNsis.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexPerl.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexPowerPro.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexPowerShell.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexProgress.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexRuby.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexSML.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSQL.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSmalltalk.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexSorcus.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSpecman.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSpice.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexTACL.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexTADS3.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexTAL.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexTCL.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LineMarker.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\PerLine.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\PositionCache.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\ScintillaBase.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\Selection.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\Style.cxx"\r
                                >\r
index bc1eec7ebc02923c999d2459b95ad0a108597158..7592e8946879a3c9fcc56e384c42f8e6c51d785e 100644 (file)
                        Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
                        >\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\Array.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\AutoComplete.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexCLW.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexCOBOL.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexCPP.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMSSQL.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMagik.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMarkdown.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMatlab.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexMetapost.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexMySQL.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexNimrod.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexNsis.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexPerl.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexPowerPro.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexPowerShell.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexProgress.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexRuby.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexSML.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSQL.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSmalltalk.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexSorcus.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSpecman.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LexSpice.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexTACL.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexTADS3.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\LexTAL.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\LexTCL.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\LineMarker.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\PerLine.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\PositionCache.cxx"\r
                                >\r
                                RelativePath="..\..\src\stc\scintilla\src\ScintillaBase.cxx"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\stc\scintilla\src\Selection.cxx"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\stc\scintilla\src\Style.cxx"\r
                                >\r
index 40018e90bc85477e25c3cfd08011be255ec05247..60825df2237de44fa0b2c57cef8284943fb829aa 100644 (file)
@@ -235,6 +235,10 @@ LIB32=link.exe -lib
 # PROP Default_Filter ""\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\Array.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\AutoComplete.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -339,6 +343,10 @@ SOURCE=..\..\src\stc\scintilla\src\LexCLW.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexCOBOL.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexCPP.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -443,6 +451,14 @@ SOURCE=..\..\src\stc\scintilla\src\LexMSSQL.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexMagik.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\stc\scintilla\src\LexMarkdown.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexMatlab.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -451,6 +467,14 @@ SOURCE=..\..\src\stc\scintilla\src\LexMetapost.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexMySQL.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\stc\scintilla\src\LexNimrod.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexNsis.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -487,6 +511,14 @@ SOURCE=..\..\src\stc\scintilla\src\LexPerl.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexPowerPro.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\src\stc\scintilla\src\LexPowerShell.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexProgress.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -507,6 +539,10 @@ SOURCE=..\..\src\stc\scintilla\src\LexRuby.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexSML.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexSQL.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -519,6 +555,10 @@ SOURCE=..\..\src\stc\scintilla\src\LexSmalltalk.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexSorcus.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexSpecman.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -527,10 +567,18 @@ SOURCE=..\..\src\stc\scintilla\src\LexSpice.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexTACL.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexTADS3.cxx\r
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\LexTAL.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\LexTCL.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -559,6 +607,10 @@ SOURCE=..\..\src\stc\scintilla\src\LineMarker.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\PerLine.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\PositionCache.cxx\r
 # End Source File\r
 # Begin Source File\r
@@ -579,6 +631,10 @@ SOURCE=..\..\src\stc\scintilla\src\ScintillaBase.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\src\stc\scintilla\src\Selection.cxx\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\src\stc\scintilla\src\Style.cxx\r
 # End Source File\r
 # Begin Source File\r
index ad0f3c16c1d7dd5193a0b32ba0413e87163a009a..be225a574ce0f0ee31c7bf32294bca17c13c3adf 100644 (file)
@@ -111,6 +111,9 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_MARK_ARROWS 24
 #define wxSTC_MARK_PIXMAP 25
 #define wxSTC_MARK_FULLRECT 26
+#define wxSTC_MARK_LEFTRECT 27
+#define wxSTC_MARK_AVAILABLE 28
+#define wxSTC_MARK_UNDERLINE 29
 #define wxSTC_MARK_CHARACTER 10000
 
 // Markers used for outlining column.
@@ -126,6 +129,8 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_MARGIN_NUMBER 1
 #define wxSTC_MARGIN_BACK 2
 #define wxSTC_MARGIN_FORE 3
+#define wxSTC_MARGIN_TEXT 4
+#define wxSTC_MARGIN_RTEXT 5
 
 // Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles.
 // Style 39 is for future use.
@@ -208,17 +213,12 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #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
@@ -229,13 +229,26 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_WRAPVISUALFLAGLOC_DEFAULT 0x0000
 #define wxSTC_WRAPVISUALFLAGLOC_END_BY_TEXT 0x0001
 #define wxSTC_WRAPVISUALFLAGLOC_START_BY_TEXT 0x0002
+#define wxSTC_WRAPINDENT_FIXED 0
+#define wxSTC_WRAPINDENT_SAME 1
+#define wxSTC_WRAPINDENT_INDENT 2
 #define wxSTC_CACHE_NONE 0
 #define wxSTC_CACHE_CARET 1
 #define wxSTC_CACHE_PAGE 2
 #define wxSTC_CACHE_DOCUMENT 3
+
+// Control font anti-aliasing.
+#define wxSTC_EFF_QUALITY_MASK 0xF
+#define wxSTC_EFF_QUALITY_DEFAULT 0
+#define wxSTC_EFF_QUALITY_NON_ANTIALIASED 1
+#define wxSTC_EFF_QUALITY_ANTIALIASED 2
+#define wxSTC_EFF_QUALITY_LCD_OPTIMIZED 3
 #define wxSTC_EDGE_NONE 0
 #define wxSTC_EDGE_LINE 1
 #define wxSTC_EDGE_BACKGROUND 2
+#define wxSTC_STATUS_OK 0
+#define wxSTC_STATUS_FAILURE 1
+#define wxSTC_STATUS_BADALLOC 2
 #define wxSTC_CURSORNORMAL -1
 #define wxSTC_CURSORWAIT 4
 
@@ -268,19 +281,23 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 // This way, we favour the displaying of useful information: the begining of lines,
 // where most code reside, and the lines after the caret, eg. the body of a function.
 #define wxSTC_CARET_EVEN 0x08
-
-// Selection Modes
 #define wxSTC_SEL_STREAM 0
 #define wxSTC_SEL_RECTANGLE 1
 #define wxSTC_SEL_LINES 2
+#define wxSTC_SEL_THIN 3
 #define wxSTC_ALPHA_TRANSPARENT 0
 #define wxSTC_ALPHA_OPAQUE 255
 #define wxSTC_ALPHA_NOALPHA 256
-
-// Caret Styles
 #define wxSTC_CARETSTYLE_INVISIBLE 0
 #define wxSTC_CARETSTYLE_LINE 1
 #define wxSTC_CARETSTYLE_BLOCK 2
+#define wxSTC_ANNOTATION_HIDDEN 0
+#define wxSTC_ANNOTATION_STANDARD 1
+#define wxSTC_ANNOTATION_BOXED 2
+#define wxSTC_UNDO_MAY_COALESCE 1
+#define wxSTC_SCVS_NONE 0
+#define wxSTC_SCVS_RECTANGULARSELECTION 1
+#define wxSTC_SCVS_USERACCESSIBLE 2
 
 // Maximum value of keywordSet parameter of SetKeyWords.
 #define wxSTC_KEYWORDSET_MAX 8
@@ -305,7 +322,10 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_STARTACTION 0x2000
 #define wxSTC_MOD_CHANGEINDICATOR 0x4000
 #define wxSTC_MOD_CHANGELINESTATE 0x8000
-#define wxSTC_MODEVENTMASKALL 0xFFFF
+#define wxSTC_MOD_CHANGEMARGIN 0x10000
+#define wxSTC_MOD_CHANGEANNOTATION 0x20000
+#define wxSTC_MOD_CONTAINER 0x40000
+#define wxSTC_MODEVENTMASKALL 0x7FFFF
 
 // Symbolic key codes and modifier flags.
 // ASCII and other printable characters below 256.
@@ -334,6 +354,7 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_SCMOD_SHIFT 1
 #define wxSTC_SCMOD_CTRL 2
 #define wxSTC_SCMOD_ALT 4
+#define wxSTC_SCMOD_SUPER 8
 
 // For SciLexer.h
 #define wxSTC_LEX_CONTAINER 0
@@ -421,6 +442,18 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_LEX_ABAQUS 84
 #define wxSTC_LEX_ASYMPTOTE 85
 #define wxSTC_LEX_R 86
+#define wxSTC_LEX_MAGIK 87
+#define wxSTC_LEX_POWERSHELL 88
+#define wxSTC_LEX_MYSQL 89
+#define wxSTC_LEX_PO 90
+#define wxSTC_LEX_TAL 91
+#define wxSTC_LEX_COBOL 92
+#define wxSTC_LEX_TACL 93
+#define wxSTC_LEX_SORCUS 94
+#define wxSTC_LEX_POWERPRO 95
+#define wxSTC_LEX_NIMROD 96
+#define wxSTC_LEX_SML 97
+#define wxSTC_LEX_MARKDOWN 98
 
 // When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 // value assigned in sequence from SCLEX_AUTOMATIC+1.
@@ -485,6 +518,11 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_D_COMMENTLINEDOC 15
 #define wxSTC_D_COMMENTDOCKEYWORD 16
 #define wxSTC_D_COMMENTDOCKEYWORDERROR 17
+#define wxSTC_D_STRINGB 18
+#define wxSTC_D_STRINGR 19
+#define wxSTC_D_WORD5 20
+#define wxSTC_D_WORD6 21
+#define wxSTC_D_WORD7 22
 
 // Lexical states for SCLEX_TCL
 #define wxSTC_TCL_DEFAULT 0
@@ -829,6 +867,7 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_DIFF_POSITION 4
 #define wxSTC_DIFF_DELETED 5
 #define wxSTC_DIFF_ADDED 6
+#define wxSTC_DIFF_CHANGED 7
 
 // Lexical states for SCLEX_CONF (Apache Configuration Files Lexer)
 #define wxSTC_CONF_DEFAULT 0
@@ -1021,6 +1060,11 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_CSS_SINGLESTRING 14
 #define wxSTC_CSS_IDENTIFIER2 15
 #define wxSTC_CSS_ATTRIBUTE 16
+#define wxSTC_CSS_IDENTIFIER3 17
+#define wxSTC_CSS_PSEUDOELEMENT 18
+#define wxSTC_CSS_EXTENDED_IDENTIFIER 19
+#define wxSTC_CSS_EXTENDED_PSEUDOCLASS 20
+#define wxSTC_CSS_EXTENDED_PSEUDOELEMENT 21
 
 // Lexical states for SCLEX_POV
 #define wxSTC_POV_DEFAULT 0
@@ -1195,8 +1239,19 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_ERLANG_CHARACTER 9
 #define wxSTC_ERLANG_MACRO 10
 #define wxSTC_ERLANG_RECORD 11
-#define wxSTC_ERLANG_SEPARATOR 12
+#define wxSTC_ERLANG_PREPROC 12
 #define wxSTC_ERLANG_NODE_NAME 13
+#define wxSTC_ERLANG_COMMENT_FUNCTION 14
+#define wxSTC_ERLANG_COMMENT_MODULE 15
+#define wxSTC_ERLANG_COMMENT_DOC 16
+#define wxSTC_ERLANG_COMMENT_DOC_MACRO 17
+#define wxSTC_ERLANG_ATOM_QUOTED 18
+#define wxSTC_ERLANG_MACRO_QUOTED 19
+#define wxSTC_ERLANG_RECORD_QUOTED 20
+#define wxSTC_ERLANG_NODE_NAME_QUOTED 21
+#define wxSTC_ERLANG_BIFS 22
+#define wxSTC_ERLANG_MODULES 23
+#define wxSTC_ERLANG_MODULES_ATT 24
 #define wxSTC_ERLANG_UNKNOWN 31
 
 // Lexical states for SCLEX_OCTAVE are identical to MatLab
@@ -1368,6 +1423,7 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_CAML_OPERATOR 7
 #define wxSTC_CAML_NUMBER 8
 #define wxSTC_CAML_CHAR 9
+#define wxSTC_CAML_WHITE 10
 #define wxSTC_CAML_STRING 11
 #define wxSTC_CAML_COMMENT 12
 #define wxSTC_CAML_COMMENT1 13
@@ -1541,7 +1597,7 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_INNO_PARAMETER 3
 #define wxSTC_INNO_SECTION 4
 #define wxSTC_INNO_PREPROC 5
-#define wxSTC_INNO_PREPROC_INLINE 6
+#define wxSTC_INNO_INLINE_EXPANSION 6
 #define wxSTC_INNO_COMMENT_PASCAL 7
 #define wxSTC_INNO_KEYWORD_PASCAL 8
 #define wxSTC_INNO_KEYWORD_USER 9
@@ -1690,6 +1746,162 @@ class WXDLLIMPEXP_FWD_CORE wxScrollBar;
 #define wxSTC_R_INFIX 10
 #define wxSTC_R_INFIXEOL 11
 
+// Lexical state for SCLEX_MAGIKSF
+#define wxSTC_MAGIK_DEFAULT 0
+#define wxSTC_MAGIK_COMMENT 1
+#define wxSTC_MAGIK_HYPER_COMMENT 16
+#define wxSTC_MAGIK_STRING 2
+#define wxSTC_MAGIK_CHARACTER 3
+#define wxSTC_MAGIK_NUMBER 4
+#define wxSTC_MAGIK_IDENTIFIER 5
+#define wxSTC_MAGIK_OPERATOR 6
+#define wxSTC_MAGIK_FLOW 7
+#define wxSTC_MAGIK_CONTAINER 8
+#define wxSTC_MAGIK_BRACKET_BLOCK 9
+#define wxSTC_MAGIK_BRACE_BLOCK 10
+#define wxSTC_MAGIK_SQBRACKET_BLOCK 11
+#define wxSTC_MAGIK_UNKNOWN_KEYWORD 12
+#define wxSTC_MAGIK_KEYWORD 13
+#define wxSTC_MAGIK_PRAGMA 14
+#define wxSTC_MAGIK_SYMBOL 15
+
+// Lexical state for SCLEX_POWERSHELL
+#define wxSTC_POWERSHELL_DEFAULT 0
+#define wxSTC_POWERSHELL_COMMENT 1
+#define wxSTC_POWERSHELL_STRING 2
+#define wxSTC_POWERSHELL_CHARACTER 3
+#define wxSTC_POWERSHELL_NUMBER 4
+#define wxSTC_POWERSHELL_VARIABLE 5
+#define wxSTC_POWERSHELL_OPERATOR 6
+#define wxSTC_POWERSHELL_IDENTIFIER 7
+#define wxSTC_POWERSHELL_KEYWORD 8
+#define wxSTC_POWERSHELL_CMDLET 9
+#define wxSTC_POWERSHELL_ALIAS 10
+
+// Lexical state for SCLEX_MYSQL
+#define wxSTC_MYSQL_DEFAULT 0
+#define wxSTC_MYSQL_COMMENT 1
+#define wxSTC_MYSQL_COMMENTLINE 2
+#define wxSTC_MYSQL_VARIABLE 3
+#define wxSTC_MYSQL_SYSTEMVARIABLE 4
+#define wxSTC_MYSQL_KNOWNSYSTEMVARIABLE 5
+#define wxSTC_MYSQL_NUMBER 6
+#define wxSTC_MYSQL_MAJORKEYWORD 7
+#define wxSTC_MYSQL_KEYWORD 8
+#define wxSTC_MYSQL_DATABASEOBJECT 9
+#define wxSTC_MYSQL_PROCEDUREKEYWORD 10
+#define wxSTC_MYSQL_STRING 11
+#define wxSTC_MYSQL_SQSTRING 12
+#define wxSTC_MYSQL_DQSTRING 13
+#define wxSTC_MYSQL_OPERATOR 14
+#define wxSTC_MYSQL_FUNCTION 15
+#define wxSTC_MYSQL_IDENTIFIER 16
+#define wxSTC_MYSQL_QUOTEDIDENTIFIER 17
+#define wxSTC_MYSQL_USER1 18
+#define wxSTC_MYSQL_USER2 19
+#define wxSTC_MYSQL_USER3 20
+#define wxSTC_MYSQL_HIDDENCOMMAND 21
+
+// Lexical state for SCLEX_PO
+#define wxSTC_PO_DEFAULT 0
+#define wxSTC_PO_COMMENT 1
+#define wxSTC_PO_MSGID 2
+#define wxSTC_PO_MSGID_TEXT 3
+#define wxSTC_PO_MSGSTR 4
+#define wxSTC_PO_MSGSTR_TEXT 5
+#define wxSTC_PO_MSGCTXT 6
+#define wxSTC_PO_MSGCTXT_TEXT 7
+#define wxSTC_PO_FUZZY 8
+
+// Lexical states for SCLEX_PASCAL
+#define wxSTC_PAS_DEFAULT 0
+#define wxSTC_PAS_IDENTIFIER 1
+#define wxSTC_PAS_COMMENT 2
+#define wxSTC_PAS_COMMENT2 3
+#define wxSTC_PAS_COMMENTLINE 4
+#define wxSTC_PAS_PREPROCESSOR 5
+#define wxSTC_PAS_PREPROCESSOR2 6
+#define wxSTC_PAS_NUMBER 7
+#define wxSTC_PAS_HEXNUMBER 8
+#define wxSTC_PAS_WORD 9
+#define wxSTC_PAS_STRING 10
+#define wxSTC_PAS_STRINGEOL 11
+#define wxSTC_PAS_CHARACTER 12
+#define wxSTC_PAS_OPERATOR 13
+#define wxSTC_PAS_ASM 14
+
+// Lexical state for SCLEX_SORCUS
+#define wxSTC_SORCUS_DEFAULT 0
+#define wxSTC_SORCUS_COMMAND 1
+#define wxSTC_SORCUS_PARAMETER 2
+#define wxSTC_SORCUS_COMMENTLINE 3
+#define wxSTC_SORCUS_STRING 4
+#define wxSTC_SORCUS_STRINGEOL 5
+#define wxSTC_SORCUS_IDENTIFIER 6
+#define wxSTC_SORCUS_OPERATOR 7
+#define wxSTC_SORCUS_NUMBER 8
+#define wxSTC_SORCUS_CONSTANT 9
+
+// Lexical state for SCLEX_POWERPRO
+#define wxSTC_POWERPRO_DEFAULT 0
+#define wxSTC_POWERPRO_COMMENTBLOCK 1
+#define wxSTC_POWERPRO_COMMENTLINE 2
+#define wxSTC_POWERPRO_NUMBER 3
+#define wxSTC_POWERPRO_WORD 4
+#define wxSTC_POWERPRO_WORD2 5
+#define wxSTC_POWERPRO_WORD3 6
+#define wxSTC_POWERPRO_WORD4 7
+#define wxSTC_POWERPRO_DOUBLEQUOTEDSTRING 8
+#define wxSTC_POWERPRO_SINGLEQUOTEDSTRING 9
+#define wxSTC_POWERPRO_LINECONTINUE 10
+#define wxSTC_POWERPRO_OPERATOR 11
+#define wxSTC_POWERPRO_IDENTIFIER 12
+#define wxSTC_POWERPRO_STRINGEOL 13
+#define wxSTC_POWERPRO_VERBATIM 14
+#define wxSTC_POWERPRO_ALTQUOTE 15
+#define wxSTC_POWERPRO_FUNCTION 16
+
+// Lexical states for SCLEX_SML
+#define wxSTC_SML_DEFAULT 0
+#define wxSTC_SML_IDENTIFIER 1
+#define wxSTC_SML_TAGNAME 2
+#define wxSTC_SML_KEYWORD 3
+#define wxSTC_SML_KEYWORD2 4
+#define wxSTC_SML_KEYWORD3 5
+#define wxSTC_SML_LINENUM 6
+#define wxSTC_SML_OPERATOR 7
+#define wxSTC_SML_NUMBER 8
+#define wxSTC_SML_CHAR 9
+#define wxSTC_SML_STRING 11
+#define wxSTC_SML_COMMENT 12
+#define wxSTC_SML_COMMENT1 13
+#define wxSTC_SML_COMMENT2 14
+#define wxSTC_SML_COMMENT3 15
+
+// Lexical state for SCLEX_MARKDOWN
+#define wxSTC_MARKDOWN_DEFAULT 0
+#define wxSTC_MARKDOWN_LINE_BEGIN 1
+#define wxSTC_MARKDOWN_STRONG1 2
+#define wxSTC_MARKDOWN_STRONG2 3
+#define wxSTC_MARKDOWN_EM1 4
+#define wxSTC_MARKDOWN_EM2 5
+#define wxSTC_MARKDOWN_HEADER1 6
+#define wxSTC_MARKDOWN_HEADER2 7
+#define wxSTC_MARKDOWN_HEADER3 8
+#define wxSTC_MARKDOWN_HEADER4 9
+#define wxSTC_MARKDOWN_HEADER5 10
+#define wxSTC_MARKDOWN_HEADER6 11
+#define wxSTC_MARKDOWN_PRECHAR 12
+#define wxSTC_MARKDOWN_ULIST_ITEM 13
+#define wxSTC_MARKDOWN_OLIST_ITEM 14
+#define wxSTC_MARKDOWN_BLOCKQUOTE 15
+#define wxSTC_MARKDOWN_STRIKEOUT 16
+#define wxSTC_MARKDOWN_HRULE 17
+#define wxSTC_MARKDOWN_LINK 18
+#define wxSTC_MARKDOWN_CODE 19
+#define wxSTC_MARKDOWN_CODE2 20
+#define wxSTC_MARKDOWN_CODEBK 21
+
 //}}}
 //----------------------------------------------------------------------
 
@@ -2039,7 +2251,7 @@ public:
     // Set all style bytes to 0, remove all folding information.
     void ClearDocumentStyle();
 
-    // Returns the number of characters in the document.
+    // Returns the number of bytes in the document.
     int GetLength() const;
 
     // Returns the character byte at the position.
@@ -2290,10 +2502,10 @@ public:
     // 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.
+    // Set the foreground colour of the main and additional selections and whether to use this setting.
     void SetSelForeground(bool useSetting, const wxColour& fore);
 
-    // Set the background colour of the selection and whether to use this setting.
+    // Set the background colour of the main and additional selections and whether to use this setting.
     void SetSelBackground(bool useSetting, const wxColour& back);
 
     // Get the alpha of the selection.
@@ -2333,7 +2545,7 @@ public:
     void SetCaretPeriod(int periodMilliseconds);
 
     // Set the set of characters making up words for when moving or selecting by word.
-    // First sets deaults like SetCharsDefault.
+    // First sets defaults like SetCharsDefault.
     void SetWordChars(const wxString& characters);
 
     // Start a sequence of actions that is undone and redone as a unit.
@@ -2367,6 +2579,12 @@ public:
     // Set the background colour of all whitespace and whether to use this setting.
     void SetWhitespaceBackground(bool useSetting, const wxColour& back);
 
+    // Set the size of the dots used to mark space characters.
+    void SetWhitespaceSize(int size);
+
+    // Get the size of the dots used to mark space characters.
+    int GetWhitespaceSize() const;
+
     // Divide each styling byte into lexical class bits (default: 5) and indicator
     // bits (default: 3). If a lexer requires more than 32 lexical states, then this
     // is used to expand the possible states.
@@ -2852,6 +3070,12 @@ public:
     // Retrive the start indent for wrapped lines.
     int GetWrapStartIndent() const;
 
+    // Sets how wrapped sublines are placed. Default is fixed.
+    void SetWrapIndentMode(int mode);
+
+    // Retrieve how wrapped sublines are placed. Default is fixed.
+    int GetWrapIndentMode() const;
+
     // Sets the degree of caching of layout information.
     void SetLayoutCache(int mode);
 
@@ -2903,6 +3127,9 @@ public:
     // and then the foreground. This avoids chopping off characters that overlap the next run.
     void SetTwoPhaseDraw(bool twoPhase);
 
+    // Scroll so that a display line is at the top of the display.
+    void SetFirstVisibleLine(int lineDisplay);
+
     // Make the target range start and end be the same as the selection range start and end.
     void TargetFromSelection();
 
@@ -3093,7 +3320,7 @@ public:
     // Move the caret inside current view if it's not there already.
     void MoveCaretInsideView();
 
-    // How many characters are on a line, not including end of line characters?
+    // How many characters are on a line, including end of line characters?
     int LineLength(int line) const;
 
     // Highlight the characters at two positions.
@@ -3301,7 +3528,7 @@ public:
     // Copy argument text to the clipboard.
     void CopyText(int length, const wxString& text);
 
-    // Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE) or
+    // Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or
     // by lines (SC_SEL_LINES).
     void SetSelectionMode(int mode);
 
@@ -3450,6 +3677,217 @@ public:
     // How many entries are allocated to the position cache?
     int GetPositionCacheSize() const;
 
+    // Copy the selection, if selection empty copy the line with the caret
+    void CopyAllowLine();
+
+    // Compact the document buffer and return a read-only pointer to the
+    // characters in the document.
+    const char* GetCharacterPointer();
+
+    // Always interpret keyboard input as Unicode
+    void SetKeysUnicode(bool keysUnicode);
+
+    // Are keys always interpreted as Unicode?
+    bool GetKeysUnicode() const;
+
+    // Set the alpha fill colour of the given indicator.
+    void IndicatorSetAlpha(int indicator, int alpha);
+
+    // Get the alpha fill colour of the given indicator.
+    int IndicatorGetAlpha(int indicator) const;
+
+    // Set extra ascent for each line
+    void SetExtraAscent(int extraAscent);
+
+    // Get extra ascent for each line
+    int GetExtraAscent() const;
+
+    // Set extra descent for each line
+    void SetExtraDescent(int extraDescent);
+
+    // Get extra descent for each line
+    int GetExtraDescent() const;
+
+    // Which symbol was defined for markerNumber with MarkerDefine
+    int GetMarkerSymbolDefined(int markerNumber);
+
+    // Set the text in the text margin for a line
+    void MarginSetText(int line, const wxString& text);
+
+    // Get the text in the text margin for a line
+    wxString MarginGetText(int line) const;
+
+    // Set the style number for the text margin for a line
+    void MarginSetStyle(int line, int style);
+
+    // Get the style number for the text margin for a line
+    int MarginGetStyle(int line) const;
+
+    // Set the style in the text margin for a line
+    void MarginSetStyles(int line, const wxString& styles);
+
+    // Get the styles in the text margin for a line
+    wxString MarginGetStyles(int line) const;
+
+    // Clear the margin text on all lines
+    void MarginTextClearAll();
+
+    // Get the start of the range of style numbers used for margin text
+    void MarginSetStyleOffset(int style);
+
+    // Get the start of the range of style numbers used for margin text
+    int MarginGetStyleOffset() const;
+
+    // Set the annotation text for a line
+    void AnnotationSetText(int line, const wxString& text);
+
+    // Get the annotation text for a line
+    wxString AnnotationGetText(int line) const;
+
+    // Set the style number for the annotations for a line
+    void AnnotationSetStyle(int line, int style);
+
+    // Get the style number for the annotations for a line
+    int AnnotationGetStyle(int line) const;
+
+    // Set the annotation styles for a line
+    void AnnotationSetStyles(int line, const wxString& styles);
+
+    // Get the annotation styles for a line
+    wxString AnnotationGetStyles(int line) const;
+
+    // Get the number of annotation lines for a line
+    int AnnotationGetLines(int line) const;
+
+    // Clear the annotations from all lines
+    void AnnotationClearAll();
+
+    // Set the visibility for the annotations for a view
+    void AnnotationSetVisible(int visible);
+
+    // Get the visibility for the annotations for a view
+    int AnnotationGetVisible() const;
+
+    // Get the start of the range of style numbers used for annotations
+    void AnnotationSetStyleOffset(int style);
+
+    // Get the start of the range of style numbers used for annotations
+    int AnnotationGetStyleOffset() const;
+
+    // Add a container action to the undo stack
+    void AddUndoAction(int token, int flags);
+
+    // Find the position of a character from a point within the window.
+    int CharPositionFromPoint(int x, int y);
+
+    // Find the position of a character from a point within the window.
+    // Return INVALID_POSITION if not close to text.
+    int CharPositionFromPointClose(int x, int y);
+
+    // Set whether multiple selections can be made
+    void SetMultipleSelection(bool multipleSelection);
+
+    // Whether multiple selections can be made
+    bool GetMultipleSelection() const;
+
+    // Set whether typing can be performed into multiple selections
+    void SetAdditionalSelectionTyping(bool additionalSelectionTyping);
+
+    // Whether typing can be performed into multiple selections
+    bool GetAdditionalSelectionTyping() const;
+
+    // Set whether additional carets will blink
+    void SetAdditionalCaretsBlink(bool additionalCaretsBlink);
+
+    // Whether additional carets will blink
+    bool GetAdditionalCaretsBlink() const;
+
+    // Set whether additional carets are visible
+    void SetAdditionalCaretsVisible(bool additionalCaretsBlink);
+
+    // Whether additional carets are visible
+    bool GetAdditionalCaretsVisible() const;
+
+    // How many selections are there?
+    int GetSelections() const;
+
+    // Clear selections to a single empty stream selection
+    void ClearSelections();
+
+    // Add a selection
+    int AddSelection(int caret, int anchor);
+
+    // Set the main selection
+    void SetMainSelection(int selection);
+
+    // Which selection is the main selection
+    int GetMainSelection() const;
+    void SetSelectionNCaret(int selection, int pos);
+    int GetSelectionNCaret(int selection) const;
+    void SetSelectionNAnchor(int selection, int posAnchor);
+    int GetSelectionNAnchor(int selection) const;
+    void SetSelectionNCaretVirtualSpace(int selection, int space);
+    int GetSelectionNCaretVirtualSpace(int selection) const;
+    void SetSelectionNAnchorVirtualSpace(int selection, int space);
+    int GetSelectionNAnchorVirtualSpace(int selection) const;
+
+    // Sets the position that starts the selection - this becomes the anchor.
+    void SetSelectionNStart(int selection, int pos);
+
+    // Returns the position at the start of the selection.
+    int GetSelectionNStart(int selection) const;
+
+    // Sets the position that ends the selection - this becomes the currentPosition.
+    void SetSelectionNEnd(int selection, int pos);
+
+    // Returns the position at the end of the selection.
+    int GetSelectionNEnd(int selection) const;
+    void SetRectangularSelectionCaret(int pos);
+    int GetRectangularSelectionCaret() const;
+    void SetRectangularSelectionAnchor(int posAnchor);
+    int GetRectangularSelectionAnchor() const;
+    void SetRectangularSelectionCaretVirtualSpace(int space);
+    int GetRectangularSelectionCaretVirtualSpace() const;
+    void SetRectangularSelectionAnchorVirtualSpace(int space);
+    int GetRectangularSelectionAnchorVirtualSpace() const;
+    void SetVirtualSpaceOptions(int virtualSpaceOptions);
+    int GetVirtualSpaceOptions() const;
+
+    // On GTK+, allow selecting the modifier key to use for mouse-based
+    // rectangular selection. Often the window manager requires Alt+Mouse Drag
+    // for moving windows.
+    // Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER.
+    void SetRectangularSelectionModifier(int modifier);
+
+    // Get the modifier key used for rectangular selection.
+    int GetRectangularSelectionModifier() const;
+
+    // Set the foreground colour of additional selections.
+    // Must have previously called SetSelFore with non-zero first argument for this to have an effect.
+    void SetAdditionalSelForeground(const wxColour& fore);
+
+    // Set the background colour of additional selections.
+    // Must have previously called SetSelBack with non-zero first argument for this to have an effect.
+    void SetAdditionalSelBackground(const wxColour& back);
+
+    // Set the alpha of the selection.
+    void SetAdditionalSelAlpha(int alpha);
+
+    // Get the alpha of the selection.
+    int GetAdditionalSelAlpha() const;
+
+    // Set the foreground colour of additional carets.
+    void SetAdditionalCaretForeground(const wxColour& fore);
+
+    // Get the foreground colour of additional carets.
+    wxColour GetAdditionalCaretForeground() const;
+
+    // Set the main selection to the next selection.
+    void RotateSelection();
+
+    // Swap that caret and anchor of the main selection.
+    void SwapMainAnchorCaret();
+
     // Start notifying the container of all key presses and commands.
     void StartRecord();
 
@@ -3988,6 +4426,8 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_CALLTIP_CLICK, wxStyledText
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_SELECTION, wxStyledTextEvent );
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_INDICATOR_CLICK, wxStyledTextEvent );
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_INDICATOR_RELEASE, wxStyledTextEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_CANCELLED, wxStyledTextEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_CHAR_DELETED, wxStyledTextEvent );
 #else
     enum {
         wxEVT_STC_CHANGE,
@@ -4017,7 +4457,9 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_INDICATOR_RELEASE, wxStyled
         wxEVT_STC_CALLTIP_CLICK,
         wxEVT_STC_AUTOCOMP_SELECTION,
         wxEVT_STC_INDICATOR_CLICK,
-        wxEVT_STC_INDICATOR_RELEASE
+        wxEVT_STC_INDICATOR_RELEASE,
+        wxEVT_STC_AUTOCOMP_CANCELLED,
+        wxEVT_STC_AUTOCOMP_CHAR_DELETED
     };
 #endif
 
@@ -4057,6 +4499,8 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&);
 #define EVT_STC_AUTOCOMP_SELECTION(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_SELECTION,    id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
 #define EVT_STC_INDICATOR_CLICK(id, fn)    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_INDICATOR_CLICK,       id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
 #define EVT_STC_INDICATOR_RELEASE(id, fn)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_INDICATOR_RELEASE,     id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
+#define EVT_STC_AUTOCOMP_CANCELLED(id, fn)    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_CANCELLED,    id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
+#define EVT_STC_AUTOCOMP_CHAR_DELETED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_CHAR_DELETED, id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
 
 #endif
 
index ff4494dcf98fdc178cafebe848e20695965efee3..e1b0d08617b70afe4678467fd3a0b085c3c5dedc 100644 (file)
@@ -316,6 +316,14 @@ public:
         TOWRITE
     @event{EVT_STC_AUTOCOMP_SELECTION(id, fn)}
         TOWRITE
+    @event{EVT_STC_INDICATOR_CLICK(id, fn)}
+        TOWRITE
+    @event{EVT_STC_INDICATOR_RELEASE(id, fn)}
+        TOWRITE
+    @event{EVT_STC_AUTOCOMP_CANCELLED(id, fn)}
+        TOWRITE
+    @event{EVT_STC_AUTOCOMP_CHAR_DELETED(id, fn)}
+        TOWRITE
     @endEventTable
 
     @library{wxbase}
@@ -1040,7 +1048,7 @@ public:
     int GetLayoutCache() const;
 
     /**
-        Returns the number of characters in the document.
+        Returns the number of bytes in the document.
     */
     int GetLength() const;
 
@@ -1568,7 +1576,7 @@ public:
     int LineFromPosition(int pos) const;
 
     /**
-        How many characters are on a line, not including end of line characters?
+        How many characters are on a line, including end of line characters?
     */
     int LineLength(int line) const;
 
@@ -2234,12 +2242,12 @@ public:
     void SetSelAlpha(int alpha);
 
     /**
-        Set the background colour of the selection and whether to use this setting.
+        Set the background colour of the main and additional selections and whether to use this setting.
     */
     void SetSelBackground(bool useSetting, const wxColour& back);
 
     /**
-        Set the foreground colour of the selection and whether to use this setting.
+        Set the foreground colour of the main and additional selections and whether to use this setting.
     */
     void SetSelForeground(bool useSetting, const wxColour& fore);
 
@@ -2254,9 +2262,8 @@ public:
     void SetSelectionEnd(int pos);
 
     /**
-        Set the selection mode to stream (SC_SEL_STREAM) or rectangular
-        (SC_SEL_RECTANGLE) or
-        by lines (SC_SEL_LINES).
+        Set the selection mode to stream (wxSTC_SEL_STREAM) or rectangular
+        (wxSTC_SEL_RECTANGLE/wxSTC_SEL_THIN) or by lines (wxSTC_SEL_LINES).
     */
     void SetSelectionMode(int mode);
 
@@ -2398,9 +2405,20 @@ public:
     void SetWhitespaceForeground(bool useSetting,
                                  const wxColour& fore);
 
+    /**
+       Set the size of the dots used to mark space characters.
+    */
+    void SetWhitespaceSize(int size);
+
+    /**
+       Get the size of the dots used to mark space characters.
+    */
+    int GetWhitespaceSize() const;
+
+    
     /**
         Set the set of characters making up words for when moving or selecting by word.
-        First sets deaults like SetCharsDefault.
+        First sets defaults like SetCharsDefault.
     */
     void SetWordChars(const wxString& characters);
 
@@ -2780,5 +2798,372 @@ public:
         Make the displayed text smaller by decreasing the sizes by 1 point.
     */
     void ZoomOut();
+
+
+
+    
+    /**
+       Set the size of the dots used to mark space characters.
+    */
+    void SetWhitespaceSize(int size);
+
+    /**
+       Get the size of the dots used to mark space characters.
+    */
+    int GetWhitespaceSize() const;
+
+    /**
+       Sets how wrapped sublines are placed. Default is fixed.
+    */
+    void SetWrapIndentMode(int mode);
+
+    /**
+       Retrieve how wrapped sublines are placed. Default is fixed.
+    */
+    int GetWrapIndentMode() const;
+
+    /**
+       Scroll so that a display line is at the top of the display.
+    */
+    void SetFirstVisibleLine(int lineDisplay);
+
+
+
+    /**
+       Copy the selection, if selection empty copy the line with the caret
+    */
+    void CopyAllowLine();
+
+    /**
+       Compact the document buffer and return a read-only pointer to the
+       characters in the document.
+    */
+    const char* GetCharacterPointer();
+
+    /**
+       Always interpret keyboard input as Unicode
+    */
+    void SetKeysUnicode(bool keysUnicode);
+
+    /**
+       Are keys always interpreted as Unicode?
+    */
+    bool GetKeysUnicode() const;
+
+    /**
+       Set the alpha fill colour of the given indicator.
+    */
+    void IndicatorSetAlpha(int indicator, int alpha);
+
+    /**
+       Get the alpha fill colour of the given indicator.
+    */
+    int IndicatorGetAlpha(int indicator) const;
+
+    /**
+       Set extra ascent for each line
+    */
+    void SetExtraAscent(int extraAscent);
+
+    /**
+       Get extra ascent for each line
+    */
+    int GetExtraAscent() const;
+
+    /**
+       Set extra descent for each line
+    */
+    void SetExtraDescent(int extraDescent);
+
+    /**
+       Get extra descent for each line
+    */
+    int GetExtraDescent() const;
+
+    /**
+       Which symbol was defined for markerNumber with MarkerDefine
+    */
+    int GetMarkerSymbolDefined(int markerNumber);
+
+    /**
+       Set the text in the text margin for a line
+    */
+    void MarginSetText(int line, const wxString& text);
+
+    /**
+       Get the text in the text margin for a line
+    */
+    wxString MarginGetText(int line) const;
+
+    /**
+       Set the style number for the text margin for a line
+    */
+    void MarginSetStyle(int line, int style);
+
+    /**
+       Get the style number for the text margin for a line
+    */
+    int MarginGetStyle(int line) const;
+
+    /**
+       Set the style in the text margin for a line
+    */
+    void MarginSetStyles(int line, const wxString& styles);
+
+    /**
+       Get the styles in the text margin for a line
+    */
+    wxString MarginGetStyles(int line) const;
+
+    /**
+       Clear the margin text on all lines
+    */
+    void MarginTextClearAll();
+
+    /**
+       Get the start of the range of style numbers used for margin text
+    */
+    void MarginSetStyleOffset(int style);
+
+    /**
+       Get the start of the range of style numbers used for margin text
+    */
+    int MarginGetStyleOffset() const;
+
+    /**
+       Set the annotation text for a line
+    */
+    void AnnotationSetText(int line, const wxString& text);
+
+    /**
+       Get the annotation text for a line
+    */
+    wxString AnnotationGetText(int line) const;
+
+    /**
+       Set the style number for the annotations for a line
+    */
+    void AnnotationSetStyle(int line, int style);
+
+    /**
+       Get the style number for the annotations for a line
+    */
+    int AnnotationGetStyle(int line) const;
+
+    /**
+       Set the annotation styles for a line
+    */
+    void AnnotationSetStyles(int line, const wxString& styles);
+
+    /**
+       Get the annotation styles for a line
+    */
+    wxString AnnotationGetStyles(int line) const;
+
+    /**
+       Get the number of annotation lines for a line
+    */
+    int AnnotationGetLines(int line) const;
+
+    /**
+       Clear the annotations from all lines
+    */
+    void AnnotationClearAll();
+
+    /**
+       Set the visibility for the annotations for a view
+    */
+    void AnnotationSetVisible(int visible);
+
+    /**
+       Get the visibility for the annotations for a view
+    */
+    int AnnotationGetVisible() const;
+
+    /**
+       Get the start of the range of style numbers used for annotations
+    */
+    void AnnotationSetStyleOffset(int style);
+
+    /**
+       Get the start of the range of style numbers used for annotations
+    */
+    int AnnotationGetStyleOffset() const;
+
+    /**
+       Add a container action to the undo stack
+    */
+    void AddUndoAction(int token, int flags);
+
+    /**
+       Find the position of a character from a point within the window.
+    */
+    int CharPositionFromPoint(int x, int y);
+
+    /**
+       Find the position of a character from a point within the window.
+       Return INVALID_POSITION if not close to text.
+    */
+    int CharPositionFromPointClose(int x, int y);
+
+    /**
+       Set whether multiple selections can be made
+    */
+    void SetMultipleSelection(bool multipleSelection);
+
+    /**
+       Whether multiple selections can be made
+    */
+    bool GetMultipleSelection() const;
+
+    /**
+       Set whether typing can be performed into multiple selections
+    */
+    void SetAdditionalSelectionTyping(bool additionalSelectionTyping);
+
+    /**
+       Whether typing can be performed into multiple selections
+    */
+    bool GetAdditionalSelectionTyping() const;
+
+    /**
+       Set whether additional carets will blink
+    */
+    void SetAdditionalCaretsBlink(bool additionalCaretsBlink);
+
+    /**
+       Whether additional carets will blink
+    */
+    bool GetAdditionalCaretsBlink() const;
+
+    /**
+       Set whether additional carets are visible
+    */
+    void SetAdditionalCaretsVisible(bool additionalCaretsBlink);
+
+    /**
+       Whether additional carets are visible
+    */
+    bool GetAdditionalCaretsVisible() const;
+
+    /**
+       How many selections are there?
+    */
+    int GetSelections() const;
+
+    /**
+       Clear selections to a single empty stream selection
+    */
+    void ClearSelections();
+
+    /**
+       Add a selection
+    */
+    int AddSelection(int caret, int anchor);
+
+    /**
+       Set the main selection
+    */
+    void SetMainSelection(int selection);
+
+    /**
+       Which selection is the main selection
+    */
+    int GetMainSelection() const;
+
+    void SetSelectionNCaret(int selection, int pos);
+    int GetSelectionNCaret(int selection) const;
+    void SetSelectionNAnchor(int selection, int posAnchor);
+    int GetSelectionNAnchor(int selection) const;
+    void SetSelectionNCaretVirtualSpace(int selection, int space);
+    int GetSelectionNCaretVirtualSpace(int selection) const;
+    void SetSelectionNAnchorVirtualSpace(int selection, int space);
+    int GetSelectionNAnchorVirtualSpace(int selection) const;
+
+    /**
+       Sets the position that starts the selection - this becomes the anchor.
+    */
+    void SetSelectionNStart(int selection, int pos);
+
+    /**
+       Returns the position at the start of the selection.
+    */
+    int GetSelectionNStart(int selection) const;
+
+    /**
+       Sets the position that ends the selection - this becomes the currentPosition.
+    */
+    void SetSelectionNEnd(int selection, int pos);
+
+    /**
+       Returns the position at the end of the selection.
+    */
+    int GetSelectionNEnd(int selection) const;
+    
+    void SetRectangularSelectionCaret(int pos);
+    int GetRectangularSelectionCaret() const;
+    void SetRectangularSelectionAnchor(int posAnchor);
+    int GetRectangularSelectionAnchor() const;
+    void SetRectangularSelectionCaretVirtualSpace(int space);
+    int GetRectangularSelectionCaretVirtualSpace() const;
+    void SetRectangularSelectionAnchorVirtualSpace(int space);
+    int GetRectangularSelectionAnchorVirtualSpace() const;
+    void SetVirtualSpaceOptions(int virtualSpaceOptions);
+    int GetVirtualSpaceOptions() const;
+
+    /**
+       Select the modifier key to use for mouse-based rectangular selection.
+    */
+    void SetRectangularSelectionModifier(int modifier);
+
+    /**
+       Get the modifier key used for rectangular selection.
+    */
+    int GetRectangularSelectionModifier() const;
+
+    /**
+       Set the foreground colour of additional selections.  Must have
+       previously called SetSelFore with non-zero first argument for this to
+       have an effect.
+    */
+    void SetAdditionalSelForeground(const wxColour& fore);
+
+    /**
+       Set the background colour of additional selections. Must have
+       previously called SetSelBack with non-zero first argument for this to
+       have an effect.
+    */
+    void SetAdditionalSelBackground(const wxColour& back);
+
+    /**
+       Set the alpha of the selection.
+    */
+    void SetAdditionalSelAlpha(int alpha);
+
+    /**
+       Get the alpha of the selection.
+    */
+    int GetAdditionalSelAlpha() const;
+
+    /**
+       Set the foreground colour of additional carets.
+    */
+    void SetAdditionalCaretForeground(const wxColour& fore);
+
+    /**
+       Get the foreground colour of additional carets.
+    */
+    wxColour GetAdditionalCaretForeground() const;
+
+    /**
+       Set the main selection to the next selection.
+    */
+    void RotateSelection();
+
+    /**
+       Swap that caret and anchor of the main selection.
+    */
+    void SwapMainAnchorCaret();
+    
 };
 
index df2fdf1530425631f5cabfe5392a64b6a23e4c48..777f19078931f1429a61afabf03e7a953ed6628b 100644 (file)
@@ -102,6 +102,7 @@ BEGIN_EVENT_TABLE (Edit, wxStyledTextCtrl)
     // stc
     EVT_STC_MARGINCLICK (wxID_ANY,     Edit::OnMarginClick)
     EVT_STC_CHARADDED (wxID_ANY,       Edit::OnCharAdded)
+    EVT_STC_KEY( wxID_ANY , Edit::OnKey )
 END_EVENT_TABLE()
 
 Edit::Edit (wxWindow *parent, wxWindowID id,
@@ -189,6 +190,11 @@ void Edit::OnEditClear (wxCommandEvent &WXUNUSED(event)) {
     Clear ();
 }
 
+void Edit::OnKey  (wxStyledTextEvent &event)
+{
+    wxMessageBox("OnKey");
+}
+
 void Edit::OnEditCut (wxCommandEvent &WXUNUSED(event)) {
     if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return;
     Cut ();
index 44e185ead93f1c74132e9268f30f0d10515af18c..780076d77a42c8e1ff9b6486d48f544c14aa6aa6 100644 (file)
@@ -97,6 +97,7 @@ public:
     // stc
     void OnMarginClick (wxStyledTextEvent &event);
     void OnCharAdded  (wxStyledTextEvent &event);
+    void OnKey  (wxStyledTextEvent &event);
 
     //! language/lexer
     wxString DeterminePrefs (const wxString &filename);
index e67ee6a67b738af3204f44ec06a53863b7b5a662..fdeecde22213c39396ba63c56681ab6372c2659d 100644 (file)
@@ -1275,7 +1275,7 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove)
 
     // NOTE: the wxWindow event handler list is always terminated with "this" handler
     wxEvtHandler *handlerCur = GetEventHandler()->GetNextHandler();
-    while ( handlerCur != this )
+    while ( handlerCur != this && handlerCur )
     {
         wxEvtHandler *handlerNext = handlerCur->GetNextHandler();
 
index 35a213e58dde3c1c246b6ac2ca6e2d6a72780e98..74e7aa46f1869b22bd5ba161457cd40075830c25 100644 (file)
@@ -141,6 +141,7 @@ STCDLL_OBJECTS =  \
        stcdll_PropSet.o \
        stcdll_RESearch.o \
        stcdll_ScintillaBase.o \
+        stcdll_Selection.o \
        stcdll_Style.o \
        stcdll_StyleContext.o \
        stcdll_UniConversion.o \
@@ -231,6 +232,7 @@ STCLIB_OBJECTS =  \
        stclib_PropSet.o \
        stclib_RESearch.o \
        stclib_ScintillaBase.o \
+        stcdll_Selection.o \
        stclib_Style.o \
        stclib_StyleContext.o \
        stclib_UniConversion.o \
@@ -661,6 +663,9 @@ stcdll_RESearch.o: $(srcdir)/scintilla/src/RESearch.cxx
 stcdll_ScintillaBase.o: $(srcdir)/scintilla/src/ScintillaBase.cxx
        $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/ScintillaBase.cxx
 
+stcdll_Selection.o: $(srcdir)/scintilla/src/Selction.cxx
+       $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/Selection.cxx
+
 stcdll_Style.o: $(srcdir)/scintilla/src/Style.cxx
        $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/Style.cxx
 
@@ -913,6 +918,9 @@ stclib_RESearch.o: $(srcdir)/scintilla/src/RESearch.cxx
 stclib_ScintillaBase.o: $(srcdir)/scintilla/src/ScintillaBase.cxx
        $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/ScintillaBase.cxx
 
+stclib_Selection.o: $(srcdir)/scintilla/src/Selection.cxx
+       $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/Selection.cxx
+
 stclib_Style.o: $(srcdir)/scintilla/src/Style.cxx
        $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/Style.cxx
 
index ac4c035126c6e7b8674a1f276d0c5d7ccc110ce0..fbc9ce00a387d8a374f7c43877f86a2073067368 100644 (file)
@@ -45,7 +45,6 @@
 #include "wx/stc/private.h"
 
 
-
 Point Point::FromLong(long lpoint) {
     return Point(lpoint & 0xFFFF, lpoint >> 16);
 }
@@ -142,7 +141,7 @@ void Palette::Allocate(Window &) {
 //----------------------------------------------------------------------
 
 Font::Font() {
-    id = 0;
+    fid = 0;
     ascent = 0;
 }
 
@@ -151,7 +150,7 @@ Font::~Font() {
 
 void Font::Create(const char *faceName, int characterSet,
                   int size, bool bold, bool italic,
-                  bool WXUNUSED(extraFontFlag)) {
+                  int WXUNUSED(extraFontFlag)) {
     Release();
 
     // The minus one is done because since Scintilla uses SC_SHARSET_DEFAULT
@@ -171,14 +170,14 @@ void Font::Create(const char *faceName, int characterSet,
                     false,
                     stc2wx(faceName),
                     encoding);
-    id = font;
+    fid = font;
 }
 
 
 void Font::Release() {
-    if (id)
-        delete (wxFont*)id;
-    id = 0;
+    if (fid)
+        delete (wxFont*)fid;
+    fid = 0;
 }
 
 //----------------------------------------------------------------------
@@ -648,26 +647,26 @@ Window::~Window() {
 }
 
 void Window::Destroy() {
-    if (id) {
+    if (wid) {
         Show(false);
-        GETWIN(id)->Destroy();
+        GETWIN(wid)->Destroy();
     }
-    id = 0;
+    wid = 0;
 }
 
 bool Window::HasFocus() {
-    return wxWindow::FindFocus() == GETWIN(id);
+    return wxWindow::FindFocus() == GETWIN(wid);
 }
 
 PRectangle Window::GetPosition() {
-    if (! id) return PRectangle();
-    wxRect rc(GETWIN(id)->GetPosition(), GETWIN(id)->GetSize());
+    if (! wid) return PRectangle();
+    wxRect rc(GETWIN(wid)->GetPosition(), GETWIN(wid)->GetSize());
     return PRectangleFromwxRect(rc);
 }
 
 void Window::SetPosition(PRectangle rc) {
     wxRect r = wxRectFromPRectangle(rc);
-    GETWIN(id)->SetSize(r);
+    GETWIN(wid)->SetSize(r);
 }
 
 void Window::SetPositionRelative(PRectangle rc, Window) {
@@ -675,26 +674,26 @@ void Window::SetPositionRelative(PRectangle rc, Window) {
 }
 
 PRectangle Window::GetClientPosition() {
-    if (! id) return PRectangle();
-    wxSize sz = GETWIN(id)->GetClientSize();
+    if (! wid) return PRectangle();
+    wxSize sz = GETWIN(wid)->GetClientSize();
     return  PRectangle(0, 0, sz.x, sz.y);
 }
 
 void Window::Show(bool show) {
-    GETWIN(id)->Show(show);
+    GETWIN(wid)->Show(show);
 }
 
 void Window::InvalidateAll() {
-    GETWIN(id)->Refresh(false);
+    GETWIN(wid)->Refresh(false);
 }
 
 void Window::InvalidateRectangle(PRectangle rc) {
     wxRect r = wxRectFromPRectangle(rc);
-    GETWIN(id)->Refresh(false, &r);
+    GETWIN(wid)->Refresh(false, &r);
 }
 
 void Window::SetFont(Font &font) {
-    GETWIN(id)->SetFont(*((wxFont*)font.GetID()));
+    GETWIN(wid)->SetFont(*((wxFont*)font.GetID()));
 }
 
 void Window::SetCursor(Cursor curs) {
@@ -733,21 +732,21 @@ void Window::SetCursor(Cursor curs) {
     wxCursor wc = wxCursor(cursorId);
     if(curs != cursorLast)
     {
-        GETWIN(id)->SetCursor(wc);
+        GETWIN(wid)->SetCursor(wc);
         cursorLast = curs;
     }
 }
 
 
 void Window::SetTitle(const char *s) {
-    GETWIN(id)->SetLabel(stc2wx(s));
+    GETWIN(wid)->SetLabel(stc2wx(s));
 }
 
 
 // Returns rectangle of monitor pt is on
 PRectangle Window::GetMonitorRect(Point pt) {
     wxRect rect;
-    if (! id) return PRectangle();
+    if (! wid) return PRectangle();
 #if wxUSE_DISPLAY
     // Get the display the point is found on
     int n = wxDisplay::GetFromPoint(wxPoint(pt.x, pt.y));
@@ -823,15 +822,6 @@ END_EVENT_TABLE()
 #if wxUSE_POPUPWIN //-----------------------------------
 #include "wx/popupwin.h"
 
-
-//
-// TODO: Refactor these two classes to have a common base (or a mix-in) to get
-// rid of the code duplication.  (Either that or convince somebody to
-// implement wxPopupWindow for the Mac!!)
-//
-// In the meantime, be careful to duplicate any changes as needed...
-//
-
 // A popup window to place the wxSTCListBox upon
 class wxSTCListBoxWin : public wxPopupWindow
 {
@@ -841,11 +831,9 @@ private:
     void*               doubleClickActionData;
 public:
     wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point WXUNUSED(location)) :
-        wxPopupWindow(parent, wxBORDER_NONE)
+        wxPopupWindow(parent, wxBORDER_SIMPLE)
     {
 
-        SetBackgroundColour(*wxBLACK);  // for our simple border
-
         lv = new wxSTCListBox(parent, id, wxPoint(-50,-50), wxDefaultSize,
                               wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxBORDER_NONE);
         lv->SetCursor(wxCursor(wxCURSOR_ARROW));
@@ -919,11 +907,9 @@ public:
     }
 
     void OnSize(wxSizeEvent& event) {
-        // resize the child
-        wxSize sz = GetSize();
-        sz.x -= 2;
-        sz.y -= 2;
-        lv->SetSize(1, 1, sz.x, sz.y);
+        // resize the child to fill the popup
+        wxSize sz = GetClientSize();
+        lv->SetSize(0, 0, sz.x, sz.y);
         // reset the column widths
         lv->SetColumnWidth(0, IconWidth()+4);
         lv->SetColumnWidth(1, sz.x - 2 - lv->GetColumnWidth(0) -
@@ -1170,7 +1156,7 @@ ListBoxImpl::~ListBoxImpl() {
 
 
 void ListBoxImpl::SetFont(Font &font) {
-    GETLB(id)->SetFont(*((wxFont*)font.GetID()));
+    GETLB(wid)->SetFont(*((wxFont*)font.GetID()));
 }
 
 
@@ -1179,9 +1165,9 @@ void ListBoxImpl::Create(Window &parent, int ctrlID, Point location_, int lineHe
     lineHeight =  lineHeight_;
     unicodeMode = unicodeMode_;
     maxStrWidth = 0;
-    id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID, location);
+    wid = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID, location);
     if (imgList != NULL)
-        GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
+        GETLB(wid)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
 }
 
 
@@ -1208,15 +1194,15 @@ PRectangle ListBoxImpl::GetDesiredRect() {
     // 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);
+            GETLBW(wid)->IconWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
     if (maxw > 350)
         maxw = 350;
 
     // estimate a desired height
-    int count = GETLB(id)->GetItemCount();
+    int count = GETLB(wid)->GetItemCount();
     if (count) {
         wxRect rect;
-        GETLB(id)->GetItemRect(0, rect);
+        GETLB(wid)->GetItemRect(0, rect);
         maxh = count * rect.GetHeight();
         if (maxh > 140)  // TODO:  Use desiredVisibleRows??
             maxh = 140;
@@ -1238,12 +1224,12 @@ PRectangle ListBoxImpl::GetDesiredRect() {
 
 
 int ListBoxImpl::CaretFromEdge() {
-    return 4 + GETLBW(id)->IconWidth();
+    return 4 + GETLBW(wid)->IconWidth();
 }
 
 
 void ListBoxImpl::Clear() {
-    GETLB(id)->DeleteAllItems();
+    GETLB(wid)->DeleteAllItems();
 }
 
 
@@ -1252,20 +1238,20 @@ void ListBoxImpl::Append(char *s, int type) {
 }
 
 void ListBoxImpl::Append(const wxString& text, int type) {
-    long count  = GETLB(id)->GetItemCount();
-    long itemID  = GETLB(id)->InsertItem(count, wxEmptyString);
+    long count  = GETLB(wid)->GetItemCount();
+    long itemID  = GETLB(wid)->InsertItem(count, wxEmptyString);
     long idx = -1;
-    GETLB(id)->SetItem(itemID, 1, text);
+    GETLB(wid)->SetItem(itemID, 1, text);
     maxStrWidth = wxMax(maxStrWidth, text.length());
     if (type != -1) {
         wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
         idx = imgTypeMap->Item(type);
     }
-    GETLB(id)->SetItemImage(itemID, idx, idx);
+    GETLB(wid)->SetItemImage(itemID, idx, idx);
 }
 
 void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
-    GETLB(id)->Freeze();
+    GETLB(wid)->Freeze();
     Clear();
     wxStringTokenizer tkzr(stc2wx(list), (wxChar)separator);
     while ( tkzr.HasMoreTokens() ) {
@@ -1278,12 +1264,12 @@ void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
         }
         Append(token, (int)type);
     }
-    GETLB(id)->Thaw();
+    GETLB(wid)->Thaw();
 }
 
 
 int ListBoxImpl::Length() {
-    return GETLB(id)->GetItemCount();
+    return GETLB(wid)->GetItemCount();
 }
 
 
@@ -1293,13 +1279,13 @@ void ListBoxImpl::Select(int n) {
         n = 0;
         select = false;
     }
-    GETLB(id)->EnsureVisible(n);
-    GETLB(id)->Select(n, select);
+    GETLB(wid)->EnsureVisible(n);
+    GETLB(wid)->Select(n, select);
 }
 
 
 int ListBoxImpl::GetSelection() {
-    return GETLB(id)->GetFirstSelected();
+    return GETLB(wid)->GetFirstSelected();
 }
 
 
@@ -1314,7 +1300,7 @@ void ListBoxImpl::GetValue(int n, char *value, int len) {
     item.SetId(n);
     item.SetColumn(1);
     item.SetMask(wxLIST_MASK_TEXT);
-    GETLB(id)->GetItem(item);
+    GETLB(wid)->GetItem(item);
     strncpy(value, wx2stc(item.GetText()), len);
     value[len-1] = '\0';
 }
@@ -1351,13 +1337,13 @@ void ListBoxImpl::ClearRegisteredImages() {
         delete imgTypeMap;
         imgTypeMap = NULL;
     }
-    if (id)
-        GETLB(id)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
+    if (wid)
+        GETLB(wid)->SetImageList(NULL, wxIMAGE_LIST_SMALL);
 }
 
 
 void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) {
-    GETLBW(id)->SetDoubleClickAction(action, data);
+    GETLBW(wid)->SetDoubleClickAction(action, data);
 }
 
 
@@ -1373,22 +1359,22 @@ ListBox *ListBox::Allocate() {
 
 //----------------------------------------------------------------------
 
-Menu::Menu() : id(0) {
+Menu::Menu() : mid(0) {
 }
 
 void Menu::CreatePopUp() {
     Destroy();
-    id = new wxMenu();
+    mid = new wxMenu();
 }
 
 void Menu::Destroy() {
-    if (id)
-        delete (wxMenu*)id;
-    id = 0;
+    if (mid)
+        delete (wxMenu*)mid;
+    mid = 0;
 }
 
 void Menu::Show(Point pt, Window &w) {
-    GETWIN(w.GetID())->PopupMenu((wxMenu*)id, pt.x - 4, pt.y);
+    GETWIN(w.GetID())->PopupMenu((wxMenu*)mid, pt.x - 4, pt.y);
     Destroy();
 }
 
index 0f9a5281ab967649f50a8625af41d8da0a4451f7..0850bcbcedc11fa8be37bb795c55bce0b788f6fd 100644 (file)
@@ -301,7 +301,7 @@ void ScintillaWX::StartDrag() {
         if (result == wxDragMove && dropWentOutside)
             ClearSelection();
         inDragDrop = ddNone;
-        SetDragPosition(invalidPosition);
+        SetDragPosition(SelectionPosition(invalidPosition));
     }
 #endif // wxUSE_DRAG_AND_DROP
 }
@@ -472,7 +472,7 @@ void ScintillaWX::CancelModes() {
 
 
 void ScintillaWX::Copy() {
-    if (currentPos != anchor) {
+    if (!sel.Empty()) {
         SelectionText st;
         CopySelectionRange(&st);
         CopyToClipboard(st);
@@ -504,8 +504,9 @@ void ScintillaWX::Paste() {
         text = wxEmptyString;
 #endif
         int len = strlen(buf);
-        pdoc->InsertString(currentPos, buf, len);
-        SetEmptySelection(currentPos + len);
+        int caretMain = sel.MainCaret();
+        pdoc->InsertString(caretMain, buf, len);
+        SetEmptySelection(caretMain + len);
     }
 #endif // wxUSE_DATAOBJ
 
@@ -580,7 +581,7 @@ void ScintillaWX::AddToPopUp(const char *label, int cmd, bool enabled) {
 void ScintillaWX::ClaimSelection() {
 #ifdef __WXGTK__
     // Put the selected text in the PRIMARY selection
-    if (currentPos != anchor) {
+    if (!sel.Empty()) {
         SelectionText st;
         CopySelectionRange(&st);
         wxTheClipboard->UsePrimarySelection(true);
@@ -602,7 +603,7 @@ void ScintillaWX::UpdateSystemCaret() {
             DestroySystemCaret();
             CreateSystemCaret();
         }
-        Point pos = LocationFromPosition(currentPos);
+        Point pos = PointMainCaret();
         ::SetCaretPos(pos.x, pos.y);
     }
 #endif
@@ -679,7 +680,8 @@ sptr_t ScintillaWX::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam)
           {
               ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
           }
-          PRectangle rc = ct.CallTipStart(currentPos, pt,
+          int caretMain = sel.MainCaret();
+          PRectangle rc = ct.CallTipStart(caretMain, pt,
                                           defn,
                                           vs.styles[ctStyle].fontName,
                                           vs.styles[ctStyle].sizeZoomed,
@@ -862,7 +864,7 @@ void ScintillaWX::DoMiddleButtonUp(Point pt) {
     // Set the current position to the mouse click point and
     // then paste in the PRIMARY selection, if any.  wxGTK only.
     int newPos = PositionFromLocation(pt);
-    MovePositionTo(newPos, noSel, true);
+    MovePositionTo(newPos, Selection::noSel, true);
 
     pdoc->BeginUndoAction();
     wxTextDataObject data;
@@ -878,8 +880,9 @@ void ScintillaWX::DoMiddleButtonUp(Point pt) {
                                                   wxConvertEOLMode(pdoc->eolMode));
         wxWX2MBbuf buf = (wxWX2MBbuf)wx2stc(text);
         int        len = strlen(buf);
-        pdoc->InsertString(currentPos, buf, len);
-        SetEmptySelection(currentPos + len);
+        int caretMain = sel.MainCaret();
+        pdoc->InsertString(caretMain, buf, len);
+        SetEmptySelection(caretMain + len);
     }
     pdoc->EndUndoAction();
     NotifyChange();
@@ -1007,7 +1010,7 @@ void ScintillaWX::DoOnIdle(wxIdleEvent& evt) {
 
 #if wxUSE_DRAG_AND_DROP
 bool ScintillaWX::DoDropText(long x, long y, const wxString& data) {
-    SetDragPosition(invalidPosition);
+    SetDragPosition(SelectionPosition(invalidPosition));
 
     wxString text = wxTextBuffer::Translate(data,
                                             wxConvertEOLMode(pdoc->eolMode));
@@ -1024,7 +1027,7 @@ bool ScintillaWX::DoDropText(long x, long y, const wxString& data) {
 
     dragResult = evt.GetDragResult();
     if (dragResult == wxDragMove || dragResult == wxDragCopy) {
-        DropAt(evt.GetPosition(),
+        DropAt(SelectionPosition(evt.GetPosition()),
                wx2stc(evt.GetDragText()),
                dragResult == wxDragMove,
                false); // TODO: rectangular?
@@ -1041,7 +1044,7 @@ wxDragResult ScintillaWX::DoDragEnter(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
 
 
 wxDragResult ScintillaWX::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) {
-    SetDragPosition(PositionFromLocation(Point(x, y)));
+    SetDragPosition(SelectionPosition(PositionFromLocation(Point(x, y))));
 
     // Send an event to allow the drag result to be changed
     wxStyledTextEvent evt(wxEVT_STC_DRAG_OVER, stc->GetId());
@@ -1058,7 +1061,7 @@ wxDragResult ScintillaWX::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) {
 
 
 void ScintillaWX::DoDragLeave() {
-    SetDragPosition(invalidPosition);
+    SetDragPosition(SelectionPosition(invalidPosition));
 }
 #endif // wxUSE_DRAG_AND_DROP
 //----------------------------------------------------------------------
index d74ea4a0d72663463ec47e47fcc644eb651ba20c..ae27a5d50047a3a88152e78c03cd845ac756c1fd 100644 (file)
 #include <string.h>
 
 #include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
-
+#include "SplitVector.h"
+#include "Partitioning.h"
+#include "RunStyles.h"
 #include "Scintilla.h"
-#include "CharClassify.h"
-#include "XPM.h"
+#include "ScintillaWidget.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
 #endif
-#include "SplitVector.h"
-#include "Partitioning.h"
-#include "RunStyles.h"
 #include "ContractionState.h"
+#include "SVector.h"
 #include "CellBuffer.h"
 #include "CallTip.h"
 #include "KeyMap.h"
 #include "Indicator.h"
+#include "XPM.h"
 #include "LineMarker.h"
 #include "Style.h"
-#include "ViewStyle.h"
 #include "AutoComplete.h"
+#include "ViewStyle.h"
+#include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 #include "Editor.h"
+#include "PropSetSimple.h"
 #include "ScintillaBase.h"
 
 #ifdef __WXMSW__
index 54efef00db1bf0f4840ec94d8556423e64d3837e..8fddb97722086ead377df4f7c72ac46a2b997344 100755 (executable)
@@ -21,7 +21,10 @@ H_TEMPLATE    = os.path.abspath('./stc.h.in')
 CPP_TEMPLATE  = os.path.abspath('./stc.cpp.in')
 H_DEST        = os.path.abspath('../../include/wx/stc/stc.h')
 CPP_DEST      = os.path.abspath('./stc.cpp')
-DOCSTR_DEST   = '/dev/null' #os.path.abspath('../../../wxPython/contrib/stc/_stc_gendocs.i')
+if len(sys.argv) > 1 and sys.argv[1] == '--wxpython':
+    DOCSTR_DEST   = os.path.abspath('../../../wxPython/src/_stc_gendocs.i')
+else:
+    DOCSTR_DEST   = '/dev/null'
 
 
 # Value prefixes to convert
@@ -29,6 +32,7 @@ valPrefixes = [('SCI_', ''),
                ('SC_',  ''),
                ('SCN_', None),  # just toss these out...
                ('SCEN_', None),
+               ('SC_EFF', None),
                ('SCE_', ''),
                ('SCLEX_', 'LEX_'),
                ('SCK_', 'KEY_'),
@@ -177,6 +181,8 @@ methodOverrideMap = {
     'MarkerSetFore' : ('MarkerSetForeground', 0, 0, 0),
     'MarkerSetBack' : ('MarkerSetBackground', 0, 0, 0),
 
+    'MarkerSymbolDefined' : ('GetMarkerSymbolDefined', 0, 0, 0),
+
     'MarkerDefine' :
     (0,
      '''void %s(int markerNumber, int markerSymbol,
@@ -226,6 +232,74 @@ methodOverrideMap = {
     'SetMarginSensitiveN' : ('SetMarginSensitive', 0, 0, 0),
     'GetMarginSensitiveN' : ('GetMarginSensitive', 0, 0, 0),
 
+    'MarginGetText' :
+    (0,
+    'wxString %s(int line) const;',
+
+     '''wxString %s(int line) const {
+         long msg = %s;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+     0),
+     
+     'MarginGetStyles' :
+     (0,
+    'wxString %s(int line) const;',
+
+     '''wxString %s(int line) const {
+         long msg = %s;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+     0),
+
+    'SetAdditionalSelFore' : ('SetAdditionalSelForeground', 0, 0, 0),
+    'SetAdditionalSelBack' : ('SetAdditionalSelBackground', 0, 0, 0),
+    'SetAdditionalCaretFore' : ('SetAdditionalCaretForeground', 0, 0, 0),
+    'GetAdditionalCaretFore' : ('GetAdditionalCaretForeground', 0, 0, 0),
+
+    'AnnotationGetText' :
+    (0,
+    'wxString %s(int line) const;',
+
+     '''wxString %s(int line) const {
+         long msg = %s;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+     0),
+
+    'AnnotationGetStyles' :
+    (0,
+    'wxString %s(int line) const;',
+
+     '''wxString %s(int line) const {
+         long msg = %s;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);''',
+     0),
 
     'StyleGetFore' : ('StyleGetForeground', 0, 0, 0),
     'StyleGetBack' : ('StyleGetBackground', 0, 0, 0),
@@ -279,6 +353,8 @@ methodOverrideMap = {
      0),
 
 
+    'IndicSetAlpha' : ('IndicatorSetAlpha', 0, 0, 0),
+    'IndicGetAlpha' : ('IndicatorGetAlpha', 0, 0, 0),
     'IndicSetStyle' : ('IndicatorSetStyle', 0, 0, 0),
     'IndicGetStyle' : ('IndicatorGetStyle', 0, 0, 0),
     'IndicSetFore' : ('IndicatorSetForeground', 0, 0, 0),
@@ -312,6 +388,7 @@ methodOverrideMap = {
     'AutoCGetTypeSeparator' : ('AutoCompGetTypeSeparator', 0, 0, 0),
     'AutoCSetTypeSeparator' : ('AutoCompSetTypeSeparator', 0, 0, 0),
     'AutoCGetCurrent'       : ('AutoCompGetCurrent', 0, 0, 0),
+    'AutoCGetCurrentText'   : (None, 0, 0, 0),
     'AutoCSetMaxWidth'      : ('AutoCompSetMaxWidth', 0, 0, 0),
     'AutoCGetMaxWidth'      : ('AutoCompGetMaxWidth', 0, 0, 0),
     'AutoCSetMaxHeight'     : ('AutoCompSetMaxHeight', 0, 0, 0),
@@ -650,6 +727,17 @@ methodOverrideMap = {
     'SetPositionCache' : ('SetPositionCacheSize', 0, 0, 0),
     'GetPositionCache' : ('GetPositionCacheSize', 0, 0, 0),
 
+    'GetLexerLanguage' : (None, 0, 0, 0),
+    'SetFontQuality' : (None, 0, 0, 0),
+    'GetFontQuality' : (None, 0, 0, 0),
+    'SetSelection' : (None, 0, 0, 0),
+
+    'GetCharacterPointer' : (0,
+                             'const char* %s();',
+                             'const char* %s() {\n'
+                             '    return (const char*)SendMsg(%s, 0, 0);',
+                             0),
+    
 
     '' : ('', 0, 0, 0),
 
@@ -889,7 +977,7 @@ funregex = re.compile(r'\s*([a-zA-Z0-9_]+)'  # <ws>return type
                       '\s+([a-zA-Z0-9_]+)='  # <ws>name=
                       '([0-9]+)'             # number
                       '\(([ a-zA-Z0-9_]*),'  # (param,
-                      '([ a-zA-Z0-9_]*)\)')  # param)
+                      '([ a-zA-Z0-9_]*),*\)')  # param)
 
 def parseFun(line, methods, docs, values, is_const):
     def parseParam(param):
index 13390ddda6ed44297645893197d90862f21dda93..27a2157fefb691b7e4f813ea7af517c12bdddb92 100644 (file)
@@ -1,7 +1,7 @@
 This directory contains copies of the scintilla/src and
-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.
+scintilla/include directories from the Scintilla source distribution.
+All other code needed to implement Scintilla on top of wxWidgets is
+located in the directory above this one.
 
-The current version of the Scintilla code is 1.75
+The current version of the Scintilla code is 2.03
 
index 6abae594538d22399d268f55044a9fcfea48fd93..5593b7d091ae3241901be36467acd0f71c96088a 100644 (file)
@@ -9,6 +9,29 @@
 namespace Scintilla {
 #endif
 
+/**
+ */
+class WordList {
+public:
+       // Each word contains at least one character - a empty word acts as sentinel at the end.
+       char **words;
+       char *list;
+       int len;
+       bool onlyLineEnds;      ///< Delimited by any white space or only line ends
+       bool sorted;
+       int starts[256];
+       WordList(bool onlyLineEnds_ = false) :
+               words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
+               sorted(false)
+               {}
+       ~WordList() { Clear(); }
+       operator bool() { return len ? true : false; }
+       void Clear();
+       void Set(const char *s);
+       bool InList(const char *s);
+       bool InListAbbreviated(const char *s, const char marker);
+};
+
 typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
                   WordList *keywordlists[], Accessor &styler);
                   
index 79be33f6bae81d8de4e04d5d30040f6b06280e30..b5d6d9bf8d4b543eaebcd364072bf52b05fa5221 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-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef PLATFORM_H
 #undef PLAT_GTK
 #define PLAT_GTK 1
 
-#ifdef _MSC_VER
+#if defined(__WIN32__) || defined(_MSC_VER)
 #undef PLAT_GTK_WIN32
 #define PLAT_GTK_WIN32 1
 #endif
 
-#elif defined(MACOSX)
+#elif defined(__APPLE__)
+
 #undef PLAT_MACOSX
 #define PLAT_MACOSX 1
 
@@ -122,7 +123,7 @@ public:
        }
        int Width() { return right - left; }
        int Height() { return bottom - top; }
-       bool Empty() { 
+       bool Empty() {
                return (Height() <= 0) || (Width() <= 0);
        }
 };
@@ -282,24 +283,24 @@ public:
  */
 class Font {
 protected:
-       FontID id;
+       FontID fid;
 #if PLAT_WX
        int ascent;
 #endif
        // Private so Font objects can not be copied
        Font(const Font &) {}
-       Font &operator=(const Font &) { id=0; return *this; }
+       Font &operator=(const Font &) { fid=0; return *this; }
 public:
        Font();
        virtual ~Font();
 
        virtual void Create(const char *faceName, int characterSet, int size,
-               bool bold, bool italic, bool extraFontFlag=false);
+               bool bold, bool italic, int extraFontFlag=0);
        virtual void Release();
 
-       FontID GetID() { return id; }
+       FontID GetID() { return fid; }
        // Alias another font - caller guarantees not to Release
-       void SetID(FontID id_) { id = id_; }
+       void SetID(FontID fid_) { fid = fid_; }
        friend class Surface;
         friend class SurfaceImpl;
 };
@@ -370,31 +371,31 @@ typedef void (*CallBackAction)(void*);
  */
 class Window {
 protected:
-       WindowID id;
+       WindowID wid;
 #if PLAT_MACOSX
        void *windowRef;
        void *control;
 #endif
 public:
-       Window() : id(0), cursorLast(cursorInvalid) {
+       Window() : wid(0), cursorLast(cursorInvalid) {
 #if PLAT_MACOSX
          windowRef = 0;
          control = 0;
 #endif
        }
-       Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {
+       Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
 #if PLAT_MACOSX
          windowRef = 0;
          control = 0;
 #endif
        }
        virtual ~Window();
-       Window &operator=(WindowID id_) {
-               id = id_;
+       Window &operator=(WindowID wid_) {
+               wid = wid_;
                return *this;
        }
-       WindowID GetID() const { return id; }
-       bool Created() const { return id != 0; }
+       WindowID GetID() const { return wid; }
+       bool Created() const { return wid != 0; }
        void Destroy();
        bool HasFocus();
        PRectangle GetPosition();
@@ -451,10 +452,10 @@ public:
  * Menu management.
  */
 class Menu {
-       MenuID id;
+       MenuID mid;
 public:
        Menu();
-       MenuID GetID() { return id; }
+       MenuID GetID() { return mid; }
        void CreatePopUp();
        void Destroy();
        void Show(Point pt, Window &w);
index 91bc7072ba68d46b2847261e37724e4b72c015aa..c95202174f29bdbf96841ded89cfb4ccd9f62f35 100644 (file)
 // Scintilla source code edit control
 /** @file PropSet.h
- ** A Java style properties file module.
+ ** An interface to the methods needed for access to property sets inside lexers.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef PROPSET_H
 #define PROPSET_H
-#include "SString.h"
-
-bool EqualCaseInsensitive(const char *a, const char *b);
-
-bool isprefix(const char *target, const char *prefix);
 
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
 
-struct Property {
-       unsigned int hash;
-       char *key;
-       char *val;
-       Property *next;
-       Property() : hash(0), key(0), val(0), next(0) {}
-};
-
-/**
- */
-class PropSet {
-protected:
-       enum { hashRoots=31 };
-       Property *props[hashRoots];
-       Property *enumnext;
-       int enumhash;
-       static unsigned int HashString(const char *s, size_t len) {
-               unsigned int ret = 0;
-               while (len--) {
-                       ret <<= 4;
-                       ret ^= *s;
-                       s++;
-               }
-               return ret;
-       }
-
+class PropertyGet {
 public:
-       PropSet *superPS;
-       PropSet();
-       ~PropSet();
-       void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
-       void Set(const char *keyVal);
-       void Unset(const char *key, int lenKey=-1);
-       void SetMultiple(const char *s);
-       SString Get(const char *key) const;
-       SString GetExpanded(const char *key) const;
-       SString Expand(const char *withVars, int maxExpands=100) const;
-       int GetInt(const char *key, int defaultValue=0) const;
-       void Clear();
-       char *ToString() const; // Caller must delete[] the return value
-
-private:
-       // copy-value semantics not implemented
-       PropSet(const PropSet &copy);
-       void operator=(const PropSet &assign);
+       virtual char *ToString() const=0;       // Caller must delete[] the return value
+       virtual int GetInt(const char *key, int defaultValue=0) const=0;
+       virtual ~PropertyGet() {}
 };
 
-/**
- */
-class WordList {
-public:
-       // Each word contains at least one character - a empty word acts as sentinel at the end.
-       char **words;
-       char *list;
-       int len;
-       bool onlyLineEnds;      ///< Delimited by any white space or only line ends
-       bool sorted;
-       int starts[256];
-       WordList(bool onlyLineEnds_ = false) :
-               words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
-               sorted(false)
-               {}
-       ~WordList() { Clear(); }
-       operator bool() { return len ? true : false; }
-       void Clear();
-       void Set(const char *s);
-       bool InList(const char *s);
-       bool InListAbbreviated(const char *s, const char marker);
-};
-
-inline bool IsAlphabetic(unsigned int ch) {
-       return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'));
-}
-
 #ifdef SCI_NAMESPACE
 }
 #endif
 
-#ifdef _MSC_VER
-// Visual C++ doesn't like the private copy idiom for disabling
-// the default copy constructor and operator=, but it's fine.
-#pragma warning(disable: 4511 4512)
-#endif
-
 #endif
index 2354aa87656dd2041d19c5aaa044985bf6cd1c60..ced86f4339b3601a47ab0c974ec356b489a7d7d2 100644 (file)
@@ -1,19 +1,19 @@
-// Scintilla source code edit control
+/* Scintilla source code edit control */
 /** @file SciLexer.h
  ** Interface to the added lexer functions in the SciLexer version of the edit control.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/* Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+ * The License.txt file describes the conditions under which this software may be distributed. */
 
-// Most of this file is automatically generated from the Scintilla.iface interface definition
-// file which contains any comments about the definitions. HFacer.py does the generation.
+/* Most of this file is automatically generated from the Scintilla.iface interface definition
+ * file which contains any comments about the definitions. HFacer.py does the generation. */
 
 #ifndef SCILEXER_H
 #define SCILEXER_H
 
-// SciLexer features - not in standard Scintilla
+/* SciLexer features - not in standard Scintilla */
 
-//++Autogenerated -- start of section automatically generated from Scintilla.iface
+/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
 #define SCLEX_CONTAINER 0
 #define SCLEX_NULL 1
 #define SCLEX_PYTHON 2
 #define SCLEX_ABAQUS 84
 #define SCLEX_ASYMPTOTE 85
 #define SCLEX_R 86
+#define SCLEX_MAGIK 87
+#define SCLEX_POWERSHELL 88
+#define SCLEX_MYSQL 89
+#define SCLEX_PO 90
+#define SCLEX_TAL 91
+#define SCLEX_COBOL 92
+#define SCLEX_TACL 93
+#define SCLEX_SORCUS 94
+#define SCLEX_POWERPRO 95
+#define SCLEX_NIMROD 96
+#define SCLEX_SML 97
+#define SCLEX_MARKDOWN 98
 #define SCLEX_AUTOMATIC 1000
 #define SCE_P_DEFAULT 0
 #define SCE_P_COMMENTLINE 1
 #define SCE_D_COMMENTLINEDOC 15
 #define SCE_D_COMMENTDOCKEYWORD 16
 #define SCE_D_COMMENTDOCKEYWORDERROR 17
+#define SCE_D_STRINGB 18
+#define SCE_D_STRINGR 19
+#define SCE_D_WORD5 20
+#define SCE_D_WORD6 21
+#define SCE_D_WORD7 22
 #define SCE_TCL_DEFAULT 0
 #define SCE_TCL_COMMENT 1
 #define SCE_TCL_COMMENTLINE 2
 #define SCE_DIFF_POSITION 4
 #define SCE_DIFF_DELETED 5
 #define SCE_DIFF_ADDED 6
+#define SCE_DIFF_CHANGED 7
 #define SCE_CONF_DEFAULT 0
 #define SCE_CONF_COMMENT 1
 #define SCE_CONF_NUMBER 2
 #define SCE_CSS_SINGLESTRING 14
 #define SCE_CSS_IDENTIFIER2 15
 #define SCE_CSS_ATTRIBUTE 16
+#define SCE_CSS_IDENTIFIER3 17
+#define SCE_CSS_PSEUDOELEMENT 18
+#define SCE_CSS_EXTENDED_IDENTIFIER 19
+#define SCE_CSS_EXTENDED_PSEUDOCLASS 20
+#define SCE_CSS_EXTENDED_PSEUDOELEMENT 21
 #define SCE_POV_DEFAULT 0
 #define SCE_POV_COMMENT 1
 #define SCE_POV_COMMENTLINE 2
 #define SCE_ERLANG_CHARACTER 9
 #define SCE_ERLANG_MACRO 10
 #define SCE_ERLANG_RECORD 11
-#define SCE_ERLANG_SEPARATOR 12
+#define SCE_ERLANG_PREPROC 12
 #define SCE_ERLANG_NODE_NAME 13
+#define SCE_ERLANG_COMMENT_FUNCTION 14
+#define SCE_ERLANG_COMMENT_MODULE 15
+#define SCE_ERLANG_COMMENT_DOC 16
+#define SCE_ERLANG_COMMENT_DOC_MACRO 17
+#define SCE_ERLANG_ATOM_QUOTED 18
+#define SCE_ERLANG_MACRO_QUOTED 19
+#define SCE_ERLANG_RECORD_QUOTED 20
+#define SCE_ERLANG_NODE_NAME_QUOTED 21
+#define SCE_ERLANG_BIFS 22
+#define SCE_ERLANG_MODULES 23
+#define SCE_ERLANG_MODULES_ATT 24
 #define SCE_ERLANG_UNKNOWN 31
 #define SCE_MSSQL_DEFAULT 0
 #define SCE_MSSQL_COMMENT 1
 #define SCE_CAML_OPERATOR 7
 #define SCE_CAML_NUMBER 8
 #define SCE_CAML_CHAR 9
+#define SCE_CAML_WHITE 10
 #define SCE_CAML_STRING 11
 #define SCE_CAML_COMMENT 12
 #define SCE_CAML_COMMENT1 13
 #define SCE_INNO_PARAMETER 3
 #define SCE_INNO_SECTION 4
 #define SCE_INNO_PREPROC 5
-#define SCE_INNO_PREPROC_INLINE 6
+#define SCE_INNO_INLINE_EXPANSION 6
 #define SCE_INNO_COMMENT_PASCAL 7
 #define SCE_INNO_KEYWORD_PASCAL 8
 #define SCE_INNO_KEYWORD_USER 9
 #define SCE_R_IDENTIFIER 9
 #define SCE_R_INFIX 10
 #define SCE_R_INFIXEOL 11
-#define SCLEX_ASP 29
-#define SCLEX_PHP 30
-//--Autogenerated -- end of section automatically generated from Scintilla.iface
+#define SCE_MAGIK_DEFAULT 0
+#define SCE_MAGIK_COMMENT 1
+#define SCE_MAGIK_HYPER_COMMENT 16
+#define SCE_MAGIK_STRING 2
+#define SCE_MAGIK_CHARACTER 3
+#define SCE_MAGIK_NUMBER 4
+#define SCE_MAGIK_IDENTIFIER 5
+#define SCE_MAGIK_OPERATOR 6
+#define SCE_MAGIK_FLOW 7
+#define SCE_MAGIK_CONTAINER 8
+#define SCE_MAGIK_BRACKET_BLOCK 9
+#define SCE_MAGIK_BRACE_BLOCK 10
+#define SCE_MAGIK_SQBRACKET_BLOCK 11
+#define SCE_MAGIK_UNKNOWN_KEYWORD 12
+#define SCE_MAGIK_KEYWORD 13
+#define SCE_MAGIK_PRAGMA 14
+#define SCE_MAGIK_SYMBOL 15
+#define SCE_POWERSHELL_DEFAULT 0
+#define SCE_POWERSHELL_COMMENT 1
+#define SCE_POWERSHELL_STRING 2
+#define SCE_POWERSHELL_CHARACTER 3
+#define SCE_POWERSHELL_NUMBER 4
+#define SCE_POWERSHELL_VARIABLE 5
+#define SCE_POWERSHELL_OPERATOR 6
+#define SCE_POWERSHELL_IDENTIFIER 7
+#define SCE_POWERSHELL_KEYWORD 8
+#define SCE_POWERSHELL_CMDLET 9
+#define SCE_POWERSHELL_ALIAS 10
+#define SCE_MYSQL_DEFAULT 0
+#define SCE_MYSQL_COMMENT 1
+#define SCE_MYSQL_COMMENTLINE 2
+#define SCE_MYSQL_VARIABLE 3
+#define SCE_MYSQL_SYSTEMVARIABLE 4
+#define SCE_MYSQL_KNOWNSYSTEMVARIABLE 5
+#define SCE_MYSQL_NUMBER 6
+#define SCE_MYSQL_MAJORKEYWORD 7
+#define SCE_MYSQL_KEYWORD 8
+#define SCE_MYSQL_DATABASEOBJECT 9
+#define SCE_MYSQL_PROCEDUREKEYWORD 10
+#define SCE_MYSQL_STRING 11
+#define SCE_MYSQL_SQSTRING 12
+#define SCE_MYSQL_DQSTRING 13
+#define SCE_MYSQL_OPERATOR 14
+#define SCE_MYSQL_FUNCTION 15
+#define SCE_MYSQL_IDENTIFIER 16
+#define SCE_MYSQL_QUOTEDIDENTIFIER 17
+#define SCE_MYSQL_USER1 18
+#define SCE_MYSQL_USER2 19
+#define SCE_MYSQL_USER3 20
+#define SCE_MYSQL_HIDDENCOMMAND 21
+#define SCE_PO_DEFAULT 0
+#define SCE_PO_COMMENT 1
+#define SCE_PO_MSGID 2
+#define SCE_PO_MSGID_TEXT 3
+#define SCE_PO_MSGSTR 4
+#define SCE_PO_MSGSTR_TEXT 5
+#define SCE_PO_MSGCTXT 6
+#define SCE_PO_MSGCTXT_TEXT 7
+#define SCE_PO_FUZZY 8
+#define SCE_PAS_DEFAULT 0
+#define SCE_PAS_IDENTIFIER 1
+#define SCE_PAS_COMMENT 2
+#define SCE_PAS_COMMENT2 3
+#define SCE_PAS_COMMENTLINE 4
+#define SCE_PAS_PREPROCESSOR 5
+#define SCE_PAS_PREPROCESSOR2 6
+#define SCE_PAS_NUMBER 7
+#define SCE_PAS_HEXNUMBER 8
+#define SCE_PAS_WORD 9
+#define SCE_PAS_STRING 10
+#define SCE_PAS_STRINGEOL 11
+#define SCE_PAS_CHARACTER 12
+#define SCE_PAS_OPERATOR 13
+#define SCE_PAS_ASM 14
+#define SCE_SORCUS_DEFAULT 0
+#define SCE_SORCUS_COMMAND 1
+#define SCE_SORCUS_PARAMETER 2
+#define SCE_SORCUS_COMMENTLINE 3
+#define SCE_SORCUS_STRING 4
+#define SCE_SORCUS_STRINGEOL 5
+#define SCE_SORCUS_IDENTIFIER 6
+#define SCE_SORCUS_OPERATOR 7
+#define SCE_SORCUS_NUMBER 8
+#define SCE_SORCUS_CONSTANT 9
+#define SCE_POWERPRO_DEFAULT 0
+#define SCE_POWERPRO_COMMENTBLOCK 1
+#define SCE_POWERPRO_COMMENTLINE 2
+#define SCE_POWERPRO_NUMBER 3
+#define SCE_POWERPRO_WORD 4
+#define SCE_POWERPRO_WORD2 5
+#define SCE_POWERPRO_WORD3 6
+#define SCE_POWERPRO_WORD4 7
+#define SCE_POWERPRO_DOUBLEQUOTEDSTRING 8
+#define SCE_POWERPRO_SINGLEQUOTEDSTRING 9
+#define SCE_POWERPRO_LINECONTINUE 10
+#define SCE_POWERPRO_OPERATOR 11
+#define SCE_POWERPRO_IDENTIFIER 12
+#define SCE_POWERPRO_STRINGEOL 13
+#define SCE_POWERPRO_VERBATIM 14
+#define SCE_POWERPRO_ALTQUOTE 15
+#define SCE_POWERPRO_FUNCTION 16
+#define SCE_SML_DEFAULT 0
+#define SCE_SML_IDENTIFIER 1
+#define SCE_SML_TAGNAME 2
+#define SCE_SML_KEYWORD 3
+#define SCE_SML_KEYWORD2 4
+#define SCE_SML_KEYWORD3 5
+#define SCE_SML_LINENUM 6
+#define SCE_SML_OPERATOR 7
+#define SCE_SML_NUMBER 8
+#define SCE_SML_CHAR 9
+#define SCE_SML_STRING 11
+#define SCE_SML_COMMENT 12
+#define SCE_SML_COMMENT1 13
+#define SCE_SML_COMMENT2 14
+#define SCE_SML_COMMENT3 15
+#define SCE_MARKDOWN_DEFAULT 0
+#define SCE_MARKDOWN_LINE_BEGIN 1
+#define SCE_MARKDOWN_STRONG1 2
+#define SCE_MARKDOWN_STRONG2 3
+#define SCE_MARKDOWN_EM1 4
+#define SCE_MARKDOWN_EM2 5
+#define SCE_MARKDOWN_HEADER1 6
+#define SCE_MARKDOWN_HEADER2 7
+#define SCE_MARKDOWN_HEADER3 8
+#define SCE_MARKDOWN_HEADER4 9
+#define SCE_MARKDOWN_HEADER5 10
+#define SCE_MARKDOWN_HEADER6 11
+#define SCE_MARKDOWN_PRECHAR 12
+#define SCE_MARKDOWN_ULIST_ITEM 13
+#define SCE_MARKDOWN_OLIST_ITEM 14
+#define SCE_MARKDOWN_BLOCKQUOTE 15
+#define SCE_MARKDOWN_STRIKEOUT 16
+#define SCE_MARKDOWN_HRULE 17
+#define SCE_MARKDOWN_LINK 18
+#define SCE_MARKDOWN_CODE 19
+#define SCE_MARKDOWN_CODE2 20
+#define SCE_MARKDOWN_CODEBK 21
+/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
 
 #endif
index 36aed76b8eef3d93f246d603dd99b8d7b32a9e11..0687c5df260524393c0453189a07d56bbf0ebe74 100644 (file)
@@ -1,12 +1,12 @@
-// Scintilla source code edit control
+/* Scintilla source code edit control */
 /** @file Scintilla.h
  ** Interface to the edit control.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/* Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+ * The License.txt file describes the conditions under which this software may be distributed. */
 
-// Most of this file is automatically generated from the Scintilla.iface interface definition
-// file which contains any comments about the definitions. HFacer.py does the generation.
+/* Most of this file is automatically generated from the Scintilla.iface interface definition
+ * file which contains any comments about the definitions. HFacer.py does the generation. */
 
 #ifndef SCINTILLA_H
 #define SCINTILLA_H
 typedef BOOL bool;
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #if PLAT_WIN
-// Return false on failure:
+/* Return false on failure: */
 bool Scintilla_RegisterClasses(void *hInstance);
 bool Scintilla_ReleaseResources();
 #endif
 int Scintilla_LinkLexers();
 
-// Here should be placed typedefs for uptr_t, an unsigned integer type large enough to
-// hold a pointer and sptr_t, a signed integer large enough to hold a pointer.
-// May need to be changed for 64 bit platforms.
-#ifdef _WIN32
-#include <windows.h>
+#ifdef __cplusplus
+}
+#endif
+
+/* Here should be placed typedefs for uptr_t, an unsigned integer type large enough to
+ * hold a pointer and sptr_t, a signed integer large enough to hold a pointer.
+ * May need to be changed for 64 bit platforms. */
+#if defined(_WIN32)
+#include <basetsd.h>
 #endif
 #ifdef MAXULONG_PTR
 typedef ULONG_PTR uptr_t;
@@ -38,7 +46,7 @@ typedef long sptr_t;
 
 typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 
-//++Autogenerated -- start of section automatically generated from Scintilla.iface
+/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
 #define INVALID_POSITION -1
 #define SCI_START 2000
 #define SCI_OPTIONAL_START 3000
@@ -118,6 +126,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MARK_ARROWS 24
 #define SC_MARK_PIXMAP 25
 #define SC_MARK_FULLRECT 26
+#define SC_MARK_LEFTRECT 27
+#define SC_MARK_AVAILABLE 28
+#define SC_MARK_UNDERLINE 29
 #define SC_MARK_CHARACTER 10000
 #define SC_MARKNUM_FOLDEREND 25
 #define SC_MARKNUM_FOLDEROPENMID 26
@@ -143,6 +154,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MARGIN_NUMBER 1
 #define SC_MARGIN_BACK 2
 #define SC_MARGIN_FORE 3
+#define SC_MARGIN_TEXT 4
+#define SC_MARGIN_RTEXT 5
 #define SCI_SETMARGINTYPEN 2240
 #define SCI_GETMARGINTYPEN 2241
 #define SCI_SETMARGINWIDTHN 2242
@@ -249,6 +262,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_INDICGETUNDER 2511
 #define SCI_SETWHITESPACEFORE 2084
 #define SCI_SETWHITESPACEBACK 2085
+#define SCI_SETWHITESPACESIZE 2086
+#define SCI_GETWHITESPACESIZE 2087
 #define SCI_SETSTYLEBITS 2090
 #define SCI_GETSTYLEBITS 2091
 #define SCI_SETLINESTATE 2092
@@ -394,10 +409,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #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
@@ -415,7 +426,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #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
@@ -444,6 +454,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETWRAPVISUALFLAGSLOCATION 2463
 #define SCI_SETWRAPSTARTINDENT 2464
 #define SCI_GETWRAPSTARTINDENT 2465
+#define SC_WRAPINDENT_FIXED 0
+#define SC_WRAPINDENT_SAME 1
+#define SC_WRAPINDENT_INDENT 2
+#define SCI_SETWRAPINDENTMODE 2472
+#define SCI_GETWRAPINDENTMODE 2473
 #define SC_CACHE_NONE 0
 #define SC_CACHE_CARET 1
 #define SC_CACHE_PAGE 2
@@ -463,6 +478,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_APPENDTEXT 2282
 #define SCI_GETTWOPHASEDRAW 2283
 #define SCI_SETTWOPHASEDRAW 2284
+#define SC_EFF_QUALITY_MASK 0xF
+#define SC_EFF_QUALITY_DEFAULT 0
+#define SC_EFF_QUALITY_NON_ANTIALIASED 1
+#define SC_EFF_QUALITY_ANTIALIASED 2
+#define SC_EFF_QUALITY_LCD_OPTIMIZED 3
+#define SCI_SETFONTQUALITY 2611
+#define SCI_GETFONTQUALITY 2612
+#define SCI_SETFIRSTVISIBLELINE 2613
 #define SCI_TARGETFROMSELECTION 2287
 #define SCI_LINESJOIN 2288
 #define SCI_LINESSPLIT 2289
@@ -559,6 +582,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETMODEVENTMASK 2378
 #define SCI_SETFOCUS 2380
 #define SCI_GETFOCUS 2381
+#define SC_STATUS_OK 0
+#define SC_STATUS_FAILURE 1
+#define SC_STATUS_BADALLOC 2
 #define SCI_SETSTATUS 2382
 #define SCI_GETSTATUS 2383
 #define SCI_SETMOUSEDOWNCAPTURES 2384
@@ -609,6 +635,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_SEL_STREAM 0
 #define SC_SEL_RECTANGLE 1
 #define SC_SEL_LINES 2
+#define SC_SEL_THIN 3
 #define SCI_SETSELECTIONMODE 2422
 #define SCI_GETSELECTIONMODE 2423
 #define SCI_GETLINESELSTARTPOSITION 2424
@@ -633,6 +660,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETWHITESPACECHARS 2443
 #define SCI_SETCHARSDEFAULT 2444
 #define SCI_AUTOCGETCURRENT 2445
+#define SCI_AUTOCGETCURRENTTEXT 2610
 #define SCI_ALLOCATE 2446
 #define SCI_TARGETASUTF8 2447
 #define SCI_SETLENGTHFORENCODE 2448
@@ -666,6 +694,94 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_INDICATOREND 2509
 #define SCI_SETPOSITIONCACHE 2514
 #define SCI_GETPOSITIONCACHE 2515
+#define SCI_COPYALLOWLINE 2519
+#define SCI_GETCHARACTERPOINTER 2520
+#define SCI_SETKEYSUNICODE 2521
+#define SCI_GETKEYSUNICODE 2522
+#define SCI_INDICSETALPHA 2523
+#define SCI_INDICGETALPHA 2524
+#define SCI_SETEXTRAASCENT 2525
+#define SCI_GETEXTRAASCENT 2526
+#define SCI_SETEXTRADESCENT 2527
+#define SCI_GETEXTRADESCENT 2528
+#define SCI_MARKERSYMBOLDEFINED 2529
+#define SCI_MARGINSETTEXT 2530
+#define SCI_MARGINGETTEXT 2531
+#define SCI_MARGINSETSTYLE 2532
+#define SCI_MARGINGETSTYLE 2533
+#define SCI_MARGINSETSTYLES 2534
+#define SCI_MARGINGETSTYLES 2535
+#define SCI_MARGINTEXTCLEARALL 2536
+#define SCI_MARGINSETSTYLEOFFSET 2537
+#define SCI_MARGINGETSTYLEOFFSET 2538
+#define SCI_ANNOTATIONSETTEXT 2540
+#define SCI_ANNOTATIONGETTEXT 2541
+#define SCI_ANNOTATIONSETSTYLE 2542
+#define SCI_ANNOTATIONGETSTYLE 2543
+#define SCI_ANNOTATIONSETSTYLES 2544
+#define SCI_ANNOTATIONGETSTYLES 2545
+#define SCI_ANNOTATIONGETLINES 2546
+#define SCI_ANNOTATIONCLEARALL 2547
+#define ANNOTATION_HIDDEN 0
+#define ANNOTATION_STANDARD 1
+#define ANNOTATION_BOXED 2
+#define SCI_ANNOTATIONSETVISIBLE 2548
+#define SCI_ANNOTATIONGETVISIBLE 2549
+#define SCI_ANNOTATIONSETSTYLEOFFSET 2550
+#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
+#define UNDO_MAY_COALESCE 1
+#define SCI_ADDUNDOACTION 2560
+#define SCI_CHARPOSITIONFROMPOINT 2561
+#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562
+#define SCI_SETMULTIPLESELECTION 2563
+#define SCI_GETMULTIPLESELECTION 2564
+#define SCI_SETADDITIONALSELECTIONTYPING 2565
+#define SCI_GETADDITIONALSELECTIONTYPING 2566
+#define SCI_SETADDITIONALCARETSBLINK 2567
+#define SCI_GETADDITIONALCARETSBLINK 2568
+#define SCI_SETADDITIONALCARETSVISIBLE 2608
+#define SCI_GETADDITIONALCARETSVISIBLE 2609
+#define SCI_GETSELECTIONS 2570
+#define SCI_CLEARSELECTIONS 2571
+#define SCI_SETSELECTION 2572
+#define SCI_ADDSELECTION 2573
+#define SCI_SETMAINSELECTION 2574
+#define SCI_GETMAINSELECTION 2575
+#define SCI_SETSELECTIONNCARET 2576
+#define SCI_GETSELECTIONNCARET 2577
+#define SCI_SETSELECTIONNANCHOR 2578
+#define SCI_GETSELECTIONNANCHOR 2579
+#define SCI_SETSELECTIONNCARETVIRTUALSPACE 2580
+#define SCI_GETSELECTIONNCARETVIRTUALSPACE 2581
+#define SCI_SETSELECTIONNANCHORVIRTUALSPACE 2582
+#define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583
+#define SCI_SETSELECTIONNSTART 2584
+#define SCI_GETSELECTIONNSTART 2585
+#define SCI_SETSELECTIONNEND 2586
+#define SCI_GETSELECTIONNEND 2587
+#define SCI_SETRECTANGULARSELECTIONCARET 2588
+#define SCI_GETRECTANGULARSELECTIONCARET 2589
+#define SCI_SETRECTANGULARSELECTIONANCHOR 2590
+#define SCI_GETRECTANGULARSELECTIONANCHOR 2591
+#define SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE 2592
+#define SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE 2593
+#define SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2594
+#define SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2595
+#define SCVS_NONE 0
+#define SCVS_RECTANGULARSELECTION 1
+#define SCVS_USERACCESSIBLE 2
+#define SCI_SETVIRTUALSPACEOPTIONS 2596
+#define SCI_GETVIRTUALSPACEOPTIONS 2597
+#define SCI_SETRECTANGULARSELECTIONMODIFIER 2598
+#define SCI_GETRECTANGULARSELECTIONMODIFIER 2599
+#define SCI_SETADDITIONALSELFORE 2600
+#define SCI_SETADDITIONALSELBACK 2601
+#define SCI_SETADDITIONALSELALPHA 2602
+#define SCI_GETADDITIONALSELALPHA 2603
+#define SCI_SETADDITIONALCARETFORE 2604
+#define SCI_GETADDITIONALCARETFORE 2605
+#define SCI_ROTATESELECTION 2606
+#define SCI_SWAPMAINANCHORCARET 2607
 #define SCI_STARTRECORD 3001
 #define SCI_STOPRECORD 3002
 #define SCI_SETLEXER 4001
@@ -680,6 +796,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETPROPERTYEXPANDED 4009
 #define SCI_GETPROPERTYINT 4010
 #define SCI_GETSTYLEBITSNEEDED 4011
+#define SCI_GETLEXERLANGUAGE 4012
 #define SC_MOD_INSERTTEXT 0x1
 #define SC_MOD_DELETETEXT 0x2
 #define SC_MOD_CHANGESTYLE 0x4
@@ -696,7 +813,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_STARTACTION 0x2000
 #define SC_MOD_CHANGEINDICATOR 0x4000
 #define SC_MOD_CHANGELINESTATE 0x8000
-#define SC_MODEVENTMASKALL 0xFFFF
+#define SC_MOD_CHANGEMARGIN 0x10000
+#define SC_MOD_CHANGEANNOTATION 0x20000
+#define SC_MOD_CONTAINER 0x40000
+#define SC_MODEVENTMASKALL 0x7FFFF
 #define SCEN_CHANGE 768
 #define SCEN_SETFOCUS 512
 #define SCEN_KILLFOCUS 256
@@ -724,6 +844,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCMOD_SHIFT 1
 #define SCMOD_CTRL 2
 #define SCMOD_ALT 4
+#define SCMOD_SUPER 8
 #define SCN_STYLENEEDED 2000
 #define SCN_CHARADDED 2001
 #define SCN_SAVEPOINTREACHED 2002
@@ -748,95 +869,91 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCN_AUTOCSELECTION 2022
 #define SCN_INDICATORCLICK 2023
 #define SCN_INDICATORRELEASE 2024
-//--Autogenerated -- end of section automatically generated from Scintilla.iface
+#define SCN_AUTOCCANCELLED 2025
+#define SCN_AUTOCCHARDELETED 2026
+/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
 
-// These structures are defined to be exactly the same shape as the Win32
-// CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs.
-// So older code that treats Scintilla as a RichEdit will work.
+/* These structures are defined to be exactly the same shape as the Win32
+ * CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs.
+ * So older code that treats Scintilla as a RichEdit will work. */
 
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
 
-struct CharacterRange {
+struct Sci_CharacterRange {
        long cpMin;
        long cpMax;
 };
 
-struct TextRange {
-       struct CharacterRange chrg;
+struct Sci_TextRange {
+       struct Sci_CharacterRange chrg;
        char *lpstrText;
 };
 
-struct TextToFind {
-       struct CharacterRange chrg;
+struct Sci_TextToFind {
+       struct Sci_CharacterRange chrg;
        char *lpstrText;
-       struct CharacterRange chrgText;
+       struct Sci_CharacterRange chrgText;
 };
 
+#define CharacterRange Sci_CharacterRange
+#define TextRange Sci_TextRange
+#define TextToFind Sci_TextToFind
+
 #ifdef PLATFORM_H
 
-// This structure is used in printing and requires some of the graphics types
-// from Platform.h.  Not needed by most client code.
+/* This structure is used in printing and requires some of the graphics types
+ * from Platform.h.  Not needed by most client code. */
 
-struct RangeToFormat {
+struct Sci_RangeToFormat {
        SurfaceID hdc;
        SurfaceID hdcTarget;
        PRectangle rc;
        PRectangle rcPage;
-       CharacterRange chrg;
+       Sci_CharacterRange chrg;
 };
 
+#define RangeToFormat Sci_RangeToFormat
+
 #endif
 
-struct NotifyHeader {
-       // Compatible with Windows NMHDR.
-       // hwndFrom is really an environment specific window handle or pointer
-       // but most clients of Scintilla.h do not have this type visible.
+struct Sci_NotifyHeader {
+       /* Compatible with Windows NMHDR.
+        * hwndFrom is really an environment specific window handle or pointer
+        * but most clients of Scintilla.h do not have this type visible. */
        void *hwndFrom;
        uptr_t idFrom;
        unsigned int code;
 };
 
+#define NotifyHeader Sci_NotifyHeader
+
 struct SCNotification {
-       struct NotifyHeader nmhdr;
-       int position;   // SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND
-       int ch;         // SCN_CHARADDED, SCN_KEY
-       int modifiers;  // SCN_KEY
-       int modificationType;   // SCN_MODIFIED
-       const char *text;       // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION
-       int length;             // SCN_MODIFIED
-       int linesAdded; // SCN_MODIFIED
-       int message;    // SCN_MACRORECORD
-       uptr_t wParam;  // SCN_MACRORECORD
-       sptr_t lParam;  // SCN_MACRORECORD
-       int line;               // SCN_MODIFIED
-       int foldLevelNow;       // SCN_MODIFIED
-       int foldLevelPrev;      // SCN_MODIFIED
-       int margin;             // SCN_MARGINCLICK
-       int listType;   // SCN_USERLISTSELECTION
-       int x;                  // SCN_DWELLSTART, SCN_DWELLEND
-       int y;          // SCN_DWELLSTART, SCN_DWELLEND
+       struct Sci_NotifyHeader nmhdr;
+       int position;   /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
+       int ch;         /* SCN_CHARADDED, SCN_KEY */
+       int modifiers;  /* SCN_KEY */
+       int modificationType;   /* SCN_MODIFIED */
+       const char *text;       /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+       int length;             /* SCN_MODIFIED */
+       int linesAdded; /* SCN_MODIFIED */
+       int message;    /* SCN_MACRORECORD */
+       uptr_t wParam;  /* SCN_MACRORECORD */
+       sptr_t lParam;  /* SCN_MACRORECORD */
+       int line;               /* SCN_MODIFIED */
+       int foldLevelNow;       /* SCN_MODIFIED */
+       int foldLevelPrev;      /* SCN_MODIFIED */
+       int margin;             /* SCN_MARGINCLICK */
+       int listType;   /* SCN_USERLISTSELECTION */
+       int x;                  /* SCN_DWELLSTART, SCN_DWELLEND */
+       int y;          /* SCN_DWELLSTART, SCN_DWELLEND */
+       int token;              /* SCN_MODIFIED with SC_MOD_CONTAINER */
+       int annotationLinesAdded;       /* SC_MOD_CHANGEANNOTATION */
 };
 
 #ifdef SCI_NAMESPACE
 }
 #endif
 
-// Deprecation section listing all API features that are deprecated and will
-// will be removed completely in a future version.
-// To enable these features define INCLUDE_DEPRECATED_FEATURES
-
-#ifdef INCLUDE_DEPRECATED_FEATURES
-
-#define SCI_SETCARETPOLICY 2369
-#define CARET_CENTER 0x02
-#define CARET_XEVEN 0x08
-#define CARET_XJUMPS 0x10
-
-#define SCN_POSCHANGED 2012
-#define SCN_CHECKBRACE 2007
-
-#endif
-
 #endif
index a6626d233593e3d776c19a23a523cff5f509197f..f2810454d5e19cb478ee459e65423fce72ec3536 100644 (file)
@@ -104,7 +104,7 @@ fun void ClearAll=2004(,)
 # Set all style bytes to 0, remove all folding information.
 fun void ClearDocumentStyle=2005(,)
 
-# Returns the number of characters in the document.
+# Returns the number of bytes in the document.
 get int GetLength=2006(,)
 
 # Returns the character byte at the position.
@@ -268,6 +268,9 @@ val SC_MARK_DOTDOTDOT=23
 val SC_MARK_ARROWS=24
 val SC_MARK_PIXMAP=25
 val SC_MARK_FULLRECT=26
+val SC_MARK_LEFTRECT=27
+val SC_MARK_AVAILABLE=28
+val SC_MARK_UNDERLINE=29
 
 val SC_MARK_CHARACTER=10000
 
@@ -324,6 +327,8 @@ val SC_MARGIN_SYMBOL=0
 val SC_MARGIN_NUMBER=1
 val SC_MARGIN_BACK=2
 val SC_MARGIN_FORE=3
+val SC_MARGIN_TEXT=4
+val SC_MARGIN_RTEXT=5
 
 # Set a margin to be either numeric or symbolic.
 set void SetMarginTypeN=2240(int margin, int marginType)
@@ -472,10 +477,10 @@ 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.
+# Set the foreground colour of the main and additional selections and whether to use this setting.
 fun void SetSelFore=2067(bool useSetting, colour fore)
 
-# Set the background colour of the selection and whether to use this setting.
+# Set the background colour of the main and additional selections and whether to use this setting.
 fun void SetSelBack=2068(bool useSetting, colour back)
 
 # Get the alpha of the selection.
@@ -515,7 +520,7 @@ get int GetCaretPeriod=2075(,)
 set void SetCaretPeriod=2076(int periodMilliseconds,)
 
 # Set the set of characters making up words for when moving or selecting by word.
-# First sets deaults like SetCharsDefault.
+# First sets defaults like SetCharsDefault.
 set void SetWordChars=2077(, string characters)
 
 # Start a sequence of actions that is undone and redone as a unit.
@@ -566,6 +571,12 @@ fun void SetWhitespaceFore=2084(bool useSetting, colour fore)
 # Set the background colour of all whitespace and whether to use this setting.
 fun void SetWhitespaceBack=2085(bool useSetting, colour back)
 
+# Set the size of the dots used to mark space characters.
+set void SetWhitespaceSize=2086(int size,)
+
+# Get the size of the dots used to mark space characters.
+get int GetWhitespaceSize=2087(,)
+
 # Divide each styling byte into lexical class bits (default: 5) and indicator
 # bits (default: 3). If a lexer requires more than 32 lexical states, then this
 # is used to expand the possible states.
@@ -1010,10 +1021,6 @@ 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.
@@ -1057,7 +1064,6 @@ 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,)
@@ -1131,6 +1137,17 @@ set void SetWrapStartIndent=2464(int indent,)
 # Retrive the start indent for wrapped lines.
 get int GetWrapStartIndent=2465(,)
 
+enu WrapIndentMode=SC_WRAPINDENT_
+val SC_WRAPINDENT_FIXED=0
+val SC_WRAPINDENT_SAME=1
+val SC_WRAPINDENT_INDENT=2
+
+# Sets how wrapped sublines are placed. Default is fixed.
+set void SetWrapIndentMode=2472(int mode,)
+
+# Retrieve how wrapped sublines are placed. Default is fixed.
+get int GetWrapIndentMode=2473(,)
+
 enu LineCache=SC_CACHE_
 val SC_CACHE_NONE=0
 val SC_CACHE_CARET=1
@@ -1188,6 +1205,24 @@ get bool GetTwoPhaseDraw=2283(,)
 # and then the foreground. This avoids chopping off characters that overlap the next run.
 set void SetTwoPhaseDraw=2284(bool twoPhase,)
 
+# Control font anti-aliasing.
+
+enu FontQuality=SC_EFF_
+val SC_EFF_QUALITY_MASK=0xF
+val SC_EFF_QUALITY_DEFAULT=0
+val SC_EFF_QUALITY_NON_ANTIALIASED=1
+val SC_EFF_QUALITY_ANTIALIASED=2
+val SC_EFF_QUALITY_LCD_OPTIMIZED=3
+
+# Choose the quality level for text from the FontQuality enumeration.
+set void SetFontQuality=2611(int fontQuality,)
+
+# Retrieve the quality level for text.
+get int GetFontQuality=2612(,)
+
+# Scroll so that a display line is at the top of the display.
+set void SetFirstVisibleLine=2613(int lineDisplay,)
+
 # Make the target range start and end be the same as the selection range start and end.
 fun void TargetFromSelection=2287(,)
 
@@ -1382,7 +1417,7 @@ fun void LineCopy=2455(,)
 # Move the caret inside current view if it's not there already.
 fun void MoveCaretInsideView=2401(,)
 
-# How many characters are on a line, not including end of line characters?
+# How many characters are on a line, including end of line characters?
 fun int LineLength=2350(int line,)
 
 # Highlight the characters at two positions.
@@ -1477,6 +1512,11 @@ set void SetFocus=2380(bool focus,)
 # Get internal focus flag.
 get bool GetFocus=2381(,)
 
+enu Status=SC_STATUS_
+val SC_STATUS_OK=0
+val SC_STATUS_FAILURE=1
+val SC_STATUS_BADALLOC=2
+
 # Change error status - 0 = OK.
 set void SetStatus=2382(int statusCode,)
 # Get error status.
@@ -1535,7 +1575,7 @@ fun void ChooseCaretX=2399(,)
 # Set the focus to this Scintilla widget.
 fun void GrabFocus=2400(,)
 
-enu CaretPolicy = CARET_
+enu CaretPolicy=CARET_
 # Caret policy, used by SetXCaretPolicy and SetYCaretPolicy.
 # If CARET_SLOP is set, we can define a slop value: caretSlop.
 # This value defines an unwanted zone (UZ) where the caret is... unwanted.
@@ -1617,13 +1657,13 @@ fun void CopyRange=2419(position start, position end)
 # Copy argument text to the clipboard.
 fun void CopyText=2420(int length, string text)
 
-# Selection Modes
 enu SelectionMode=SC_SEL_
 val SC_SEL_STREAM=0
 val SC_SEL_RECTANGLE=1
 val SC_SEL_LINES=2
+val SC_SEL_THIN=3
 
-# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE) or
+# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or
 # by lines (SC_SEL_LINES).
 set void SetSelectionMode=2422(int mode,)
 
@@ -1702,6 +1742,10 @@ fun void SetCharsDefault=2444(,)
 # Get currently selected item position in the auto-completion list
 fun int AutoCGetCurrent=2445(,)
 
+# Get currently selected item text in the auto-completion list
+# Returns the length of the item text
+fun int AutoCGetCurrentText=2610(, stringresult s)
+
 # Enlarge the document to a particular size of text bytes.
 fun void Allocate=2446(int bytes,)
 
@@ -1750,7 +1794,6 @@ set void SetCaretLineBackAlpha=2470(int alpha,)
 # Get the background alpha of the caret line.
 get int GetCaretLineBackAlpha=2471(,)
 
-# Caret Styles
 enu CaretStyle=CARETSTYLE_
 val CARETSTYLE_INVISIBLE=0
 val CARETSTYLE_LINE=1
@@ -1798,6 +1841,236 @@ set void SetPositionCache=2514(int size,)
 # How many entries are allocated to the position cache?
 get int GetPositionCache=2515(,)
 
+# Copy the selection, if selection empty copy the line with the caret
+fun void CopyAllowLine=2519(,)
+
+# Compact the document buffer and return a read-only pointer to the
+# characters in the document.
+get int GetCharacterPointer=2520(,)
+
+# Always interpret keyboard input as Unicode
+set void SetKeysUnicode=2521(bool keysUnicode,)
+
+# Are keys always interpreted as Unicode?
+get bool GetKeysUnicode=2522(,)
+
+# Set the alpha fill colour of the given indicator.
+set void IndicSetAlpha=2523(int indicator, int alpha)
+
+# Get the alpha fill colour of the given indicator.
+get int IndicGetAlpha=2524(int indicator,)
+
+# Set extra ascent for each line
+set void SetExtraAscent=2525(int extraAscent,)
+
+# Get extra ascent for each line
+get int GetExtraAscent=2526(,)
+
+# Set extra descent for each line
+set void SetExtraDescent=2527(int extraDescent,)
+
+# Get extra descent for each line
+get int GetExtraDescent=2528(,)
+
+# Which symbol was defined for markerNumber with MarkerDefine
+fun int MarkerSymbolDefined=2529(int markerNumber,)
+
+# Set the text in the text margin for a line
+set void MarginSetText=2530(int line, string text)
+
+# Get the text in the text margin for a line
+get int MarginGetText=2531(int line, stringresult text)
+
+# Set the style number for the text margin for a line
+set void MarginSetStyle=2532(int line, int style)
+
+# Get the style number for the text margin for a line
+get int MarginGetStyle=2533(int line,)
+
+# Set the style in the text margin for a line
+set void MarginSetStyles=2534(int line, string styles)
+
+# Get the styles in the text margin for a line
+get int MarginGetStyles=2535(int line, stringresult styles)
+
+# Clear the margin text on all lines
+fun void MarginTextClearAll=2536(,)
+
+# Get the start of the range of style numbers used for margin text
+set void MarginSetStyleOffset=2537(int style,)
+
+# Get the start of the range of style numbers used for margin text
+get int MarginGetStyleOffset=2538(,)
+
+# Set the annotation text for a line
+set void AnnotationSetText=2540(int line, string text)
+
+# Get the annotation text for a line
+get int AnnotationGetText=2541(int line, stringresult text)
+
+# Set the style number for the annotations for a line
+set void AnnotationSetStyle=2542(int line, int style)
+
+# Get the style number for the annotations for a line
+get int AnnotationGetStyle=2543(int line,)
+
+# Set the annotation styles for a line
+set void AnnotationSetStyles=2544(int line, string styles)
+
+# Get the annotation styles for a line
+get int AnnotationGetStyles=2545(int line, stringresult styles)
+
+# Get the number of annotation lines for a line
+get int AnnotationGetLines=2546(int line,)
+
+# Clear the annotations from all lines
+fun void AnnotationClearAll=2547(,)
+
+enu AnnotationVisible=ANNOTATION_
+val ANNOTATION_HIDDEN=0
+val ANNOTATION_STANDARD=1
+val ANNOTATION_BOXED=2
+
+# Set the visibility for the annotations for a view
+set void AnnotationSetVisible=2548(int visible,)
+
+# Get the visibility for the annotations for a view
+get int AnnotationGetVisible=2549(,)
+
+# Get the start of the range of style numbers used for annotations
+set void AnnotationSetStyleOffset=2550(int style,)
+
+# Get the start of the range of style numbers used for annotations
+get int AnnotationGetStyleOffset=2551(,)
+
+val UNDO_MAY_COALESCE=1
+
+# Add a container action to the undo stack
+fun void AddUndoAction=2560(int token, int flags)
+
+# Find the position of a character from a point within the window.
+fun position CharPositionFromPoint=2561(int x, int y)
+
+# Find the position of a character from a point within the window.
+# Return INVALID_POSITION if not close to text.
+fun position CharPositionFromPointClose=2562(int x, int y)
+
+# Set whether multiple selections can be made
+set void SetMultipleSelection=2563(bool multipleSelection,)
+
+# Whether multiple selections can be made
+get bool GetMultipleSelection=2564(,)
+
+# Set whether typing can be performed into multiple selections
+set void SetAdditionalSelectionTyping=2565(bool additionalSelectionTyping,)
+
+# Whether typing can be performed into multiple selections
+get bool GetAdditionalSelectionTyping=2566(,)
+
+# Set whether additional carets will blink
+set void SetAdditionalCaretsBlink=2567(bool additionalCaretsBlink,)
+
+# Whether additional carets will blink
+get bool GetAdditionalCaretsBlink=2568(,)
+
+# Set whether additional carets are visible
+set void SetAdditionalCaretsVisible=2608(bool additionalCaretsBlink,)
+
+# Whether additional carets are visible
+get bool GetAdditionalCaretsVisible=2609(,)
+
+# How many selections are there?
+get int GetSelections=2570(,)
+
+# Clear selections to a single empty stream selection
+fun void ClearSelections=2571(,)
+
+# Set a simple selection
+fun int SetSelection=2572(int caret,int anchor)
+
+# Add a selection
+fun int AddSelection=2573(int caret,int anchor)
+
+# Set the main selection
+set void SetMainSelection=2574(int selection,)
+
+# Which selection is the main selection
+get int GetMainSelection=2575(,)
+
+set void SetSelectionNCaret=2576(int selection, position pos)
+get position GetSelectionNCaret=2577(int selection,)
+set void SetSelectionNAnchor=2578(int selection, position posAnchor)
+get position GetSelectionNAnchor=2579(int selection,)
+set void SetSelectionNCaretVirtualSpace=2580(int selection, int space)
+get int GetSelectionNCaretVirtualSpace=2581(int selection,)
+set void SetSelectionNAnchorVirtualSpace=2582(int selection, int space)
+get int GetSelectionNAnchorVirtualSpace=2583(int selection,)
+
+# Sets the position that starts the selection - this becomes the anchor.
+set void SetSelectionNStart=2584(int selection, position pos)
+
+# Returns the position at the start of the selection.
+get position GetSelectionNStart=2585(int selection,)
+
+# Sets the position that ends the selection - this becomes the currentPosition.
+set void SetSelectionNEnd=2586(int selection, position pos,)
+
+# Returns the position at the end of the selection.
+get position GetSelectionNEnd=2587(int selection,)
+
+set void SetRectangularSelectionCaret=2588(position pos,)
+get position GetRectangularSelectionCaret=2589(,)
+set void SetRectangularSelectionAnchor=2590(position posAnchor,)
+get position GetRectangularSelectionAnchor=2591(,)
+set void SetRectangularSelectionCaretVirtualSpace=2592(int space,)
+get int GetRectangularSelectionCaretVirtualSpace=2593(,)
+set void SetRectangularSelectionAnchorVirtualSpace=2594(int space,)
+get int GetRectangularSelectionAnchorVirtualSpace=2595(,)
+
+enu VirtualSpace=SCVS_
+val SCVS_NONE=0
+val SCVS_RECTANGULARSELECTION=1
+val SCVS_USERACCESSIBLE=2
+
+set void SetVirtualSpaceOptions=2596(int virtualSpaceOptions,)
+get int GetVirtualSpaceOptions=2597(,)
+
+# On GTK+, allow selecting the modifier key to use for mouse-based
+# rectangular selection. Often the window manager requires Alt+Mouse Drag
+# for moving windows.
+# Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER.
+
+set void SetRectangularSelectionModifier=2598(int modifier,)
+
+# Get the modifier key used for rectangular selection.
+get int GetRectangularSelectionModifier=2599(,)
+
+# Set the foreground colour of additional selections.
+# Must have previously called SetSelFore with non-zero first argument for this to have an effect.
+set void SetAdditionalSelFore=2600(colour fore,)
+
+# Set the background colour of additional selections.
+# Must have previously called SetSelBack with non-zero first argument for this to have an effect.
+set void SetAdditionalSelBack=2601(colour back,)
+
+# Set the alpha of the selection.
+set void SetAdditionalSelAlpha=2602(int alpha,)
+
+# Get the alpha of the selection.
+get int GetAdditionalSelAlpha=2603(,)
+
+# Set the foreground colour of additional carets.
+set void SetAdditionalCaretFore=2604(colour fore,)
+
+# Get the foreground colour of additional carets.
+get colour GetAdditionalCaretFore=2605(,)
+
+# Set the main selection to the next selection.
+fun void RotateSelection=2606(,)
+
+# Swap that caret and anchor of the main selection.
+fun void SwapMainAnchorCaret=2607(,)
+
 # Start notifying the container of all key presses and commands.
 fun void StartRecord=3001(,)
 
@@ -1842,6 +2115,10 @@ get int GetPropertyInt=4010(string key,)
 # Retrieve the number of bits the current lexer needs for styling.
 get int GetStyleBitsNeeded=4011(,)
 
+# Retrieve the name of the lexer.
+# Return the length of the text.
+get int GetLexerLanguage=4012(, stringresult text)
+
 # 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.
@@ -1863,7 +2140,10 @@ val SC_MULTILINEUNDOREDO=0x1000
 val SC_STARTACTION=0x2000
 val SC_MOD_CHANGEINDICATOR=0x4000
 val SC_MOD_CHANGELINESTATE=0x8000
-val SC_MODEVENTMASKALL=0xFFFF
+val SC_MOD_CHANGEMARGIN=0x10000
+val SC_MOD_CHANGEANNOTATION=0x20000
+val SC_MOD_CONTAINER=0x40000
+val SC_MODEVENTMASKALL=0x7FFFF
 
 # For compatibility, these go through the COMMAND notification rather than NOTIFY
 # and should have had exactly the same values as the EN_* constants.
@@ -1904,6 +2184,7 @@ val SCMOD_NORM=0
 val SCMOD_SHIFT=1
 val SCMOD_CTRL=2
 val SCMOD_ALT=4
+val SCMOD_SUPER=8
 
 ################################################
 # For SciLexer.h
@@ -1993,12 +2274,25 @@ val SCLEX_PROGRESS=83
 val SCLEX_ABAQUS=84
 val SCLEX_ASYMPTOTE=85
 val SCLEX_R=86
+val SCLEX_MAGIK=87
+val SCLEX_POWERSHELL=88
+val SCLEX_MYSQL=89
+val SCLEX_PO=90
+val SCLEX_TAL=91
+val SCLEX_COBOL=92
+val SCLEX_TACL=93
+val SCLEX_SORCUS=94
+val SCLEX_POWERPRO=95
+val SCLEX_NIMROD=96
+val SCLEX_SML=97
+val SCLEX_MARKDOWN=98
 
 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 # value assigned in sequence from SCLEX_AUTOMATIC+1.
 val SCLEX_AUTOMATIC=1000
 # Lexical states for SCLEX_PYTHON
 lex Python=SCLEX_PYTHON SCE_P_
+lex Nimrod=SCLEX_NIMROD SCE_P_
 val SCE_P_DEFAULT=0
 val SCE_P_COMMENTLINE=1
 val SCE_P_NUMBER=2
@@ -2017,7 +2311,6 @@ val SCE_P_WORD2=14
 val SCE_P_DECORATOR=15
 # Lexical states for SCLEX_CPP
 lex Cpp=SCLEX_CPP SCE_C_
-lex Pascal=SCLEX_PASCAL SCE_C_
 lex BullAnt=SCLEX_BULLANT SCE_C_
 val SCE_C_DEFAULT=0
 val SCE_C_COMMENT=1
@@ -2059,6 +2352,11 @@ val SCE_D_IDENTIFIER=14
 val SCE_D_COMMENTLINEDOC=15
 val SCE_D_COMMENTDOCKEYWORD=16
 val SCE_D_COMMENTDOCKEYWORDERROR=17
+val SCE_D_STRINGB=18
+val SCE_D_STRINGR=19
+val SCE_D_WORD5=20
+val SCE_D_WORD6=21
+val SCE_D_WORD7=22
 # Lexical states for SCLEX_TCL
 lex TCL=SCLEX_TCL SCE_TCL_
 val SCE_TCL_DEFAULT=0
@@ -2396,6 +2694,7 @@ val SCE_DIFF_HEADER=3
 val SCE_DIFF_POSITION=4
 val SCE_DIFF_DELETED=5
 val SCE_DIFF_ADDED=6
+val SCE_DIFF_CHANGED=7
 # Lexical states for SCLEX_CONF (Apache Configuration Files Lexer)
 lex Conf=SCLEX_CONF SCE_CONF_
 val SCE_CONF_DEFAULT=0
@@ -2589,6 +2888,11 @@ val SCE_CSS_DOUBLESTRING=13
 val SCE_CSS_SINGLESTRING=14
 val SCE_CSS_IDENTIFIER2=15
 val SCE_CSS_ATTRIBUTE=16
+val SCE_CSS_IDENTIFIER3=17
+val SCE_CSS_PSEUDOELEMENT=18
+val SCE_CSS_EXTENDED_IDENTIFIER=19
+val SCE_CSS_EXTENDED_PSEUDOCLASS=20
+val SCE_CSS_EXTENDED_PSEUDOELEMENT=21
 # Lexical states for SCLEX_POV
 lex POV=SCLEX_POV SCE_POV_
 val SCE_POV_DEFAULT=0
@@ -2764,8 +3068,19 @@ val SCE_ERLANG_FUNCTION_NAME=8
 val SCE_ERLANG_CHARACTER=9
 val SCE_ERLANG_MACRO=10
 val SCE_ERLANG_RECORD=11
-val SCE_ERLANG_SEPARATOR=12
+val SCE_ERLANG_PREPROC=12
 val SCE_ERLANG_NODE_NAME=13
+val SCE_ERLANG_COMMENT_FUNCTION=14
+val SCE_ERLANG_COMMENT_MODULE=15
+val SCE_ERLANG_COMMENT_DOC=16
+val SCE_ERLANG_COMMENT_DOC_MACRO=17
+val SCE_ERLANG_ATOM_QUOTED=18
+val SCE_ERLANG_MACRO_QUOTED=19
+val SCE_ERLANG_RECORD_QUOTED=20
+val SCE_ERLANG_NODE_NAME_QUOTED=21
+val SCE_ERLANG_BIFS=22
+val SCE_ERLANG_MODULES=23
+val SCE_ERLANG_MODULES_ATT=24
 val SCE_ERLANG_UNKNOWN=31
 # Lexical states for SCLEX_OCTAVE are identical to MatLab
 lex Octave=SCLEX_OCTAVE SCE_MATLAB_
@@ -2937,6 +3252,7 @@ val SCE_CAML_LINENUM=6
 val SCE_CAML_OPERATOR=7
 val SCE_CAML_NUMBER=8
 val SCE_CAML_CHAR=9
+val SCE_CAML_WHITE=10
 val SCE_CAML_STRING=11
 val SCE_CAML_COMMENT=12
 val SCE_CAML_COMMENT1=13
@@ -3110,7 +3426,7 @@ val SCE_INNO_KEYWORD=2
 val SCE_INNO_PARAMETER=3
 val SCE_INNO_SECTION=4
 val SCE_INNO_PREPROC=5
-val SCE_INNO_PREPROC_INLINE=6
+val SCE_INNO_INLINE_EXPANSION=6
 val SCE_INNO_COMMENT_PASCAL=7
 val SCE_INNO_KEYWORD_PASCAL=8
 val SCE_INNO_KEYWORD_USER=9
@@ -3258,6 +3574,162 @@ val SCE_R_OPERATOR=8
 val SCE_R_IDENTIFIER=9
 val SCE_R_INFIX=10
 val SCE_R_INFIXEOL=11
+# Lexical state for SCLEX_MAGIKSF
+lex MagikSF=SCLEX_MAGIKSF SCE_MAGIK_
+val SCE_MAGIK_DEFAULT=0
+val SCE_MAGIK_COMMENT=1
+val SCE_MAGIK_HYPER_COMMENT=16
+val SCE_MAGIK_STRING=2
+val SCE_MAGIK_CHARACTER=3
+val SCE_MAGIK_NUMBER=4
+val SCE_MAGIK_IDENTIFIER=5
+val SCE_MAGIK_OPERATOR=6
+val SCE_MAGIK_FLOW=7
+val SCE_MAGIK_CONTAINER=8
+val SCE_MAGIK_BRACKET_BLOCK=9
+val SCE_MAGIK_BRACE_BLOCK=10
+val SCE_MAGIK_SQBRACKET_BLOCK=11
+val SCE_MAGIK_UNKNOWN_KEYWORD=12
+val SCE_MAGIK_KEYWORD=13
+val SCE_MAGIK_PRAGMA=14
+val SCE_MAGIK_SYMBOL=15
+# Lexical state for SCLEX_POWERSHELL
+lex PowerShell=SCLEX_POWERSHELL SCE_POWERSHELL_
+val SCE_POWERSHELL_DEFAULT=0
+val SCE_POWERSHELL_COMMENT=1
+val SCE_POWERSHELL_STRING=2
+val SCE_POWERSHELL_CHARACTER=3
+val SCE_POWERSHELL_NUMBER=4
+val SCE_POWERSHELL_VARIABLE=5
+val SCE_POWERSHELL_OPERATOR=6
+val SCE_POWERSHELL_IDENTIFIER=7
+val SCE_POWERSHELL_KEYWORD=8
+val SCE_POWERSHELL_CMDLET=9
+val SCE_POWERSHELL_ALIAS=10
+# Lexical state for SCLEX_MYSQL
+lex MySQL=SCLEX_MYSQL SCE_MYSQL_
+val SCE_MYSQL_DEFAULT=0
+val SCE_MYSQL_COMMENT=1
+val SCE_MYSQL_COMMENTLINE=2
+val SCE_MYSQL_VARIABLE=3
+val SCE_MYSQL_SYSTEMVARIABLE=4
+val SCE_MYSQL_KNOWNSYSTEMVARIABLE=5
+val SCE_MYSQL_NUMBER=6
+val SCE_MYSQL_MAJORKEYWORD=7
+val SCE_MYSQL_KEYWORD=8
+val SCE_MYSQL_DATABASEOBJECT=9
+val SCE_MYSQL_PROCEDUREKEYWORD=10
+val SCE_MYSQL_STRING=11
+val SCE_MYSQL_SQSTRING=12
+val SCE_MYSQL_DQSTRING=13
+val SCE_MYSQL_OPERATOR=14
+val SCE_MYSQL_FUNCTION=15
+val SCE_MYSQL_IDENTIFIER=16
+val SCE_MYSQL_QUOTEDIDENTIFIER=17
+val SCE_MYSQL_USER1=18
+val SCE_MYSQL_USER2=19
+val SCE_MYSQL_USER3=20
+val SCE_MYSQL_HIDDENCOMMAND=21
+# Lexical state for SCLEX_PO
+lex Po=SCLEX_PO SCE_PO_
+val SCE_PO_DEFAULT=0
+val SCE_PO_COMMENT=1
+val SCE_PO_MSGID=2
+val SCE_PO_MSGID_TEXT=3
+val SCE_PO_MSGSTR=4
+val SCE_PO_MSGSTR_TEXT=5
+val SCE_PO_MSGCTXT=6
+val SCE_PO_MSGCTXT_TEXT=7
+val SCE_PO_FUZZY=8
+# Lexical states for SCLEX_PASCAL
+lex Pascal=SCLEX_PASCAL SCE_PAS_
+val SCE_PAS_DEFAULT=0
+val SCE_PAS_IDENTIFIER=1
+val SCE_PAS_COMMENT=2
+val SCE_PAS_COMMENT2=3
+val SCE_PAS_COMMENTLINE=4
+val SCE_PAS_PREPROCESSOR=5
+val SCE_PAS_PREPROCESSOR2=6
+val SCE_PAS_NUMBER=7
+val SCE_PAS_HEXNUMBER=8
+val SCE_PAS_WORD=9
+val SCE_PAS_STRING=10
+val SCE_PAS_STRINGEOL=11
+val SCE_PAS_CHARACTER=12
+val SCE_PAS_OPERATOR=13
+val SCE_PAS_ASM=14
+# Lexical state for SCLEX_SORCUS
+lex SORCUS=SCLEX_SORCUS SCE_SORCUS_
+val SCE_SORCUS_DEFAULT=0
+val SCE_SORCUS_COMMAND=1
+val SCE_SORCUS_PARAMETER=2
+val SCE_SORCUS_COMMENTLINE=3
+val SCE_SORCUS_STRING=4
+val SCE_SORCUS_STRINGEOL=5
+val SCE_SORCUS_IDENTIFIER=6
+val SCE_SORCUS_OPERATOR=7
+val SCE_SORCUS_NUMBER=8
+val SCE_SORCUS_CONSTANT=9
+# Lexical state for SCLEX_POWERPRO
+lex PowerPro=SCLEX_POWERPRO SCE_POWERPRO_
+val SCE_POWERPRO_DEFAULT=0
+val SCE_POWERPRO_COMMENTBLOCK=1
+val SCE_POWERPRO_COMMENTLINE=2
+val SCE_POWERPRO_NUMBER=3
+val SCE_POWERPRO_WORD=4
+val SCE_POWERPRO_WORD2=5
+val SCE_POWERPRO_WORD3=6
+val SCE_POWERPRO_WORD4=7
+val SCE_POWERPRO_DOUBLEQUOTEDSTRING=8
+val SCE_POWERPRO_SINGLEQUOTEDSTRING=9
+val SCE_POWERPRO_LINECONTINUE=10
+val SCE_POWERPRO_OPERATOR=11
+val SCE_POWERPRO_IDENTIFIER=12
+val SCE_POWERPRO_STRINGEOL=13
+val SCE_POWERPRO_VERBATIM=14
+val SCE_POWERPRO_ALTQUOTE=15
+val SCE_POWERPRO_FUNCTION=16
+# Lexical states for SCLEX_SML
+lex SML=SCLEX_SML SCE_SML_
+val SCE_SML_DEFAULT=0
+val SCE_SML_IDENTIFIER=1
+val SCE_SML_TAGNAME=2
+val SCE_SML_KEYWORD=3
+val SCE_SML_KEYWORD2=4
+val SCE_SML_KEYWORD3=5
+val SCE_SML_LINENUM=6
+val SCE_SML_OPERATOR=7
+val SCE_SML_NUMBER=8
+val SCE_SML_CHAR=9
+val SCE_SML_STRING=11
+val SCE_SML_COMMENT=12
+val SCE_SML_COMMENT1=13
+val SCE_SML_COMMENT2=14
+val SCE_SML_COMMENT3=15
+# Lexical state for SCLEX_MARKDOWN
+lex Markdown=SCLEX_MARKDOWN SCE_MARKDOWN_
+val SCE_MARKDOWN_DEFAULT=0
+val SCE_MARKDOWN_LINE_BEGIN=1
+val SCE_MARKDOWN_STRONG1=2
+val SCE_MARKDOWN_STRONG2=3
+val SCE_MARKDOWN_EM1=4
+val SCE_MARKDOWN_EM2=5
+val SCE_MARKDOWN_HEADER1=6
+val SCE_MARKDOWN_HEADER2=7
+val SCE_MARKDOWN_HEADER3=8
+val SCE_MARKDOWN_HEADER4=9
+val SCE_MARKDOWN_HEADER5=10
+val SCE_MARKDOWN_HEADER6=11
+val SCE_MARKDOWN_PRECHAR=12
+val SCE_MARKDOWN_ULIST_ITEM=13
+val SCE_MARKDOWN_OLIST_ITEM=14
+val SCE_MARKDOWN_BLOCKQUOTE=15
+val SCE_MARKDOWN_STRIKEOUT=16
+val SCE_MARKDOWN_HRULE=17
+val SCE_MARKDOWN_LINK=18
+val SCE_MARKDOWN_CODE=19
+val SCE_MARKDOWN_CODE2=20
+val SCE_MARKDOWN_CODEBK=21
 
 # Events
 
@@ -3286,19 +3758,5 @@ evt void CallTipClick=2021(int position)
 evt void AutoCSelection=2022(string text)
 evt void IndicatorClick=2023(int modifiers, int position)
 evt void IndicatorRelease=2024(int modifiers, int position)
-
-cat Deprecated
-
-# CARET_POLICY changed in 1.47
-fun void SetCaretPolicy=2369(int caretPolicy, int caretSlop)
-val CARET_CENTER=0x02
-val CARET_XEVEN=0x08
-val CARET_XJUMPS=0x10
-
-# The old name for SCN_UPDATEUI
-val SCN_CHECKBRACE=2007
-evt void PosChanged=2012(int position)
-
-# SCLEX_HTML should be used in preference to these.
-val SCLEX_ASP=29
-val SCLEX_PHP=30
+evt void AutoCCancelled=2025(void)
+evt void AutoCCharDeleted=2026(void)
index 9d23ce2a9180759f56d7889397d1ab5d972e5e0e..c60c4a21b95249d52d0bdb1461bf76015696e16a 100644 (file)
@@ -1,10 +1,10 @@
-// Scintilla source code edit control
+/* Scintilla source code edit control */
 /** @file ScintillaWidget.h
  ** Definition of Scintilla widget for GTK+.
  ** Only needed by GTK+ code but is harmless on other platforms.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/* Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+ * The License.txt file describes the conditions under which this software may be distributed. */
 
 #ifndef SCINTILLAWIDGET_H
 #define SCINTILLAWIDGET_H
index e107a0659caebd545912d0ca0f6d3b1e291daeb8..6f265f658095267c2c2221602566a92a5fcb981b 100644 (file)
@@ -12,13 +12,14 @@ namespace Scintilla {
 
 /**
  */
+
 class WindowAccessor : public Accessor {
        // Private so WindowAccessor objects can not be copied
        WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
        WindowAccessor &operator=(const WindowAccessor &) { return *this; }
 protected:
        WindowID id;
-       PropSet &props;
+       PropertyGet &props;
        int lenDoc;
 
        char styleBuf[bufferSize];
@@ -30,7 +31,7 @@ protected:
        bool InternalIsLeadByte(char ch);
        void Fill(int position);
 public:
-       WindowAccessor(WindowID id_, PropSet &props_) : 
+       WindowAccessor(WindowID id_, PropertyGet &props_) : 
                Accessor(), id(id_), props(props_), 
                lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
        }
diff --git a/src/stc/scintilla/src/Array.cpp b/src/stc/scintilla/src/Array.cpp
new file mode 100644 (file)
index 0000000..a2ec27b
--- /dev/null
@@ -0,0 +1,380 @@
+/** file Array.cpp
+* This file is defining a kind of tool for simulating std::vector
+* for using wx on OS which are not supporting the STL
+* @author foldink (foldink@gmail.com)
+* @date 26-February-2010
+*/
+
+#include <string.h>
+
+#include "Platform.h"
+#include "Scintilla.h"
+#include "Selection.h"
+#include "Array.h"
+
+SelectionRange& ArrayIterator::operator*()
+{
+       if ( m_idx >= m_parent->size() )
+               throw "Error access out of bounds";
+
+       return (*m_parent)[m_idx];
+}
+
+ArrayIterator ArrayIterator::operator++(int)
+{
+       ArrayIterator ret(*this);
+       ret.m_idx++;
+       return ret;
+}
+
+ArrayIterator& ArrayIterator::operator++()
+{
+       m_idx++;
+       return (*this);
+}
+
+ArrayIterator ArrayIterator::operator--(int)
+{
+       if ( m_idx == 0 )
+               throw "Error access out of bounds";
+
+       ArrayIterator ret(*this);
+       ret.m_idx--;
+       return ret;
+}
+
+ArrayIterator& ArrayIterator::operator--()
+{
+       if ( m_idx == 0 )
+
+
+               m_idx--;
+       return (*this);
+}
+
+ArrayIterator ArrayIterator::operator+(size_t idx)
+{
+       ArrayIterator ret(*this);
+       ret.m_idx += idx;
+       return ret;
+}
+
+ArrayIterator ArrayIterator::operator-(size_t idx)
+{
+       if ( idx > m_idx )
+               throw "Error access out of bounds";
+
+       ArrayIterator ret(*this);
+       ret.m_idx -= idx;
+       return ret;
+}
+
+ArrayIterator& ArrayIterator::operator+=(size_t idx)
+{
+       m_idx += idx;
+       return (*this);
+}
+
+ArrayIterator& ArrayIterator::operator-=(size_t idx)
+{
+       if ( idx > m_idx )
+               throw "Error access out of bounds";
+
+       m_idx -= idx;
+       return (*this);
+}
+
+bool ArrayIterator::operator!=(const ArrayIterator& rhs)
+{
+       if ( m_parent == rhs.m_parent && m_idx == rhs.m_idx )
+               return false;
+
+       return true;
+}
+
+bool ArrayIterator::operator==(const ArrayIterator& rhs)
+{
+       if ( m_parent == rhs.m_parent && m_idx == rhs.m_idx )
+               return true;
+
+       return false;
+}
+
+Array::Array( size_t len ):
+               m_data(0L),
+               m_size(0)
+{
+       if ( len == 0 )
+               return;
+
+       m_data = new SelectionRange[len];
+       m_size = len;
+}
+
+Array::Array( size_t len , const SelectionRange& val ):
+               m_data(0L),
+               m_size(0)
+{
+       if ( len == 0 )
+               return;
+
+       m_data = new SelectionRange[len];
+       m_size = len;
+
+       for ( size_t i = 0; i < len ; ++i )
+               *(m_data + i) = val;
+}
+
+Array::Array( const Array& rhs ):
+               m_data(0L),
+               m_size(0)
+{
+       if ( rhs.m_size == 0 )
+               return;
+
+       m_data = new SelectionRange[rhs.m_size];
+       m_size = rhs.m_size;
+       memcpy( m_data , rhs.m_data , m_size*sizeof(SelectionRange) );
+}
+
+Array::~Array()
+{
+       if ( m_data )
+               delete m_data;
+}
+
+Array& Array::operator=( const Array& rhs )
+{
+       if ( m_data )
+               delete m_data;
+
+       m_data = 0L;
+       m_size = 0;
+
+       if ( rhs.m_size == 0 )
+               return (*this);
+
+       m_data = new SelectionRange[rhs.m_size];
+       m_size = rhs.m_size;
+       memcpy( m_data , rhs.m_data , m_size*sizeof(SelectionRange) );
+
+       return (*this);
+}
+
+void Array::reserve( size_t len )
+{
+       if ( len <= m_size || len == 0 )
+               return;
+
+       SelectionRange* data = 0L;
+       data = new SelectionRange[len];
+
+       if ( m_data ) {
+               memcpy( data , m_data , m_size*sizeof(SelectionRange) );
+               delete m_data;
+               m_data = data;
+       } else
+               m_data = data;
+}
+
+void Array::push_back( const SelectionRange& val )
+{
+       if ( !m_data ) {
+               m_data = new SelectionRange[1];
+               *m_data = val;
+               m_size = 1;
+               return;
+       }
+
+       SelectionRange* data = 0L;
+       data = new SelectionRange[m_size+1];
+       memcpy( data , m_data , m_size*sizeof(SelectionRange) );
+       m_data = data;
+       *(m_data+m_size) = val;
+       m_size++;
+}
+
+void Array::pop_back( )
+{
+       if ( !m_data )
+               throw "Error access out of bounds";
+
+       m_size--;
+       SelectionRange* data = 0L;
+
+       if ( m_size > 0 ) {
+               data = new SelectionRange[m_size];
+               memcpy( data , m_data , m_size*sizeof(SelectionRange) );
+       }
+
+       delete m_data;
+       m_data = data;
+}
+
+void Array::insert( ArrayIterator it , SelectionRange& val )
+{
+       size_t idx = it.GetIdx();
+       SelectionRange* data = 0L;
+       if (!m_data) {
+               m_size = idx+1;
+               m_data = new SelectionRange[m_size];
+       } else if ( idx >= m_size ) {
+               data = new SelectionRange[idx+1];
+               memcpy( data , m_data , m_size*sizeof(SelectionRange) );
+               m_size = idx+1;
+               delete m_data;
+               m_data = data;
+       } else if ( idx == 0 ) {
+               data = new SelectionRange[m_size+1];
+               memcpy( data + 1 , m_data , m_size*sizeof(SelectionRange) );
+               delete m_data;
+               m_size++;
+               m_data = data;
+       } else {
+               data = new SelectionRange[m_size+1];
+               memcpy( data , m_data , idx*sizeof(SelectionRange) );
+               memcpy( data + idx + 1 , m_data + idx , (m_size-idx)*sizeof(SelectionRange) );
+               delete m_data;
+               m_size++;
+               m_data = data;
+       }
+
+       *(m_data + idx) = val;
+}
+
+void Array::erase( ArrayIterator it )
+{
+       size_t idx = it.GetIdx();
+       if (!m_data || idx >= m_size )
+               throw "Error access out of bounds";
+
+       SelectionRange* data = 0L;
+       if ( m_size == 1 ) {
+               delete m_data;
+               m_data = 0L;
+               return;
+       } else if ( idx == 0) {
+               data = new SelectionRange[m_size-1];
+               memcpy( data , m_data + 1 , (m_size-1)*sizeof(SelectionRange) );
+               delete m_data;
+               m_size--;
+               m_data = data;
+       } else {
+               data = new SelectionRange[m_size-1];
+               memcpy( data , m_data , (idx)*sizeof(SelectionRange) );
+               memcpy( data + idx , m_data + idx + 1 , (m_size-idx-1)*sizeof(SelectionRange) );
+               delete m_data;
+               m_size--;
+               m_data = data;
+       }
+}
+
+void Array::clear( )
+{
+       if ( !m_data )
+               return;
+
+       delete m_data;
+       m_data = 0L;
+       m_size = 0;
+}
+
+void Array::resize( size_t n , SelectionRange val )
+{
+       if ( (n == 0 && !m_data) || n <= m_size )
+               return;
+
+       if ( n == 0 ) {
+               delete m_data;
+               m_data = 0L;
+               m_size = 0;
+       }
+
+       SelectionRange* data = 0L;
+       data = new SelectionRange[n];
+       memcpy( data , m_data , m_size*sizeof(SelectionRange) );
+       delete m_data;
+       m_data = data;
+
+       for ( size_t i = m_size ; i < n ; ++i )
+               *( m_data + i ) = val;
+
+       m_size = n;
+}
+
+bool Array::operator==(const Array& rhs)
+{
+       if ( m_size != rhs.m_size )
+               return false;
+
+       if ( m_size == 0 && rhs.m_size == 0 )
+               return true;
+
+       for ( size_t i = 0 ; i < m_size ; ++i )
+               if ( ! ((*(m_data +i)) == (*(rhs.m_data+i))) )
+                       return false;
+
+       return true;
+}
+
+ArrayIterator Array::begin()
+{
+       ArrayIterator ret(this,0);
+       return ret;
+}
+
+ArrayIterator Array::end()
+{
+       ArrayIterator ret(this,m_size);
+       return ret;
+}
+
+
+int partition(Array &array, int top, int bottom)
+{
+       SelectionRange x = array[top];
+       int i = top - 1;
+       int j = bottom + 1;
+       SelectionRange temp;
+       do {
+               do {
+                       j--;
+               } while (x < array[j]);
+
+               do {
+                       i++;
+               } while (array[j] < x);
+
+               if (i < j) {
+                       temp = array[i];
+                       array[i] = array[j];
+                       array[j] = temp;
+               }
+       } while (i < j);
+       return j;           // returns middle subscript
+}
+
+void quicksort(Array &num, int top, int bottom)
+{
+       // top = subscript of beginning of array
+       // bottom = subscript of end of array
+
+       int middle;
+       if (top < bottom) {
+               middle = partition(num, top, bottom);
+               quicksort(num, top, middle);   // sort first section
+               quicksort(num, middle+1, bottom);    // sort second section
+       }
+       return;
+}
+
+void ArraySort( ArrayIterator start , ArrayIterator finish )
+{
+       if ( start.m_parent != finish.m_parent )
+               throw "Invalid iterators parent mismatch";
+       
+       if ( start.m_idx >= finish.m_idx-1 )
+               throw "Invalid iterators are refering to bad values";
+               
+       quicksort( *(start.m_parent) , start.m_idx , finish.m_idx-1 );
+}
diff --git a/src/stc/scintilla/src/Array.h b/src/stc/scintilla/src/Array.h
new file mode 100644 (file)
index 0000000..e556912
--- /dev/null
@@ -0,0 +1,209 @@
+/** file Array.h
+* This file is defining a kind of tool for simulating std::vector
+* for using wx on OS which are not supporting the STL
+* @author foldink (foldink@gmail.com)
+* @date 26-February-2010
+*/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include <stdio.h>
+/* defines */
+class Array;
+class ArrayIterator;
+//struct SelectionRange;
+
+/**
+ * @class ArrayIterator
+ * @brief This class is used to simulate an iterator in the array
+ * @author foldink (foldink@gmail.com)
+ * @date 26-February-2010
+ */
+class ArrayIterator
+{
+       friend class Array;
+       
+public :
+       /** ctor 
+        * @param parent, parented array to store positions in
+        */
+       ArrayIterator( Array* parent , size_t idx ):
+               m_parent(parent),
+               m_idx(idx) {};
+       
+       /** dtor */
+       virtual ~ArrayIterator()
+       {
+               m_parent = 0L;
+       }
+       
+       /** copy ctor */
+       ArrayIterator(const ArrayIterator& rhs):
+               m_parent(rhs.m_parent),
+               m_idx(rhs.m_idx) { }
+       
+       /***********************************************************************
+       * OPERATOR OVERLOADS
+       **********************************************************************/
+       /** the equal operator is used to overload copy for the array */
+       ArrayIterator& operator=(const ArrayIterator& rhs)
+       {
+               m_parent = rhs.m_parent;
+               m_idx = rhs.m_idx;
+               
+               return (*this);
+       }
+       
+       /** Smart pointer part overload as it is in standard templates arrays */
+       SelectionRange& operator*();
+       
+       /** a++ operator */
+       ArrayIterator operator++(int);
+       
+       /** ++a operator */
+       ArrayIterator& operator++();
+       
+       /** a-- operator */
+       ArrayIterator operator--(int);
+       
+       /** --a operator */
+       ArrayIterator& operator--();
+       
+       /** a + int operator */
+       ArrayIterator operator+(size_t idx);
+       
+       /** a - int operator */
+       ArrayIterator operator-(size_t idx);
+       
+       /** a += int operator */
+       ArrayIterator& operator+=(size_t idx);
+       
+       /** a -= int operator */
+       ArrayIterator& operator-=(size_t idx);
+       
+       /** != operator */
+       bool operator!=(const ArrayIterator& rhs);
+       
+       /** == operator */
+       bool operator==(const ArrayIterator& rhs);
+       
+       /** Set the idx if needed */
+       void SetIdx(size_t idx) {m_idx = idx;};
+       /** Get the idx if needed */
+       size_t GetIdx() {return m_idx;};
+       
+       Array* m_parent;
+       size_t m_idx;
+};
+
+/** 
+ * @class Array
+ * @brief simple array of SelectionRange
+ * @brief This class is used to simulate an iterator in the array
+ * @author foldink (foldink@gmail.com)
+ * @date 26-February-2010
+ */
+class Array
+{
+       friend class ArrayIterator;
+       
+public :
+       /** default ctor taking the len in input */ 
+       Array( size_t len = 0 );
+       
+       /** ctor with len and initial value */
+       Array( size_t len , const SelectionRange& val );
+       
+       /** copy ctor */
+       Array( const Array& rhs );
+       
+       /** dtor */
+       virtual ~Array();
+       
+       /** operator= */
+       Array& operator=( const Array& rhs );
+       
+       /** operator[] */
+       SelectionRange& operator[]( size_t idx )
+       {
+               if( idx >= m_size )
+                       throw "Error access to vector range out of bounds";
+               
+               return *(m_data + idx);
+       }
+       
+       /** operator[] */
+       const SelectionRange& operator[]( size_t idx ) const
+       {
+               if( idx >= m_size )
+                       throw "Error access to vector range out of bounds";
+               
+               return *(m_data + idx);
+       }
+       
+       /** Get the size */
+       size_t size() const {return m_size;};
+       
+       /** check if the array is empty or not */
+       bool empty() const {return (m_size == 0);};
+       
+       /** reserve */
+       void reserve( size_t len );
+       
+       /** front */
+       SelectionRange& front() { 
+               if( !m_data )
+                       throw "Trying to access to an uninitialized array";
+                       
+               return (*m_data);
+       }
+       
+       /** back */
+       SelectionRange& back() {
+               if( !m_data )
+                       throw "Trying to access to an uninitialized array";
+                       
+               return *(m_data + m_size-1);
+       }
+       
+       /** push back */
+       void push_back( const SelectionRange& val );
+       
+       /** pop back */
+       void pop_back( );
+       
+       /** insert before the given iterator position */
+       void insert( ArrayIterator it , SelectionRange& val );
+       
+       /** erase */
+       void erase( ArrayIterator it );
+       
+       /** clear */
+       void clear( );
+       
+       /** resize */
+       void resize( size_t n , SelectionRange val = SelectionRange() );
+       
+       /** == operator */
+       bool operator==(const Array& rhs);
+       
+       /** begin */
+       ArrayIterator begin();
+       
+       /** end */
+       ArrayIterator end();
+
+private :
+       SelectionRange* m_data;
+       size_t m_size;
+};
+
+/** 
+ * @brief Sorting method for a replace in Editor.cxx
+ * @author foldink (foldink@gmail.com)
+ * @date 26-February-2010
+ */
+extern void ArraySort( ArrayIterator start , ArrayIterator finish );
+
+#endif
index af6154ea13bf0ebb14b588c698a02e9f0565ffa7..86c64df56355dc0885279c041722b152a50373e2 100644 (file)
@@ -11,7 +11,7 @@
 
 #include "Platform.h"
 
-#include "PropSet.h"
+#include "CharClassify.h"
 #include "AutoComplete.h"
 
 #ifdef SCI_NAMESPACE
index 5f795d561a872282f939c47184fe2cddcf44e29b..3ea2d48fd31b65b402bf160760205f18244b9785 100644 (file)
@@ -229,7 +229,7 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
        offsetMain = insetX;    // initial alignment assuming no arrows
        PaintContents(surfaceWindow, true);
 
-#if !defined(__APPLE__) || defined(__WX__)
+#ifndef __APPLE__
        // OSX doesn't put borders on "help tags"
        // Draw a raised border around the edges of the window
        surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
@@ -254,11 +254,9 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
                                  const char *faceName, int size,
                                  int codePage_, int characterSet, Window &wParent) {
        clickPlace = 0;
-       if (val)
-               delete []val;
+       delete []val;
+       val = 0;
        val = new char[strlen(defn) + 1];
-       if (!val)
-               return PRectangle();
        strcpy(val, defn);
        codePage = codePage_;
        Surface *surfaceMeasure = Surface::Allocate();
index bdf1123c74a8447a896433ee060befc6a7999b56..a64755fd18b2b77f8bc4837fbca21792c22b579c 100644 (file)
@@ -27,8 +27,8 @@ class CallTip {
        bool useStyleCallTip;   // if true, STYLE_CALLTIP should be used
 
        // Private so CallTip objects can not be copied
-       CallTip(const CallTip &) {}
-       CallTip &operator=(const CallTip &) { return *this; }
+       CallTip(const CallTip &);
+       CallTip &operator=(const CallTip &);
        void DrawChunk(Surface *surface, int &x, const char *s,
                int posStart, int posEnd, int ytext, PRectangle rcClient,
                bool highlight, bool draw);
index 6d04e04c9141de3cfbc9bbe748ab4b175c14ae20..be0440304d1bac27d7e1c427ade6e95661d28fef 100644 (file)
 using namespace Scintilla;
 #endif
 
-MarkerHandleSet::MarkerHandleSet() {
-       root = 0;
-}
-
-MarkerHandleSet::~MarkerHandleSet() {
-       MarkerHandleNumber *mhn = root;
-       while (mhn) {
-               MarkerHandleNumber *mhnToFree = mhn;
-               mhn = mhn->next;
-               delete mhnToFree;
-       }
-       root = 0;
-}
-
-int MarkerHandleSet::Length() const {
-       int c = 0;
-       MarkerHandleNumber *mhn = root;
-       while (mhn) {
-               c++;
-               mhn = mhn->next;
-       }
-       return c;
-}
-
-int MarkerHandleSet::NumberFromHandle(int handle) const {
-       MarkerHandleNumber *mhn = root;
-       while (mhn) {
-               if (mhn->handle == handle) {
-                       return mhn->number;
-               }
-               mhn = mhn->next;
-       }
-       return - 1;
-}
-
-int MarkerHandleSet::MarkValue() const {
-       unsigned int m = 0;
-       MarkerHandleNumber *mhn = root;
-       while (mhn) {
-               m |= (1 << mhn->number);
-               mhn = mhn->next;
-       }
-       return m;
-}
-
-bool MarkerHandleSet::Contains(int handle) const {
-       MarkerHandleNumber *mhn = root;
-       while (mhn) {
-               if (mhn->handle == handle) {
-                       return true;
-               }
-               mhn = mhn->next;
-       }
-       return false;
-}
-
-bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
-       MarkerHandleNumber *mhn = new MarkerHandleNumber;
-       if (!mhn)
-               return false;
-       mhn->handle = handle;
-       mhn->number = markerNum;
-       mhn->next = root;
-       root = mhn;
-       return true;
-}
-
-void MarkerHandleSet::RemoveHandle(int handle) {
-       MarkerHandleNumber **pmhn = &root;
-       while (*pmhn) {
-               MarkerHandleNumber *mhn = *pmhn;
-               if (mhn->handle == handle) {
-                       *pmhn = mhn->next;
-                       delete mhn;
-                       return;
-               }
-               pmhn = &((*pmhn)->next);
-       }
-}
-
-bool MarkerHandleSet::RemoveNumber(int markerNum) {
-       bool performedDeletion = false;
-       MarkerHandleNumber **pmhn = &root;
-       while (*pmhn) {
-               MarkerHandleNumber *mhn = *pmhn;
-               if (mhn->number == markerNum) {
-                       *pmhn = mhn->next;
-                       delete mhn;
-                       performedDeletion = true;
-               } else {
-                       pmhn = &((*pmhn)->next);
-               }
-       }
-       return performedDeletion;
-}
-
-void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
-       MarkerHandleNumber **pmhn = &root;
-       while (*pmhn) {
-               pmhn = &((*pmhn)->next);
-       }
-       *pmhn = other->root;
-       other->root = 0;
-}
-
-LineVector::LineVector() : starts(256) {
-       handleCurrent = 1;
-
+LineVector::LineVector() : starts(256), perLine(0) {
        Init();
 }
 
 LineVector::~LineVector() {
        starts.DeleteAll();
-       for (int line = 0; line < markers.Length(); line++) {
-               delete markers[line];
-               markers[line] = 0;
-       }
-       markers.DeleteAll();
-       levels.DeleteAll();
 }
 
 void LineVector::Init() {
        starts.DeleteAll();
-       for (int line = 0; line < markers.Length(); line++) {
-               delete markers[line];
-               markers[line] = 0;
+       if (perLine) {
+               perLine->Init();
        }
-       markers.DeleteAll();
-       levels.DeleteAll();
-}
-
-void LineVector::ExpandLevels(int sizeNew) {
-       levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
-}
-
-void LineVector::ClearLevels() {
-       levels.DeleteAll();
 }
 
-int LineVector::SetLevel(int line, int level) {
-       int prev = 0;
-       if ((line >= 0) && (line < Lines())) {
-               if (!levels.Length()) {
-                       ExpandLevels(Lines() + 1);
-               }
-               prev = levels[line];
-               if (prev != level) {
-                       levels[line] = level;
-               }
-       }
-       return prev;
-}
-
-int LineVector::GetLevel(int line) {
-       if (levels.Length() && (line >= 0) && (line < Lines())) {
-               return levels[line];
-       } else {
-               return SC_FOLDLEVELBASE;
-       }
+void LineVector::SetPerLine(PerLine *pl) {
+       perLine = pl;
 }
 
 void LineVector::InsertText(int line, int delta) {
@@ -188,15 +46,8 @@ void LineVector::InsertText(int line, int delta) {
 
 void LineVector::InsertLine(int line, int position) {
        starts.InsertPartition(line, position);
-       if (markers.Length()) {
-               markers.Insert(line, 0);
-       }
-       if (levels.Length()) {
-               int level = SC_FOLDLEVELBASE;
-               if ((line > 0) && (line < Lines())) {
-                       level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
-               }
-               levels.InsertValue(line, 1, level);
+       if (perLine) {
+               perLine->InsertLine(line);
        }
 }
 
@@ -206,108 +57,21 @@ void LineVector::SetLineStart(int line, int position) {
 
 void LineVector::RemoveLine(int line) {
        starts.RemovePartition(line);
-       // Retain the markers from the deleted line by oring them into the previous line
-       if (markers.Length()) {
-               if (line > 0) {
-                       MergeMarkers(line - 1);
-               }
-               markers.Delete(line);
-       }
-       if (levels.Length()) {
-               // Move up following lines but merge header flag from this line
-               // to line before to avoid a temporary disappearence causing expansion.
-               int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
-               levels.Delete(line);
-               if (line > 0)
-                       levels[line-1] |= firstHeader;
+       if (perLine) {
+               perLine->RemoveLine(line);
        }
 }
 
-int LineVector::LineFromPosition(int pos) {
+int LineVector::LineFromPosition(int pos) const {
        return starts.PartitionFromPosition(pos);
 }
 
-int LineVector::MarkValue(int line) {
-       if (markers.Length() && markers[line])
-               return markers[line]->MarkValue();
-       else
-               return 0;
-}
-
-int LineVector::AddMark(int line, int markerNum) {
-       handleCurrent++;
-       if (!markers.Length()) {
-               // No existing markers so allocate one element per line
-               markers.InsertValue(0, Lines(), 0);
-       }
-       if (!markers[line]) {
-               // Need new structure to hold marker handle
-               markers[line] = new MarkerHandleSet();
-               if (!markers[line])
-                       return - 1;
-       }
-       markers[line]->InsertHandle(handleCurrent, markerNum);
-
-       return handleCurrent;
-}
-
-void LineVector::MergeMarkers(int pos) {
-       if (markers[pos + 1] != NULL) {
-               if (markers[pos] == NULL)
-                       markers[pos] = new MarkerHandleSet;
-               markers[pos]->CombineWith(markers[pos + 1]);
-               delete markers[pos + 1];
-               markers[pos + 1] = NULL;
-       }
-}
-
-void LineVector::DeleteMark(int line, int markerNum, bool all) {
-       if (markers.Length() && markers[line]) {
-               if (markerNum == -1) {
-                       delete markers[line];
-                       markers[line] = NULL;
-               } else {
-                       bool performedDeletion = markers[line]->RemoveNumber(markerNum);
-                       while (all && performedDeletion) {
-                               performedDeletion = markers[line]->RemoveNumber(markerNum);
-                       }
-                       if (markers[line]->Length() == 0) {
-                               delete markers[line];
-                               markers[line] = NULL;
-                       }
-               }
-       }
-}
-
-void LineVector::DeleteMarkFromHandle(int markerHandle) {
-       int line = LineFromHandle(markerHandle);
-       if (line >= 0) {
-               markers[line]->RemoveHandle(markerHandle);
-               if (markers[line]->Length() == 0) {
-                       delete markers[line];
-                       markers[line] = NULL;
-               }
-       }
-}
-
-int LineVector::LineFromHandle(int markerHandle) {
-       if (markers.Length()) {
-               for (int line = 0; line < Lines(); line++) {
-                       if (markers[line]) {
-                               if (markers[line]->Contains(markerHandle)) {
-                                       return line;
-                               }
-                       }
-               }
-       }
-       return -1;
-}
-
 Action::Action() {
        at = startAction;
        position = 0;
        data = 0;
        lenData = 0;
+       mayCoalesce = false;
 }
 
 Action::~Action() {
@@ -387,8 +151,6 @@ void UndoHistory::EnsureUndoRoom() {
                // Run out of undo nodes so extend the array
                int lenActionsNew = lenActions * 2;
                Action *actionsNew = new Action[lenActionsNew];
-               if (!actionsNew)
-                       return;
                for (int act = 0; act <= currentAction; act++)
                        actionsNew[act].Grab(&actions[act]);
                delete []actions;
@@ -398,7 +160,7 @@ void UndoHistory::EnsureUndoRoom() {
 }
 
 void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData,
-       bool &startSequence) {
+       bool &startSequence, bool mayCoalesce) {
        EnsureUndoRoom();
        //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction);
        //Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at,
@@ -410,25 +172,35 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
        if (currentAction >= 1) {
                if (0 == undoSequenceDepth) {
                        // Top level actions may not always be coalesced
-                       Action &actPrevious = actions[currentAction - 1];
+                       int targetAct = -1;
+                       const Action *actPrevious = &(actions[currentAction + targetAct]);
+                       // Container actions may forward the coalesce state of Scintilla Actions.
+                       while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) {
+                               targetAct--;
+                               actPrevious = &(actions[currentAction + targetAct]);
+                       }
                        // See if current action can be coalesced into previous action
                        // Will work if both are inserts or deletes and position is same
-                       if (at != actPrevious.at) {
+                       if (currentAction == savePoint) {
+                               currentAction++;
+                       } else if (!actions[currentAction].mayCoalesce) {
+                               // Not allowed to coalesce if this set
+                               currentAction++;
+                       } else if (!mayCoalesce || !actPrevious->mayCoalesce) {
                                currentAction++;
-                       } else if (currentAction == savePoint) {
+                       } else if (at == containerAction || actions[currentAction].at == containerAction) {
+                               ;       // A coalescible containerAction
+                       } else if ((at != actPrevious->at) && (actPrevious->at != startAction)) {
                                currentAction++;
                        } else if ((at == insertAction) &&
-                                  (position != (actPrevious.position + actPrevious.lenData))) {
+                                  (position != (actPrevious->position + actPrevious->lenData))) {
                                // Insertions must be immediately after to coalesce
                                currentAction++;
-                       } else if (!actions[currentAction].mayCoalesce) {
-                               // Not allowed to coalesce if this set
-                               currentAction++;
                        } else if (at == removeAction) {
                                if ((lengthData == 1) || (lengthData == 2)){
-                                       if ((position + lengthData) == actPrevious.position) {
+                                       if ((position + lengthData) == actPrevious->position) {
                                                ; // Backspace -> OK
-                                       } else if (position == actPrevious.position) {
+                                       } else if (position == actPrevious->position) {
                                                ; // Delete -> OK
                                        } else {
                                                // Removals must be at same position to coalesce
@@ -451,7 +223,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
                currentAction++;
        }
        startSequence = oldCurrentAction != currentAction;
-       actions[currentAction].Create(at, position, data, lengthData);
+       actions[currentAction].Create(at, position, data, lengthData, mayCoalesce);
        currentAction++;
        actions[currentAction].Create(startAction);
        maxAction = currentAction;
@@ -587,6 +359,10 @@ char CellBuffer::StyleAt(int position) {
        return style.ValueAt(position);
 }
 
+const char *CellBuffer::BufferPointer() { 
+       return substance.BufferPointer();
+}
+
 // The char* returned is to an allocation owned by the undo history
 const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) {
        char *data = 0;
@@ -662,6 +438,10 @@ void CellBuffer::Allocate(int newSize) {
        style.ReAllocate(newSize);
 }
 
+void CellBuffer::SetPerLine(PerLine *pl) {
+       lv.SetPerLine(pl);
+}
+
 int CellBuffer::Lines() const {
        return lv.Lines();
 }
@@ -691,53 +471,14 @@ bool CellBuffer::IsSavePoint() {
        return uh.IsSavePoint();
 }
 
-int CellBuffer::AddMark(int line, int markerNum) {
-       if ((line >= 0) && (line < Lines())) {
-               return lv.AddMark(line, markerNum);
-       }
-       return - 1;
-}
-
-void CellBuffer::DeleteMark(int line, int markerNum) {
-       if ((line >= 0) && (line < Lines())) {
-               lv.DeleteMark(line, markerNum, false);
-       }
-}
-
-void CellBuffer::DeleteMarkFromHandle(int markerHandle) {
-       lv.DeleteMarkFromHandle(markerHandle);
-}
-
-int CellBuffer::GetMark(int line) {
-       if ((line >= 0) && (line < Lines()))
-               return lv.MarkValue(line);
-       return 0;
-}
-
-void CellBuffer::DeleteAllMarks(int markerNum) {
-       for (int line = 0; line < Lines(); line++) {
-               lv.DeleteMark(line, markerNum, true);
-       }
-}
-
-int CellBuffer::LineFromHandle(int markerHandle) {
-       return lv.LineFromHandle(markerHandle);
-}
-
 // Without undo
 
 void CellBuffer::InsertLine(int line, int position) {
        lv.InsertLine(line, position);
-       if (lineStates.Length()) {
-               lineStates.Insert(line, 0);
-       }
 }
 
 void CellBuffer::RemoveLine(int line) {
        lv.RemoveLine(line);
-       if (lineStates.Length()) {
-               lineStates.Delete(line);
-       }
 }
 
 void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
@@ -857,6 +598,11 @@ void CellBuffer::EndUndoAction() {
        uh.EndUndoAction();
 }
 
+void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
+       bool startSequence;
+       uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
+}
+
 void CellBuffer::DeleteUndoHistory() {
        uh.DeleteUndoHistory();
 }
@@ -905,30 +651,3 @@ void CellBuffer::PerformRedoStep() {
        uh.CompletedRedoStep();
 }
 
-int CellBuffer::SetLineState(int line, int state) {
-       lineStates.EnsureLength(line + 1);
-       int stateOld = lineStates[line];
-       lineStates[line] = state;
-       return stateOld;
-}
-
-int CellBuffer::GetLineState(int line) {
-       lineStates.EnsureLength(line + 1);
-       return lineStates[line];
-}
-
-int CellBuffer::GetMaxLineState() {
-       return lineStates.Length();
-}
-
-int CellBuffer::SetLevel(int line, int level) {
-       return lv.SetLevel(line, level);
-}
-
-int CellBuffer::GetLevel(int line) {
-       return lv.GetLevel(line);
-}
-
-void CellBuffer::ClearLevels() {
-       lv.ClearLevels();
-}
index 4f654a8fd99aec2651734f0dbeccc2e710f9bf76..3381c19c2c6ad90c3b6726d930d3af5fadeaf4f6 100644 (file)
 namespace Scintilla {
 #endif
 
-/**
- * This holds the marker identifier and the marker type to display.
- * MarkerHandleNumbers are members of lists.
- */
-struct MarkerHandleNumber {
-       int handle;
-       int number;
-       MarkerHandleNumber *next;
-};
-
-/**
- * A marker handle set contains any number of MarkerHandleNumbers.
- */
-class MarkerHandleSet {
-       MarkerHandleNumber *root;
-
+// Interface to per-line data that wants to see each line insertion and deletion
+class PerLine {
 public:
-       MarkerHandleSet();
-       ~MarkerHandleSet();
-       int Length() const;
-       int NumberFromHandle(int handle) const;
-       int MarkValue() const;  ///< Bit set of marker numbers.
-       bool Contains(int handle) const;
-       bool InsertHandle(int handle, int markerNum);
-       void RemoveHandle(int handle);
-       bool RemoveNumber(int markerNum);
-       void CombineWith(MarkerHandleSet *other);
+       virtual ~PerLine() {}
+       virtual void Init()=0;
+       virtual void InsertLine(int)=0;
+       virtual void RemoveLine(int)=0;
 };
 
 /**
@@ -47,21 +27,14 @@ public:
 class LineVector {
 
        Partitioning starts;
-       SplitVector<MarkerHandleSet *> markers;
-       SplitVector<int> levels;
-       /// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big.
-       int handleCurrent;
+       PerLine *perLine;
 
 public:
 
        LineVector();
        ~LineVector();
        void Init();
-
-       void ExpandLevels(int sizeNew=-1);
-       void ClearLevels();
-       int SetLevel(int line, int level);
-       int GetLevel(int line);
+       void SetPerLine(PerLine *pl);
 
        void InsertText(int line, int delta);
        void InsertLine(int line, int position);
@@ -70,7 +43,7 @@ public:
        int Lines() const {
                return starts.Partitions();
        }
-       int LineFromPosition(int pos);
+       int LineFromPosition(int pos) const;
        int LineStart(int line) const {
                return starts.PositionFromPartition(line);
        }
@@ -81,9 +54,18 @@ public:
        void DeleteMark(int line, int markerNum, bool all);
        void DeleteMarkFromHandle(int markerHandle);
        int LineFromHandle(int markerHandle);
+
+       void ClearLevels();
+       int SetLevel(int line, int level);
+       int GetLevel(int line);
+
+       int SetLineState(int line, int state);
+       int GetLineState(int line);
+       int GetMaxLineState();
+
 };
 
-enum actionType { insertAction, removeAction, startAction };
+enum actionType { insertAction, removeAction, startAction, containerAction };
 
 /**
  * Actions are used to store all the information required to perform one undo/redo step.
@@ -120,7 +102,7 @@ public:
        UndoHistory();
        ~UndoHistory();
 
-       void AppendAction(actionType at, int position, char *data, int length, bool &startSequence);
+       void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, bool mayCoalesce=true);
 
        void BeginUndoAction();
        void EndUndoAction();
@@ -160,8 +142,6 @@ private:
 
        LineVector lv;
 
-       SplitVector<int> lineStates;
-
 public:
 
        CellBuffer();
@@ -171,12 +151,14 @@ public:
        char CharAt(int position) const;
        void GetCharRange(char *buffer, int position, int lengthRetrieve);
        char StyleAt(int position);
+       const char *BufferPointer();
 
        int Length() const;
        void Allocate(int newSize);
+       void SetPerLine(PerLine *pl);
        int Lines() const;
        int LineStart(int line) const;
-       int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
+       int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
        void InsertLine(int line, int position);
        void RemoveLine(int line);
        const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
@@ -196,14 +178,6 @@ public:
        void SetSavePoint();
        bool IsSavePoint();
 
-       /// Line marker functions
-       int AddMark(int line, int markerNum);
-       void DeleteMark(int line, int markerNum);
-       void DeleteMarkFromHandle(int markerHandle);
-       int GetMark(int line);
-       void DeleteAllMarks(int markerNum);
-       int LineFromHandle(int markerHandle);
-
        /// Actions without undo
        void BasicInsertString(int position, const char *s, int insertLength);
        void BasicDeleteChars(int position, int deleteLength);
@@ -212,6 +186,7 @@ public:
        bool IsCollectingUndo();
        void BeginUndoAction();
        void EndUndoAction();
+       void AddUndoAction(int token, bool mayCoalesce);
        void DeleteUndoHistory();
 
        /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
@@ -224,14 +199,6 @@ public:
        int StartRedo();
        const Action &GetRedoStep() const;
        void PerformRedoStep();
-
-       int SetLineState(int line, int state);
-       int GetLineState(int line);
-       int GetMaxLineState();
-
-       int SetLevel(int line, int level);
-       int GetLevel(int line);
-       void ClearLevels();
 };
 
 #ifdef SCI_NAMESPACE
index acab4b2295522ff19d1e1f54c71a84c661c6df0e..bbd25a0f8db3f0011916b72ee3dec437c080a81f 100644 (file)
@@ -5,6 +5,7 @@
 // Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#include <stdlib.h>
 #include <ctype.h>
 
 #include "CharClassify.h"
@@ -41,3 +42,37 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
                }
        }
 }
+
+int CompareCaseInsensitive(const char *a, const char *b) {
+       while (*a && *b) {
+               if (*a != *b) {
+                       char upperA = MakeUpperCase(*a);
+                       char upperB = MakeUpperCase(*b);
+                       if (upperA != upperB)
+                               return upperA - upperB;
+               }
+               a++;
+               b++;
+       }
+       // Either *a or *b is nul
+       return *a - *b;
+}
+
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
+       while (*a && *b && len) {
+               if (*a != *b) {
+                       char upperA = MakeUpperCase(*a);
+                       char upperB = MakeUpperCase(*b);
+                       if (upperA != upperB)
+                               return upperA - upperB;
+               }
+               a++;
+               b++;
+               len--;
+       }
+       if (len == 0)
+               return 0;
+       else
+               // Either *a or *b is nul
+               return *a - *b;
+}
index 881d3a114b3db12fbbe8e4e60214518952accc66..d746fe02dd59769710c8ea2dac82351aabbf17e1 100644 (file)
@@ -2,7 +2,7 @@
 /** @file CharClassify.h
  ** Character classifications used by Document and RESearch.
  **/
-// Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 2006-2009 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef CHARCLASSIFY_H
@@ -22,4 +22,16 @@ private:
        enum { maxChar=256 };
        unsigned char charClass[maxChar];    // not type cc to save space
 };
+
+// These functions are implemented because each platform calls them something different.
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+inline char MakeUpperCase(char ch) {
+       if (ch < 'a' || ch > 'z')
+               return ch;
+       else
+               return static_cast<char>(ch - 'a' + 'A');
+}
+
 #endif
index ff8d0fbcfcb374c404399f7adb74c615b6ebc0f0..a5d1adbbb14b61701a77064e936f7d6ac7d76c35 100644 (file)
@@ -17,6 +17,7 @@
 #include "Partitioning.h"
 #include "RunStyles.h"
 #include "CellBuffer.h"
+#include "PerLine.h"
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
@@ -73,8 +74,15 @@ Document::Document() {
        lenWatchers = 0;
 
        matchesValid = false;
-       pre = 0;
-       substituted = 0;
+       regex = 0;
+
+       perLineData[ldMarkers] = new LineMarkers();
+       perLineData[ldLevels] = new LineLevels();
+       perLineData[ldState] = new LineState();
+       perLineData[ldMargin] = new LineAnnotation();
+       perLineData[ldAnnotation] = new LineAnnotation();
+
+       cb.SetPerLine(this);
 }
 
 Document::~Document() {
@@ -82,12 +90,35 @@ Document::~Document() {
                watchers[i].watcher->NotifyDeleted(this, watchers[i].userData);
        }
        delete []watchers;
+       for (int j=0; j<ldSize; j++) {
+               delete perLineData[j];
+               perLineData[j] = 0;
+       }
        watchers = 0;
        lenWatchers = 0;
-       delete pre;
-       pre = 0;
-       delete []substituted;
-       substituted = 0;
+       delete regex;
+       regex = 0;
+}
+
+void Document::Init() {
+       for (int j=0; j<ldSize; j++) {
+               if (perLineData[j])
+                       perLineData[j]->Init();
+       }
+}
+
+void Document::InsertLine(int line) {
+       for (int j=0; j<ldSize; j++) {
+               if (perLineData[j])
+                       perLineData[j]->InsertLine(line);
+       }
+}
+
+void Document::RemoveLine(int line) {
+       for (int j=0; j<ldSize; j++) {
+               if (perLineData[j])
+                       perLineData[j]->RemoveLine(line);
+       }
 }
 
 // Increase reference count and return its previous value.
@@ -109,42 +140,58 @@ void Document::SetSavePoint() {
        NotifySavePoint(true);
 }
 
+int Document::GetMark(int line) { 
+       return static_cast<LineMarkers*>(perLineData[ldMarkers])->MarkValue(line); 
+}
+
 int Document::AddMark(int line, int markerNum) {
-       int prev = cb.AddMark(line, markerNum);
-       DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
-       NotifyModified(mh);
-       return prev;
+       if (line <= LinesTotal()) {
+               int prev = static_cast<LineMarkers*>(perLineData[ldMarkers])->
+                       AddMark(line, markerNum, LinesTotal());
+               DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+               NotifyModified(mh);
+               return prev;
+       } else {
+               return 0;
+       }
 }
 
 void Document::AddMarkSet(int line, int valueSet) {
        unsigned int m = valueSet;
        for (int i = 0; m; i++, m >>= 1)
                if (m & 1)
-                       cb.AddMark(line, i);
+                       static_cast<LineMarkers*>(perLineData[ldMarkers])->
+                               AddMark(line, i, LinesTotal());
        DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
        NotifyModified(mh);
 }
 
 void Document::DeleteMark(int line, int markerNum) {
-       cb.DeleteMark(line, markerNum);
+       static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
        DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
        NotifyModified(mh);
 }
 
 void Document::DeleteMarkFromHandle(int markerHandle) {
-       cb.DeleteMarkFromHandle(markerHandle);
+       static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
        DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
        mh.line = -1;
        NotifyModified(mh);
 }
 
 void Document::DeleteAllMarks(int markerNum) {
-       cb.DeleteAllMarks(markerNum);
+       for (int line = 0; line < LinesTotal(); line++) {
+               static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true);
+       }
        DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
        mh.line = -1;
        NotifyModified(mh);
 }
 
+int Document::LineFromHandle(int markerHandle) { 
+       return static_cast<LineMarkers*>(perLineData[ldMarkers])->LineFromHandle(markerHandle); 
+}
+
 int Document::LineStart(int line) const {
        return cb.LineStart(line);
 }
@@ -162,18 +209,22 @@ int Document::LineEnd(int line) const {
        }
 }
 
-int Document::LineFromPosition(int pos) {
+int Document::LineFromPosition(int pos) const {
        return cb.LineFromPosition(pos);
 }
 
-int Document::LineEndPosition(int position) {
+int Document::LineEndPosition(int position) const {
        return LineEnd(LineFromPosition(position));
 }
 
-int Document::VCHomePosition(int position) {
+bool Document::IsLineEndPosition(int position) const {
+       return LineEnd(LineFromPosition(position)) == position;
+}
+
+int Document::VCHomePosition(int position) const {
        int line = LineFromPosition(position);
        int startPosition = LineStart(line);
-       int endLine = LineStart(line + 1) - 1;
+       int endLine = LineEnd(line);
        int startText = startPosition;
        while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t' ) )
                startText++;
@@ -184,7 +235,7 @@ int Document::VCHomePosition(int position) {
 }
 
 int Document::SetLevel(int line, int level) {
-       int prev = cb.SetLevel(line, level);
+       int prev = static_cast<LineLevels*>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
        if (prev != level) {
                DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
                                   LineStart(line), 0, 0, 0, line);
@@ -195,6 +246,14 @@ int Document::SetLevel(int line, int level) {
        return prev;
 }
 
+int Document::GetLevel(int line) { 
+       return static_cast<LineLevels*>(perLineData[ldLevels])->GetLevel(line); 
+}
+
+void Document::ClearLevels() { 
+       static_cast<LineLevels*>(perLineData[ldLevels])->ClearLevels(); 
+}
+
 static bool IsSubordinate(int levelStart, int levelTry) {
        if (levelTry & SC_FOLDLEVELWHITEFLAG)
                return true;
@@ -506,21 +565,27 @@ int Document::Undo() {
                                if (action.at == removeAction) {
                                        NotifyModified(DocModification(
                                                                        SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
+                               } else if (action.at == containerAction) {
+                                       DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO);
+                                       dm.token = action.position;
+                                       NotifyModified(dm);
                                } else {
                                        NotifyModified(DocModification(
                                                                        SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
                                }
                                cb.PerformUndoStep();
                                int cellPosition = action.position;
-                               ModifiedAt(cellPosition);
-                               newPos = cellPosition;
+                               if (action.at != containerAction) {
+                                       ModifiedAt(cellPosition);
+                                       newPos = cellPosition;
+                               }
 
                                int modFlags = SC_PERFORMED_UNDO;
                                // With undo, an insertion action becomes a deletion notification
                                if (action.at == removeAction) {
                                        newPos += action.lenData;
                                        modFlags |= SC_MOD_INSERTTEXT;
-                               } else {
+                               } else if (action.at == insertAction) {
                                        modFlags |= SC_MOD_DELETETEXT;
                                }
                                if (steps > 1)
@@ -561,19 +626,25 @@ int Document::Redo() {
                                if (action.at == insertAction) {
                                        NotifyModified(DocModification(
                                                                        SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
+                               } else if (action.at == containerAction) {
+                                       DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO);
+                                       dm.token = action.position;
+                                       NotifyModified(dm);
                                } else {
                                        NotifyModified(DocModification(
                                                                        SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
                                }
                                cb.PerformRedoStep();
-                               ModifiedAt(action.position);
-                               newPos = action.position;
+                               if (action.at != containerAction) {
+                                       ModifiedAt(action.position);
+                                       newPos = action.position;
+                               }
 
                                int modFlags = SC_PERFORMED_REDO;
                                if (action.at == insertAction) {
                                        newPos += action.lenData;
                                        modFlags |= SC_MOD_INSERTTEXT;
-                               } else {
+                               } else if (action.at == removeAction) {
                                        modFlags |= SC_MOD_DELETETEXT;
                                }
                                if (steps > 1)
@@ -690,10 +761,9 @@ void Document::SetLineIndentation(int line, int indent) {
                CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
                int thisLineStart = LineStart(line);
                int indentPos = GetLineIndentPosition(line);
-               BeginUndoAction();
+               UndoGroup ug(this);
                DeleteChars(thisLineStart, indentPos - thisLineStart);
                InsertCString(thisLineStart, linebuf);
-               EndUndoAction();
        }
 }
 
@@ -734,8 +804,8 @@ int Document::GetColumn(int pos) {
 
 int Document::FindColumn(int line, int column) {
        int position = LineStart(line);
-       int columnCurrent = 0;
        if ((line >= 0) && (line < LinesTotal())) {
+               int columnCurrent = 0;
                while ((columnCurrent < column) && (position < Length())) {
                        char ch = cb.CharAt(position);
                        if (ch == '\t') {
@@ -800,7 +870,7 @@ char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int e
 }
 
 void Document::ConvertLineEnds(int eolModeSet) {
-       BeginUndoAction();
+       UndoGroup ug(this);
 
        for (int pos = 0; pos < Length(); pos++) {
                if (cb.CharAt(pos) == '\r') {
@@ -835,7 +905,6 @@ void Document::ConvertLineEnds(int eolModeSet) {
                }
        }
 
-       EndUndoAction();
 }
 
 bool Document::IsWhiteLine(int line) const {
@@ -998,16 +1067,6 @@ bool Document::IsWordAt(int start, int end) {
        return IsWordStartAt(start) && IsWordEndAt(end);
 }
 
-// The comparison and case changing functions here assume ASCII
-// or extended ASCII such as the normal Windows code page.
-
-static inline char MakeUpperCase(char ch) {
-       if (ch < 'a' || ch > 'z')
-               return ch;
-       else
-               return static_cast<char>(ch - 'a' + 'A');
-}
-
 static inline char MakeLowerCase(char ch) {
        if (ch < 'A' || ch > 'Z')
                return ch;
@@ -1015,123 +1074,18 @@ static inline char MakeLowerCase(char ch) {
                return static_cast<char>(ch - 'A' + 'a');
 }
 
-// Define a way for the Regular Expression code to access the document
-class DocumentIndexer : public CharacterIndexer {
-       Document *pdoc;
-       int end;
-public:
-       DocumentIndexer(Document *pdoc_, int end_) :
-               pdoc(pdoc_), end(end_) {
-       }
-
-       virtual ~DocumentIndexer() {
-       }
-
-       virtual char CharAt(int index) {
-               if (index < 0 || index >= end)
-                       return 0;
-               else
-                       return pdoc->CharAt(index);
-       }
-};
-
 /**
  * Find text in document, supporting both forward and backward
  * searches (just pass minPos > maxPos to do a backward search)
  * Has not been tested with backwards DBCS searches yet.
  */
 long Document::FindText(int minPos, int maxPos, const char *s,
-                        bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix,
+                        bool caseSensitive, bool word, bool wordStart, bool regExp, int flags,
                         int *length) {
        if (regExp) {
-               if (!pre)
-                       pre = new RESearch(&charClass);
-               if (!pre)
-                       return -1;
-
-               int increment = (minPos <= maxPos) ? 1 : -1;
-
-               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, posix);
-               if (errmsg) {
-                       return -1;
-               }
-               // Find a variable in a property file: \$(\([A-Za-z0-9_.]+\))
-               // Replace first '.' with '-' in each property file variable reference:
-               //     Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\))
-               //     Replace: $(\1-\2)
-               int lineRangeStart = LineFromPosition(startPos);
-               int lineRangeEnd = LineFromPosition(endPos);
-               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);
-               }
-               int pos = -1;
-               int lenRet = 0;
-               char searchEnd = s[*length - 1];
-               int lineRangeBreak = lineRangeEnd + increment;
-               for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
-                       int startOfLine = LineStart(line);
-                       int endOfLine = LineEnd(line);
-                       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, pos+1, endOfLine);
-                                               if (success) {
-                                                       if (pre->eopat[0] <= minPos) {
-                                                               pos = pre->bopat[0];
-                                                               lenRet = pre->eopat[0] - pre->bopat[0];
-                                                       } else {
-                                                               success = 0;
-                                                       }
-                                               }
-                                       }
-                               }
-                               break;
-                       }
-               }
-               *length = lenRet;
-               return pos;
-
+               if (!regex)
+                       regex = CreateRegexSearch(&charClass);
+               return regex->FindText(this, minPos, maxPos, s, caseSensitive, word, wordStart, flags, length);
        } else {
 
                bool forward = minPos <= maxPos;
@@ -1167,8 +1121,8 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                                        }
                                        if (found) {
                                                if ((!word && !wordStart) ||
-                                                       word && IsWordAt(pos, pos + lengthFind) ||
-                                                       wordStart && IsWordStartAt(pos))
+                                                       (word && IsWordAt(pos, pos + lengthFind)) ||
+                                                       (wordStart && IsWordStartAt(pos)))
                                                        return pos;
                                        }
                                }
@@ -1183,8 +1137,8 @@ long Document::FindText(int minPos, int maxPos, const char *s,
                                        }
                                        if (found) {
                                                if ((!word && !wordStart) ||
-                                                       word && IsWordAt(pos, pos + lengthFind) ||
-                                                       wordStart && IsWordStartAt(pos))
+                                                       (word && IsWordAt(pos, pos + lengthFind)) ||
+                                                       (wordStart && IsWordStartAt(pos)))
                                                        return pos;
                                        }
                                }
@@ -1201,86 +1155,7 @@ long Document::FindText(int minPos, int maxPos, const char *s,
 }
 
 const char *Document::SubstituteByPosition(const char *text, int *length) {
-       if (!pre)
-               return 0;
-       delete []substituted;
-       substituted = 0;
-       DocumentIndexer di(this, Length());
-       if (!pre->GrabMatches(di))
-               return 0;
-       unsigned int lenResult = 0;
-       for (int i = 0; i < *length; i++) {
-               if (text[i] == '\\') {
-                       if (text[i + 1] >= '1' && text[i + 1] <= '9') {
-                               unsigned int patNum = text[i + 1] - '0';
-                               lenResult += pre->eopat[patNum] - pre->bopat[patNum];
-                               i++;
-                       } else {
-                               switch (text[i + 1]) {
-                               case 'a':
-                               case 'b':
-                               case 'f':
-                               case 'n':
-                               case 'r':
-                               case 't':
-                               case 'v':
-                                       i++;
-                               }
-                               lenResult++;
-                       }
-               } else {
-                       lenResult++;
-               }
-       }
-       substituted = new char[lenResult + 1];
-       if (!substituted)
-               return 0;
-       char *o = substituted;
-       for (int j = 0; j < *length; j++) {
-               if (text[j] == '\\') {
-                       if (text[j + 1] >= '1' && text[j + 1] <= '9') {
-                               unsigned int patNum = text[j + 1] - '0';
-                               unsigned int len = pre->eopat[patNum] - pre->bopat[patNum];
-                               if (pre->pat[patNum])   // Will be null if try for a match that did not occur
-                                       memcpy(o, pre->pat[patNum], len);
-                               o += len;
-                               j++;
-                       } else {
-                               j++;
-                               switch (text[j]) {
-                               case 'a':
-                                       *o++ = '\a';
-                                       break;
-                               case 'b':
-                                       *o++ = '\b';
-                                       break;
-                               case 'f':
-                                       *o++ = '\f';
-                                       break;
-                               case 'n':
-                                       *o++ = '\n';
-                                       break;
-                               case 'r':
-                                       *o++ = '\r';
-                                       break;
-                               case 't':
-                                       *o++ = '\t';
-                                       break;
-                               case 'v':
-                                       *o++ = '\v';
-                                       break;
-                               default:
-                                       *o++ = '\\';
-                                       j--;
-                               }
-                       }
-               } else {
-                       *o++ = text[j];
-               }
-       }
-       *o = '\0';
-       *length = lenResult;
-       return substituted;
+       return regex->SubstituteByPosition(this, text, length);
 }
 
 int Document::LinesTotal() const {
@@ -1342,7 +1217,7 @@ bool Document::SetStyleFor(int length, char style) {
        }
 }
 
-bool Document::SetStyles(int length, char *styles) {
+bool Document::SetStyles(int length, const char *styles) {
        if (enteredStyling != 0) {
                return false;
        } else {
@@ -1380,8 +1255,8 @@ void Document::EnsureStyledTo(int pos) {
        }
 }
 
-int Document::SetLineState(int line, int state) { 
-       int statePrevious = cb.SetLineState(line, state);
+int Document::SetLineState(int line, int state) {
+       int statePrevious = static_cast<LineState*>(perLineData[ldState])->SetLineState(line, state);
        if (state != statePrevious) {
                DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
                NotifyModified(mh);
@@ -1389,6 +1264,89 @@ int Document::SetLineState(int line, int state) {
        return statePrevious;
 }
 
+int Document::GetLineState(int line) { 
+       return static_cast<LineState*>(perLineData[ldState])->GetLineState(line); 
+}
+
+int Document::GetMaxLineState() { 
+       return static_cast<LineState*>(perLineData[ldState])->GetMaxLineState(); 
+}
+
+StyledText Document::MarginStyledText(int line) {
+       LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldMargin]);
+       return StyledText(pla->Length(line), pla->Text(line), 
+               pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
+}
+
+void Document::MarginSetText(int line, const char *text) {
+       static_cast<LineAnnotation*>(perLineData[ldMargin])->SetText(line, text); 
+       DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line);
+       NotifyModified(mh);
+}
+
+void Document::MarginSetStyle(int line, int style) {
+       static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyle(line, style); 
+}
+
+void Document::MarginSetStyles(int line, const unsigned char *styles) {
+       static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyles(line, styles); 
+}
+
+int Document::MarginLength(int line) const {
+       return static_cast<LineAnnotation*>(perLineData[ldMargin])->Length(line);
+}
+
+void Document::MarginClearAll() {
+       int maxEditorLine = LinesTotal();
+       for (int l=0;l<maxEditorLine;l++)
+               MarginSetText(l, 0);
+       // Free remaining data
+       static_cast<LineAnnotation*>(perLineData[ldMargin])->ClearAll();
+}
+
+bool Document::AnnotationAny() const {
+       return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->AnySet(); 
+}
+
+StyledText Document::AnnotationStyledText(int line) {
+       LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldAnnotation]);
+       return StyledText(pla->Length(line), pla->Text(line), 
+               pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
+}
+
+void Document::AnnotationSetText(int line, const char *text) {
+       const int linesBefore = AnnotationLines(line);
+       static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetText(line, text); 
+       const int linesAfter = AnnotationLines(line);
+       DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+       mh.annotationLinesAdded = linesAfter - linesBefore;
+       NotifyModified(mh);
+}
+
+void Document::AnnotationSetStyle(int line, int style) {
+       static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyle(line, style); 
+}
+
+void Document::AnnotationSetStyles(int line, const unsigned char *styles) {
+       static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyles(line, styles); 
+}
+
+int Document::AnnotationLength(int line) const {
+       return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Length(line);
+}
+
+int Document::AnnotationLines(int line) const {
+       return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Lines(line);
+}
+
+void Document::AnnotationClearAll() {
+       int maxEditorLine = LinesTotal();
+       for (int l=0;l<maxEditorLine;l++)
+               AnnotationSetText(l, 0);
+       // Free remaining data
+       static_cast<LineAnnotation*>(perLineData[ldAnnotation])->ClearAll();
+}
+
 void Document::IncrementStyleClock() {
        styleClock = (styleClock + 1) % 0x100000;
 }
@@ -1408,8 +1366,6 @@ bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
                        return false;
        }
        WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers + 1];
-       if (!pwNew)
-               return false;
        for (int j = 0; j < lenWatchers; j++)
                pwNew[j] = watchers[j];
        pwNew[lenWatchers].watcher = watcher;
@@ -1430,8 +1386,6 @@ bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) {
                                lenWatchers = 0;
                        } else {
                                WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers];
-                               if (!pwNew)
-                                       return false;
                                for (int j = 0; j < lenWatchers - 1; j++) {
                                        pwNew[j] = (j < i) ? watchers[j] : watchers[j + 1];
                                }
@@ -1630,3 +1584,230 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
        }
        return - 1;
 }
+
+/**
+ * Implementation of RegexSearchBase for the default built-in regular expression engine
+ */
+class BuiltinRegex : public RegexSearchBase {
+public:
+       BuiltinRegex(CharClassify *charClassTable) : search(charClassTable), substituted(NULL) {}
+
+       virtual ~BuiltinRegex() {
+               delete substituted;
+       }
+
+       virtual long FindText(Document *doc, int minPos, int maxPos, const char *s,
+                        bool caseSensitive, bool word, bool wordStart, int flags,
+                        int *length);
+
+       virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length);
+
+private:
+       RESearch search;
+       char *substituted;
+};
+
+// Define a way for the Regular Expression code to access the document
+class DocumentIndexer : public CharacterIndexer {
+       Document *pdoc;
+       int end;
+public:
+       DocumentIndexer(Document *pdoc_, int end_) :
+               pdoc(pdoc_), end(end_) {
+       }
+
+       virtual ~DocumentIndexer() {
+       }
+
+       virtual char CharAt(int index) {
+               if (index < 0 || index >= end)
+                       return 0;
+               else
+                       return pdoc->CharAt(index);
+       }
+};
+
+long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s,
+                        bool caseSensitive, bool, bool, int flags,
+                        int *length) {
+       bool posix = (flags & SCFIND_POSIX) != 0;
+       int increment = (minPos <= maxPos) ? 1 : -1;
+
+       int startPos = minPos;
+       int endPos = maxPos;
+
+       // Range endpoints should not be inside DBCS characters, but just in case, move them.
+       startPos = doc->MovePositionOutsideChar(startPos, 1, false);
+       endPos = doc->MovePositionOutsideChar(endPos, 1, false);
+
+       const char *errmsg = search.Compile(s, *length, caseSensitive, posix);
+       if (errmsg) {
+               return -1;
+       }
+       // Find a variable in a property file: \$(\([A-Za-z0-9_.]+\))
+       // Replace first '.' with '-' in each property file variable reference:
+       //     Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\))
+       //     Replace: $(\1-\2)
+       int lineRangeStart = doc->LineFromPosition(startPos);
+       int lineRangeEnd = doc->LineFromPosition(endPos);
+       if ((increment == 1) &&
+               (startPos >= doc->LineEnd(lineRangeStart)) &&
+               (lineRangeStart < lineRangeEnd)) {
+               // the start position is at end of line or between line end characters.
+               lineRangeStart++;
+               startPos = doc->LineStart(lineRangeStart);
+       }
+       int pos = -1;
+       int lenRet = 0;
+       char searchEnd = s[*length - 1];
+       int lineRangeBreak = lineRangeEnd + increment;
+       for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
+               int startOfLine = doc->LineStart(line);
+               int endOfLine = doc->LineEnd(line);
+               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(doc, endOfLine);
+               int success = search.Execute(di, startOfLine, endOfLine);
+               if (success) {
+                       pos = search.bopat[0];
+                       lenRet = search.eopat[0] - search.bopat[0];
+                       if (increment == -1) {
+                               // Check for the last match on this line.
+                               int repetitions = 1000; // Break out of infinite loop
+                               while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {
+                                       success = search.Execute(di, pos+1, endOfLine);
+                                       if (success) {
+                                               if (search.eopat[0] <= minPos) {
+                                                       pos = search.bopat[0];
+                                                       lenRet = search.eopat[0] - search.bopat[0];
+                                               } else {
+                                                       success = 0;
+                                               }
+                                       }
+                               }
+                       }
+                       break;
+               }
+       }
+       *length = lenRet;
+       return pos;
+}
+
+const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text, int *length) {
+       delete []substituted;
+       substituted = 0;
+       DocumentIndexer di(doc, doc->Length());
+       if (!search.GrabMatches(di))
+               return 0;
+       unsigned int lenResult = 0;
+       for (int i = 0; i < *length; i++) {
+               if (text[i] == '\\') {
+                       if (text[i + 1] >= '1' && text[i + 1] <= '9') {
+                               unsigned int patNum = text[i + 1] - '0';
+                               lenResult += search.eopat[patNum] - search.bopat[patNum];
+                               i++;
+                       } else {
+                               switch (text[i + 1]) {
+                               case 'a':
+                               case 'b':
+                               case 'f':
+                               case 'n':
+                               case 'r':
+                               case 't':
+                               case 'v':
+                                       i++;
+                               }
+                               lenResult++;
+                       }
+               } else {
+                       lenResult++;
+               }
+       }
+       substituted = new char[lenResult + 1];
+       char *o = substituted;
+       for (int j = 0; j < *length; j++) {
+               if (text[j] == '\\') {
+                       if (text[j + 1] >= '1' && text[j + 1] <= '9') {
+                               unsigned int patNum = text[j + 1] - '0';
+                               unsigned int len = search.eopat[patNum] - search.bopat[patNum];
+                               if (search.pat[patNum]) // Will be null if try for a match that did not occur
+                                       memcpy(o, search.pat[patNum], len);
+                               o += len;
+                               j++;
+                       } else {
+                               j++;
+                               switch (text[j]) {
+                               case 'a':
+                                       *o++ = '\a';
+                                       break;
+                               case 'b':
+                                       *o++ = '\b';
+                                       break;
+                               case 'f':
+                                       *o++ = '\f';
+                                       break;
+                               case 'n':
+                                       *o++ = '\n';
+                                       break;
+                               case 'r':
+                                       *o++ = '\r';
+                                       break;
+                               case 't':
+                                       *o++ = '\t';
+                                       break;
+                               case 'v':
+                                       *o++ = '\v';
+                                       break;
+                               default:
+                                       *o++ = '\\';
+                                       j--;
+                               }
+                       }
+               } else {
+                       *o++ = text[j];
+               }
+       }
+       *o = '\0';
+       *length = lenResult;
+       return substituted;
+}
+
+#ifndef SCI_OWNREGEX
+
+#ifdef SCI_NAMESPACE
+
+RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) {
+       return new BuiltinRegex(charClassTable);
+}
+
+#else
+
+RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable) {
+       return new BuiltinRegex(charClassTable);
+}
+
+#endif
+
+#endif
index a36c4aafeedac24beecc954682d0ab2dc83ccf25..240d59e39015c8e8432058f92b18a4a5cc4a3b90 100644 (file)
@@ -74,11 +74,50 @@ public:
 
 class DocWatcher;
 class DocModification;
-class RESearch;
+class Document;
 
 /**
+ * Interface class for regular expression searching
  */
-class Document {
+class RegexSearchBase {
+public:
+       virtual ~RegexSearchBase(){}
+
+       virtual long FindText(Document* doc, int minPos, int maxPos, const char *s,
+                        bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0;
+
+       ///@return String with the substitutions, must remain valid until the next call or destruction
+       virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length) = 0;
+};
+
+/// Factory function for RegexSearchBase
+extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
+
+struct StyledText {
+       size_t length;
+       const char *text;
+       bool multipleStyles;
+       size_t style;
+       const unsigned char *styles;
+       StyledText(     size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) : 
+               length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
+       }
+       // Return number of bytes from start to before '\n' or end of text.
+       // Return 1 when start is outside text
+       size_t LineLength(size_t start) const {
+               size_t cur = start;
+               while ((cur < length) && (text[cur] != '\n'))
+                       cur++;
+               return cur-start;
+       }
+       size_t StyleAt(size_t i) const {
+               return multipleStyles ? styles[i] : style;
+       }
+};
+
+/**
+ */
+class Document : PerLine {
 
 public:
        /** Used to pair watcher pointer with user data. */
@@ -93,7 +132,6 @@ public:
        };
 
        enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
-
 private:
        int refCount;
        CellBuffer cb;
@@ -108,9 +146,12 @@ private:
        WatcherWithUserData *watchers;
        int lenWatchers;
 
+       // ldSize is not real data - it is for dimensions and loops
+       enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize }; 
+       PerLine *perLineData[ldSize];
+
        bool matchesValid;
-       RESearch *pre;
-       char *substituted;
+       RegexSearchBase* regex;
 
 public:
        int stylingBits;
@@ -134,7 +175,11 @@ public:
        int AddRef();
        int Release();
 
-       int LineFromPosition(int pos);
+       virtual void Init();
+       virtual void InsertLine(int line);
+       virtual void RemoveLine(int line);
+
+       int LineFromPosition(int pos) const;
        int ClampPositionIntoDocument(int pos);
        bool IsCrLf(int pos);
        int LenChar(int pos);
@@ -157,8 +202,10 @@ public:
        bool IsCollectingUndo() { return cb.IsCollectingUndo(); }
        void BeginUndoAction() { cb.BeginUndoAction(); }
        void EndUndoAction() { cb.EndUndoAction(); }
+       void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
        void SetSavePoint();
        bool IsSavePoint() { return cb.IsSavePoint(); }
+       const char *BufferPointer() { return cb.BufferPointer(); }
 
        int GetLineIndentation(int line);
        void SetLineIndentation(int line, int indent);
@@ -182,21 +229,22 @@ public:
                cb.GetCharRange(buffer, position, lengthRetrieve);
        }
        char StyleAt(int position) { return cb.StyleAt(position); }
-       int GetMark(int line) { return cb.GetMark(line); }
+       int GetMark(int line);
        int AddMark(int line, int markerNum);
        void AddMarkSet(int line, int valueSet);
        void DeleteMark(int line, int markerNum);
        void DeleteMarkFromHandle(int markerHandle);
        void DeleteAllMarks(int markerNum);
-       int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); }
+       int LineFromHandle(int markerHandle);
        int LineStart(int line) const;
        int LineEnd(int line) const;
-       int LineEndPosition(int position);
-       int VCHomePosition(int position);
+       int LineEndPosition(int position) const;
+       bool IsLineEndPosition(int position) const;
+       int VCHomePosition(int position) const;
 
        int SetLevel(int line, int level);
-       int GetLevel(int line) { return cb.GetLevel(line); }
-       void ClearLevels() { cb.ClearLevels(); }
+       int GetLevel(int line);
+       void ClearLevels();
        int GetLastChild(int lineParent, int level=-1);
        int GetFoldParent(int line);
 
@@ -207,7 +255,7 @@ public:
        int Length() const { return cb.Length(); }
        void Allocate(int newSize) { cb.Allocate(newSize); }
        long FindText(int minPos, int maxPos, const char *s,
-               bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length);
+               bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, int *length);
        long FindText(int iMessage, unsigned long wParam, long lParam);
        const char *SubstituteByPosition(const char *text, int *length);
        int LinesTotal() const;
@@ -219,7 +267,7 @@ public:
        void SetStylingBits(int bits);
        void StartStyling(int position, char mask);
        bool SetStyleFor(int length, char style);
-       bool SetStyles(int length, char *styles);
+       bool SetStyles(int length, const char *styles);
        int GetEndStyled() { return endStyled; }
        void EnsureStyledTo(int pos);
        int GetStyleClock() { return styleClock; }
@@ -227,8 +275,24 @@ public:
        void DecorationFillRange(int position, int value, int fillLength);
 
        int SetLineState(int line, int state);
-       int GetLineState(int line) { return cb.GetLineState(line); }
-       int GetMaxLineState() { return cb.GetMaxLineState(); }
+       int GetLineState(int line);
+       int GetMaxLineState();
+
+       StyledText MarginStyledText(int line);
+       void MarginSetStyle(int line, int style);
+       void MarginSetStyles(int line, const unsigned char *styles);
+       void MarginSetText(int line, const char *text);
+       int MarginLength(int line) const;
+       void MarginClearAll();
+
+       bool AnnotationAny() const;
+       StyledText AnnotationStyledText(int line);
+       void AnnotationSetText(int line, const char *text);
+       void AnnotationSetStyle(int line, int style);
+       void AnnotationSetStyles(int line, const unsigned char *styles);
+       int AnnotationLength(int line) const;
+       int AnnotationLines(int line) const;
+       void AnnotationClearAll();
 
        bool AddWatcher(DocWatcher *watcher, void *userData);
        bool RemoveWatcher(DocWatcher *watcher, void *userData);
@@ -256,6 +320,27 @@ private:
        void NotifyModified(DocModification mh);
 };
 
+class UndoGroup {
+       Document *pdoc;
+       bool groupNeeded;
+public:
+       UndoGroup(Document *pdoc_, bool groupNeeded_=true) : 
+               pdoc(pdoc_), groupNeeded(groupNeeded_) {
+               if (groupNeeded) {
+                       pdoc->BeginUndoAction();
+               }
+       }
+       ~UndoGroup() {
+               if (groupNeeded) {
+                       pdoc->EndUndoAction();
+               }
+       }
+       bool Needed() const {
+               return groupNeeded;
+       }
+};
+
+
 /**
  * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
  * scope of the change.
@@ -271,6 +356,8 @@ public:
        int line;
        int foldLevelNow;
        int foldLevelPrev;
+       int annotationLinesAdded;
+       int token;
 
        DocModification(int modificationType_, int position_=0, int length_=0,
                int linesAdded_=0, const char *text_=0, int line_=0) :
@@ -281,7 +368,9 @@ public:
                text(text_),
                line(line_),
                foldLevelNow(0),
-               foldLevelPrev(0) {}
+               foldLevelPrev(0),
+               annotationLinesAdded(0),
+               token(0) {}
 
        DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
                modificationType(modificationType_),
@@ -291,7 +380,9 @@ public:
                text(act.data),
                line(0),
                foldLevelNow(0),
-               foldLevelPrev(0) {}
+               foldLevelPrev(0),
+               annotationLinesAdded(0),
+               token(0) {}
 };
 
 /**
index a3a939d0d3068fa67397d37ac0d5b25ce24009b2..899865fc1ae3cbd20b48e2965eb6eee25e9d75d3 100644 (file)
@@ -14,14 +14,15 @@ class Document;
 
 /**
  */
+
 class DocumentAccessor : public Accessor {
        // Private so DocumentAccessor objects can not be copied
-       DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {}
-       DocumentAccessor &operator=(const DocumentAccessor &) { return *this; }
+       DocumentAccessor(const DocumentAccessor &source);
+       DocumentAccessor &operator=(const DocumentAccessor &);
 
 protected:
        Document *pdoc;
-       PropSet &props;
+       PropertyGet &props;
        WindowID id;
        int lenDoc;
 
@@ -37,7 +38,7 @@ protected:
        void Fill(int position);
 
 public:
-       DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : 
+       DocumentAccessor(Document *pdoc_, PropertyGet &props_, WindowID id_=0) : 
                Accessor(), pdoc(pdoc_), props(props_), id(id_),
                lenDoc(-1), validLen(0), chFlags(0), chWhile(0), 
                startSeg(0), startPosStyling(0),
index 9107102ff6f654834596f7e22bf523563f0c1c00..d319a7ac0dff60a49ad74ff189ee8ff35a6518d0 100644 (file)
 #include <stdio.h>
 #include <ctype.h>
 
-#include "Platform.h"
+#include <string>
 
-#ifndef PLAT_QT
-#define INCLUDE_DEPRECATED_FEATURES
+// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
+// FindText to FindTextA which makes calls here to Document::FindText fail.
+#ifdef __BORLANDC__
+#ifdef FindText
+#undef FindText
+#endif
 #endif
+
+#include "Platform.h"
+
 #include "Scintilla.h"
 
 #include "SplitVector.h"
@@ -31,6 +38,7 @@
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 #include "Editor.h"
 
@@ -111,18 +119,14 @@ Editor::Editor() {
        ptMouseLast.y = 0;
        inDragDrop = ddNone;
        dropWentOutside = false;
-       posDrag = invalidPosition;
-       posDrop = invalidPosition;
+       posDrag = SelectionPosition(invalidPosition);
+       posDrop = SelectionPosition(invalidPosition);
        selectionType = selChar;
 
        lastXChosen = 0;
        lineAnchor = 0;
        originalAnchorPos = 0;
 
-       selType = selStream;
-       moveExtendsSelection = false;
-       xStartSelect = 0;
-       xEndSelect = 0;
        primarySelection = true;
 
        caretXPolicy = CARET_SLOP | CARET_EVEN;
@@ -142,6 +146,11 @@ Editor::Editor() {
        verticalScrollBarVisible = true;
        endAtLastLine = true;
        caretSticky = false;
+       multipleSelection = false;
+       additionalSelectionTyping = false;
+       additionalCaretsBlink = true;
+       additionalCaretsVisible = true;
+       virtualSpaceOptions = SCVS_NONE;
 
        pixmapLine = Surface::Allocate();
        pixmapSelMargin = Surface::Allocate();
@@ -149,9 +158,6 @@ Editor::Editor() {
        pixmapIndentGuide = Surface::Allocate();
        pixmapIndentGuideHighlight = Surface::Allocate();
 
-       currentPos = 0;
-       anchor = 0;
-
        targetStart = 0;
        targetEnd = 0;
        searchFlags = 0;
@@ -187,7 +193,8 @@ Editor::Editor() {
        wrapVisualFlags = 0;
        wrapVisualFlagsLocation = 0;
        wrapVisualStartIndent = 0;
-       actualWrapVisualStartIndent = 0;
+       wrapIndentMode = SC_WRAPINDENT_FIXED;
+       wrapAddIndent = 0;
 
        convertPastes = true;
 
@@ -225,14 +232,10 @@ void Editor::DropGraphics() {
 
 void Editor::InvalidateStyleData() {
        stylesValid = false;
-       palette.Release();
        DropGraphics();
+       palette.Release();
        llc.Invalidate(LineLayout::llInvalid);
        posCache.Clear();
-       if (selType == selRectangle) {
-               xStartSelect = XFromPosition(anchor);
-               xEndSelect = XFromPosition(currentPos);
-       }
 }
 
 void Editor::InvalidateStyleRedraw() {
@@ -255,7 +258,17 @@ void Editor::RefreshStyleData() {
                        palette.Allocate(wMain);
                        RefreshColourPalette(palette, false);
                }
+               if (wrapIndentMode == SC_WRAPINDENT_INDENT) {
+                       wrapAddIndent = pdoc->IndentSize() * vs.spaceWidth;
+               } else if (wrapIndentMode == SC_WRAPINDENT_SAME) {
+                       wrapAddIndent = 0;
+               } else { //SC_WRAPINDENT_FIXED
+                       wrapAddIndent = wrapVisualStartIndent * vs.aveCharWidth;
+                       if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (wrapAddIndent <= 0))
+                               wrapAddIndent = vs.aveCharWidth; // must indent to show start visual
+               }
                SetScrollBars();
+               SetRectangularRange();
        }
 }
 
@@ -321,7 +334,7 @@ const char *ControlCharacterString(unsigned char ch) {
 class AutoLineLayout {
        LineLayoutCache &llc;
        LineLayout *ll;
-       AutoLineLayout &operator=(const AutoLineLayout &) { return * this; }
+       AutoLineLayout &operator=(const AutoLineLayout &);
 public:
        AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {}
        ~AutoLineLayout() {
@@ -340,98 +353,25 @@ public:
        }
 };
 
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-/**
- * Allows to iterate through the lines of a selection.
- * Althought it can be called for a stream selection, in most cases
- * it is inefficient and it should be used only for
- * a rectangular or a line selection.
- */
-class SelectionLineIterator {
-private:
-       Editor *ed;
-       int line;       ///< Current line within the iteration.
-       bool forward;   ///< True if iterating by increasing line number, false otherwise.
-       int selStart, selEnd;   ///< Positions of the start and end of the selection relative to the start of the document.
-       int minX, maxX; ///< Left and right of selection rectangle.
-
-public:
-       int lineStart, lineEnd; ///< Line numbers, first and last lines of the selection.
-       int startPos, endPos;   ///< Positions of the beginning and end of the selection on the current line.
-
-       void Reset() {
-               if (forward) {
-                       line = lineStart;
-               } else {
-                       line = lineEnd;
-               }
-       }
-
-       SelectionLineIterator(Editor *ed_, bool forward_ = true) : line(0), startPos(0), endPos(0) {
-               ed = ed_;
-               forward = forward_;
-               selStart = ed->SelectionStart();
-               selEnd = ed->SelectionEnd();
-               lineStart = ed->pdoc->LineFromPosition(selStart);
-               lineEnd = ed->pdoc->LineFromPosition(selEnd);
-               // Left of rectangle
-               minX = Platform::Minimum(ed->xStartSelect, ed->xEndSelect);
-               // Right of rectangle
-               maxX = Platform::Maximum(ed->xStartSelect, ed->xEndSelect);
-               Reset();
-       }
-       ~SelectionLineIterator() {}
-
-       void SetAt(int line) {
-               if (line < lineStart || line > lineEnd) {
-                       startPos = endPos = INVALID_POSITION;
-               } else {
-                       if (ed->selType == ed->selRectangle) {
-                               // Measure line and return character closest to minX
-                               startPos = ed->PositionFromLineX(line, minX);
-                               // Measure line and return character closest to maxX
-                               endPos = ed->PositionFromLineX(line, maxX);
-                       } else if (ed->selType == ed->selLines) {
-                               startPos = ed->pdoc->LineStart(line);
-                               endPos = ed->pdoc->LineStart(line + 1);
-                       } else {        // Stream selection, here only for completion
-                               if (line == lineStart) {
-                                       startPos = selStart;
-                               } else {
-                                       startPos = ed->pdoc->LineStart(line);
-                               }
-                               if (line == lineEnd) {
-                                       endPos = selEnd;
-                               } else {
-                                       endPos = ed->pdoc->LineStart(line + 1);
-                               }
-                       }
-               }
-       }
-       bool Iterate() {
-               SetAt(line);
-               if (forward) {
-                       line++;
-               } else {
-                       line--;
-               }
-               return startPos != INVALID_POSITION;
+SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const {
+       if (sp.Position() < 0) {
+               return SelectionPosition(0);
+       } else if (sp.Position() > pdoc->Length()) {
+               return SelectionPosition(pdoc->Length());
+       } else {
+               // If not at end of line then set offset to 0
+               if (!pdoc->IsLineEndPosition(sp.Position()))
+                       sp.SetVirtualSpace(0);
+               return sp;
        }
-};
-
-#ifdef SCI_NAMESPACE
 }
-#endif
 
-Point Editor::LocationFromPosition(int pos) {
+Point Editor::LocationFromPosition(SelectionPosition pos) {
        Point pt;
        RefreshStyleData();
-       if (pos == INVALID_POSITION)
+       if (pos.Position() == INVALID_POSITION)
                return pt;
-       int line = pdoc->LineFromPosition(pos);
+       int line = pdoc->LineFromPosition(pos.Position());
        int lineVisible = cs.DisplayFromDoc(line);
        //Platform::DebugPrintf("line=%d\n", line);
        AutoSurface surface(this);
@@ -442,7 +382,7 @@ Point Editor::LocationFromPosition(int pos) {
                pt.x = 0;
                unsigned int posLineStart = pdoc->LineStart(line);
                LayoutLine(line, surface, vs, ll, wrapWidth);
-               int posInLine = pos - posLineStart;
+               int posInLine = pos.Position() - posLineStart;
                // In case of very long line put x at arbitrary large position
                if (posInLine > ll->maxLineLength) {
                        pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
@@ -451,10 +391,10 @@ Point Editor::LocationFromPosition(int pos) {
                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 (actualWrapVisualStartIndent != 0) {
+                               if (ll->wrapIndent != 0) {
                                        int lineStart = ll->LineStart(subLine);
                                        if (lineStart != 0)     // Wrapped
-                                               pt.x += actualWrapVisualStartIndent * vs.aveCharWidth;
+                                               pt.x += ll->wrapIndent;
                                }
                        }
                        if (posInLine >= ll->LineStart(subLine)) {
@@ -463,14 +403,24 @@ Point Editor::LocationFromPosition(int pos) {
                }
                pt.x += vs.fixedColumnWidth - xOffset;
        }
+       pt.x += pos.VirtualSpace() * static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
        return pt;
 }
 
+Point Editor::LocationFromPosition(int pos) {
+       return LocationFromPosition(SelectionPosition(pos));
+}
+
 int Editor::XFromPosition(int pos) {
        Point pt = LocationFromPosition(pos);
        return pt.x - vs.fixedColumnWidth + xOffset;
 }
 
+int Editor::XFromPosition(SelectionPosition sp) {
+       Point pt = LocationFromPosition(sp);
+       return pt.x - vs.fixedColumnWidth + xOffset;
+}
+
 int Editor::LineFromLocation(Point pt) {
        return cs.DocFromDisplay(pt.y / vs.lineHeight + topLine);
 }
@@ -480,20 +430,31 @@ void Editor::SetTopLine(int topLineNew) {
        posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
 }
 
-int Editor::PositionFromLocation(Point pt) {
+SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace) {
        RefreshStyleData();
+       if (canReturnInvalid) {
+               PRectangle rcClient = GetTextRectangle();
+               if (!rcClient.Contains(pt))
+                       return SelectionPosition(INVALID_POSITION);
+               if (pt.x < vs.fixedColumnWidth)
+                       return SelectionPosition(INVALID_POSITION);
+               if (pt.y < 0)
+                       return SelectionPosition(INVALID_POSITION);
+       }
        pt.x = pt.x - vs.fixedColumnWidth + xOffset;
        int visibleLine = pt.y / vs.lineHeight + topLine;
        if (pt.y < 0) { // Division rounds towards 0
                visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
        }
-       if (visibleLine < 0)
+       if (!canReturnInvalid && (visibleLine < 0))
                visibleLine = 0;
        int lineDoc = cs.DocFromDisplay(visibleLine);
+       if (canReturnInvalid && (lineDoc < 0))
+               return SelectionPosition(INVALID_POSITION);
        if (lineDoc >= pdoc->LinesTotal())
-               return pdoc->Length();
+               return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length());
        unsigned int posLineStart = pdoc->LineStart(lineDoc);
-       int retVal = posLineStart;
+       SelectionPosition retVal(canReturnInvalid ? INVALID_POSITION : static_cast<int>(posLineStart));
        AutoSurface surface(this);
        AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
        if (surface && ll) {
@@ -505,84 +466,91 @@ int Editor::PositionFromLocation(Point pt) {
                        int lineEnd = ll->LineLastVisible(subLine);
                        int subLineStart = ll->positions[lineStart];
 
-                       if (actualWrapVisualStartIndent != 0) {
+                       if (ll->wrapIndent != 0) {
                                if (lineStart != 0)     // Wrapped
-                                       pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;
+                                       pt.x -= ll->wrapIndent;
                        }
                        int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
                        while (i < lineEnd) {
-                               if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
-                                       return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+                               if (charPosition) {
+                                       if ((pt.x + subLineStart) < (ll->positions[i + 1])) {
+                                               return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
+                                       }
+                               } else {
+                                       if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+                                               return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
+                                       }
                                }
                                i++;
                        }
-                       return lineEnd + posLineStart;
+                       if (virtualSpace) {
+                               const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+                               int spaceOffset = (pt.x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) /
+                                       spaceWidth;
+                               return SelectionPosition(lineEnd + posLineStart, spaceOffset);
+                       } else if (canReturnInvalid) {
+                               if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
+                                       return SelectionPosition(pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1));
+                               }
+                       } else {
+                               return SelectionPosition(lineEnd + posLineStart);
+                       }
                }
-               retVal = ll->numCharsInLine + posLineStart;
+               if (!canReturnInvalid)
+                       return SelectionPosition(ll->numCharsInLine + posLineStart);
        }
        return retVal;
 }
 
-// Like PositionFromLocation but INVALID_POSITION returned when not near any text.
-int Editor::PositionFromLocationClose(Point pt) {
+int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) {
+       return SPositionFromLocation(pt, canReturnInvalid, charPosition, false).Position();
+}
+
+/**
+ * Find the document position corresponding to an x coordinate on a particular document line.
+ * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
+ */
+int Editor::PositionFromLineX(int lineDoc, int x) {
        RefreshStyleData();
-       PRectangle rcClient = GetTextRectangle();
-       if (!rcClient.Contains(pt))
-               return INVALID_POSITION;
-       if (pt.x < vs.fixedColumnWidth)
-               return INVALID_POSITION;
-       if (pt.y < 0)
-               return INVALID_POSITION;
-       pt.x = pt.x - vs.fixedColumnWidth + xOffset;
-       int visibleLine = pt.y / vs.lineHeight + topLine;
-       if (pt.y < 0) { // Division rounds towards 0
-               visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
-       }
-       int lineDoc = cs.DocFromDisplay(visibleLine);
-       if (lineDoc < 0)
-               return INVALID_POSITION;
        if (lineDoc >= pdoc->LinesTotal())
-               return INVALID_POSITION;
+               return pdoc->Length();
+       //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
        AutoSurface surface(this);
        AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
+       int retVal = 0;
        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->LineLastVisible(subLine);
-                       int subLineStart = ll->positions[lineStart];
+               LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
+               retVal = ll->numCharsBeforeEOL + posLineStart;
+               int subLine = 0;
+               int lineStart = ll->LineStart(subLine);
+               int lineEnd = ll->LineLastVisible(subLine);
+               int subLineStart = ll->positions[lineStart];
 
-                       if (actualWrapVisualStartIndent != 0) {
-                               if (lineStart != 0)     // Wrapped
-                                       pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;
-                       }
-                       int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
-                       while (i < lineEnd) {
-                               if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
-                                       return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
-                               }
-                               i++;
-                       }
-                       if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
-                               return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);
+               if (ll->wrapIndent != 0) {
+                       if (lineStart != 0)     // Wrapped
+                               x -= ll->wrapIndent;
+               }
+               int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
+               while (i < lineEnd) {
+                       if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+                               retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+                               break;
                        }
+                       i++;
                }
        }
-
-       return INVALID_POSITION;
+       return retVal;
 }
 
 /**
  * Find the document position corresponding to an x coordinate on a particular document line.
  * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
  */
-int Editor::PositionFromLineX(int lineDoc, int x) {
+SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) {
        RefreshStyleData();
        if (lineDoc >= pdoc->LinesTotal())
-               return pdoc->Length();
+               return SelectionPosition(pdoc->Length());
        //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
        AutoSurface surface(this);
        AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
@@ -590,26 +558,28 @@ int Editor::PositionFromLineX(int lineDoc, int x) {
        if (surface && ll) {
                unsigned int posLineStart = pdoc->LineStart(lineDoc);
                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
-               retVal = ll->numCharsInLine + posLineStart;
                int subLine = 0;
                int lineStart = ll->LineStart(subLine);
                int lineEnd = ll->LineLastVisible(subLine);
                int subLineStart = ll->positions[lineStart];
 
-               if (actualWrapVisualStartIndent != 0) {
+               if (ll->wrapIndent != 0) {
                        if (lineStart != 0)     // Wrapped
-                               x -= actualWrapVisualStartIndent * vs.aveCharWidth;
+                               x -= ll->wrapIndent;
                }
                int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
                while (i < lineEnd) {
                        if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
                                retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
-                               break;
+                               return SelectionPosition(retVal);
                        }
                        i++;
                }
+               const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+               int spaceOffset = (x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth;
+               return SelectionPosition(lineEnd + posLineStart, spaceOffset);
        }
-       return retVal;
+       return SelectionPosition(retVal);
 }
 
 /**
@@ -697,73 +667,125 @@ void Editor::InvalidateRange(int start, int end) {
 }
 
 int Editor::CurrentPosition() {
-       return currentPos;
+       return sel.MainCaret();
 }
 
 bool Editor::SelectionEmpty() {
-       return anchor == currentPos;
+       return sel.Empty();
 }
 
-int Editor::SelectionStart() {
-       return Platform::Minimum(currentPos, anchor);
+SelectionPosition Editor::SelectionStart() {
+       return sel.RangeMain().Start();
 }
 
-int Editor::SelectionEnd() {
-       return Platform::Maximum(currentPos, anchor);
+SelectionPosition Editor::SelectionEnd() {
+       return sel.RangeMain().End();
 }
 
 void Editor::SetRectangularRange() {
-       if (selType == selRectangle) {
-               xStartSelect = XFromPosition(anchor);
-               xEndSelect = XFromPosition(currentPos);
-       }
-}
-
-void Editor::InvalidateSelection(int currentPos_, int anchor_) {
-       int firstAffected = anchor;
-       if (firstAffected > currentPos)
-               firstAffected = currentPos;
-       if (firstAffected > anchor_)
-               firstAffected = anchor_;
-       if (firstAffected > currentPos_)
-               firstAffected = currentPos_;
-       int lastAffected = anchor;
-       if (lastAffected < currentPos)
-               lastAffected = currentPos;
-       if (lastAffected < anchor_)
-               lastAffected = anchor_;
-       if (lastAffected < (currentPos_ + 1))   // +1 ensures caret repainted
-               lastAffected = (currentPos_ + 1);
+       if (sel.IsRectangular()) {
+               int xAnchor = XFromPosition(sel.Rectangular().anchor);
+               int xCaret = XFromPosition(sel.Rectangular().caret);
+               if (sel.selType == Selection::selThin) {
+                       xCaret = xAnchor;
+               }
+               int lineAnchor = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
+               int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position());
+               int increment = (lineCaret > lineAnchor) ? 1 : -1;
+               for (int line=lineAnchor; line != lineCaret+increment; line += increment) {
+                       SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
+                       if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
+                               range.ClearVirtualSpace();
+                       if (line == lineAnchor)
+                               sel.SetSelection(range);
+                       else
+                               sel.AddSelection(range);
+               }
+       }
+}
+
+void Editor::ThinRectangularRange() {
+       if (sel.IsRectangular()) {
+               sel.selType = Selection::selThin;
+               if (sel.Rectangular().caret < sel.Rectangular().anchor) {
+                       sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).caret, sel.Range(0).anchor);
+               } else {
+                       sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).anchor, sel.Range(0).caret);
+               }
+               SetRectangularRange();
+       }
+}
+
+void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection) {
+       if (sel.Count() > 1 || !(sel.RangeMain().anchor == newMain.anchor) || sel.IsRectangular()) {
+               invalidateWholeSelection = true;
+       }
+       int firstAffected = Platform::Minimum(sel.RangeMain().Start().Position(), newMain.Start().Position());
+       // +1 for lastAffected ensures caret repainted
+       int lastAffected = Platform::Maximum(newMain.caret.Position()+1, newMain.anchor.Position());
+       lastAffected = Platform::Maximum(lastAffected, sel.RangeMain().End().Position());
+       if (invalidateWholeSelection) {
+               for (size_t r=0; r<sel.Count(); r++) {
+                       firstAffected = Platform::Minimum(firstAffected, sel.Range(r).caret.Position());
+                       firstAffected = Platform::Minimum(firstAffected, sel.Range(r).anchor.Position());
+                       lastAffected = Platform::Maximum(lastAffected, sel.Range(r).caret.Position()+1);
+                       lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
+               }
+       }
        needUpdateUI = true;
        InvalidateRange(firstAffected, lastAffected);
 }
 
-void Editor::SetSelection(int currentPos_, int anchor_) {
-       currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);
-       anchor_ = pdoc->ClampPositionIntoDocument(anchor_);
-       if ((currentPos != currentPos_) || (anchor != anchor_)) {
-               InvalidateSelection(currentPos_, anchor_);
-               currentPos = currentPos_;
-               anchor = anchor_;
+void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
+       SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_),
+               ClampPositionIntoDocument(anchor_));
+       if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
+               InvalidateSelection(rangeNew);
        }
+       sel.RangeMain() = rangeNew;
        SetRectangularRange();
        ClaimSelection();
 }
 
+void Editor::SetSelection(int currentPos_, int anchor_) {
+       SetSelection(SelectionPosition(currentPos_), SelectionPosition(anchor_));
+}
+
+// Just move the caret on the main selection
+void Editor::SetSelection(SelectionPosition currentPos_) {
+       currentPos_ = ClampPositionIntoDocument(currentPos_);
+       if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
+               InvalidateSelection(SelectionRange(currentPos_));
+       }
+       if (sel.IsRectangular()) {
+               sel.Rectangular() =
+                       SelectionRange(SelectionPosition(currentPos_), sel.Rectangular().anchor);
+               SetRectangularRange();
+       } else {
+               sel.RangeMain() =
+                       SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
+       }
+       ClaimSelection();
+}
+
 void Editor::SetSelection(int currentPos_) {
-       currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);
-       if (currentPos != currentPos_) {
-               InvalidateSelection(currentPos_, currentPos_);
-               currentPos = currentPos_;
+       SetSelection(SelectionPosition(currentPos_));
+}
+
+void Editor::SetEmptySelection(SelectionPosition currentPos_) {
+       SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
+       if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
+               InvalidateSelection(rangeNew);
        }
+       sel.Clear();
+       sel.RangeMain() = rangeNew;
        SetRectangularRange();
        ClaimSelection();
+
 }
 
 void Editor::SetEmptySelection(int currentPos_) {
-       selType = selStream;
-       moveExtendsSelection = false;
-       SetSelection(currentPos_, currentPos_);
+       SetEmptySelection(SelectionPosition(currentPos_));
 }
 
 bool Editor::RangeContainsProtected(int start, int end) const {
@@ -783,54 +805,59 @@ bool Editor::RangeContainsProtected(int start, int end) const {
 }
 
 bool Editor::SelectionContainsProtected() {
-       // DONE, but untested...: make support rectangular selection
-       bool scp = false;
-       if (selType == selStream) {
-               scp = RangeContainsProtected(anchor, currentPos);
-       } else {
-               SelectionLineIterator lineIterator(this);
-               while (lineIterator.Iterate()) {
-                       if (RangeContainsProtected(lineIterator.startPos, lineIterator.endPos)) {
-                               scp = true;
-                               break;
-                       }
+       for (size_t r=0; r<sel.Count(); r++) {
+               if (RangeContainsProtected(sel.Range(r).Start().Position(),
+                       sel.Range(r).End().Position())) {
+                       return true;
                }
        }
-       return scp;
+       return false;
 }
 
 /**
  * Asks document to find a good position and then moves out of any invisible positions.
  */
-int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
-       pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd);
+int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) const {
+       return MovePositionOutsideChar(SelectionPosition(pos), moveDir, checkLineEnd).Position();
+}
+
+SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd) const {
+       int posMoved = pdoc->MovePositionOutsideChar(pos.Position(), moveDir, checkLineEnd);
+       if (posMoved != pos.Position())
+               pos.SetPosition(posMoved);
        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++;
+                       if ((pos.Position() > 0) && vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()) {
+                               while ((pos.Position() < pdoc->Length()) &&
+                                       (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()))
+                                       pos.Add(1);
                        }
                } else if (moveDir < 0) {
-                       if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) {
-                               while ((pos > 0) &&
-                                       (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
-                                       pos--;
+                       if (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()) {
+                               while ((pos.Position() > 0) &&
+                                       (vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()))
+                                       pos.Add(-1);
                        }
                }
        }
        return pos;
 }
 
-int Editor::MovePositionTo(int newPos, selTypes sel, bool ensureVisible) {
-       int delta = newPos - currentPos;
-       newPos = pdoc->ClampPositionIntoDocument(newPos);
+int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) {
+       int delta = newPos.Position() - sel.MainCaret();
+       newPos = ClampPositionIntoDocument(newPos);
        newPos = MovePositionOutsideChar(newPos, delta);
-       if (sel != noSel) {
-               selType = sel;
+       if (!sel.IsRectangular() && (selt == Selection::selRectangle)) {
+               // Switching to rectangular
+               SelectionRange rangeMain = sel.RangeMain();
+               sel.Clear();
+               sel.Rectangular() = rangeMain;
        }
-       if (sel != noSel || moveExtendsSelection) {
+       if (selt != Selection::noSel) {
+               sel.selType = selt;
+       }
+       if (selt != Selection::noSel || sel.MoveExtends()) {
                SetSelection(newPos);
        } else {
                SetEmptySelection(newPos);
@@ -839,14 +866,17 @@ int Editor::MovePositionTo(int newPos, selTypes sel, bool ensureVisible) {
        if (ensureVisible) {
                EnsureCaretVisible();
        }
-       NotifyMove(newPos);
        return 0;
 }
 
-int Editor::MovePositionSoVisible(int pos, int moveDir) {
-       pos = pdoc->ClampPositionIntoDocument(pos);
+int Editor::MovePositionTo(int newPos, Selection::selTypes selt, bool ensureVisible) {
+       return MovePositionTo(SelectionPosition(newPos), selt, ensureVisible);
+}
+
+SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveDir) {
+       pos = ClampPositionIntoDocument(pos);
        pos = MovePositionOutsideChar(pos, moveDir);
-       int lineDoc = pdoc->LineFromPosition(pos);
+       int lineDoc = pdoc->LineFromPosition(pos.Position());
        if (cs.GetVisible(lineDoc)) {
                return pos;
        } else {
@@ -854,20 +884,28 @@ int Editor::MovePositionSoVisible(int pos, int moveDir) {
                if (moveDir > 0) {
                        // lineDisplay is already line before fold as lines in fold use display line of line after fold
                        lineDisplay = Platform::Clamp(lineDisplay, 0, cs.LinesDisplayed());
-                       return pdoc->LineStart(cs.DocFromDisplay(lineDisplay));
+                       return SelectionPosition(pdoc->LineStart(cs.DocFromDisplay(lineDisplay)));
                } else {
                        lineDisplay = Platform::Clamp(lineDisplay - 1, 0, cs.LinesDisplayed());
-                       return pdoc->LineEnd(cs.DocFromDisplay(lineDisplay));
+                       return SelectionPosition(pdoc->LineEnd(cs.DocFromDisplay(lineDisplay)));
                }
        }
 }
 
+SelectionPosition Editor::MovePositionSoVisible(int pos, int moveDir) {
+       return MovePositionSoVisible(SelectionPosition(pos), moveDir);
+}
+
+Point Editor::PointMainCaret() {
+       return LocationFromPosition(sel.Range(sel.Main()).caret);
+}
+
 /**
  * Choose the x position that the caret will try to stick to
  * as it moves up and down.
  */
 void Editor::SetLastXChosen() {
-       Point pt = LocationFromPosition(currentPos);
+       Point pt = PointMainCaret();
        lastXChosen = pt.x;
 }
 
@@ -912,16 +950,16 @@ void Editor::HorizontalScrollTo(int xPos) {
 
 void Editor::MoveCaretInsideView(bool ensureVisible) {
        PRectangle rcClient = GetTextRectangle();
-       Point pt = LocationFromPosition(currentPos);
+       Point pt = PointMainCaret();
        if (pt.y < rcClient.top) {
-               MovePositionTo(PositionFromLocation(
+               MovePositionTo(SPositionFromLocation(
                            Point(lastXChosen, rcClient.top)),
-                       noSel, ensureVisible);
+                                       Selection::noSel, ensureVisible);
        } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
                int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
-               MovePositionTo(PositionFromLocation(
+               MovePositionTo(SPositionFromLocation(
                            Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
-                       noSel, ensureVisible);
+                       Selection::noSel, ensureVisible);
        }
 }
 
@@ -972,7 +1010,7 @@ This way, we favour the displaying of useful information: the begining of lines,
 where most code reside, and the lines after the caret, eg. the body of a function.
 
      |        |       |      |                                            |
-slop | strict | jumps | even | Caret can go to the margin                 | When reaching limitÝ(caret going out of
+slop | strict | jumps | even | Caret can go to the margin                 | When reaching limit (caret going out of
      |        |       |      |                                            | visibility or going into the UZ) display is...
 -----+--------+-------+------+--------------------------------------------+--------------------------------------------------------------
   0  |   0    |   0   |   0  | Yes                                        | moved to put caret on top/on right
@@ -993,14 +1031,14 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
        //Platform::DebugPrintf("EnsureCaretVisible %d %s\n", xOffset, useMargin ? " margin" : " ");
        PRectangle rcClient = GetTextRectangle();
        //int rcClientFullWidth = rcClient.Width();
-       int posCaret = currentPos;
-       if (posDrag >= 0) {
+       SelectionPosition posCaret = sel.RangeMain().caret;
+       if (posDrag.IsValid()) {
                posCaret = posDrag;
        }
        Point pt = LocationFromPosition(posCaret);
        Point ptBottomCaret = pt;
        ptBottomCaret.y += vs.lineHeight - 1;
-       int lineCaret = DisplayFromPosition(posCaret);
+       int lineCaret = DisplayFromPosition(posCaret.Position());
        bool bSlop, bStrict, bJump, bEven;
 
        // Vertical positioning
@@ -1237,10 +1275,13 @@ void Editor::DropCaret() {
 }
 
 void Editor::InvalidateCaret() {
-       if (posDrag >= 0)
-               InvalidateRange(posDrag, posDrag + 1);
-       else
-               InvalidateRange(currentPos, currentPos + 1);
+       if (posDrag.IsValid()) {
+               InvalidateRange(posDrag.Position(), posDrag.Position() + 1);
+       } else {
+               for (size_t r=0; r<sel.Count(); r++) {
+                       InvalidateRange(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1);
+               }
+       }
        UpdateSystemCaret();
 }
 
@@ -1270,13 +1311,14 @@ bool Editor::WrapOneLine(Surface *surface, int lineToWrap) {
                LayoutLine(lineToWrap, surface, vs, ll, wrapWidth);
                linesWrapped = ll->lines;
        }
-       return cs.SetHeight(lineToWrap, linesWrapped);
+       return cs.SetHeight(lineToWrap, linesWrapped +
+               (vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0));
 }
 
 // Check if wrapping needed and perform any needed wrapping.
 // fullwrap: if true, all lines which need wrapping will be done,
 //           in this single call.
-// priorityWrapLineStart: If greater than zero, all lines starting from
+// priorityWrapLineStart: If greater than or equal to zero, all lines starting from
 //           here to 1 page + 100 lines past will be wrapped (even if there are
 //           more lines under wrapping process in idle).
 // If it is neither fullwrap, nor priorityWrap, then 1 page + 100 lines will be
@@ -1308,7 +1350,8 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
                        if (wrapWidth != LineLayout::wrapWidthInfinite) {
                                wrapWidth = LineLayout::wrapWidthInfinite;
                                for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
-                                       cs.SetHeight(lineDoc, 1);
+                                       cs.SetHeight(lineDoc, 1 +
+                                               (vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0));
                                }
                                wrapOccurred = true;
                        }
@@ -1381,7 +1424,7 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
 
 void Editor::LinesJoin() {
        if (!RangeContainsProtected(targetStart, targetEnd)) {
-               pdoc->BeginUndoAction();
+               UndoGroup ug(pdoc);
                bool prevNonWS = true;
                for (int pos = targetStart; pos < targetEnd; pos++) {
                        if (IsEOLChar(pdoc->CharAt(pos))) {
@@ -1396,11 +1439,10 @@ void Editor::LinesJoin() {
                                prevNonWS = pdoc->CharAt(pos) != ' ';
                        }
                }
-               pdoc->EndUndoAction();
        }
 }
 
-const char *StringFromEOLMode(int eolMode) {
+const char *Editor::StringFromEOLMode(int eolMode) {
        if (eolMode == SC_EOL_CRLF) {
                return "\r\n";
        } else if (eolMode == SC_EOL_CR) {
@@ -1419,7 +1461,7 @@ void Editor::LinesSplit(int pixelWidth) {
                int lineStart = pdoc->LineFromPosition(targetStart);
                int lineEnd = pdoc->LineFromPosition(targetEnd);
                const char *eol = StringFromEOLMode(pdoc->eolMode);
-               pdoc->BeginUndoAction();
+               UndoGroup ug(pdoc);
                for (int line = lineStart; line <= lineEnd; line++) {
                        AutoSurface surface(this);
                        AutoLineLayout ll(llc, RetrieveLineLayout(line));
@@ -1434,7 +1476,6 @@ void Editor::LinesSplit(int pixelWidth) {
                        }
                        lineEnd = pdoc->LineFromPosition(targetEnd);
                }
-               pdoc->EndUndoAction();
        }
 }
 
@@ -1450,6 +1491,84 @@ static int istrlen(const char *s) {
        return static_cast<int>(strlen(s));
 }
 
+bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) {
+       if (st.multipleStyles) {
+               for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+                       if (!vs.ValidStyle(styleOffset + st.styles[iStyle]))
+                               return false;
+               }
+       } else {
+               if (!vs.ValidStyle(styleOffset + st.style))
+                       return false;
+       }
+       return true;
+}
+
+static int WidthStyledText(Surface *surface, ViewStyle &vs, int styleOffset,
+       const char *text, const unsigned char *styles, size_t len) {
+       int width = 0;
+       size_t start = 0;
+       while (start < len) {
+               size_t style = styles[start];
+               size_t endSegment = start;
+               while ((endSegment+1 < len) && (static_cast<size_t>(styles[endSegment+1]) == style))
+                       endSegment++;
+               width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, endSegment - start + 1);
+               start = endSegment + 1;
+       }
+       return width;
+}
+
+static int WidestLineWidth(Surface *surface, ViewStyle &vs, int styleOffset, const StyledText &st) {
+       int widthMax = 0;
+       size_t start = 0;
+       while (start < st.length) {
+               size_t lenLine = st.LineLength(start);
+               int widthSubLine;
+               if (st.multipleStyles) {
+                       widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine);
+               } else {
+                       widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font, st.text + start, lenLine);
+               }
+               if (widthSubLine > widthMax)
+                       widthMax = widthSubLine;
+               start += lenLine + 1;
+       }
+       return widthMax;
+}
+
+void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent,
+       const StyledText &st, size_t start, size_t length) {
+
+       if (st.multipleStyles) {
+               int x = rcText.left;
+               size_t i = 0;
+               while (i < length) {
+                       size_t end = i;
+                       int style = st.styles[i + start];
+                       while (end < length-1 && st.styles[start+end+1] == style)
+                               end++;
+                       style += styleOffset;
+                       int width = surface->WidthText(vs.styles[style].font, st.text + start + i, end - i + 1);
+                       PRectangle rcSegment = rcText;
+                       rcSegment.left = x;
+                       rcSegment.right = x + width + 1;
+                       surface->DrawTextNoClip(rcSegment, vs.styles[style].font,
+                                       ascent, st.text + start + i, end - i + 1,
+                                       vs.styles[style].fore.allocated,
+                                       vs.styles[style].back.allocated);
+                       x += width;
+                       i = end + 1;
+               }
+       } else {
+               int style = st.style + styleOffset;
+               surface->DrawTextNoClip(rcText, vs.styles[style].font,
+                               rcText.top + vs.maxAscent, st.text + start, length,
+                               vs.styles[style].fore.allocated,
+                               vs.styles[style].back.allocated);
+       }
+}
+
 void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
        if (vs.fixedColumnWidth == 0)
                return;
@@ -1631,6 +1750,20 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
                                                rcNumber.top + vs.maxAscent, number, istrlen(number),
                                                vs.styles[STYLE_LINENUMBER].fore.allocated,
                                                vs.styles[STYLE_LINENUMBER].back.allocated);
+                               } else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) {
+                                       if (firstSubLine) {
+                                               const StyledText stMargin  = pdoc->MarginStyledText(lineDoc);
+                                               if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) {
+                                                       surface->FillRectangle(rcMarker,
+                                                               vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back.allocated);
+                                                       if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
+                                                               int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin);
+                                                               rcMarker.left = rcMarker.right - width - 3;
+                                                       }
+                                                       DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent,
+                                                               stMargin, 0, stMargin.length);
+                                               }
+                                       }
                                }
 
                                if (marks) {
@@ -1678,7 +1811,7 @@ LineLayout *Editor::RetrieveLineLayout(int lineNumber) {
        int posLineStart = pdoc->LineStart(lineNumber);
        int posLineEnd = pdoc->LineStart(lineNumber + 1);
        PLATFORM_ASSERT(posLineEnd >= posLineStart);
-       int lineCaret = pdoc->LineFromPosition(currentPos);
+       int lineCaret = pdoc->LineFromPosition(sel.MainCaret());
        return llc.Retrieve(lineNumber, lineCaret,
                posLineEnd - posLineStart, pdoc->GetStyleClock(),
                LinesOnScreen() + 1, pdoc->LinesTotal());
@@ -1805,6 +1938,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                ll->widthLine = LineLayout::wrapWidthInfinite;
                ll->lines = 1;
                int numCharsInLine = 0;
+               int numCharsBeforeEOL = 0;
                if (vstyle.edgeState == EDGE_BACKGROUND) {
                        ll->edgeColumn = pdoc->FindColumn(line, theEdge);
                        if (ll->edgeColumn >= posLineStart) {
@@ -1831,6 +1965,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
                                        ll->chars[numCharsInLine] = static_cast<char>(tolower(chDoc));
                                numCharsInLine++;
+                               if (!IsEOLChar(chDoc))
+                                       numCharsBeforeEOL++;
                        }
                }
                ll->xHighlightGuide = 0;
@@ -1913,6 +2049,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        ll->positions[startseg] += 2;
                }
                ll->numCharsInLine = numCharsInLine;
+               ll->numCharsBeforeEOL = numCharsBeforeEOL;
                ll->validity = LineLayout::llPositions;
        }
        // Hard to cope when too narrow, so just assume there is space
@@ -1930,6 +2067,20 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                        if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) {
                                width -= vstyle.aveCharWidth; // take into account the space for end wrap mark
                        }
+                       ll->wrapIndent = wrapAddIndent;
+                       if (wrapIndentMode != SC_WRAPINDENT_FIXED)
+                               for (int i = 0; i < ll->numCharsInLine; i++) {
+                                       if (!IsSpaceOrTab(ll->chars[i])) {
+                                               ll->wrapIndent += ll->positions[i]; // Add line indent
+                                               break;
+                                       }
+                               }
+                       // Check for text width minimum
+                       if (ll->wrapIndent > width - static_cast<int>(vstyle.aveCharWidth) * 15)
+                               ll->wrapIndent = wrapAddIndent;
+                       // Check for wrapIndent minimum
+                       if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < static_cast<int>(vstyle.aveCharWidth)))
+                               ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual
                        ll->lines = 0;
                        // Calculate line start positions based upon width.
                        int lastGoodBreak = 0;
@@ -1955,7 +2106,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
                                        ll->SetLineStart(ll->lines, lastGoodBreak);
                                        startOffset = ll->positions[lastGoodBreak];
                                        // take into account the space for start wrap mark and indent
-                                       startOffset -= actualWrapVisualStartIndent * vstyle.aveCharWidth;
+                                       startOffset -= ll->wrapIndent;
                                        p = lastGoodBreak + 1;
                                        continue;
                                }
@@ -1979,15 +2130,21 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
        }
 }
 
-ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw) {
-       return primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated;
+ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw, bool main) {
+       return main ?
+               (primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated) :
+               vsDraw.selAdditionalBackground.allocated;
 }
 
 ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
-        ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
-       if (inSelection) {
+        ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+       if (inSelection == 1) {
                if (vsDraw.selbackset && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
-                       return SelectionBackground(vsDraw);
+                       return SelectionBackground(vsDraw, true);
+               }
+       } else if (inSelection == 2) {
+               if (vsDraw.selbackset && (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)) {
+                       return SelectionBackground(vsDraw, false);
                }
        } else {
                if ((vsDraw.edgeState == EDGE_BACKGROUND) &&
@@ -2061,47 +2218,132 @@ static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourAllocate
        }
 }
 
+void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
+                                 const char *s, ColourAllocated textBack, ColourAllocated textFore, bool twoPhaseDraw) {
+       if (!twoPhaseDraw) {
+               surface->FillRectangle(rcSegment, textBack);
+       }
+       Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
+       int normalCharHeight = surface->Ascent(ctrlCharsFont) -
+               surface->InternalLeading(ctrlCharsFont);
+       PRectangle rcCChar = rcSegment;
+       rcCChar.left = rcCChar.left + 1;
+       rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight;
+       rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1;
+       PRectangle rcCentral = rcCChar;
+       rcCentral.top++;
+       rcCentral.bottom--;
+       surface->FillRectangle(rcCentral, textFore);
+       PRectangle rcChar = rcCChar;
+       rcChar.left++;
+       rcChar.right--;
+       surface->DrawTextClipped(rcChar, ctrlCharsFont,
+               rcSegment.top + vsDraw.maxAscent, s, istrlen(s),
+               textBack, textFore);
+}
+
 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,
         bool drawWrapMarkEnd, ColourAllocated wrapColour) {
 
-       int styleMask = pdoc->stylingBitsMask;
+       const int posLineStart = pdoc->LineStart(line);
+       const int styleMask = pdoc->stylingBitsMask;
        PRectangle rcSegment = rcLine;
 
+       const bool lastSubLine = subLine == (ll->lines - 1);
+       int virtualSpace = 0;
+       if (lastSubLine) {
+               const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+               virtualSpace = sel.VirtualSpaceFor(pdoc->LineEnd(line)) * spaceWidth;
+       }
+
        // 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) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
-               surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+       // Fill the virtual space and show selections within it
+       if (virtualSpace) {
+               rcSegment.left = xEol + xStart;
+               rcSegment.right = xEol + xStart + virtualSpace;
+               surface->FillRectangle(rcSegment, overrideBackground ? background : vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+               if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) {
+                       SelectionSegment virtualSpaceRange(SelectionPosition(pdoc->LineEnd(line)), SelectionPosition(pdoc->LineEnd(line), sel.VirtualSpaceFor(pdoc->LineEnd(line))));
+                       for (size_t r=0; r<sel.Count(); r++) {
+                               int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+                               if (alpha == SC_ALPHA_NOALPHA) {
+                                       SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+                                       if (!portion.Empty()) {
+                                               const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+                                               rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+                                               rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+                                               rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+                                               rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+                                               surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == sel.Main()));
+                                       }
+                               }
+                       }
+               }
+       }
+
+       int posAfterLineEnd = pdoc->LineStart(line + 1);
+       int eolInSelection = (subLine == (ll->lines - 1)) ? sel.InSelectionForEOL(posAfterLineEnd) : 0;
+       int alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+
+       // Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on
+       int blobsWidth = 0;
+       if (lastSubLine) {
+               for (int eolPos=ll->numCharsBeforeEOL; eolPos<ll->numCharsInLine; eolPos++) {
+                       rcSegment.left = xStart + ll->positions[eolPos] - subLineStart + virtualSpace;
+                       rcSegment.right = xStart + ll->positions[eolPos+1] - subLineStart + virtualSpace;
+                       blobsWidth += rcSegment.Width();
+                       const char *ctrlChar = ControlCharacterString(ll->chars[eolPos]);
+                       int inSelection = 0;
+                       bool inHotspot = false;
+                       int styleMain = ll->styles[eolPos];
+                       ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, eolPos, ll);
+                       ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
+                       if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) {
+                               if (alpha == SC_ALPHA_NOALPHA) {
+                                       surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
+                               } else {
+                                       surface->FillRectangle(rcSegment, textBack);
+                                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
+                               }
+                       } else {
+                               surface->FillRectangle(rcSegment, textBack);
+                       }
+                       DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw);
+               }
+       }
+
+       // Draw the eol-is-selected rectangle
+       rcSegment.left = xEol + xStart + virtualSpace + blobsWidth;
+       rcSegment.right = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+
+       if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+               surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
        } else {
                if (overrideBackground) {
                        surface->FillRectangle(rcSegment, background);
-               } else {
+               } else if (line < pdoc->LinesTotal() - 1) {
+                       surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+               } 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 (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
-                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+               if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
                }
        }
 
-       rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
+       // Fill the remainder of the line
+       rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
        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 (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
-               surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+       if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+               surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
        } else {
                if (overrideBackground) {
                        surface->FillRectangle(rcSegment, background);
@@ -2110,8 +2352,8 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
                } else {
                        surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
                }
-               if (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
-                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+               if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
                }
        }
 
@@ -2119,7 +2361,7 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
                PRectangle rcPlace = rcSegment;
 
                if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) {
-                       rcPlace.left = xEol + xStart;
+                       rcPlace.left = xEol + xStart + virtualSpace;
                        rcPlace.right = rcPlace.left + vsDraw.aveCharWidth;
                } else {
                        // draw left of the right text margin, to avoid clipping by the current clip rect
@@ -2197,28 +2439,56 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
        }
 }
 
-void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
-                                 const char *s, ColourAllocated textBack, ColourAllocated textFore, bool twoPhaseDraw) {
-       if (!twoPhaseDraw) {
-               surface->FillRectangle(rcSegment, textBack);
+void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+    PRectangle rcLine, LineLayout *ll, int subLine) {
+       int indent = pdoc->GetLineIndentation(line) * vsDraw.spaceWidth;
+       PRectangle rcSegment = rcLine;
+       int annotationLine = subLine - ll->lines;
+       const StyledText stAnnotation  = pdoc->AnnotationStyledText(line);
+       if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) {
+               surface->FillRectangle(rcSegment, vsDraw.styles[0].back.allocated);
+               if (vs.annotationVisible == ANNOTATION_BOXED) {
+                       // Only care about calculating width if need to draw box
+                       int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation);
+                       widthAnnotation += vsDraw.spaceWidth * 2; // Margins
+                       rcSegment.left = xStart + indent;
+                       rcSegment.right = rcSegment.left + widthAnnotation;
+                       surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore.allocated);
+               } else {
+                       rcSegment.left = xStart;
+               }
+               const int annotationLines = pdoc->AnnotationLines(line);
+               size_t start = 0;
+               size_t lengthAnnotation = stAnnotation.LineLength(start);
+               int lineInAnnotation = 0;
+               while ((lineInAnnotation < annotationLine) && (start < stAnnotation.length)) {
+                       start += lengthAnnotation + 1;
+                       lengthAnnotation = stAnnotation.LineLength(start);
+                       lineInAnnotation++;
+               }
+               PRectangle rcText = rcSegment;
+               if (vs.annotationVisible == ANNOTATION_BOXED) {
+                       surface->FillRectangle(rcText,
+                               vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back.allocated);
+                       rcText.left += vsDraw.spaceWidth;
+               }
+               DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent,
+                       stAnnotation, start, lengthAnnotation);
+               if (vs.annotationVisible == ANNOTATION_BOXED) {
+                       surface->MoveTo(rcSegment.left, rcSegment.top);
+                       surface->LineTo(rcSegment.left, rcSegment.bottom);
+                       surface->MoveTo(rcSegment.right, rcSegment.top);
+                       surface->LineTo(rcSegment.right, rcSegment.bottom);
+                       if (subLine == ll->lines){
+                               surface->MoveTo(rcSegment.left, rcSegment.top);
+                               surface->LineTo(rcSegment.right, rcSegment.top);
+                       }
+                       if (subLine == ll->lines+annotationLines-1) {
+                               surface->MoveTo(rcSegment.left, rcSegment.bottom - 1);
+                               surface->LineTo(rcSegment.right, rcSegment.bottom - 1);
+                       }
+               }
        }
-       Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
-       int normalCharHeight = surface->Ascent(ctrlCharsFont) -
-               surface->InternalLeading(ctrlCharsFont);
-       PRectangle rcCChar = rcSegment;
-       rcCChar.left = rcCChar.left + 1;
-       rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight;
-       rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1;
-       PRectangle rcCentral = rcCChar;
-       rcCentral.top++;
-       rcCentral.bottom--;
-       surface->FillRectangle(rcCentral, textFore);
-       PRectangle rcChar = rcCChar;
-       rcChar.left++;
-       rcChar.right--;
-       surface->DrawTextClipped(rcChar, ctrlCharsFont,
-               rcSegment.top + vsDraw.maxAscent, s, istrlen(s),
-               textBack, textFore);
 }
 
 void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
@@ -2280,11 +2550,18 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 
        int startseg = ll->LineStart(subLine);
        int subLineStart = ll->positions[startseg];
+       if (subLine >= ll->lines) {
+               DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine);
+               return; // No further drawing
+       }
        int lineStart = 0;
        int lineEnd = 0;
        if (subLine < ll->lines) {
                lineStart = ll->LineStart(subLine);
                lineEnd = ll->LineStart(subLine + 1);
+               if (subLine == ll->lines - 1) {
+                       lineEnd = ll->numCharsBeforeEOL;
+               }
        }
 
        ColourAllocated wrapColour = vsDraw.styles[STYLE_DEFAULT].fore.allocated;
@@ -2299,7 +2576,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                }
        }
 
-       if (actualWrapVisualStartIndent != 0) {
+       if (ll->wrapIndent != 0) {
 
                bool continuedWrapLine = false;
                if (subLine < ll->lines) {
@@ -2311,7 +2588,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                        PRectangle rcPlace = rcSegment;
 
                        rcPlace.left = ll->positions[startseg] + xStart - subLineStart;
-                       rcPlace.right = rcPlace.left + actualWrapVisualStartIndent * vsDraw.aveCharWidth;
+                       rcPlace.right = rcPlace.left + ll->wrapIndent;
 
                        // default bgnd here..
                        surface->FillRectangle(rcSegment, overrideBackground ? background :
@@ -2332,14 +2609,19 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                DrawWrapMarker(surface, rcPlace, false, wrapColour);
                        }
 
-                       xStart += actualWrapVisualStartIndent * vsDraw.aveCharWidth;
+                       xStart += ll->wrapIndent;
                }
        }
 
+       bool selBackDrawn = vsDraw.selbackset &&
+               ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA));
+
        // Does not take margin into account but not significant
        int xStartVisible = subLineStart - xStart;
 
-       BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
+       ll->psel = &sel;
+
+       BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible, selBackDrawn);
        int next = bfBack.First();
 
        // Background drawing loop
@@ -2360,7 +2642,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                        rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
 
                        int styleMain = ll->styles[i];
-                       bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+                       const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
                        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') {
@@ -2382,8 +2664,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                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);
+                                                               PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart,
+                                                                       rcSegment.top,
+                                                                       ll->positions[cpos + startseg + 1] + xStart - subLineStart,
+                                                                       rcSegment.bottom);
                                                                surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground.allocated);
                                                        }
                                                } else {
@@ -2412,9 +2696,23 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated);
        }
 
+       // Draw underline mark as part of background if not transparent
+       int marks = pdoc->GetMark(line);
+       int markBit;
+       for (markBit = 0; (markBit < 32) && marks; markBit++) {
+               if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) &&
+                   (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
+                       PRectangle rcUnderline = rcLine;
+                       rcUnderline.top = rcUnderline.bottom - 2;
+                       surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back.allocated);
+               }
+               marks >>= 1;
+       }
+
        inIndentation = subLine == 0;   // Do not handle indentation except on first subline.
        // Foreground drawing loop
-       BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
+       BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible,
+               ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset));
        next = bfFore.First();
 
        while (next < lineEnd) {
@@ -2438,9 +2736,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                if (vsDraw.hotspotForegroundSet)
                                        textFore = vsDraw.hotspotForeground.allocated;
                        }
-                       bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+                       const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
                        if (inSelection && (vsDraw.selforeset)) {
-                               textFore = vsDraw.selforeground.allocated;
+                               textFore = (inSelection == 1) ? vsDraw.selforeground.allocated : vsDraw.selAdditionalForeground.allocated;
                        }
                        bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
                        ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
@@ -2515,12 +2813,15 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                                                                        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);
+                                                                               PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart,
+                                                                                       rcSegment.top,
+                                                                                       ll->positions[cpos + startseg + 1] + xStart - subLineStart,
+                                                                                       rcSegment.bottom);
                                                                                surface->FillRectangle(rcSpace, textBack);
                                                                        }
                                                                        PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
-                                                                       rcDot.right = rcDot.left + 1;
-                                                                       rcDot.bottom = rcDot.top + 1;
+                                                                       rcDot.right = rcDot.left + vs.whitespaceSize;
+                                                                       rcDot.bottom = rcDot.top + vs.whitespaceSize;
                                                                        surface->FillRectangle(rcDot, textFore);
                                                                }
                                                        }
@@ -2558,13 +2859,16 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth)
                && (subLine == 0)) {
                int indentSpace = pdoc->GetLineIndentation(line);
+               int xStartText = ll->positions[pdoc->GetLineIndentPosition(line) - posLineStart];
+
                // Find the most recent line with some text
 
                int lineLastWithText = line;
-               while (lineLastWithText > 0 && pdoc->IsWhiteLine(lineLastWithText)) {
+               while (lineLastWithText > Platform::Maximum(line-20, 0) && pdoc->IsWhiteLine(lineLastWithText)) {
                        lineLastWithText--;
                }
                if (lineLastWithText < line) {
+                       xStartText = 100000;    // Don't limit to visible indentation on empty line
                        // This line is empty, so use indentation of last line with text
                        int indentLastWithText = pdoc->GetLineIndentation(lineLastWithText);
                        int isFoldHeader = pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG;
@@ -2583,7 +2887,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                }
 
                int lineNextWithText = line;
-               while (lineNextWithText < pdoc->LinesTotal() && pdoc->IsWhiteLine(lineNextWithText)) {
+               while (lineNextWithText < Platform::Minimum(line+20, pdoc->LinesTotal()) && pdoc->IsWhiteLine(lineNextWithText)) {
                        lineNextWithText++;
                }
                if (lineNextWithText > line) {
@@ -2594,8 +2898,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 
                for (int indentPos = pdoc->IndentSize(); indentPos < indentSpace; indentPos += pdoc->IndentSize()) {
                        int xIndent = indentPos * vsDraw.spaceWidth;
-                       DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
-                               (ll->xHighlightGuide == xIndent));
+                       if (xIndent < xStartText) {
+                               DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
+                                       (ll->xHighlightGuide == xIndent));
+                       }
                }
        }
 
@@ -2607,15 +2913,28 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
                        xStart, subLine, subLineStart, overrideBackground, background,
                        drawWrapMarkEnd, wrapColour);
        }
-       if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) && (ll->selStart >= 0) && (ll->selEnd >= 0)) {
-               int startPosSel = (ll->selStart < posLineStart) ? posLineStart : ll->selStart;
-               int endPosSel = (ll->selEnd < (lineEnd + posLineStart)) ? ll->selEnd : (lineEnd + posLineStart);
-               if (startPosSel < endPosSel) {
-                       rcSegment.left = xStart + ll->positions[startPosSel - posLineStart] - subLineStart;
-                       rcSegment.right = xStart + ll->positions[endPosSel - posLineStart] - subLineStart;
-                       rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
-                       rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
-                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+       if (!hideSelection && ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA))) {
+               // For each selection draw
+               int virtualSpaces = 0;
+               if (subLine == (ll->lines - 1)) {
+                       virtualSpaces = sel.VirtualSpaceFor(pdoc->LineEnd(line));
+               }
+               SelectionPosition posStart(posLineStart);
+               SelectionPosition posEnd(posLineStart + lineEnd, virtualSpaces);
+               SelectionSegment virtualSpaceRange(posStart, posEnd);
+               for (size_t r=0; r<sel.Count(); r++) {
+                       int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+                       if (alpha != SC_ALPHA_NOALPHA) {
+                               SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+                               if (!portion.Empty()) {
+                                       const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+                                       rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+                                       rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+                                       rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+                                       rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+                                       SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == sel.Main()), alpha);
+                               }
+                       }
                }
        }
 
@@ -2625,17 +2944,21 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
                SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
        }
-       int marks = pdoc->GetMark(line);
-       for (int markBit = 0; (markBit < 32) && marks; markBit++) {
+       marks = pdoc->GetMark(line);
+       for (markBit = 0; (markBit < 32) && marks; markBit++) {
                if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND)) {
                        SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
+               } else if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE)) {
+                       PRectangle rcUnderline = rcSegment;
+                       rcUnderline.top = rcUnderline.bottom - 2;
+                       SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
                }
                marks >>= 1;
        }
        if (vsDraw.maskInLine) {
                int marksMasked = pdoc->GetMark(line) & vsDraw.maskInLine;
                if (marksMasked) {
-                       for (int markBit = 0; (markBit < 32) && marksMasked; markBit++) {
+                       for (markBit = 0; (markBit < 32) && marksMasked; markBit++) {
                                if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY)) {
                                        SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
                                }
@@ -2645,7 +2968,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
        }
 }
 
-void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret) {
+void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
+                                                       int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour) {
 
        int lineStart = ll->LineStart(subLine);
        int posBefore = posCaret;
@@ -2688,8 +3012,15 @@ void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll,
        }
 
        // We now know what to draw, update the caret drawing rectangle
-       rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[ll->LineStart(subLine)] + xStart;
-       rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[ll->LineStart(subLine)] + xStart;
+       rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[lineStart] + xStart;
+       rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[lineStart] + xStart;
+
+       // Adjust caret position to take into account any word wrapping symbols.
+       if ((ll->wrapIndent != 0) && (lineStart != 0)) {
+               int wordWrapCharWidth = ll->wrapIndent;
+               rcCaret.left += wordWrapCharWidth;
+               rcCaret.right += wordWrapCharWidth;
+       }
 
        // This character is where the caret block is, we override the colours
        // (inversed) for drawing the caret here.
@@ -2697,7 +3028,7 @@ void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll,
        surface->DrawTextClipped(rcCaret, vsDraw.styles[styleMain].font,
                rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar,
                numCharsToDraw, vsDraw.styles[styleMain].back.allocated,
-               vsDraw.caretcolour.allocated);
+               caretColour);
 }
 
 void Editor::RefreshPixMaps(Surface *surfaceWindow) {
@@ -2766,10 +3097,94 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
        }
 }
 
+void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xStart,
+        PRectangle rcLine, LineLayout *ll, int subLine) {
+       // When drag is active it is the only caret drawn
+       bool drawDrag = posDrag.IsValid();
+       if (hideSelection && !drawDrag)
+               return;
+       const int posLineStart = pdoc->LineStart(lineDoc);
+       // For each selection draw
+       for (size_t r=0; (r<sel.Count()) || drawDrag; r++) {
+               const bool mainCaret = r == sel.Main();
+               const SelectionPosition posCaret = (drawDrag ? posDrag : sel.Range(r).caret);
+               const int offset = posCaret.Position() - posLineStart;
+               const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+               const int virtualOffset = posCaret.VirtualSpace() * spaceWidth;
+               if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) {
+                       int xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)];
+                       if (ll->wrapIndent != 0) {
+                               int lineStart = ll->LineStart(subLine);
+                               if (lineStart != 0)     // Wrapped
+                                       xposCaret += ll->wrapIndent;
+                       }
+                       bool caretBlinkState = (caret.active && caret.on) || (!additionalCaretsBlink && !mainCaret);
+                       bool caretVisibleState = additionalCaretsVisible || mainCaret;
+                       if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) &&
+                               ((posDrag.IsValid()) || (caretBlinkState && caretVisibleState))) {
+                               bool caretAtEOF = false;
+                               bool caretAtEOL = false;
+                               bool drawBlockCaret = false;
+                               int widthOverstrikeCaret;
+                               int caretWidthOffset = 0;
+                               PRectangle rcCaret = rcLine;
+
+                               if (posCaret.Position() == pdoc->Length())      {   // At end of document
+                                       caretAtEOF = true;
+                                       widthOverstrikeCaret = vsDraw.aveCharWidth;
+                               } else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) {        // At end of line
+                                       caretAtEOL = true;
+                                       widthOverstrikeCaret = vsDraw.aveCharWidth;
+                               } else {
+                                       widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset];
+                               }
+                               if (widthOverstrikeCaret < 3)   // Make sure its visible
+                                       widthOverstrikeCaret = 3;
+
+                               if (xposCaret > 0)
+                                       caretWidthOffset = 1;   // Move back so overlaps both character cells.
+                               xposCaret += xStart;
+                               if (posDrag.IsValid()) {
+                                       /* Dragging text, use a line caret */
+                                       rcCaret.left = xposCaret - caretWidthOffset;
+                                       rcCaret.right = rcCaret.left + vsDraw.caretWidth;
+                               } else if (inOverstrike) {
+                                       /* Overstrike (insert mode), use a modified bar caret */
+                                       rcCaret.top = rcCaret.bottom - 2;
+                                       rcCaret.left = xposCaret + 1;
+                                       rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1;
+                               } else if (vsDraw.caretStyle == CARETSTYLE_BLOCK) {
+                                       /* Block caret */
+                                       rcCaret.left = xposCaret;
+                                       if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) {
+                                               drawBlockCaret = true;
+                                               rcCaret.right = xposCaret + widthOverstrikeCaret;
+                                       } else {
+                                               rcCaret.right = xposCaret + vsDraw.aveCharWidth;
+                                       }
+                               } else {
+                                       /* Line caret */
+                                       rcCaret.left = xposCaret - caretWidthOffset;
+                                       rcCaret.right = rcCaret.left + vsDraw.caretWidth;
+                               }
+                               ColourAllocated caretColour = mainCaret ? vsDraw.caretcolour.allocated : vsDraw.additionalCaretColour.allocated;
+                               if (drawBlockCaret) {
+                                       DrawBlockCaret(surface, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour);
+                               } else {
+                                       surface->FillRectangle(rcCaret, caretColour);
+                               }
+                       }
+               }
+               if (drawDrag)
+                       break;
+       }
+}
+
 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);
 
+       pixmapLine->Release();
        RefreshStyleData();
        RefreshPixMaps(surfaceWindow);
 
@@ -2787,7 +3202,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
        //Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast);
        int endPosPaint = pdoc->Length();
        if (lineStyleLast < cs.LinesDisplayed())
-               endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast + 1));
+               endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast) + 1);
 
        int xStart = vs.fixedColumnWidth - xOffset;
        int ypos = 0;
@@ -2799,10 +3214,17 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
        pdoc->EnsureStyledTo(endPosPaint);
        bool paintAbandonedByStyling = paintState == paintAbandoned;
        if (needUpdateUI) {
+               // Deselect palette by selecting a temporary palette
+               Palette palTemp;
+               surfaceWindow->SetPalette(&palTemp, true);
+
                NotifyUpdateUI();
                needUpdateUI = false;
+
                RefreshStyleData();
                RefreshPixMaps(surfaceWindow);
+               surfaceWindow->SetPalette(&palette, true);
+               pixmapLine->SetPalette(&palette, !hasFocus);
        }
 
        // Call priority lines wrap on a window of lines which are likely
@@ -2810,7 +3232,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
        //      lines first).
        int startLineToWrap = cs.DocFromDisplay(topLine) - 5;
        if (startLineToWrap < 0)
-               startLineToWrap = -1;
+               startLineToWrap = 0;
        if (WrapLines(false, startLineToWrap)) {
                // The wrapping process has changed the height of some lines so
                // abandon this paint for a complete repaint.
@@ -2857,10 +3279,10 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 
                int visibleLine = topLine + screenLinePaintFirst;
 
-               int posCaret = currentPos;
-               if (posDrag >= 0)
+               SelectionPosition posCaret = sel.RangeMain().caret;
+               if (posDrag.IsValid())
                        posCaret = posDrag;
-               int lineCaret = pdoc->LineFromPosition(posCaret);
+               int lineCaret = pdoc->LineFromPosition(posCaret.Position());
 
                // Remove selection margin from drawing area so text will not be drawn
                // on it in unbuffered mode.
@@ -2876,7 +3298,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                //ElapsedTime etWhole;
                int lineDocPrevious = -1;       // Used to avoid laying out one document line multiple times
                AutoLineLayout ll(llc, 0);
-               SelectionLineIterator lineIterator(this);
                while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) {
 
                        int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -2890,8 +3311,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        //ElapsedTime et;
                        if (lineDoc != lineDocPrevious) {
                                ll.Set(0);
-                               // For rectangular selection this accesses the layout cache so should be after layout returned.
-                               lineIterator.SetAt(lineDoc);
                                ll.Set(RetrieveLineLayout(lineDoc));
                                LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
                                lineDocPrevious = lineDoc;
@@ -2899,17 +3318,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        //durLayout += et.Duration(true);
 
                        if (ll) {
-                               if (selType == selStream) {
-                                       ll->selStart = SelectionStart();
-                                       ll->selEnd = SelectionEnd();
-                               } else {
-                                       ll->selStart = lineIterator.startPos;
-                                       ll->selEnd = lineIterator.endPos;
-                               }
                                ll->containsCaret = lineDoc == lineCaret;
                                if (hideSelection) {
-                                       ll->selStart = -1;
-                                       ll->selEnd = -1;
                                        ll->containsCaret = false;
                                }
 
@@ -2932,128 +3342,28 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                ll->RestoreBracesHighlight(rangeLine, braces);
 
                                bool expanded = cs.GetExpanded(lineDoc);
-                               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) & ~(0xFFF0000);
-                                       int indentationStep = pdoc->IndentSize();
-                                       // Draw line above fold
-                                       if ((FoldLevelPrev < FoldLevelCurr)
-                                               ||
-                                               (FoldLevelFlags & SC_FOLDLEVELBOXHEADERFLAG
-                                                &&
-                                                (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELBOXFOOTERFLAG) == 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;
-                                               rcFoldLine.left += xStart + FoldLevelCurr * vs.spaceWidth * indentationStep - 1;
                                                surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
                                        }
-
-                                       // Line below the fold (or below a contracted fold)
-                                       if (FoldLevelFlags & SC_FOLDLEVELBOXFOOTERFLAG
-                                               ||
-                                               (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
+                               }
+                               // 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;
-                                               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 (ll->InLine(offset, subLine)) {
-                                               int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;
-
-                                               if (actualWrapVisualStartIndent != 0) {
-                                                       int lineStart = ll->LineStart(subLine);
-                                                       if (lineStart != 0)     // Wrapped
-                                                               xposCaret += actualWrapVisualStartIndent * vs.aveCharWidth;
-                                               }
-                                               if ((xposCaret >= 0) && (vs.caretWidth > 0) && (vs.caretStyle != CARETSTYLE_INVISIBLE) &&
-                                                       ((posDrag >= 0) || (caret.active && caret.on))) {
-                                                       bool caretAtEOF = false;
-                                                       bool caretAtEOL = false;
-                                                       bool drawBlockCaret = false;
-                                                       int widthOverstrikeCaret;
-                                                       int caretWidthOffset = 0;
-                                                       PRectangle rcCaret = rcLine;
-
-                                                       if (posCaret == pdoc->Length()) {   // At end of document
-                                                               caretAtEOF = true;
-                                                               widthOverstrikeCaret = vs.aveCharWidth;
-                                                       } else if ((posCaret - rangeLine.start) >= ll->numCharsInLine) {        // At end of line
-                                                               caretAtEOL = true;
-                                                               widthOverstrikeCaret = vs.aveCharWidth;
-                                                       } else {
-                                                               widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset];
-                                                       }
-                                                       if (widthOverstrikeCaret < 3)   // Make sure its visible
-                                                               widthOverstrikeCaret = 3;
-
-                                                       if (offset > ll->LineStart(subLine))
-                                                               caretWidthOffset = 1;   // Move back so overlaps both character cells.
-                                                       if (posDrag >= 0) {
-                                                               /* Dragging text, use a line caret */
-                                                               rcCaret.left = xposCaret - caretWidthOffset;
-                                                               rcCaret.right = rcCaret.left + vs.caretWidth;
-                                                       } else if (inOverstrike) {
-                                                               /* Overstrike (insert mode), use a modified bar caret */
-                                                               rcCaret.top = rcCaret.bottom - 2;
-                                                               rcCaret.left = xposCaret + 1;
-                                                               rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1;
-                                                       } else if (vs.caretStyle == CARETSTYLE_BLOCK) {
-                                                               /* Block caret */
-                                                               rcCaret.left = xposCaret;
-                                                               if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) {
-                                                                       drawBlockCaret = true;
-                                                                       rcCaret.right = xposCaret + widthOverstrikeCaret;
-                                                               } else {
-                                                                       rcCaret.right = xposCaret + vs.aveCharWidth;
-                                                               }
-                                                       } else {
-                                                               /* Line caret */
-                                                               rcCaret.left = xposCaret - caretWidthOffset;
-                                                               rcCaret.right = rcCaret.left + vs.caretWidth;
-                                                       }
-                                                       if (drawBlockCaret) {
-                                                               DrawBlockCaret(surface, vs, ll, subLine, xStart, offset, posCaret, rcCaret);
-                                                       } else {
-                                                               surface->FillRectangle(rcCaret, vs.caretcolour.allocated);
-                                                       }
-                                               }
-                                       }
-                               }
+                               DrawCarets(surface, vs, lineDoc, xStart, rcLine, ll, subLine);
 
                                if (bufferedDraw) {
                                        Point from(vs.fixedColumnWidth, 0);
@@ -3061,6 +3371,9 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                                                rcClient.right, yposScreen + vs.lineHeight);
                                        surfaceWindow->Copy(rcCopyArea, from, *pixmapLine);
                                }
+
+                               lineWidthMaxSeen = Platform::Maximum(
+                                           lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
                                //durCopy += et.Duration(true);
                        }
 
@@ -3071,8 +3384,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
                        yposScreen += vs.lineHeight;
                        visibleLine++;
 
-                       lineWidthMaxSeen = Platform::Maximum(
-                                   lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
                        //gdk_flush();
                }
                ll.Set(0);
@@ -3120,7 +3431,7 @@ ColourDesired InvertedLight(ColourDesired orig) {
 // This is mostly copied from the Paint method but with some things omitted
 // such as the margin markers, line numbers, selection and caret
 // Should be merged back into a combined Draw method.
-long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
+long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
        if (!pfr)
                return 0;
 
@@ -3155,6 +3466,7 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
        vsPrint.selbackset = false;
        vsPrint.selforeset = false;
        vsPrint.selAlpha = SC_ALPHA_NOALPHA;
+       vsPrint.selAdditionalAlpha = SC_ALPHA_NOALPHA;
        vsPrint.whitespaceBackgroundSet = false;
        vsPrint.whitespaceForegroundSet = false;
        vsPrint.showCaretLineBackground = false;
@@ -3232,8 +3544,6 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
                LineLayout ll(8000);
                LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
 
-               ll.selStart = -1;
-               ll.selEnd = -1;
                ll.containsCaret = false;
 
                PRectangle rcLine;
@@ -3356,6 +3666,15 @@ void Editor::ChangeSize() {
        }
 }
 
+int Editor::InsertSpace(int position, unsigned int spaces) {
+       if (spaces > 0) {
+               std::string spaceText(spaces, ' ');
+               pdoc->InsertString(position, spaceText.c_str(), spaces);
+               position += spaces;
+       }
+       return position;
+}
+
 void Editor::AddChar(char ch) {
        char s[2];
        s[0] = ch;
@@ -3363,34 +3682,60 @@ void Editor::AddChar(char ch) {
        AddCharUTF(s, 1);
 }
 
+void Editor::FilterSelections() {
+       if (!additionalSelectionTyping && (sel.Count() > 1)) {
+               SelectionRange rangeOnly = sel.RangeMain();
+               InvalidateSelection(rangeOnly, true);
+               sel.SetSelection(rangeOnly);
+       }
+}
+
 // AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
 void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
-       bool wasSelection = currentPos != anchor;
-       ClearSelection();
-       bool charReplaceAction = false;
-       if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
-               if (currentPos < (pdoc->Length())) {
-                       if (!IsEOLChar(pdoc->CharAt(currentPos))) {
-                               charReplaceAction = true;
-                               pdoc->BeginUndoAction();
-                               pdoc->DelChar(currentPos);
+       FilterSelections();
+       {
+               UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
+               for (size_t r=0; r<sel.Count(); r++) {
+                       if (!RangeContainsProtected(sel.Range(r).Start().Position(),
+                               sel.Range(r).End().Position())) {
+                               int positionInsert = sel.Range(r).Start().Position();
+                               if (!sel.Range(r).Empty()) {
+                                       if (sel.Range(r).Length()) {
+                                               pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
+                                               sel.Range(r).ClearVirtualSpace();
+                                       } else {
+                                               // Range is all virtual so collapse to start of virtual space
+                                               sel.Range(r).MinimizeVirtualSpace();
+                                       }
+                               } else if (inOverstrike) {
+                                       if (positionInsert < pdoc->Length()) {
+                                               if (!IsEOLChar(pdoc->CharAt(positionInsert))) {
+                                                       pdoc->DelChar(positionInsert);
+                                                       sel.Range(r).ClearVirtualSpace();
+                                               }
+                                       }
+                               }
+                               positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+                               if (pdoc->InsertString(positionInsert, s, len)) {
+                                       sel.Range(r).caret.SetPosition(positionInsert + len);
+                                       sel.Range(r).anchor.SetPosition(positionInsert + len);
+                               }
+                               sel.Range(r).ClearVirtualSpace();
+                               // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
+                               if (wrapState != eWrapNone) {
+                                       AutoSurface surface(this);
+                                       if (surface) {
+                                               WrapOneLine(surface, pdoc->LineFromPosition(positionInsert));
+                                       }
+                               }
                        }
                }
        }
-       if (pdoc->InsertString(currentPos, s, len)) {
-               SetEmptySelection(currentPos + len);
-       }
-       if (charReplaceAction) {
-               pdoc->EndUndoAction();
-       }
-       // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
        if (wrapState != eWrapNone) {
-               AutoSurface surface(this);
-               if (surface) {
-                       WrapOneLine(surface, pdoc->LineFromPosition(currentPos));
-               }
                SetScrollBars();
        }
+       ThinRectangularRange();
+       // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
        EnsureCaretVisible();
        // Avoid blinking during rapid typing:
        ShowCaretAtCurrentPosition();
@@ -3434,58 +3779,72 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
                }
                NotifyChar(byte);
        }
+
+       if (recordingMacro) {
+               NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(s));
+       }
 }
 
 void Editor::ClearSelection() {
-       if (!SelectionContainsProtected()) {
-               int startPos = SelectionStart();
-               if (selType == selStream) {
-                       unsigned int chars = SelectionEnd() - startPos;
-                       if (0 != chars) {
-                               pdoc->BeginUndoAction();
-                               pdoc->DeleteChars(startPos, chars);
-                               pdoc->EndUndoAction();
+       if (!sel.IsRectangular())
+               FilterSelections();
+       UndoGroup ug(pdoc);
+       for (size_t r=0; r<sel.Count(); r++) {
+               if (!sel.Range(r).Empty()) {
+                       if (!RangeContainsProtected(sel.Range(r).Start().Position(),
+                               sel.Range(r).End().Position())) {
+                               pdoc->DeleteChars(sel.Range(r).Start().Position(),
+                                       sel.Range(r).Length());
+                               sel.Range(r) = sel.Range(r).Start();
                        }
-               } else {
-                       pdoc->BeginUndoAction();
-                       SelectionLineIterator lineIterator(this, false);
-                       while (lineIterator.Iterate()) {
-                               startPos = lineIterator.startPos;
-                               unsigned int chars = lineIterator.endPos - startPos;
-                               if (0 != chars) {
-                                       pdoc->DeleteChars(startPos, chars);
-                               }
-                       }
-                       pdoc->EndUndoAction();
-                       selType = selStream;
                }
-               SetEmptySelection(startPos);
        }
+       ThinRectangularRange();
+       sel.RemoveDuplicates();
+       ClaimSelection();
 }
 
 void Editor::ClearAll() {
-       pdoc->BeginUndoAction();
-       if (0 != pdoc->Length()) {
-               pdoc->DeleteChars(0, pdoc->Length());
-       }
-       if (!pdoc->IsReadOnly()) {
-               cs.Clear();
+       {
+               UndoGroup ug(pdoc);
+               if (0 != pdoc->Length()) {
+                       pdoc->DeleteChars(0, pdoc->Length());
+               }
+               if (!pdoc->IsReadOnly()) {
+                       cs.Clear();
+                       pdoc->AnnotationClearAll();
+                       pdoc->MarginClearAll();
+               }
        }
-       pdoc->EndUndoAction();
-       anchor = 0;
-       currentPos = 0;
+       sel.Clear();
        SetTopLine(0);
        SetVerticalScrollPos();
        InvalidateStyleRedraw();
 }
 
 void Editor::ClearDocumentStyle() {
+       Decoration *deco = pdoc->decorations.root;
+       while (deco) {
+               // Save next in case deco deleted
+               Decoration *decoNext = deco->next;
+               if (deco->indicator < INDIC_CONTAINER) {
+                       pdoc->decorations.SetCurrentIndicator(deco->indicator);
+                       pdoc->DecorationFillRange(0, 0, pdoc->Length());
+               }
+               deco = decoNext;
+       }
        pdoc->StartStyling(0, '\377');
        pdoc->SetStyleFor(pdoc->Length(), 0);
        cs.ShowAll();
        pdoc->ClearLevels();
 }
 
+void Editor::CopyAllowLine() {
+       SelectionText selectedText;
+       CopySelectionRange(&selectedText, true);
+       CopyToClipboard(selectedText);
+}
+
 void Editor::Cut() {
        pdoc->CheckReadOnly();
        if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) {
@@ -3494,15 +3853,20 @@ void Editor::Cut() {
        }
 }
 
-void Editor::PasteRectangular(int pos, const char *ptr, int len) {
+void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, int len) {
        if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
                return;
        }
-       currentPos = pos;
-       int xInsert = XFromPosition(currentPos);
-       int line = pdoc->LineFromPosition(currentPos);
+       sel.Clear();
+       sel.RangeMain() = SelectionRange(pos);
+       int line = pdoc->LineFromPosition(sel.MainCaret());
+       UndoGroup ug(pdoc);
+       sel.RangeMain().caret = SelectionPosition(
+               InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+       int xInsert = XFromPosition(sel.RangeMain().caret);
        bool prevCr = false;
-       pdoc->BeginUndoAction();
+       while ((len > 0) && IsEOLChar(ptr[len-1]))
+               len--;
        for (int i = 0; i < len; i++) {
                if (IsEOLChar(ptr[i])) {
                        if ((ptr[i] == '\r') || (!prevCr))
@@ -3514,21 +3878,20 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) {
                                        pdoc->InsertChar(pdoc->Length(), '\n');
                        }
                        // Pad the end of lines with spaces if required
-                       currentPos = PositionFromLineX(line, xInsert);
-                       if ((XFromPosition(currentPos) < xInsert) && (i + 1 < len)) {
-                               for (int i = 0; i < xInsert - XFromPosition(currentPos); i++) {
-                                       pdoc->InsertChar(currentPos, ' ');
-                                       currentPos++;
+                       sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert));
+                       if ((XFromPosition(sel.MainCaret()) < xInsert) && (i + 1 < len)) {
+                               while (XFromPosition(sel.MainCaret()) < xInsert) {
+                                       pdoc->InsertChar(sel.MainCaret(), ' ');
+                                       sel.RangeMain().caret.Add(1);
                                }
                        }
                        prevCr = ptr[i] == '\r';
                } else {
-                       pdoc->InsertString(currentPos, ptr + i, 1);
-                       currentPos++;
+                       pdoc->InsertString(sel.MainCaret(), ptr + i, 1);
+                       sel.RangeMain().caret.Add(1);
                        prevCr = false;
                }
        }
-       pdoc->EndUndoAction();
        SetEmptySelection(pos);
 }
 
@@ -3537,17 +3900,33 @@ bool Editor::CanPaste() {
 }
 
 void Editor::Clear() {
-       if (currentPos == anchor) {
-               if (!RangeContainsProtected(currentPos, currentPos + 1)) {
-                       DelChar();
+       UndoGroup ug(pdoc);
+       // If multiple selections, don't delete EOLS
+       if (sel.Empty()) {
+               for (size_t r=0; r<sel.Count(); r++) {
+                       if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+                               if (sel.Range(r).Start().VirtualSpace()) {
+                                       if (sel.Range(r).anchor < sel.Range(r).caret)
+                                               sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).anchor.Position(), sel.Range(r).anchor.VirtualSpace()));
+                                       else
+                                               sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace()));
+                               }
+                               if ((sel.Count() == 1) || !IsEOLChar(pdoc->CharAt(sel.Range(r).caret.Position()))) {
+                                       pdoc->DelChar(sel.Range(r).caret.Position());
+                                       sel.Range(r).ClearVirtualSpace();
+                               }  // else multiple selection so don't eat line ends
+                       } else {
+                               sel.Range(r).ClearVirtualSpace();
+                       }
                }
        } else {
                ClearSelection();
        }
-       SetEmptySelection(currentPos);
+       sel.RemoveDuplicates();
 }
 
 void Editor::SelectAll() {
+       sel.Clear();
        SetSelection(0, pdoc->Length());
        Redraw();
 }
@@ -3572,39 +3951,54 @@ void Editor::Redo() {
 }
 
 void Editor::DelChar() {
-       if (!RangeContainsProtected(currentPos, currentPos + 1)) {
-               pdoc->DelChar(currentPos);
+       if (!RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1)) {
+               pdoc->DelChar(sel.MainCaret());
        }
        // Avoid blinking during rapid typing:
        ShowCaretAtCurrentPosition();
 }
 
 void Editor::DelCharBack(bool allowLineStartDeletion) {
-       if (currentPos == anchor) {
-               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->IndentSize();
-                                       if (indentation % indentationStep == 0) {
-                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
-                                       } else {
-                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
-                                       }
-                                       SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-                                       pdoc->EndUndoAction();
+       if (!sel.IsRectangular())
+               FilterSelections();
+       if (sel.IsRectangular())
+               allowLineStartDeletion = false;
+       UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty());
+       if (sel.Empty()) {
+               for (size_t r=0; r<sel.Count(); r++) {
+                       if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+                               if (sel.Range(r).caret.VirtualSpace()) {
+                                       sel.Range(r).caret.SetVirtualSpace(sel.Range(r).caret.VirtualSpace() - 1);
+                                       sel.Range(r).anchor.SetVirtualSpace(sel.Range(r).caret.VirtualSpace());
                                } else {
-                                       pdoc->DelCharBack(currentPos);
+                                       int lineCurrentPos = pdoc->LineFromPosition(sel.Range(r).caret.Position());
+                                       if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != sel.Range(r).caret.Position())) {
+                                               if (pdoc->GetColumn(sel.Range(r).caret.Position()) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+                                                               pdoc->GetColumn(sel.Range(r).caret.Position()) > 0 && pdoc->backspaceUnindents) {
+                                                       UndoGroup ugInner(pdoc, !ug.Needed());
+                                                       int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+                                                       int indentationStep = pdoc->IndentSize();
+                                                       if (indentation % indentationStep == 0) {
+                                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+                                                       } else {
+                                                               pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+                                                       }
+                                                       // SetEmptySelection
+                                                       sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos),
+                                                               pdoc->GetLineIndentPosition(lineCurrentPos));
+                                               } else {
+                                                       pdoc->DelCharBack(sel.Range(r).caret.Position());
+                                               }
+                                       }
                                }
+                       } else {
+                               sel.Range(r).ClearVirtualSpace();
                        }
                }
        } else {
                ClearSelection();
-               SetEmptySelection(currentPos);
        }
+       sel.RemoveDuplicates();
        // Avoid blinking during rapid typing:
        ShowCaretAtCurrentPosition();
 }
@@ -3627,12 +4021,6 @@ void Editor::NotifyChar(int ch) {
        scn.nmhdr.code = SCN_CHARADDED;
        scn.ch = ch;
        NotifyParent(scn);
-       if (recordingMacro) {
-               char txt[2];
-               txt[0] = static_cast<char>(ch);
-               txt[1] = '\0';
-               NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(txt));
-       }
 }
 
 void Editor::NotifySavePoint(bool isSavePoint) {
@@ -3655,7 +4043,7 @@ void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) {
        SCNotification scn = {0};
        scn.nmhdr.code = SCN_DOUBLECLICK;
        scn.line = LineFromLocation(pt);
-       scn.position = PositionFromLocationClose(pt);
+       scn.position = PositionFromLocation(pt, true);
        scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
                (alt ? SCI_ALT : 0);
        NotifyParent(scn);
@@ -3736,7 +4124,7 @@ void Editor::NotifyNeedShown(int pos, int len) {
 void Editor::NotifyDwelling(Point pt, bool state) {
        SCNotification scn = {0};
        scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND;
-       scn.position = PositionFromLocationClose(pt);
+       scn.position = PositionFromLocation(pt, true);
        scn.x = pt.x;
        scn.y = pt.y;
        NotifyParent(scn);
@@ -3754,13 +4142,6 @@ void Editor::NotifyModifyAttempt(Document*, void *) {
        NotifyModifyAttempt();
 }
 
-void Editor::NotifyMove(int position) {
-       SCNotification scn = {0};
-       scn.nmhdr.code = SCN_POSCHANGED;
-       scn.position = position;
-       NotifyParent(scn);
-}
-
 void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
        //Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off");
        NotifySavePoint(atSavePoint);
@@ -3774,6 +4155,10 @@ void Editor::CheckModificationForWrap(DocModification mh) {
                        int lines = Platform::Maximum(0, mh.linesAdded);
                        NeedWrapping(lineDoc, lineDoc + lines + 1);
                }
+               // Fix up annotation heights
+               int lineDoc = pdoc->LineFromPosition(mh.position);
+               int lines = Platform::Maximum(0, mh.linesAdded);
+               SetAnnotationHeights(lineDoc, lineDoc + lines + 2);
        }
 }
 
@@ -3832,13 +4217,11 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
        } else {
                // Move selection and brace highlights
                if (mh.modificationType & SC_MOD_INSERTTEXT) {
-                       currentPos = MovePositionForInsertion(currentPos, mh.position, mh.length);
-                       anchor = MovePositionForInsertion(anchor, mh.position, mh.length);
+                       sel.MovePositions(true, mh.position, mh.length);
                        braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length);
                        braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length);
                } else if (mh.modificationType & SC_MOD_DELETETEXT) {
-                       currentPos = MovePositionForDeletion(currentPos, mh.position, mh.length);
-                       anchor = MovePositionForDeletion(anchor, mh.position, mh.length);
+                       sel.MovePositions(false, mh.position, mh.length);
                        braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length);
                        braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length);
                }
@@ -3861,6 +4244,12 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
                                cs.DeleteLines(lineOfPos, -mh.linesAdded);
                        }
                }
+               if (mh.modificationType & SC_MOD_CHANGEANNOTATION) {
+                       int lineDoc = pdoc->LineFromPosition(mh.position);
+                       if (vs.annotationVisible) {
+                               cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded);
+                       }
+               }
                CheckModificationForWrap(mh);
                if (mh.linesAdded != 0) {
                        // Avoid scrolling of display if change before current display
@@ -3891,7 +4280,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
                SetScrollBars();
        }
 
-       if (mh.modificationType & SC_MOD_CHANGEMARKER) {
+       if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) {
                if ((paintState == notPainting) || !PaintContainsMargin()) {
                        if (mh.modificationType & SC_MOD_CHANGEFOLD) {
                                // Fold changes can affect the drawing of following lines so redraw whole margin
@@ -3925,6 +4314,8 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
                scn.line = mh.line;
                scn.foldLevelNow = mh.foldLevelNow;
                scn.foldLevelPrev = mh.foldLevelPrev;
+               scn.token = mh.token;
+               scn.annotationLinesAdded = mh.annotationLinesAdded;
                NotifyParent(scn);
        }
 }
@@ -4036,6 +4427,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
        case SCI_PAGEUPRECTEXTEND:
        case SCI_PAGEDOWNRECTEXTEND:
        case SCI_SELECTIONDUPLICATE:
+       case SCI_COPYALLOWLINE:
                break;
 
                // Filter out all others like display changes. Also, newlines are redundant
@@ -4061,11 +4453,11 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
  * If stuttered = true and not already at first/last row, move to first/last row of window.
  * If stuttered = true and already at first/last row, scroll as normal.
  */
-void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
+void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) {
        int topLineNew, newPos;
 
        // I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem?
-       int currentLine = pdoc->LineFromPosition(currentPos);
+       int currentLine = pdoc->LineFromPosition(sel.MainCaret());
        int topStutterLine = topLine + caretYSlop;
        int bottomStutterLine =
            pdoc->LineFromPosition(PositionFromLocation(
@@ -4081,7 +4473,7 @@ void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
                newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * (LinesToScroll() - caretYSlop)));
 
        } else {
-               Point pt = LocationFromPosition(currentPos);
+               Point pt = LocationFromPosition(sel.MainCaret());
 
                topLineNew = Platform::Clamp(
                            topLine + direction * LinesToScroll(), 0, MaxScrollPos());
@@ -4091,39 +4483,29 @@ void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
 
        if (topLineNew != topLine) {
                SetTopLine(topLineNew);
-               MovePositionTo(newPos, sel);
+               MovePositionTo(SelectionPosition(newPos), selt);
                Redraw();
                SetVerticalScrollPos();
        } else {
-               MovePositionTo(newPos, sel);
+               MovePositionTo(SelectionPosition(newPos), selt);
        }
 }
 
 void Editor::ChangeCaseOfSelection(bool makeUpperCase) {
-       pdoc->BeginUndoAction();
-       int startCurrent = currentPos;
-       int startAnchor = anchor;
-       if (selType == selStream) {
-               pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()),
-                       makeUpperCase);
-               SetSelection(startCurrent, startAnchor);
-       } else {
-               SelectionLineIterator lineIterator(this, false);
-               while (lineIterator.Iterate()) {
-                       pdoc->ChangeCase(
-                           Range(lineIterator.startPos, lineIterator.endPos),
-                           makeUpperCase);
-               }
-               // Would be nicer to keep the rectangular selection but this is complex
-               SetEmptySelection(startCurrent);
+       UndoGroup ug(pdoc);
+       for (size_t r=0; r<sel.Count(); r++) {
+               SelectionRange current = sel.Range(r);
+               pdoc->ChangeCase(Range(current.Start().Position(), current.End().Position()),
+               makeUpperCase);
+               // Automatic movement cuts off last character so reset to exactly the same as it was.
+               sel.Range(r) = current;
        }
-       pdoc->EndUndoAction();
 }
 
 void Editor::LineTranspose() {
-       int line = pdoc->LineFromPosition(currentPos);
+       int line = pdoc->LineFromPosition(sel.MainCaret());
        if (line > 0) {
-               pdoc->BeginUndoAction();
+               UndoGroup ug(pdoc);
                int startPrev = pdoc->LineStart(line - 1);
                int endPrev = pdoc->LineEnd(line - 1);
                int start = pdoc->LineStart(line);
@@ -4136,37 +4518,54 @@ void Editor::LineTranspose() {
                pdoc->DeleteChars(startPrev, len1);
                pdoc->InsertString(startPrev, line2, len2);
                pdoc->InsertString(start - len1 + len2, line1, len1);
-               MovePositionTo(start - len1 + len2);
+               MovePositionTo(SelectionPosition(start - len1 + len2));
                delete []line1;
                delete []line2;
-               pdoc->EndUndoAction();
        }
 }
 
 void Editor::Duplicate(bool forLine) {
-       int start = SelectionStart();
-       int end = SelectionEnd();
-       if (start == end) {
+       if (sel.Empty()) {
                forLine = true;
        }
+       UndoGroup ug(pdoc, sel.Count() > 1);
+       SelectionPosition last;
+       const char *eol = "";
+       int eolLen = 0;
        if (forLine) {
-               int line = pdoc->LineFromPosition(currentPos);
-               start = pdoc->LineStart(line);
-               end = pdoc->LineEnd(line);
+               eol = StringFromEOLMode(pdoc->eolMode);
+               eolLen = istrlen(eol);
+       }
+       for (size_t r=0; r<sel.Count(); r++) {
+               SelectionPosition start = sel.Range(r).Start();
+               SelectionPosition end = sel.Range(r).End();
+               if (forLine) {
+                       int line = pdoc->LineFromPosition(sel.Range(r).caret.Position());
+                       start = SelectionPosition(pdoc->LineStart(line));
+                       end = SelectionPosition(pdoc->LineEnd(line));
+               }
+               char *text = CopyRange(start.Position(), end.Position());
+               if (forLine)
+                       pdoc->InsertString(end.Position(), eol, eolLen);
+               pdoc->InsertString(end.Position() + eolLen, text, SelectionRange(end, start).Length());
+               delete []text;
        }
-       char *text = CopyRange(start, end);
-       if (forLine) {
-               const char *eol = StringFromEOLMode(pdoc->eolMode);
-               pdoc->InsertCString(end, eol);
-               pdoc->InsertString(end + istrlen(eol), text, end - start);
-       } else {
-               pdoc->InsertString(end, text, end - start);
+       if (sel.Count() && sel.IsRectangular()) {
+               SelectionPosition last = sel.Last();
+               if (forLine) {
+                       int line = pdoc->LineFromPosition(last.Position());
+                       last = SelectionPosition(last.Position() + pdoc->LineStart(line+1) - pdoc->LineStart(line));
+               }
+               if (sel.Rectangular().anchor > sel.Rectangular().caret)
+                       sel.Rectangular().anchor = last;
+               else
+                       sel.Rectangular().caret = last;
+               SetRectangularRange();
        }
-       delete []text;
 }
 
 void Editor::CancelModes() {
-       moveExtendsSelection = false;
+       sel.SetMoveExtends(false);
 }
 
 void Editor::NewLine() {
@@ -4177,10 +4576,16 @@ void Editor::NewLine() {
        } else if (pdoc->eolMode == SC_EOL_CR) {
                eol = "\r";
        } // else SC_EOL_LF -> "\n" already set
-       if (pdoc->InsertCString(currentPos, eol)) {
-               SetEmptySelection(currentPos + istrlen(eol));
+       if (pdoc->InsertCString(sel.MainCaret(), eol)) {
+               SetEmptySelection(sel.MainCaret() + istrlen(eol));
                while (*eol) {
                        NotifyChar(*eol);
+                       if (recordingMacro) {
+                               char txt[2];
+                               txt[0] = *eol;
+                               txt[1] = '\0';
+                               NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(txt));
+                       }
                        eol++;
                }
        }
@@ -4191,33 +4596,50 @@ void Editor::NewLine() {
        ShowCaretAtCurrentPosition();
 }
 
-void Editor::CursorUpOrDown(int direction, selTypes sel) {
-       Point pt = LocationFromPosition(currentPos);
-       int posNew = PositionFromLocation(
-                   Point(lastXChosen, pt.y + direction * vs.lineHeight));
+void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) {
+       SelectionPosition caretToUse = sel.Range(sel.Main()).caret;
+       if (sel.IsRectangular()) {
+               if (selt ==  Selection::noSel) {
+                       caretToUse = (direction > 0) ? sel.Limits().end : sel.Limits().start;
+               } else {
+                       caretToUse = sel.Rectangular().caret;
+               }
+       }
+       Point pt = LocationFromPosition(caretToUse);
+       int lineDoc = pdoc->LineFromPosition(caretToUse.Position());
+       Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc));
+       int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
+       int commentLines = vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0;
+       SelectionPosition posNew = SPositionFromLocation(
+                   Point(lastXChosen, pt.y + direction * vs.lineHeight), false, false, UserVirtualSpace());
+       if ((direction > 0) && (subLine >= (cs.GetHeight(lineDoc) - 1 - commentLines))) {
+               posNew = SPositionFromLocation(
+                   Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
+       }
        if (direction < 0) {
                // Line wrapping may lead to a location on the same line, so
                // seek back if that is the case.
                // There is an equivalent case when moving down which skips
                // over a line but as that does not trap the user it is fine.
-               Point ptNew = LocationFromPosition(posNew);
-               while ((posNew > 0) && (pt.y == ptNew.y)) {
-                       posNew--;
-                       ptNew = LocationFromPosition(posNew);
+               Point ptNew = LocationFromPosition(posNew.Position());
+               while ((posNew.Position() > 0) && (pt.y == ptNew.y)) {
+                       posNew.Add(- 1);
+                       posNew.SetVirtualSpace(0);
+                       ptNew = LocationFromPosition(posNew.Position());
                }
        }
-       MovePositionTo(posNew, sel);
+       MovePositionTo(posNew, selt);
 }
 
-void Editor::ParaUpOrDown(int direction, selTypes sel) {
-       int lineDoc, savedPos = currentPos;
+void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) {
+       int lineDoc, savedPos = sel.MainCaret();
        do {
-               MovePositionTo(direction > 0 ? pdoc->ParaDown(currentPos) : pdoc->ParaUp(currentPos), sel);
-               lineDoc = pdoc->LineFromPosition(currentPos);
+               MovePositionTo(SelectionPosition(direction > 0 ? pdoc->ParaDown(sel.MainCaret()) : pdoc->ParaUp(sel.MainCaret())), selt);
+               lineDoc = pdoc->LineFromPosition(sel.MainCaret());
                if (direction > 0) {
-                       if (currentPos >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
-                               if (sel == noSel) {
-                                       MovePositionTo(pdoc->LineEndPosition(savedPos));
+                       if (sel.MainCaret() >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
+                               if (selt == Selection::noSel) {
+                                       MovePositionTo(SelectionPosition(pdoc->LineEndPosition(savedPos)));
                                }
                                break;
                        }
@@ -4263,16 +4685,16 @@ int Editor::KeyCommand(unsigned int iMessage) {
                CursorUpOrDown(1);
                break;
        case SCI_LINEDOWNEXTEND:
-               CursorUpOrDown(1, selStream);
+               CursorUpOrDown(1, Selection::selStream);
                break;
        case SCI_LINEDOWNRECTEXTEND:
-               CursorUpOrDown(1, selRectangle);
+               CursorUpOrDown(1, Selection::selRectangle);
                break;
        case SCI_PARADOWN:
                ParaUpOrDown(1);
                break;
        case SCI_PARADOWNEXTEND:
-               ParaUpOrDown(1, selStream);
+               ParaUpOrDown(1, Selection::selStream);
                break;
        case SCI_LINESCROLLDOWN:
                ScrollTo(topLine + 1);
@@ -4282,144 +4704,182 @@ int Editor::KeyCommand(unsigned int iMessage) {
                CursorUpOrDown(-1);
                break;
        case SCI_LINEUPEXTEND:
-               CursorUpOrDown(-1, selStream);
+               CursorUpOrDown(-1, Selection::selStream);
                break;
        case SCI_LINEUPRECTEXTEND:
-               CursorUpOrDown(-1, selRectangle);
+               CursorUpOrDown(-1, Selection::selRectangle);
                break;
        case SCI_PARAUP:
                ParaUpOrDown(-1);
                break;
        case SCI_PARAUPEXTEND:
-               ParaUpOrDown(-1, selStream);
+               ParaUpOrDown(-1, Selection::selStream);
                break;
        case SCI_LINESCROLLUP:
                ScrollTo(topLine - 1);
                MoveCaretInsideView(false);
                break;
        case SCI_CHARLEFT:
-               if (SelectionEmpty() || moveExtendsSelection) {
-                       MovePositionTo(MovePositionSoVisible(currentPos - 1, -1));
+               if (SelectionEmpty() || sel.MoveExtends()) {
+                       if ((sel.Count() == 1) && pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+                               SelectionPosition spCaret = sel.RangeMain().caret;
+                               spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+                               MovePositionTo(spCaret);
+                       } else {
+                               MovePositionTo(MovePositionSoVisible(
+                                       SelectionPosition((sel.LimitsForRectangularElseMain().start).Position() - 1), -1));
+                       }
                } else {
-                       MovePositionTo(SelectionStart());
+                       MovePositionTo(sel.LimitsForRectangularElseMain().start);
                }
                SetLastXChosen();
                break;
        case SCI_CHARLEFTEXTEND:
-               MovePositionTo(MovePositionSoVisible(currentPos - 1, -1), selStream);
+               if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+                       SelectionPosition spCaret = sel.RangeMain().caret;
+                       spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+                       MovePositionTo(spCaret, Selection::selStream);
+               } else {
+                       MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selStream);
+               }
                SetLastXChosen();
                break;
        case SCI_CHARLEFTRECTEXTEND:
-               MovePositionTo(MovePositionSoVisible(currentPos - 1, -1), selRectangle);
+               if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+                       SelectionPosition spCaret = sel.RangeMain().caret;
+                       spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+                       MovePositionTo(spCaret, Selection::selRectangle);
+               } else {
+                       MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selRectangle);
+               }
                SetLastXChosen();
                break;
        case SCI_CHARRIGHT:
-               if (SelectionEmpty() || moveExtendsSelection) {
-                       MovePositionTo(MovePositionSoVisible(currentPos + 1, 1));
+               if (SelectionEmpty() || sel.MoveExtends()) {
+                       if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+                               SelectionPosition spCaret = sel.RangeMain().caret;
+                               spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+                               MovePositionTo(spCaret);
+                       } else {
+                               MovePositionTo(MovePositionSoVisible(
+                                       SelectionPosition((sel.LimitsForRectangularElseMain().end).Position() + 1), 1));
+                       }
                } else {
-                       MovePositionTo(SelectionEnd());
+                       MovePositionTo(sel.LimitsForRectangularElseMain().end);
                }
                SetLastXChosen();
                break;
        case SCI_CHARRIGHTEXTEND:
-               MovePositionTo(MovePositionSoVisible(currentPos + 1, 1), selStream);
+               if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+                       SelectionPosition spCaret = sel.RangeMain().caret;
+                       spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+                       MovePositionTo(spCaret, Selection::selStream);
+               } else {
+                       MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selStream);
+               }
                SetLastXChosen();
                break;
        case SCI_CHARRIGHTRECTEXTEND:
-               MovePositionTo(MovePositionSoVisible(currentPos + 1, 1), selRectangle);
+               if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+                       SelectionPosition spCaret = sel.RangeMain().caret;
+                       spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+                       MovePositionTo(spCaret, Selection::selRectangle);
+               } else {
+                       MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selRectangle);
+               }
                SetLastXChosen();
                break;
        case SCI_WORDLEFT:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, -1), -1));
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1));
                SetLastXChosen();
                break;
        case SCI_WORDLEFTEXTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, -1), -1), selStream);
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_WORDRIGHT:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, 1), 1));
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1));
                SetLastXChosen();
                break;
        case SCI_WORDRIGHTEXTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, 1), 1), selStream);
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1), Selection::selStream);
                SetLastXChosen();
                break;
 
        case SCI_WORDLEFTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, -1), -1));
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1));
                SetLastXChosen();
                break;
        case SCI_WORDLEFTENDEXTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, -1), -1), selStream);
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_WORDRIGHTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, 1), 1));
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1));
                SetLastXChosen();
                break;
        case SCI_WORDRIGHTENDEXTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, 1), 1), selStream);
+               MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1), Selection::selStream);
                SetLastXChosen();
                break;
 
        case SCI_HOME:
-               MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)));
+               MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
                SetLastXChosen();
                break;
        case SCI_HOMEEXTEND:
-               MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)), selStream);
+               MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_HOMERECTEXTEND:
-               MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)), selRectangle);
+               MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selRectangle);
                SetLastXChosen();
                break;
        case SCI_LINEEND:
-               MovePositionTo(pdoc->LineEndPosition(currentPos));
+               MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()));
                SetLastXChosen();
                break;
        case SCI_LINEENDEXTEND:
-               MovePositionTo(pdoc->LineEndPosition(currentPos), selStream);
+               MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_LINEENDRECTEXTEND:
-               MovePositionTo(pdoc->LineEndPosition(currentPos), selRectangle);
+               MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selRectangle);
                SetLastXChosen();
                break;
        case SCI_HOMEWRAP: {
-                       int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-                       if (currentPos <= homePos)
-                               homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+                       SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+                       if (sel.RangeMain().caret <= homePos)
+                               homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
                        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, selStream);
+                       SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+                       if (sel.RangeMain().caret <= homePos)
+                               homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
+                       MovePositionTo(homePos, Selection::selStream);
                        SetLastXChosen();
                }
                break;
        case SCI_LINEENDWRAP: {
-                       int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
-                       int realEndPos = pdoc->LineEndPosition(currentPos);
+                       SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1);
+                       SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret()));
                        if (endPos > realEndPos      // if moved past visible EOLs
-                               || currentPos >= endPos) // if at end of display line already
+                               || sel.RangeMain().caret >= endPos) // if at end of display line already
                                endPos = realEndPos;
                        MovePositionTo(endPos);
                        SetLastXChosen();
                }
                break;
        case SCI_LINEENDWRAPEXTEND: {
-                       int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
-                       int realEndPos = pdoc->LineEndPosition(currentPos);
+                       SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1);
+                       SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret()));
                        if (endPos > realEndPos      // if moved past visible EOLs
-                               || currentPos >= endPos) // if at end of display line already
+                               || sel.RangeMain().caret >= endPos) // if at end of display line already
                                endPos = realEndPos;
-                       MovePositionTo(endPos, selStream);
+                       MovePositionTo(endPos, Selection::selStream);
                        SetLastXChosen();
                }
                break;
@@ -4428,7 +4888,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
                SetLastXChosen();
                break;
        case SCI_DOCUMENTSTARTEXTEND:
-               MovePositionTo(0, selStream);
+               MovePositionTo(0, Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_DOCUMENTEND:
@@ -4436,38 +4896,38 @@ int Editor::KeyCommand(unsigned int iMessage) {
                SetLastXChosen();
                break;
        case SCI_DOCUMENTENDEXTEND:
-               MovePositionTo(pdoc->Length(), selStream);
+               MovePositionTo(pdoc->Length(), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_STUTTEREDPAGEUP:
-               PageMove(-1, noSel, true);
+               PageMove(-1, Selection::noSel, true);
                break;
        case SCI_STUTTEREDPAGEUPEXTEND:
-               PageMove(-1, selStream, true);
+               PageMove(-1, Selection::selStream, true);
                break;
        case SCI_STUTTEREDPAGEDOWN:
-               PageMove(1, noSel, true);
+               PageMove(1, Selection::noSel, true);
                break;
        case SCI_STUTTEREDPAGEDOWNEXTEND:
-               PageMove(1, selStream, true);
+               PageMove(1, Selection::selStream, true);
                break;
        case SCI_PAGEUP:
                PageMove(-1);
                break;
        case SCI_PAGEUPEXTEND:
-               PageMove(-1, selStream);
+               PageMove(-1, Selection::selStream);
                break;
        case SCI_PAGEUPRECTEXTEND:
-               PageMove(-1, selRectangle);
+               PageMove(-1, Selection::selRectangle);
                break;
        case SCI_PAGEDOWN:
                PageMove(1);
                break;
        case SCI_PAGEDOWNEXTEND:
-               PageMove(1, selStream);
+               PageMove(1, Selection::selStream);
                break;
        case SCI_PAGEDOWNRECTEXTEND:
-               PageMove(1, selRectangle);
+               PageMove(1, Selection::selRectangle);
                break;
        case SCI_EDITTOGGLEOVERTYPE:
                inOverstrike = !inOverstrike;
@@ -4499,6 +4959,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
                        SetLastXChosen();
                }
                EnsureCaretVisible();
+               ShowCaretAtCurrentPosition();           // Avoid blinking
                break;
        case SCI_BACKTAB:
                Indent(false);
@@ -4506,6 +4967,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
                        SetLastXChosen();
                }
                EnsureCaretVisible();
+               ShowCaretAtCurrentPosition();           // Avoid blinking
                break;
        case SCI_NEWLINE:
                NewLine();
@@ -4514,21 +4976,21 @@ int Editor::KeyCommand(unsigned int iMessage) {
                AddChar('\f');
                break;
        case SCI_VCHOME:
-               MovePositionTo(pdoc->VCHomePosition(currentPos));
+               MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()));
                SetLastXChosen();
                break;
        case SCI_VCHOMEEXTEND:
-               MovePositionTo(pdoc->VCHomePosition(currentPos), selStream);
+               MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_VCHOMERECTEXTEND:
-               MovePositionTo(pdoc->VCHomePosition(currentPos), selRectangle);
+               MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selRectangle);
                SetLastXChosen();
                break;
        case SCI_VCHOMEWRAP: {
-                       int homePos = pdoc->VCHomePosition(currentPos);
-                       int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-                       if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+                       SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+                       SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+                       if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos))
                                homePos = viewLineStart;
 
                        MovePositionTo(homePos);
@@ -4536,12 +4998,12 @@ int Editor::KeyCommand(unsigned int iMessage) {
                }
                break;
        case SCI_VCHOMEWRAPEXTEND: {
-                       int homePos = pdoc->VCHomePosition(currentPos);
-                       int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-                       if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+                       SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+                       SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+                       if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos))
                                homePos = viewLineStart;
 
-                       MovePositionTo(homePos, selStream);
+                       MovePositionTo(homePos, Selection::selStream);
                        SetLastXChosen();
                }
                break;
@@ -4560,44 +5022,52 @@ int Editor::KeyCommand(unsigned int iMessage) {
                }
                break;
        case SCI_DELWORDLEFT: {
-                       int startWord = pdoc->NextWordStart(currentPos, -1);
-                       pdoc->DeleteChars(startWord, currentPos - startWord);
+                       int startWord = pdoc->NextWordStart(sel.MainCaret(), -1);
+                       pdoc->DeleteChars(startWord, sel.MainCaret() - startWord);
+                       sel.RangeMain().ClearVirtualSpace();
                        SetLastXChosen();
                }
                break;
        case SCI_DELWORDRIGHT: {
-                       int endWord = pdoc->NextWordStart(currentPos, 1);
-                       pdoc->DeleteChars(currentPos, endWord - currentPos);
+                       UndoGroup ug(pdoc);
+                       sel.RangeMain().caret = SelectionPosition(
+                               InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+                       int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
+                       pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
                }
                break;
        case SCI_DELWORDRIGHTEND: {
-                       int endWord = pdoc->NextWordEnd(currentPos, 1);
-                       pdoc->DeleteChars(currentPos, endWord - currentPos);
+                       UndoGroup ug(pdoc);
+                       sel.RangeMain().caret = SelectionPosition(
+                               InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+                       int endWord = pdoc->NextWordEnd(sel.MainCaret(), 1);
+                       pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
                }
                break;
        case SCI_DELLINELEFT: {
-                       int line = pdoc->LineFromPosition(currentPos);
+                       int line = pdoc->LineFromPosition(sel.MainCaret());
                        int start = pdoc->LineStart(line);
-                       pdoc->DeleteChars(start, currentPos - start);
+                       pdoc->DeleteChars(start, sel.MainCaret() - start);
+                       sel.RangeMain().ClearVirtualSpace();
                        SetLastXChosen();
                }
                break;
        case SCI_DELLINERIGHT: {
-                       int line = pdoc->LineFromPosition(currentPos);
+                       int line = pdoc->LineFromPosition(sel.MainCaret());
                        int end = pdoc->LineEnd(line);
-                       pdoc->DeleteChars(currentPos, end - currentPos);
+                       pdoc->DeleteChars(sel.MainCaret(), end - sel.MainCaret());
                }
                break;
        case SCI_LINECOPY: {
-                       int lineStart = pdoc->LineFromPosition(SelectionStart());
-                       int lineEnd = pdoc->LineFromPosition(SelectionEnd());
+                       int lineStart = pdoc->LineFromPosition(SelectionStart().Position());
+                       int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position());
                        CopyRangeToClipboard(pdoc->LineStart(lineStart),
                                pdoc->LineStart(lineEnd + 1));
                }
                break;
        case SCI_LINECUT: {
-                       int lineStart = pdoc->LineFromPosition(SelectionStart());
-                       int lineEnd = pdoc->LineFromPosition(SelectionEnd());
+                       int lineStart = pdoc->LineFromPosition(SelectionStart().Position());
+                       int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position());
                        int start = pdoc->LineStart(lineStart);
                        int end = pdoc->LineStart(lineEnd + 1);
                        SetSelection(start, end);
@@ -4606,7 +5076,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
                }
                break;
        case SCI_LINEDELETE: {
-                       int line = pdoc->LineFromPosition(currentPos);
+                       int line = pdoc->LineFromPosition(sel.MainCaret());
                        int start = pdoc->LineStart(line);
                        int end = pdoc->LineStart(line + 1);
                        pdoc->DeleteChars(start, end - start);
@@ -4628,39 +5098,39 @@ int Editor::KeyCommand(unsigned int iMessage) {
                ChangeCaseOfSelection(true);
                break;
        case SCI_WORDPARTLEFT:
-               MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(currentPos), -1));
+               MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1));
                SetLastXChosen();
                break;
        case SCI_WORDPARTLEFTEXTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(currentPos), -1), selStream);
+               MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_WORDPARTRIGHT:
-               MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(currentPos), 1));
+               MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(sel.MainCaret()), 1));
                SetLastXChosen();
                break;
        case SCI_WORDPARTRIGHTEXTEND:
-               MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(currentPos), 1), selStream);
+               MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(sel.MainCaret()), 1), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_HOMEDISPLAY:
                MovePositionTo(MovePositionSoVisible(
-                           StartEndDisplayLine(currentPos, true), -1));
+                           StartEndDisplayLine(sel.MainCaret(), true), -1));
                SetLastXChosen();
                break;
        case SCI_HOMEDISPLAYEXTEND:
                MovePositionTo(MovePositionSoVisible(
-                           StartEndDisplayLine(currentPos, true), -1), selStream);
+                           StartEndDisplayLine(sel.MainCaret(), true), -1), Selection::selStream);
                SetLastXChosen();
                break;
        case SCI_LINEENDDISPLAY:
                MovePositionTo(MovePositionSoVisible(
-                           StartEndDisplayLine(currentPos, false), 1));
+                           StartEndDisplayLine(sel.MainCaret(), false), 1));
                SetLastXChosen();
                break;
        case SCI_LINEENDDISPLAYEXTEND:
                MovePositionTo(MovePositionSoVisible(
-                           StartEndDisplayLine(currentPos, false), 1), selStream);
+                           StartEndDisplayLine(sel.MainCaret(), false), 1), Selection::selStream);
                SetLastXChosen();
                break;
        }
@@ -4696,77 +5166,79 @@ int Editor::GetWhitespaceVisible() {
 }
 
 void Editor::Indent(bool forwards) {
-       //Platform::DebugPrintf("INdent %d\n", forwards);
-       int lineOfAnchor = pdoc->LineFromPosition(anchor);
-       int lineCurrentPos = pdoc->LineFromPosition(currentPos);
-       if (lineOfAnchor == lineCurrentPos) {
-               if (forwards) {
-                       pdoc->BeginUndoAction();
-                       ClearSelection();
-                       if (pdoc->GetColumn(currentPos) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) &&
-                               pdoc->tabIndents) {
-                               int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-                               int indentationStep = pdoc->IndentSize();
-                               pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep);
-                               SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-                       } else {
-                               if (pdoc->useTabs) {
-                                       pdoc->InsertChar(currentPos, '\t');
-                                       SetEmptySelection(currentPos + 1);
+       for (size_t r=0; r<sel.Count(); r++) {
+               int lineOfAnchor = pdoc->LineFromPosition(sel.Range(r).anchor.Position());
+               int caretPosition = sel.Range(r).caret.Position();
+               int lineCurrentPos = pdoc->LineFromPosition(caretPosition);
+               if (lineOfAnchor == lineCurrentPos) {
+                       if (forwards) {
+                               UndoGroup ug(pdoc);
+                               pdoc->DeleteChars(sel.Range(r).Start().Position(), sel.Range(r).Length());
+                               caretPosition = sel.Range(r).caret.Position();
+                               if (pdoc->GetColumn(caretPosition) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) &&
+                                               pdoc->tabIndents) {
+                                       int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+                                       int indentationStep = pdoc->IndentSize();
+                                       pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep);
+                                       sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos));
                                } else {
-                                       int numSpaces = (pdoc->tabInChars) -
-                                               (pdoc->GetColumn(currentPos) % (pdoc->tabInChars));
-                                       if (numSpaces < 1)
-                                               numSpaces = pdoc->tabInChars;
-                                       for (int i = 0; i < numSpaces; i++) {
-                                               pdoc->InsertChar(currentPos + i, ' ');
+                                       if (pdoc->useTabs) {
+                                               pdoc->InsertChar(caretPosition, '\t');
+                                               sel.Range(r) = SelectionRange(caretPosition+1);
+                                       } else {
+                                               int numSpaces = (pdoc->tabInChars) -
+                                                               (pdoc->GetColumn(caretPosition) % (pdoc->tabInChars));
+                                               if (numSpaces < 1)
+                                                       numSpaces = pdoc->tabInChars;
+                                               for (int i = 0; i < numSpaces; i++) {
+                                                       pdoc->InsertChar(caretPosition + i, ' ');
+                                               }
+                                               sel.Range(r) = SelectionRange(caretPosition+numSpaces);
                                        }
-                                       SetEmptySelection(currentPos + numSpaces);
+                               }
+                       } else {
+                               if (pdoc->GetColumn(caretPosition) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+                                               pdoc->tabIndents) {
+                                       UndoGroup ug(pdoc);
+                                       int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+                                       int indentationStep = pdoc->IndentSize();
+                                       pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+                                       SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+                               } else {
+                                       int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) *
+                                                       pdoc->tabInChars;
+                                       if (newColumn < 0)
+                                               newColumn = 0;
+                                       int newPos = caretPosition;
+                                       while (pdoc->GetColumn(newPos) > newColumn)
+                                               newPos--;
+                                       sel.Range(r) = SelectionRange(newPos);
                                }
                        }
-                       pdoc->EndUndoAction();
-               } else {
-                       if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
-                               pdoc->tabIndents) {
-                               pdoc->BeginUndoAction();
-                               int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-                               int indentationStep = pdoc->IndentSize();
-                               pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
-                               SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-                               pdoc->EndUndoAction();
+               } else {        // Multiline
+                       int anchorPosOnLine = sel.Range(r).anchor.Position() - pdoc->LineStart(lineOfAnchor);
+                       int currentPosPosOnLine = caretPosition - pdoc->LineStart(lineCurrentPos);
+                       // Multiple lines selected so indent / dedent
+                       int lineTopSel = Platform::Minimum(lineOfAnchor, lineCurrentPos);
+                       int lineBottomSel = Platform::Maximum(lineOfAnchor, lineCurrentPos);
+                       if (pdoc->LineStart(lineBottomSel) == sel.Range(r).anchor.Position() || pdoc->LineStart(lineBottomSel) == caretPosition)
+                               lineBottomSel--;        // If not selecting any characters on a line, do not indent
+                       {
+                               UndoGroup ug(pdoc);
+                               pdoc->Indent(forwards, lineBottomSel, lineTopSel);
+                       }
+                       if (lineOfAnchor < lineCurrentPos) {
+                               if (currentPosPosOnLine == 0)
+                                       sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
+                               else
+                                       sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos + 1), pdoc->LineStart(lineOfAnchor));
                        } else {
-                               int newColumn = ((pdoc->GetColumn(currentPos) - 1) / pdoc->tabInChars) *
-                                       pdoc->tabInChars;
-                               if (newColumn < 0)
-                                       newColumn = 0;
-                               int newPos = currentPos;
-                               while (pdoc->GetColumn(newPos) > newColumn)
-                                       newPos--;
-                               SetEmptySelection(newPos);
+                               if (anchorPosOnLine == 0)
+                                       sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
+                               else
+                                       sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor + 1));
                        }
                }
-       } else {
-               int anchorPosOnLine = anchor - pdoc->LineStart(lineOfAnchor);
-               int currentPosPosOnLine = currentPos - pdoc->LineStart(lineCurrentPos);
-               // Multiple lines selected so indent / dedent
-               int lineTopSel = Platform::Minimum(lineOfAnchor, lineCurrentPos);
-               int lineBottomSel = Platform::Maximum(lineOfAnchor, lineCurrentPos);
-               if (pdoc->LineStart(lineBottomSel) == anchor || pdoc->LineStart(lineBottomSel) == currentPos)
-                       lineBottomSel--;        // If not selecting any characters on a line, do not indent
-               pdoc->BeginUndoAction();
-               pdoc->Indent(forwards, lineBottomSel, lineTopSel);
-               pdoc->EndUndoAction();
-               if (lineOfAnchor < lineCurrentPos) {
-                       if (currentPosPosOnLine == 0)
-                               SetSelection(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
-                       else
-                               SetSelection(pdoc->LineStart(lineCurrentPos + 1), pdoc->LineStart(lineOfAnchor));
-               } else {
-                       if (anchorPosOnLine == 0)
-                               SetSelection(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
-                       else
-                               SetSelection(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor + 1));
-               }
        }
 }
 
@@ -4779,14 +5251,14 @@ long Editor::FindText(
     ///< @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);
+       Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
        int lengthFound = istrlen(ft->lpstrText);
        int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
                (wParam & SCFIND_MATCHCASE) != 0,
                (wParam & SCFIND_WHOLEWORD) != 0,
                (wParam & SCFIND_WORDSTART) != 0,
                (wParam & SCFIND_REGEXP) != 0,
-               (wParam & SCFIND_POSIX) != 0,
+               wParam,
                &lengthFound);
        if (pos != -1) {
                ft->chrgText.cpMin = pos;
@@ -4807,7 +5279,7 @@ long Editor::FindText(
  * operation is self-contained.
  */
 void Editor::SearchAnchor() {
-       searchAnchor = SelectionStart();
+       searchAnchor = SelectionStart().Position();
 }
 
 /**
@@ -4830,7 +5302,7 @@ long Editor::SearchText(
                        (wParam & SCFIND_WHOLEWORD) != 0,
                        (wParam & SCFIND_WORDSTART) != 0,
                        (wParam & SCFIND_REGEXP) != 0,
-                       (wParam & SCFIND_POSIX) != 0,
+                       wParam,
                        &lengthFound);
        } else {
                pos = pdoc->FindText(searchAnchor, 0, txt,
@@ -4838,7 +5310,7 @@ long Editor::SearchText(
                        (wParam & SCFIND_WHOLEWORD) != 0,
                        (wParam & SCFIND_WORDSTART) != 0,
                        (wParam & SCFIND_REGEXP) != 0,
-                       (wParam & SCFIND_POSIX) != 0,
+                       wParam,
                        &lengthFound);
        }
 
@@ -4860,7 +5332,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,
+               searchFlags,
                &lengthFound);
        if (pos != -1) {
                targetStart = pos;
@@ -4892,62 +5364,71 @@ char *Editor::CopyRange(int start, int end) {
        if (start < end) {
                int len = end - start;
                text = new char[len + 1];
-               if (text) {
-                       for (int i = 0; i < len; i++) {
-                               text[i] = pdoc->CharAt(start + i);
-                       }
-                       text[len] = '\0';
+               for (int i = 0; i < len; i++) {
+                       text[i] = pdoc->CharAt(start + i);
                }
+               text[len] = '\0';
        }
        return text;
 }
 
-void Editor::CopySelectionFromRange(SelectionText *ss, int start, int end) {
-       ss->Set(CopyRange(start, end), end - start + 1,
-               pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
-}
-
-void Editor::CopySelectionRange(SelectionText *ss) {
-       if (selType == selStream) {
-               CopySelectionFromRange(ss, SelectionStart(), SelectionEnd());
+void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
+       if (sel.Empty()) {
+               if (allowLineCopy) {
+                       int currentLine = pdoc->LineFromPosition(sel.MainCaret());
+                       int start = pdoc->LineStart(currentLine);
+                       int end = pdoc->LineEnd(currentLine);
+
+                       char *text = CopyRange(start, end);
+                       int textLen = text ? strlen(text) : 0;
+                       // include room for \r\n\0
+                       textLen += 3;
+                       char *textWithEndl = new char[textLen];
+                       textWithEndl[0] = '\0';
+                       if (text)
+                               strncat(textWithEndl, text, textLen);
+                       if (pdoc->eolMode != SC_EOL_LF)
+                               strncat(textWithEndl, "\r", textLen);
+                       if (pdoc->eolMode != SC_EOL_CR)
+                               strncat(textWithEndl, "\n", textLen);
+                       ss->Set(textWithEndl, strlen(textWithEndl) + 1,
+                               pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, true);
+                       delete []text;
+               }
        } else {
-               char *text = 0;
-               int size = 0;
-               SelectionLineIterator lineIterator(this);
-               while (lineIterator.Iterate()) {
-                       size += lineIterator.endPos - lineIterator.startPos;
-                       if (selType != selLines) {
-                               size++;
-                               if (pdoc->eolMode == SC_EOL_CRLF) {
-                                       size++;
-                               }
+               int delimiterLength = 0;
+               if (sel.selType == Selection::selRectangle) {
+                       if (pdoc->eolMode == SC_EOL_CRLF) {
+                               delimiterLength = 2;
+                       } else {
+                               delimiterLength = 1;
                        }
                }
-               if (size > 0) {
-                       text = new char[size + 1];
-                       if (text) {
-                               int j = 0;
-                               lineIterator.Reset();
-                               while (lineIterator.Iterate()) {
-                                       for (int i = lineIterator.startPos;
-                                               i < lineIterator.endPos;
-                                               i++) {
-                                               text[j++] = pdoc->CharAt(i);
-                                       }
-                                       if (selType != selLines) {
-                                               if (pdoc->eolMode != SC_EOL_LF) {
-                                                       text[j++] = '\r';
-                                               }
-                                               if (pdoc->eolMode != SC_EOL_CR) {
-                                                       text[j++] = '\n';
-                                               }
-                                       }
+               int size = sel.Length() + delimiterLength * sel.Count();
+               char *text = new char[size + 1];
+               int j = 0;
+               SelRangeArray rangesInOrder = sel.RangesCopy();
+               if (sel.selType == Selection::selRectangle)
+                       SelRangeArraySort(rangesInOrder.begin(), rangesInOrder.end());
+               for (size_t r=0; r<rangesInOrder.size(); r++) {
+                       SelectionRange current = rangesInOrder[r];
+                       for (int i = current.Start().Position();
+                               i < current.End().Position();
+                               i++) {
+                               text[j++] = pdoc->CharAt(i);
+                       }
+                       if (sel.selType == Selection::selRectangle) {
+                               if (pdoc->eolMode != SC_EOL_LF) {
+                                       text[j++] = '\r';
+                               }
+                               if (pdoc->eolMode != SC_EOL_CR) {
+                                       text[j++] = '\n';
                                }
-                               text[size] = '\0';
                        }
                }
+               text[size] = '\0';
                ss->Set(text, size + 1, pdoc->dbcsCodePage,
-                       vs.styles[STYLE_DEFAULT].characterSet, selType == selRectangle);
+                       vs.styles[STYLE_DEFAULT].characterSet, sel.IsRectangular(), sel.selType == Selection::selLines);
        }
 }
 
@@ -4956,23 +5437,23 @@ void Editor::CopyRangeToClipboard(int start, int end) {
        end = pdoc->ClampPositionIntoDocument(end);
        SelectionText selectedText;
        selectedText.Set(CopyRange(start, end), end - start + 1,
-               pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
+               pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false);
        CopyToClipboard(selectedText);
 }
 
 void Editor::CopyText(int length, const char *text) {
        SelectionText selectedText;
        selectedText.Copy(text, length + 1,
-               pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false);
+               pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false);
        CopyToClipboard(selectedText);
 }
 
-void Editor::SetDragPosition(int newPos) {
-       if (newPos >= 0) {
+void Editor::SetDragPosition(SelectionPosition newPos) {
+       if (newPos.Position() >= 0) {
                newPos = MovePositionOutsideChar(newPos, 1);
                posDrop = newPos;
        }
-       if (posDrag != newPos) {
+       if (!(posDrag == newPos)) {
                caret.on = true;
                SetTicking(true);
                InvalidateCaret();
@@ -5001,41 +5482,40 @@ void Editor::StartDrag() {
        //DisplayCursor(Window::cursorArrow);
 }
 
-void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) {
+void Editor::DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular) {
        //Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position);
        if (inDragDrop == ddDragging)
                dropWentOutside = false;
 
-       int positionWasInSelection = PositionInSelection(position);
+       bool positionWasInSelection = PositionInSelection(position.Position());
 
        bool positionOnEdgeOfSelection =
            (position == SelectionStart()) || (position == SelectionEnd());
 
-       if ((inDragDrop != ddDragging) || !(0 == positionWasInSelection) ||
+       if ((inDragDrop != ddDragging) || !(positionWasInSelection) ||
                (positionOnEdgeOfSelection && !moving)) {
 
-               int selStart = SelectionStart();
-               int selEnd = SelectionEnd();
+               SelectionPosition selStart = SelectionStart();
+               SelectionPosition selEnd = SelectionEnd();
 
-               pdoc->BeginUndoAction();
+               UndoGroup ug(pdoc);
 
-               int positionAfterDeletion = position;
+               SelectionPosition positionAfterDeletion = position;
                if ((inDragDrop == ddDragging) && moving) {
                        // Remove dragged out text
-                       if (rectangular || selType == selLines) {
-                               SelectionLineIterator lineIterator(this);
-                               while (lineIterator.Iterate()) {
-                                       if (position >= lineIterator.startPos) {
-                                               if (position > lineIterator.endPos) {
-                                                       positionAfterDeletion -= lineIterator.endPos - lineIterator.startPos;
+                       if (rectangular || sel.selType == Selection::selLines) {
+                               for (size_t r=0; r<sel.Count(); r++) {
+                                       if (position >= sel.Range(r).Start()) {
+                                               if (position > sel.Range(r).End()) {
+                                                       positionAfterDeletion.Add(-sel.Range(r).Length());
                                                } else {
-                                                       positionAfterDeletion -= position - lineIterator.startPos;
+                                                       positionAfterDeletion.Add(-SelectionRange(position, sel.Range(r).Start()).Length());
                                                }
                                        }
                                }
                        } else {
                                if (position > selStart) {
-                                       positionAfterDeletion -= selEnd - selStart;
+                                       positionAfterDeletion.Add(-SelectionRange(selEnd, selStart).Length());
                                }
                        }
                        ClearSelection();
@@ -5044,78 +5524,56 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul
 
                if (rectangular) {
                        PasteRectangular(position, value, istrlen(value));
-                       pdoc->EndUndoAction();
                        // Should try to select new rectangle but it may not be a rectangle now so just select the drop position
-                       SetEmptySelection(position);
-               } else {
-                       position = MovePositionOutsideChar(position, currentPos - position);
-                       if (pdoc->InsertCString(position, value)) {
-                               SetSelection(position + istrlen(value), position);
-                       }
-                       pdoc->EndUndoAction();
-               }
-       } else if (inDragDrop == ddDragging) {
-               SetEmptySelection(position);
-       }
-}
-
-/**
- * @return -1 if given position is before the selection,
- *          1 if position is after the selection,
- *          0 if position is inside the selection,
- */
-int Editor::PositionInSelection(int pos) {
-       pos = MovePositionOutsideChar(pos, currentPos - pos);
-       if (pos < SelectionStart()) {
-               return -1;
-       }
-       if (pos > SelectionEnd()) {
-               return 1;
-       }
-       if (selType == selStream) {
-               return 0;
-       } else {
-               SelectionLineIterator lineIterator(this);
-               lineIterator.SetAt(pdoc->LineFromPosition(pos));
-               if (pos < lineIterator.startPos) {
-                       return -1;
-               } else if (pos > lineIterator.endPos) {
-                       return 1;
+                       SetEmptySelection(position);
                } else {
-                       return 0;
+                       position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position());
+                       position = SelectionPosition(InsertSpace(position.Position(), position.VirtualSpace()));
+                       if (pdoc->InsertCString(position.Position(), value)) {
+                               SelectionPosition posAfterInsertion = position;
+                               posAfterInsertion.Add(istrlen(value));
+                               SetSelection(posAfterInsertion, position);
+                       }
                }
+       } else if (inDragDrop == ddDragging) {
+               SetEmptySelection(position);
+       }
+}
+
+/**
+ * @return true if given position is inside the selection,
+ */
+bool Editor::PositionInSelection(int pos) {
+       pos = MovePositionOutsideChar(pos, sel.MainCaret() - pos);
+       for (size_t r=0; r<sel.Count(); r++) {
+               if (sel.Range(r).Contains(pos))
+                       return true;
        }
+       return false;
 }
 
 bool Editor::PointInSelection(Point pt) {
-       int pos = PositionFromLocation(pt);
-       if (0 == PositionInSelection(pos)) {
-               // Probably inside, but we must make a finer test
-               int selStart, selEnd;
-               if (selType == selStream) {
-                       selStart = SelectionStart();
-                       selEnd = SelectionEnd();
-               } else {
-                       SelectionLineIterator lineIterator(this);
-                       lineIterator.SetAt(pdoc->LineFromPosition(pos));
-                       selStart = lineIterator.startPos;
-                       selEnd = lineIterator.endPos;
-               }
-               if (pos == selStart) {
-                       // see if just before selection
-                       Point locStart = LocationFromPosition(pos);
-                       if (pt.x < locStart.x) {
-                               return false;
+       SelectionPosition pos = SPositionFromLocation(pt);
+       int xPos = XFromPosition(pos);
+       for (size_t r=0; r<sel.Count(); r++) {
+               SelectionRange range = sel.Range(r);
+               if (range.Contains(pos)) {
+                       bool hit = true;
+                       if (pos == range.Start()) {
+                               // see if just before selection
+                               if (pt.x < xPos) {
+                                       hit = false;
+                               }
                        }
-               }
-               if (pos == selEnd) {
-                       // see if just after selection
-                       Point locEnd = LocationFromPosition(pos);
-                       if (pt.x > locEnd.x) {
-                               return false;
+                       if (pos == range.End()) {
+                               // see if just after selection
+                               if (pt.x > xPos) {
+                                       hit = false;
+                               }
                        }
+                       if (hit)
+                               return true;
                }
-               return true;
        }
        return false;
 }
@@ -5155,28 +5613,33 @@ void Editor::DwellEnd(bool mouseMoved) {
        }
 }
 
+static bool AllowVirtualSpace(int      virtualSpaceOptions, bool rectangular) {
+       return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)
+               || (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0));
+}
+
 void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
        //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop);
        ptMouseLast = pt;
-       int newPos = PositionFromLocation(pt);
-       newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
+       SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt));
+       newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position());
        inDragDrop = ddNone;
-       moveExtendsSelection = false;
+       sel.SetMoveExtends(false);
 
        bool processed = NotifyMarginClick(pt, shift, ctrl, alt);
        if (processed)
                return;
 
-       NotifyIndicatorClick(true, newPos, shift, ctrl, alt);
+       NotifyIndicatorClick(true, newPos.Position(), shift, ctrl, alt);
 
        bool inSelMargin = PointInSelMargin(pt);
        if (shift & !inSelMargin) {
-               SetSelection(newPos);
+               SetSelection(newPos.Position());
        }
        if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick)) {
                //Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime);
                SetMouseCapture(true);
-               SetEmptySelection(newPos);
+               SetEmptySelection(newPos.Position());
                bool doubleClick = false;
                // Stop mouse button bounce changing selection type
                if (!Platform::MouseButtonBounce() || curTime != lastClickTime) {
@@ -5187,16 +5650,16 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                                selectionType = selLine;
                        } else {
                                selectionType = selChar;
-                               originalAnchorPos = currentPos;
+                               originalAnchorPos = sel.MainCaret();
                        }
                }
 
                if (selectionType == selWord) {
-                       if (currentPos >= originalAnchorPos) {  // Moved forward
-                               SetSelection(pdoc->ExtendWordSelect(currentPos, 1),
+                       if (sel.MainCaret() >= originalAnchorPos) {     // Moved forward
+                               SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
                                        pdoc->ExtendWordSelect(originalAnchorPos, -1));
                        } else {        // Moved backward
-                               SetSelection(pdoc->ExtendWordSelect(currentPos, -1),
+                               SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
                                        pdoc->ExtendWordSelect(originalAnchorPos, 1));
                        }
                } else if (selectionType == selLine) {
@@ -5204,17 +5667,17 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                        SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
                        //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
                } else {
-                       SetEmptySelection(currentPos);
+                       SetEmptySelection(sel.MainCaret());
                }
                //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos);
                if (doubleClick) {
                        NotifyDoubleClick(pt, shift, ctrl, alt);
-                       if (PositionIsHotspot(newPos))
-                               NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt);
+                       if (PositionIsHotspot(newPos.Position()))
+                               NotifyHotSpotDoubleClicked(newPos.Position(), shift, ctrl, alt);
                }
        } else {        // Single click
                if (inSelMargin) {
-                       selType = selStream;
+                       sel.selType = Selection::selStream;
                        if (ctrl) {
                                SelectAll();
                                lastClickTime = curTime;
@@ -5228,21 +5691,21 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                                        pdoc->LineStart(lineAnchor));
                        } else {
                                // Single shift+click in margin: select from line anchor to clicked line
-                               if (anchor > currentPos)
-                                       lineAnchor = pdoc->LineFromPosition(anchor - 1);
+                               if (sel.MainAnchor() > sel.MainCaret())
+                                       lineAnchor = pdoc->LineFromPosition(sel.MainAnchor() - 1);
                                else
-                                       lineAnchor = pdoc->LineFromPosition(anchor);
+                                       lineAnchor = pdoc->LineFromPosition(sel.MainAnchor());
                                int lineStart = LineFromLocation(pt);
                                LineSelection(lineStart, lineAnchor);
                                //lineAnchor = lineStart; // Keep the same anchor for ButtonMove
                        }
 
-                       SetDragPosition(invalidPosition);
+                       SetDragPosition(SelectionPosition(invalidPosition));
                        SetMouseCapture(true);
                        selectionType = selLine;
                } else {
                        if (PointIsHotspot(pt)) {
-                               NotifyHotSpotClicked(newPos, shift, ctrl, alt);
+                               NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt);
                        }
                        if (!shift) {
                                if (PointInSelection(pt) && !SelectionEmpty())
@@ -5252,13 +5715,29 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
                        }
                        SetMouseCapture(true);
                        if (inDragDrop != ddInitial) {
-                               SetDragPosition(invalidPosition);
+                               SetDragPosition(SelectionPosition(invalidPosition));
                                if (!shift) {
-                                       SetEmptySelection(newPos);
+                                       if (ctrl && multipleSelection) {
+                                               SelectionRange range(newPos);
+                                               sel.TentativeSelection(range);
+                                               InvalidateSelection(range, true);
+                                       } else {
+                                               InvalidateSelection(SelectionRange(newPos), true);
+                                               if (sel.Count() > 1)
+                                                       Redraw();
+                                               sel.Clear();
+                                               sel.selType = alt ? Selection::selRectangle : Selection::selStream;
+                                               SetSelection(newPos, newPos);
+                                       }
                                }
-                               selType = alt ? selRectangle : selStream;
+                               SelectionPosition anchorCurrent = newPos;
+                               if (shift)
+                                       anchorCurrent = sel.IsRectangular() ?
+                                               sel.Rectangular().anchor : sel.RangeMain().anchor;
+                               sel.selType = alt ? Selection::selRectangle : Selection::selStream;
                                selectionType = selChar;
-                               originalAnchorPos = currentPos;
+                               originalAnchorPos = sel.MainCaret();
+                               sel.Rectangular() = SelectionRange(newPos, anchorCurrent);
                                SetRectangularRange();
                        }
                }
@@ -5273,7 +5752,7 @@ bool Editor::PositionIsHotspot(int position) {
 }
 
 bool Editor::PointIsHotspot(Point pt) {
-       int pos = PositionFromLocationClose(pt);
+       int pos = PositionFromLocation(pt, true);
        if (pos == INVALID_POSITION)
                return false;
        return PositionIsHotspot(pos);
@@ -5322,8 +5801,9 @@ void Editor::ButtonMove(Point pt) {
                DwellEnd(true);
        }
 
-       int movePos = PositionFromLocation(pt);
-       movePos = MovePositionOutsideChar(movePos, currentPos - movePos);
+       SelectionPosition movePos = SPositionFromLocation(pt, false, false,
+               AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular()));
+       movePos = MovePositionOutsideChar(movePos, sel.MainCaret() - movePos.Position());
 
        if (inDragDrop == ddInitial) {
                if (DragThreshold(ptMouseLast, pt)) {
@@ -5346,14 +5826,23 @@ void Editor::ButtonMove(Point pt) {
                autoScrollTimer.ticksToWait = autoScrollDelay;
 
                // Adjust selection
-               if (posDrag >= 0) {
+               if (posDrag.IsValid()) {
                        SetDragPosition(movePos);
                } else {
                        if (selectionType == selChar) {
-                               SetSelection(movePos);
+                               if (sel.IsRectangular()) {
+                                       sel.Rectangular() = SelectionRange(movePos, sel.Rectangular().anchor);
+                                       SetSelection(movePos, sel.RangeMain().anchor);
+                               } else if (sel.Count() > 1) {
+                                       SelectionRange range(movePos, sel.RangeMain().anchor);
+                                       sel.TentativeSelection(range);
+                                       InvalidateSelection(range, true);
+                               } else {
+                                       SetSelection(movePos, sel.RangeMain().anchor);
+                               }
                        } else if (selectionType == selWord) {
                                // Continue selecting by word
-                               if (movePos == originalAnchorPos) {     // Didn't move
+                               if (movePos.Position() == originalAnchorPos) {  // Didn't move
                                        // No need to do anything. Previously this case was lumped
                                        // in with "Moved forward", but that can be harmful in this
                                        // case: a handler for the NotifyDoubleClick re-adjusts
@@ -5363,11 +5852,11 @@ void Editor::ButtonMove(Point pt) {
                                        // the ButtonMove() called via Tick() for auto-scrolling
                                        // could result in the fancier word selection adjustment
                                        // being unmade.
-                               } else if (movePos > originalAnchorPos) {       // Moved forward
-                                       SetSelection(pdoc->ExtendWordSelect(movePos, 1),
+                               } else if (movePos.Position() > originalAnchorPos) {    // Moved forward
+                                       SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
                                                pdoc->ExtendWordSelect(originalAnchorPos, -1));
                                } else {        // Moved backward
-                                       SetSelection(pdoc->ExtendWordSelect(movePos, -1),
+                                       SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
                                                pdoc->ExtendWordSelect(originalAnchorPos, 1));
                                }
                        } else {
@@ -5376,10 +5865,6 @@ void Editor::ButtonMove(Point pt) {
                                LineSelection(lineMove, lineAnchor);
                        }
                }
-               // While dragging to make rectangular selection, we don't want the current
-               // position to jump to the end of smaller or empty lines.
-               //xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
-               xEndSelect = XFromPosition(movePos);
 
                // Autoscroll
                PRectangle rcClient = GetClientRectangle();
@@ -5388,16 +5873,16 @@ void Editor::ButtonMove(Point pt) {
                        if (lineMove < 0) {
                                lineMove = cs.DisplayFromDoc(pdoc->LinesTotal() - 1);
                        }
-                       ScrollTo(lineMove - LinesOnScreen() + 5);
+                       ScrollTo(lineMove - LinesOnScreen() + 1);
                        Redraw();
                } else if (pt.y < rcClient.top) {
                        int lineMove = cs.DisplayFromDoc(LineFromLocation(pt));
-                       ScrollTo(lineMove - 5);
+                       ScrollTo(lineMove - 1);
                        Redraw();
                }
                EnsureCaretVisible(false, false, true);
 
-               if (hsStart != -1 && !PositionIsHotspot(movePos))
+               if (hsStart != -1 && !PositionIsHotspot(movePos.Position()))
                        SetHotSpotRange(NULL);
 
        } else {
@@ -5422,11 +5907,12 @@ void Editor::ButtonMove(Point pt) {
 
 void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
        //Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop);
-       int newPos = PositionFromLocation(pt);
-       newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
+       SelectionPosition newPos = SPositionFromLocation(pt, false, false,
+               AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular()));
+       newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position());
        if (inDragDrop == ddInitial) {
                inDragDrop = ddNone;
-               SetEmptySelection(newPos);
+               SetEmptySelection(newPos.Position());
        }
        if (HaveMouseCapture()) {
                if (PointInSelMargin(pt)) {
@@ -5437,31 +5923,29 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
                }
                ptMouseLast = pt;
                SetMouseCapture(false);
-               int newPos = PositionFromLocation(pt);
-               newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
-               NotifyIndicatorClick(false, newPos, false, false, false);
+               NotifyIndicatorClick(false, newPos.Position(), false, false, false);
                if (inDragDrop == ddDragging) {
-                       int selStart = SelectionStart();
-                       int selEnd = SelectionEnd();
+                       SelectionPosition selStart = SelectionStart();
+                       SelectionPosition selEnd = SelectionEnd();
                        if (selStart < selEnd) {
                                if (drag.len) {
                                        if (ctrl) {
-                                               if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-                                                       SetSelection(newPos, newPos + drag.len);
+                                               if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) {
+                                                       SetSelection(newPos.Position(), newPos.Position() + drag.len);
                                                }
                                        } else if (newPos < selStart) {
-                                               pdoc->DeleteChars(selStart, drag.len);
-                                               if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-                                                       SetSelection(newPos, newPos + drag.len);
+                                               pdoc->DeleteChars(selStart.Position(), drag.len);
+                                               if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) {
+                                                       SetSelection(newPos.Position(), newPos.Position() + drag.len);
                                                }
                                        } else if (newPos > selEnd) {
-                                               pdoc->DeleteChars(selStart, drag.len);
-                                               newPos -= drag.len;
-                                               if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-                                                       SetSelection(newPos, newPos + drag.len);
+                                               pdoc->DeleteChars(selStart.Position(), drag.len);
+                                               newPos.Add(-drag.len);
+                                               if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) {
+                                                       SetSelection(newPos.Position(), newPos.Position() + drag.len);
                                                }
                                        } else {
-                                               SetEmptySelection(newPos);
+                                               SetEmptySelection(newPos.Position());
                                        }
                                        drag.Free();
                                }
@@ -5469,14 +5953,21 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
                        }
                } else {
                        if (selectionType == selChar) {
-                               SetSelection(newPos);
+                               if (sel.Count() > 1) {
+                                       sel.RangeMain() =
+                                               SelectionRange(newPos, sel.Range(sel.Count() - 1).anchor);
+                                       InvalidateSelection(sel.RangeMain(), true);
+                               } else {
+                                       SetSelection(newPos, sel.RangeMain().anchor);
+                               }
                        }
+                       sel.CommitTentative();
                }
                SetRectangularRange();
                lastClickTime = curTime;
                lastClick = pt;
                lastXChosen = pt.x;
-               if (selType == selStream) {
+               if (sel.selType == Selection::selStream) {
                        SetLastXChosen();
                }
                inDragDrop = ddNone;
@@ -5605,6 +6096,14 @@ void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) {
        }
 }
 
+void Editor::SetAnnotationHeights(int start, int end) {
+       if (vs.annotationVisible) {
+               for (int line=start; line<end; line++) {
+                       cs.SetHeight(line, pdoc->AnnotationLines(line) + 1);
+               }
+       }
+}
+
 void Editor::SetDocPointer(Document *document) {
        //Platform::DebugPrintf("** %x setdoc to %x\n", pdoc, document);
        pdoc->RemoveWatcher(this, 0);
@@ -5617,9 +6116,7 @@ void Editor::SetDocPointer(Document *document) {
        pdoc->AddRef();
 
        // Ensure all positions within document
-       selType = selStream;
-       currentPos = 0;
-       anchor = 0;
+       sel.Clear();
        targetStart = 0;
        targetEnd = 0;
 
@@ -5629,6 +6126,7 @@ void Editor::SetDocPointer(Document *document) {
        // Reset the contraction state to fully shown.
        cs.Clear();
        cs.InsertLines(0, pdoc->LinesTotal() - 1);
+       SetAnnotationHeights(0, pdoc->LinesTotal());
        llc.Deallocate();
        NeedWrapping();
 
@@ -5637,6 +6135,22 @@ void Editor::SetDocPointer(Document *document) {
        Redraw();
 }
 
+void Editor::SetAnnotationVisible(int visible) {
+       if (vs.annotationVisible != visible) {
+               bool changedFromOrToHidden = ((vs.annotationVisible != 0) != (visible != 0));
+               vs.annotationVisible = visible;
+               if (changedFromOrToHidden) {
+                       int dir = vs.annotationVisible ? 1 : -1;
+                       for (int line=0; line<pdoc->LinesTotal(); line++) {
+                               int annotationLines = pdoc->AnnotationLines(line);
+                               if (annotationLines > 0) {
+                                       cs.SetHeight(line, cs.GetHeight(line) + annotationLines * dir);
+                               }
+                       }
+               }
+       }
+}
+
 /**
  * Recursively expand a fold, making lines visible except where they have an unexpanded parent.
  */
@@ -5673,7 +6187,7 @@ void Editor::ToggleContraction(int line) {
                        if (lineMaxSubord > line) {
                                cs.SetVisible(line + 1, lineMaxSubord, false);
 
-                               int lineCurrent = pdoc->LineFromPosition(currentPos);
+                               int lineCurrent = pdoc->LineFromPosition(sel.MainCaret());
                                if (lineCurrent > line && lineCurrent <= lineMaxSubord) {
                                        // This does not re-expand the fold
                                        EnsureCaretVisible();
@@ -5742,13 +6256,12 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
 }
 
 int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
-       pdoc->BeginUndoAction();
+       UndoGroup ug(pdoc);
        if (length == -1)
                length = istrlen(text);
        if (replacePatterns) {
                text = pdoc->SubstituteByPosition(text, &length);
                if (!text) {
-                       pdoc->EndUndoAction();
                        return 0;
                }
        }
@@ -5757,7 +6270,6 @@ int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
        targetEnd = targetStart;
        pdoc->InsertString(targetStart, text, length);
        targetEnd = targetStart + length;
-       pdoc->EndUndoAction();
        return length;
 }
 
@@ -5788,20 +6300,18 @@ void Editor::AddStyledText(char *buffer, int appendLength) {
        // The buffer consists of alternating character bytes and style bytes
        size_t textLength = appendLength / 2;
        char *text = new char[textLength];
-       if (text) {
-               size_t i;
-               for (i = 0;i < textLength;i++) {
-                       text[i] = buffer[i*2];
-               }
-               pdoc->InsertString(CurrentPosition(), text, textLength);
-               for (i = 0;i < textLength;i++) {
-                       text[i] = buffer[i*2+1];
-               }
-               pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
-               pdoc->SetStyles(textLength, text);
-               delete []text;
+       size_t i;
+       for (i = 0;i < textLength;i++) {
+               text[i] = buffer[i*2];
        }
-       SetEmptySelection(currentPos + textLength);
+       pdoc->InsertString(CurrentPosition(), text, textLength);
+       for (i = 0;i < textLength;i++) {
+               text[i] = buffer[i*2+1];
+       }
+       pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
+       pdoc->SetStyles(textLength, text);
+       delete []text;
+       SetEmptySelection(sel.MainCaret() + textLength);
 }
 
 static bool ValidMargin(unsigned long wParam) {
@@ -5876,6 +6386,8 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar
        case SCI_STYLEGETSIZE:
                return vs.styles[wParam].size;
        case SCI_STYLEGETFONT:
+               if (!vs.styles[wParam].fontName)
+                       return 0;
                if (lParam != 0)
                        strcpy(CharPtrFromSPtr(lParam), vs.styles[wParam].fontName);
                return strlen(vs.styles[wParam].fontName);
@@ -5895,6 +6407,15 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar
        return 0;
 }
 
+sptr_t Editor::StringResult(sptr_t lParam, const char *val) {
+       const int n = strlen(val);
+       if (lParam != 0) {
+               char *ptr = reinterpret_cast<char *>(lParam);
+               strcpy(ptr, val);
+       }
+       return n;       // Not including NUL
+}
+
 sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam);
 
@@ -5920,11 +6441,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_SETTEXT: {
                        if (lParam == 0)
                                return 0;
-                       pdoc->BeginUndoAction();
+                       UndoGroup ug(pdoc);
                        pdoc->DeleteChars(0, pdoc->Length());
                        SetEmptySelection(0);
                        pdoc->InsertCString(0, CharPtrFromSPtr(lParam));
-                       pdoc->EndUndoAction();
                        return 1;
                }
 
@@ -5940,6 +6460,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                Copy();
                break;
 
+       case SCI_COPYALLOWLINE:
+               CopyAllowLine();
+               break;
+
        case SCI_COPYRANGE:
                CopyRangeToClipboard(wParam, lParam);
                break;
@@ -5977,6 +6501,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETFIRSTVISIBLELINE:
                return topLine;
 
+       case SCI_SETFIRSTVISIBLELINE:
+               ScrollTo(wParam);
+               break;
+
        case SCI_GETLINE: {     // Risk of overwriting the end of the buffer
                        int lineStart = pdoc->LineStart(wParam);
                        int lineEnd = pdoc->LineStart(wParam + 1);
@@ -6007,41 +6535,30 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                                nEnd = pdoc->Length();
                        if (nStart < 0)
                                nStart = nEnd;  // Remove selection
-                       selType = selStream;
+                       InvalidateSelection(SelectionRange(nStart, nEnd));
+                       sel.Clear();
+                       sel.selType = Selection::selStream;
                        SetSelection(nEnd, nStart);
                        EnsureCaretVisible();
                }
                break;
 
        case SCI_GETSELTEXT: {
-                       if (lParam == 0) {
-                               if (selType == selStream) {
-                                       return 1 + SelectionEnd() - SelectionStart();
-                               } else {
-                                       // TODO: why is selLines handled the slow way?
-                                       int size = 0;
-                                       int extraCharsPerLine = 0;
-                                       if (selType != selLines)
-                                               extraCharsPerLine = (pdoc->eolMode == SC_EOL_CRLF) ? 2 : 1;
-                                       SelectionLineIterator lineIterator(this);
-                                       while (lineIterator.Iterate()) {
-                                               size += lineIterator.endPos + extraCharsPerLine - lineIterator.startPos;
-                                       }
-
-                                       return 1 + size;
-                               }
-                       }
                        SelectionText selectedText;
                        CopySelectionRange(&selectedText);
-                       char *ptr = CharPtrFromSPtr(lParam);
-                       int iChar = 0;
-                       if (selectedText.len) {
-                               for (; iChar < selectedText.len; iChar++)
-                                       ptr[iChar] = selectedText.s[iChar];
+                       if (lParam == 0) {
+                               return selectedText.len ? selectedText.len : 1;
                        } else {
-                               ptr[0] = '\0';
+                               char *ptr = CharPtrFromSPtr(lParam);
+                               int iChar = 0;
+                               if (selectedText.len) {
+                                       for (; iChar < selectedText.len; iChar++)
+                                               ptr[iChar] = selectedText.s[iChar];
+                               } else {
+                                       ptr[0] = '\0';
+                               }
+                               return iChar;
                        }
-                       return iChar;
                }
 
        case SCI_LINEFROMPOSITION:
@@ -6051,7 +6568,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_POSITIONFROMLINE:
                if (static_cast<int>(wParam) < 0)
-                       wParam = pdoc->LineFromPosition(SelectionStart());
+                       wParam = pdoc->LineFromPosition(SelectionStart().Position());
                if (wParam == 0)
                        return 0;       // Even if there is no text, there is a first line that starts at 0
                if (static_cast<int>(wParam) > pdoc->LinesTotal())
@@ -6070,12 +6587,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_REPLACESEL: {
                        if (lParam == 0)
                                return 0;
-                       pdoc->BeginUndoAction();
+                       UndoGroup ug(pdoc);
                        ClearSelection();
                        char *replacement = CharPtrFromSPtr(lParam);
-                       pdoc->InsertCString(currentPos, replacement);
-                       pdoc->EndUndoAction();
-                       SetEmptySelection(currentPos + istrlen(replacement));
+                       pdoc->InsertCString(sel.MainCaret(), replacement);
+                       SetEmptySelection(sel.MainCaret() + istrlen(replacement));
                        EnsureCaretVisible();
                }
                break;
@@ -6095,12 +6611,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return targetEnd;
 
        case SCI_TARGETFROMSELECTION:
-               if (currentPos < anchor) {
-                       targetStart = currentPos;
-                       targetEnd = anchor;
+               if (sel.MainCaret() < sel.MainAnchor()) {
+                       targetStart = sel.MainCaret();
+                       targetEnd = sel.MainAnchor();
                } else {
-                       targetStart = anchor;
-                       targetEnd = currentPos;
+                       targetStart = sel.MainAnchor();
+                       targetEnd = sel.MainCaret();
                }
                break;
 
@@ -6183,7 +6699,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETTEXTRANGE: {
                        if (lParam == 0)
                                return 0;
-                       TextRange *tr = reinterpret_cast<TextRange *>(lParam);
+                       Sci_TextRange *tr = reinterpret_cast<Sci_TextRange *>(lParam);
                        int cpMax = tr->chrg.cpMax;
                        if (cpMax == -1)
                                cpMax = pdoc->Length();
@@ -6201,7 +6717,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                break;
 
        case SCI_FORMATRANGE:
-               return FormatRange(wParam != 0, reinterpret_cast<RangeToFormat *>(lParam));
+               return FormatRange(wParam != 0, reinterpret_cast<Sci_RangeToFormat *>(lParam));
 
        case SCI_GETMARGINLEFT:
                return vs.leftMarginWidth;
@@ -6225,7 +6741,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                        if (lParam == 0)
                                return 0;
                        pdoc->InsertString(CurrentPosition(), CharPtrFromSPtr(lParam), wParam);
-                       SetEmptySelection(currentPos + wParam);
+                       SetEmptySelection(sel.MainCaret() + wParam);
                        return 0;
                }
 
@@ -6313,32 +6829,44 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return pdoc->CharAt(wParam);
 
        case SCI_SETCURRENTPOS:
-               SetSelection(wParam, anchor);
+               if (sel.IsRectangular()) {
+                       sel.Rectangular().caret.SetPosition(wParam);
+                       SetRectangularRange();
+                       Redraw();
+               } else {
+                       SetSelection(wParam, sel.MainAnchor());
+               }
                break;
 
        case SCI_GETCURRENTPOS:
-               return currentPos;
+               return sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret();
 
        case SCI_SETANCHOR:
-               SetSelection(currentPos, wParam);
+               if (sel.IsRectangular()) {
+                       sel.Rectangular().anchor.SetPosition(wParam);
+                       SetRectangularRange();
+                       Redraw();
+               } else {
+                       SetSelection(sel.MainCaret(), wParam);
+               }
                break;
 
        case SCI_GETANCHOR:
-               return anchor;
+               return sel.IsRectangular() ? sel.Rectangular().anchor.Position() : sel.MainAnchor();
 
        case SCI_SETSELECTIONSTART:
-               SetSelection(Platform::Maximum(currentPos, wParam), wParam);
+               SetSelection(Platform::Maximum(sel.MainCaret(), wParam), wParam);
                break;
 
        case SCI_GETSELECTIONSTART:
-               return Platform::Minimum(anchor, currentPos);
+               return Platform::Minimum(sel.MainAnchor(), sel.MainCaret());
 
        case SCI_SETSELECTIONEND:
-               SetSelection(wParam, Platform::Minimum(anchor, wParam));
+               SetSelection(wParam, Platform::Minimum(sel.MainAnchor(), wParam));
                break;
 
        case SCI_GETSELECTIONEND:
-               return Platform::Maximum(anchor, currentPos);
+               return Platform::Maximum(sel.MainAnchor(), sel.MainCaret());
 
        case SCI_SETPRINTMAGNIFICATION:
                printMagnification = wParam;
@@ -6382,7 +6910,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETSTYLEDTEXT: {
                        if (lParam == 0)
                                return 0;
-                       TextRange *tr = reinterpret_cast<TextRange *>(lParam);
+                       Sci_TextRange *tr = reinterpret_cast<Sci_TextRange *>(lParam);
                        int iPlace = 0;
                        for (int iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) {
                                tr->lpstrText[iPlace++] = pdoc->CharAt(iChar);
@@ -6411,11 +6939,25 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                Redraw();
                break;
 
+       case SCI_GETWHITESPACESIZE:
+               return vs.whitespaceSize;
+
+       case SCI_SETWHITESPACESIZE:
+               vs.whitespaceSize = static_cast<int>(wParam);
+               Redraw();
+               break;
+
        case SCI_POSITIONFROMPOINT:
-               return PositionFromLocation(Point(wParam, lParam));
+               return PositionFromLocation(Point(wParam, lParam), false, false);
 
        case SCI_POSITIONFROMPOINTCLOSE:
-               return PositionFromLocationClose(Point(wParam, lParam));
+               return PositionFromLocation(Point(wParam, lParam), true, false);
+
+       case SCI_CHARPOSITIONFROMPOINT:
+               return PositionFromLocation(Point(wParam, lParam), false, true);
+
+       case SCI_CHARPOSITIONFROMPOINTCLOSE:
+               return PositionFromLocation(Point(wParam, lParam), true, true);
 
        case SCI_GOTOLINE:
                GoToLine(wParam);
@@ -6428,7 +6970,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                break;
 
        case SCI_GETCURLINE: {
-                       int lineCurrentPos = pdoc->LineFromPosition(currentPos);
+                       int lineCurrentPos = pdoc->LineFromPosition(sel.MainCaret());
                        int lineStart = pdoc->LineStart(lineCurrentPos);
                        unsigned int lineEnd = pdoc->LineStart(lineCurrentPos + 1);
                        if (lParam == 0) {
@@ -6441,7 +6983,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                                ptr[iPlace++] = pdoc->CharAt(iChar);
                        }
                        ptr[iPlace] = '\0';
-                       return currentPos - lineStart;
+                       return sel.MainCaret() - lineStart;
                }
 
        case SCI_GETENDSTYLED:
@@ -6483,6 +7025,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                InvalidateStyleRedraw();
                break;
 
+       case SCI_SETFONTQUALITY:
+               vs.extraFontFlag &= ~SC_EFF_QUALITY_MASK;
+               vs.extraFontFlag |= (wParam & SC_EFF_QUALITY_MASK);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_GETFONTQUALITY:
+               return (vs.extraFontFlag & SC_EFF_QUALITY_MASK);
+
        case SCI_SETTABWIDTH:
                if (wParam > 0) {
                        pdoc->tabInChars = wParam;
@@ -6575,9 +7126,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_SETWRAPVISUALFLAGS:
                wrapVisualFlags = wParam;
-               actualWrapVisualStartIndent = wrapVisualStartIndent;
-               if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (actualWrapVisualStartIndent == 0))
-                       actualWrapVisualStartIndent = 1; // must indent to show start visual
                InvalidateStyleRedraw();
                ReconfigureScrollBars();
                break;
@@ -6595,9 +7143,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_SETWRAPSTARTINDENT:
                wrapVisualStartIndent = wParam;
-               actualWrapVisualStartIndent = wrapVisualStartIndent;
-               if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (actualWrapVisualStartIndent == 0))
-                       actualWrapVisualStartIndent = 1; // must indent to show start visual
                InvalidateStyleRedraw();
                ReconfigureScrollBars();
                break;
@@ -6605,6 +7150,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETWRAPSTARTINDENT:
                return wrapVisualStartIndent;
 
+       case SCI_SETWRAPINDENTMODE:
+               wrapIndentMode = wParam;
+               InvalidateStyleRedraw();
+               ReconfigureScrollBars();
+               break;
+
+       case SCI_GETWRAPINDENTMODE:
+               return wrapIndentMode;
+
        case SCI_SETLAYOUTCACHE:
                llc.SetLevel(wParam);
                break;
@@ -6753,6 +7307,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                InvalidateStyleData();
                RedrawSelMargin();
                break;
+
+       case SCI_MARKERSYMBOLDEFINED:
+               if (wParam <= MARKER_MAX)
+                       return vs.markers[wParam].markType;
+               else
+                       return 0;
+
        case SCI_MARKERSETFORE:
                if (wParam <= MARKER_MAX)
                        vs.markers[wParam].fore.desired = ColourDesired(lParam);
@@ -6980,7 +7541,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                break;
 
        case SCI_HIDELINES:
-               cs.SetVisible(wParam, lParam, false);
+               if (wParam > 0)
+                       cs.SetVisible(wParam, lParam, false);
                SetScrollBars();
                Redraw();
                break;
@@ -7022,13 +7584,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_SEARCHPREV:
                return SearchText(iMessage, wParam, lParam);
 
-#ifdef INCLUDE_DEPRECATED_FEATURES
-       case SCI_SETCARETPOLICY:        // Deprecated
-               caretXPolicy = caretYPolicy = wParam;
-               caretXSlop = caretYSlop = lParam;
-               break;
-#endif
-
        case SCI_SETXCARETPOLICY:
                caretXPolicy = wParam;
                caretXSlop = lParam;
@@ -7050,17 +7605,20 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_SETSELFORE:
                vs.selforeset = wParam != 0;
                vs.selforeground.desired = ColourDesired(lParam);
+               vs.selAdditionalForeground.desired = ColourDesired(lParam);
                InvalidateStyleRedraw();
                break;
 
        case SCI_SETSELBACK:
                vs.selbackset = wParam != 0;
                vs.selbackground.desired = ColourDesired(lParam);
+               vs.selAdditionalBackground.desired = ColourDesired(lParam);
                InvalidateStyleRedraw();
                break;
 
        case SCI_SETSELALPHA:
                vs.selAlpha = wParam;
+               vs.selAdditionalAlpha = wParam;
                InvalidateStyleRedraw();
                break;
 
@@ -7164,6 +7722,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_INDICGETUNDER:
                return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0;
 
+       case SCI_INDICSETALPHA:
+               if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 100) {
+                       vs.indicators[wParam].fillAlpha = lParam;
+                       InvalidateStyleRedraw();
+               }
+               break;
+
+       case SCI_INDICGETALPHA:
+               return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
+
        case SCI_SETINDICATORCURRENT:
                pdoc->decorations.SetCurrentIndicator(wParam);
                break;
@@ -7372,7 +7940,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
        case SCI_CONVERTEOLS:
                pdoc->ConvertLineEnds(wParam);
-               SetSelection(currentPos, anchor);       // Ensure selection inside document
+               SetSelection(sel.MainCaret(), sel.MainAnchor());        // Ensure selection inside document
                return 0;
 
        case SCI_SETLENGTHFORENCODE:
@@ -7380,48 +7948,56 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
                return 0;
 
        case SCI_SELECTIONISRECTANGLE:
-               return selType == selRectangle ? 1 : 0;
+               return sel.selType == Selection::selRectangle ? 1 : 0;
 
        case SCI_SETSELECTIONMODE: {
                        switch (wParam) {
                        case SC_SEL_STREAM:
-                               moveExtendsSelection = !moveExtendsSelection || (selType != selStream);
-                               selType = selStream;
+                               sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream));
+                               sel.selType = Selection::selStream;
                                break;
                        case SC_SEL_RECTANGLE:
-                               moveExtendsSelection = !moveExtendsSelection || (selType != selRectangle);
-                               selType = selRectangle;
+                               sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selRectangle));
+                               sel.selType = Selection::selRectangle;
                                break;
                        case SC_SEL_LINES:
-                               moveExtendsSelection = !moveExtendsSelection || (selType != selLines);
-                               selType = selLines;
+                               sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selLines));
+                               sel.selType = Selection::selLines;
+                               break;
+                       case SC_SEL_THIN:
+                               sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selThin));
+                               sel.selType = Selection::selThin;
                                break;
                        default:
-                               moveExtendsSelection = !moveExtendsSelection || (selType != selStream);
-                               selType = selStream;
+                               sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream));
+                               sel.selType = Selection::selStream;
                        }
-                       InvalidateSelection(currentPos, anchor);
+                       InvalidateSelection(sel.RangeMain(), true);
                }
        case SCI_GETSELECTIONMODE:
-               switch (selType) {
-               case selStream:
+               switch (sel.selType) {
+               case Selection::selStream:
                        return SC_SEL_STREAM;
-               case selRectangle:
+               case Selection::selRectangle:
                        return SC_SEL_RECTANGLE;
-               case selLines:
+               case Selection::selLines:
                        return SC_SEL_LINES;
+               case Selection::selThin:
+                       return SC_SEL_THIN;
                default:        // ?!
                        return SC_SEL_STREAM;
                }
-       case SCI_GETLINESELSTARTPOSITION: {
-                       SelectionLineIterator lineIterator(this);
-                       lineIterator.SetAt(wParam);
-                       return lineIterator.startPos;
-               }
+       case SCI_GETLINESELSTARTPOSITION:
        case SCI_GETLINESELENDPOSITION: {
-                       SelectionLineIterator lineIterator(this);
-                       lineIterator.SetAt(wParam);
-                       return lineIterator.endPos;
+                       SelectionSegment segmentLine(SelectionPosition(pdoc->LineStart(wParam)),
+                               SelectionPosition(pdoc->LineEnd(wParam)));
+                       for (size_t r=0; r<sel.Count(); r++) {
+                               SelectionSegment portion = sel.Range(r).Intersect(segmentLine);
+                               if (portion.start.IsValid()) {
+                                       return (iMessage == SCI_GETLINESELSTARTPOSITION) ? portion.start.Position() : portion.end.Position();
+                               }
+                       }
+                       return INVALID_POSITION;
                }
 
        case SCI_SETOVERTYPE:
@@ -7532,6 +8108,337 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
        case SCI_GETPASTECONVERTENDINGS:
                return convertPastes ? 1 : 0;
 
+       case SCI_GETCHARACTERPOINTER:
+               return reinterpret_cast<sptr_t>(pdoc->BufferPointer());
+
+       case SCI_SETEXTRAASCENT:
+               vs.extraAscent = wParam;
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_GETEXTRAASCENT:
+               return vs.extraAscent;
+
+       case SCI_SETEXTRADESCENT:
+               vs.extraDescent = wParam;
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_GETEXTRADESCENT:
+               return vs.extraDescent;
+
+       case SCI_MARGINSETSTYLEOFFSET:
+               vs.marginStyleOffset = wParam;
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_MARGINGETSTYLEOFFSET:
+               return vs.marginStyleOffset;
+
+       case SCI_MARGINSETTEXT:
+               pdoc->MarginSetText(wParam, CharPtrFromSPtr(lParam));
+               break;
+
+       case SCI_MARGINGETTEXT: {
+                       const StyledText st = pdoc->MarginStyledText(wParam);
+                       if (lParam) {
+                               if (st.text)
+                                       memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
+                               else
+                                       strcpy(CharPtrFromSPtr(lParam), "");
+                       }
+                       return st.length;
+               }
+
+       case SCI_MARGINSETSTYLE:
+               pdoc->MarginSetStyle(wParam, lParam);
+               break;
+
+       case SCI_MARGINGETSTYLE: {
+                       const StyledText st = pdoc->MarginStyledText(wParam);
+                       return st.style;
+               }
+
+       case SCI_MARGINSETSTYLES:
+               pdoc->MarginSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam));
+               break;
+
+       case SCI_MARGINGETSTYLES: {
+                       const StyledText st = pdoc->MarginStyledText(wParam);
+                       if (lParam) {
+                               if (st.styles)
+                                       memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
+                               else
+                                       strcpy(CharPtrFromSPtr(lParam), "");
+                       }
+                       return st.styles ? st.length : 0;
+               }
+
+       case SCI_MARGINTEXTCLEARALL:
+               pdoc->MarginClearAll();
+               break;
+
+       case SCI_ANNOTATIONSETTEXT:
+               pdoc->AnnotationSetText(wParam, CharPtrFromSPtr(lParam));
+               break;
+
+       case SCI_ANNOTATIONGETTEXT: {
+                       const StyledText st = pdoc->AnnotationStyledText(wParam);
+                       if (lParam) {
+                               if (st.text)
+                                       memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
+                               else
+                                       strcpy(CharPtrFromSPtr(lParam), "");
+                       }
+                       return st.length;
+               }
+
+       case SCI_ANNOTATIONGETSTYLE: {
+                       const StyledText st = pdoc->AnnotationStyledText(wParam);
+                       return st.style;
+               }
+
+       case SCI_ANNOTATIONSETSTYLE:
+               pdoc->AnnotationSetStyle(wParam, lParam);
+               break;
+
+       case SCI_ANNOTATIONSETSTYLES:
+               pdoc->AnnotationSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam));
+               break;
+
+       case SCI_ANNOTATIONGETSTYLES: {
+                       const StyledText st = pdoc->AnnotationStyledText(wParam);
+                       if (lParam) {
+                               if (st.styles)
+                                       memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
+                               else
+                                       strcpy(CharPtrFromSPtr(lParam), "");
+                       }
+                       return st.styles ? st.length : 0;
+               }
+
+       case SCI_ANNOTATIONGETLINES:
+               return pdoc->AnnotationLines(wParam);
+
+       case SCI_ANNOTATIONCLEARALL:
+               pdoc->AnnotationClearAll();
+               break;
+
+       case SCI_ANNOTATIONSETVISIBLE:
+               SetAnnotationVisible(wParam);
+               break;
+
+       case SCI_ANNOTATIONGETVISIBLE:
+               return vs.annotationVisible;
+
+       case SCI_ANNOTATIONSETSTYLEOFFSET:
+               vs.annotationStyleOffset = wParam;
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_ANNOTATIONGETSTYLEOFFSET:
+               return vs.annotationStyleOffset;
+
+       case SCI_ADDUNDOACTION:
+               pdoc->AddUndoAction(wParam, lParam & UNDO_MAY_COALESCE);
+               break;
+
+       case SCI_SETMULTIPLESELECTION:
+               multipleSelection = wParam != 0;
+               InvalidateCaret();
+               break;
+
+       case SCI_GETMULTIPLESELECTION:
+               return multipleSelection;
+
+       case SCI_SETADDITIONALSELECTIONTYPING:
+               additionalSelectionTyping = wParam != 0;
+               InvalidateCaret();
+               break;
+
+       case SCI_GETADDITIONALSELECTIONTYPING:
+               return additionalSelectionTyping;
+
+       case SCI_SETADDITIONALCARETSBLINK:
+               additionalCaretsBlink = wParam != 0;
+               InvalidateCaret();
+               break;
+
+       case SCI_GETADDITIONALCARETSBLINK:
+               return additionalCaretsBlink;
+
+       case SCI_SETADDITIONALCARETSVISIBLE:
+               additionalCaretsVisible = wParam != 0;
+               InvalidateCaret();
+               break;
+
+       case SCI_GETADDITIONALCARETSVISIBLE:
+               return additionalCaretsVisible;
+
+       case SCI_GETSELECTIONS:
+               return sel.Count();
+
+       case SCI_CLEARSELECTIONS:
+               sel.Clear();
+               Redraw();
+               break;
+
+       case SCI_SETSELECTION:
+               sel.SetSelection(SelectionRange(wParam, lParam));
+               Redraw();
+               break;
+
+       case SCI_ADDSELECTION:
+               sel.AddSelection(SelectionRange(wParam, lParam));
+               Redraw();
+               break;
+
+       case SCI_SETMAINSELECTION:
+               sel.SetMain(wParam);
+               Redraw();
+               break;
+
+       case SCI_GETMAINSELECTION:
+               return sel.Main();
+
+       case SCI_SETSELECTIONNCARET:
+               sel.Range(wParam).caret.SetPosition(lParam);
+               Redraw();
+               break;
+
+       case SCI_GETSELECTIONNCARET:
+               return sel.Range(wParam).caret.Position();
+
+       case SCI_SETSELECTIONNANCHOR:
+               sel.Range(wParam).anchor.SetPosition(lParam);
+               Redraw();
+               break;
+       case SCI_GETSELECTIONNANCHOR:
+               return sel.Range(wParam).anchor.Position();
+
+       case SCI_SETSELECTIONNCARETVIRTUALSPACE:
+               sel.Range(wParam).caret.SetVirtualSpace(lParam);
+               Redraw();
+               break;
+
+       case SCI_GETSELECTIONNCARETVIRTUALSPACE:
+               return sel.Range(wParam).caret.VirtualSpace();
+
+       case SCI_SETSELECTIONNANCHORVIRTUALSPACE:
+               sel.Range(wParam).anchor.SetVirtualSpace(lParam);
+               Redraw();
+               break;
+
+       case SCI_GETSELECTIONNANCHORVIRTUALSPACE:
+               return sel.Range(wParam).anchor.VirtualSpace();
+
+       case SCI_SETSELECTIONNSTART:
+               sel.Range(wParam).anchor.SetPosition(lParam);
+               Redraw();
+               break;
+
+       case SCI_GETSELECTIONNSTART:
+               return sel.Range(wParam).Start().Position();
+
+       case SCI_SETSELECTIONNEND:
+               sel.Range(wParam).caret.SetPosition(lParam);
+               Redraw();
+               break;
+
+       case SCI_GETSELECTIONNEND:
+               return sel.Range(wParam).End().Position();
+
+       case SCI_SETRECTANGULARSELECTIONCARET:
+               if (!sel.IsRectangular())
+                       sel.Clear();
+               sel.selType = Selection::selRectangle;
+               sel.Rectangular().caret.SetPosition(wParam);
+               SetRectangularRange();
+               Redraw();
+               break;
+
+       case SCI_GETRECTANGULARSELECTIONCARET:
+               return sel.Rectangular().caret.Position();
+
+       case SCI_SETRECTANGULARSELECTIONANCHOR:
+               if (!sel.IsRectangular())
+                       sel.Clear();
+               sel.selType = Selection::selRectangle;
+               sel.Rectangular().anchor.SetPosition(wParam);
+               SetRectangularRange();
+               Redraw();
+               break;
+
+       case SCI_GETRECTANGULARSELECTIONANCHOR:
+               return sel.Rectangular().anchor.Position();
+
+       case SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE:
+               if (!sel.IsRectangular())
+                       sel.Clear();
+               sel.selType = Selection::selRectangle;
+               sel.Rectangular().caret.SetVirtualSpace(wParam);
+               SetRectangularRange();
+               Redraw();
+               break;
+
+       case SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE:
+               return sel.Rectangular().caret.VirtualSpace();
+
+       case SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE:
+               if (!sel.IsRectangular())
+                       sel.Clear();
+               sel.selType = Selection::selRectangle;
+               sel.Rectangular().anchor.SetVirtualSpace(wParam);
+               SetRectangularRange();
+               Redraw();
+               break;
+
+       case SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE:
+               return sel.Rectangular().anchor.VirtualSpace();
+
+       case SCI_SETVIRTUALSPACEOPTIONS:
+               virtualSpaceOptions = wParam;
+               break;
+
+       case SCI_GETVIRTUALSPACEOPTIONS:
+               return virtualSpaceOptions;
+
+       case SCI_SETADDITIONALSELFORE:
+               vs.selAdditionalForeground.desired = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETADDITIONALSELBACK:
+               vs.selAdditionalBackground.desired = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_SETADDITIONALSELALPHA:
+               vs.selAdditionalAlpha = wParam;
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_GETADDITIONALSELALPHA:
+               return vs.selAdditionalAlpha;
+
+       case SCI_SETADDITIONALCARETFORE:
+               vs.additionalCaretColour.desired = ColourDesired(wParam);
+               InvalidateStyleRedraw();
+               break;
+
+       case SCI_GETADDITIONALCARETFORE:
+               return vs.additionalCaretColour.desired.AsLong();
+
+       case SCI_ROTATESELECTION:
+               sel.RotateMain();
+               InvalidateSelection(sel.RangeMain(), true);
+               break;
+
+       case SCI_SWAPMAINANCHORCARET:
+               InvalidateSelection(sel.RangeMain());
+               sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret);
+               break;
+
        default:
                return DefWndProc(iMessage, wParam, lParam);
        }
index 049cc373f5b24ccb380e8df32bb75addc8200d57..92dcfb14bf86eb768cc0a3a50f54bb5aefdd316d 100644 (file)
@@ -54,16 +54,17 @@ public:
        char *s;
        int len;
        bool rectangular;
+       bool lineCopy;
        int codePage;
        int characterSet;
-       SelectionText() : s(0), len(0), rectangular(false), codePage(0), characterSet(0) {}
+       SelectionText() : s(0), len(0), rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
        ~SelectionText() {
                Free();
        }
        void Free() {
-               Set(0, 0, 0, 0, false);
+               Set(0, 0, 0, 0, false, false);
        }
-       void Set(char *s_, int len_, int codePage_, int characterSet_, bool rectangular_) {
+       void Set(char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
                delete []s;
                s = s_;
                if (s)
@@ -73,24 +74,23 @@ public:
                codePage = codePage_;
                characterSet = characterSet_;
                rectangular = rectangular_;
+               lineCopy = lineCopy_;
        }
-       void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_) {
+       void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
                delete []s;
+               s = 0;
                s = new char[len_];
-               if (s) {
-                       len = len_;
-                       for (int i = 0; i < len_; i++) {
-                               s[i] = s_[i];
-                       }
-               } else {
-                       len = 0;
+               len = len_;
+               for (int i = 0; i < len_; i++) {
+                       s[i] = s_[i];
                }
                codePage = codePage_;
                characterSet = characterSet_;
                rectangular = rectangular_;
+               lineCopy = lineCopy_;
        }
        void Copy(const SelectionText &other) {
-               Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular);
+               Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular, other.lineCopy);
        }
 };
 
@@ -98,8 +98,8 @@ public:
  */
 class Editor : public DocWatcher {
        // Private so Editor objects can not be copied
-       Editor(const Editor &) : DocWatcher() {}
-       Editor &operator=(const Editor &) { return *this; }
+       Editor(const Editor &);
+       Editor &operator=(const Editor &);
 
 protected:     // ScintillaBase subclass needs access to much of Editor
 
@@ -122,7 +122,6 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        bool hasFocus;
        bool hideSelection;
        bool inOverstrike;
-       int errorStatus;
        bool mouseDownCaptures;
 
        /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
@@ -141,6 +140,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
        bool verticalScrollBarVisible;
        bool endAtLastLine;
        bool caretSticky;
+       bool multipleSelection;
+       bool additionalSelectionTyping;
+       bool additionalCaretsBlink;
+       bool additionalCaretsVisible;
+
+       int virtualSpaceOptions;
 
        Surface *pixmapLine;
        Surface *pixmapSelMargin;
@@ -169,13 +174,11 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        Point ptMouseLast;
        enum { ddNone, ddInitial, ddDragging } inDragDrop;
        bool dropWentOutside;
-       int posDrag;
-       int posDrop;
+       SelectionPosition posDrag;
+       SelectionPosition posDrop;
        int lastXChosen;
        int lineAnchor;
        int originalAnchorPos;
-       int currentPos;
-       int anchor;
        int targetStart;
        int targetEnd;
        int searchFlags;
@@ -197,11 +200,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
        int modEventMask;
 
        SelectionText drag;
-       enum selTypes { noSel, selStream, selRectangle, selLines };
-       selTypes selType;
-       bool moveExtendsSelection;
-       int xStartSelect;       ///< x position of start of rectangular selection
-       int xEndSelect;         ///< x position of end of rectangular selection
+       Selection sel;
        bool primarySelection;
 
        int caretXPolicy;
@@ -233,7 +232,8 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        int wrapVisualFlags;
        int wrapVisualFlagsLocation;
        int wrapVisualStartIndent;
-       int actualWrapVisualStartIndent;
+       int wrapAddIndent; // This will be added to initial indent of line
+       int wrapIndentMode; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
 
        bool convertPastes;
 
@@ -256,10 +256,14 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        int LinesOnScreen();
        int LinesToScroll();
        int MaxScrollPos();
+       SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
+       Point LocationFromPosition(SelectionPosition pos);
        Point LocationFromPosition(int pos);
        int XFromPosition(int pos);
-       int PositionFromLocation(Point pt);
-       int PositionFromLocationClose(Point pt);
+       int XFromPosition(SelectionPosition sp);
+       SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
+       int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false);
+       SelectionPosition SPositionFromLineX(int lineDoc, int x);
        int PositionFromLineX(int line, int x);
        int LineFromLocation(Point pt);
        void SetTopLine(int topLineNew);
@@ -271,20 +275,31 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        PRectangle RectangleFromRange(int start, int end);
        void InvalidateRange(int start, int end);
 
+       bool UserVirtualSpace() const {
+               return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0);
+       }
        int CurrentPosition();
        bool SelectionEmpty();
-       int SelectionStart();
-       int SelectionEnd();
+       SelectionPosition SelectionStart();
+       SelectionPosition SelectionEnd();
        void SetRectangularRange();
-       void InvalidateSelection(int currentPos_, int anchor_);
+       void ThinRectangularRange();
+       void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
+       void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
        void SetSelection(int currentPos_, int anchor_);
+       void SetSelection(SelectionPosition currentPos_);
        void SetSelection(int currentPos_);
+       void SetEmptySelection(SelectionPosition currentPos_);
        void SetEmptySelection(int currentPos_);
        bool RangeContainsProtected(int start, int end) const;
        bool SelectionContainsProtected();
-       int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
-       int MovePositionTo(int newPos, selTypes sel=noSel, bool ensureVisible=true);
-       int MovePositionSoVisible(int pos, int moveDir);
+       int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const;
+       SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const;
+       int MovePositionTo(SelectionPosition newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
+       int MovePositionTo(int newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
+       SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir);
+       SelectionPosition MovePositionSoVisible(int pos, int moveDir);
+       Point PointMainCaret();
        void SetLastXChosen();
 
        void ScrollTo(int line, bool moveThumb=true);
@@ -309,8 +324,8 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        LineLayout *RetrieveLineLayout(int lineNumber);
        void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
                int width=LineLayout::wrapWidthInfinite);
-       ColourAllocated SelectionBackground(ViewStyle &vsDraw);
-       ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
+       ColourAllocated SelectionBackground(ViewStyle &vsDraw, bool main);
+       ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
        void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
        void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour);
        void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
@@ -319,12 +334,17 @@ protected:        // ScintillaBase subclass needs access to much of Editor
                bool drawWrapMark, ColourAllocated wrapColour);
        void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
                PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
+       void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+        PRectangle rcLine, LineLayout *ll, int subLine);
        void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
-               PRectangle rcLine, LineLayout *ll, int subLine=0);
-       void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret);
+               PRectangle rcLine, LineLayout *ll, int subLine);
+       void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, 
+               int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour);
+       void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+               PRectangle rcLine, LineLayout *ll, int subLine);
        void RefreshPixMaps(Surface *surfaceWindow);
        void Paint(Surface *surfaceWindow, PRectangle rcArea);
-       long FormatRange(bool draw, RangeToFormat *pfr);
+       long FormatRange(bool draw, Sci_RangeToFormat *pfr);
        int TextWidth(int style, const char *text);
 
        virtual void SetVerticalScrollPos() = 0;
@@ -334,14 +354,17 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        void SetScrollBars();
        void ChangeSize();
 
+       void FilterSelections();
+       int InsertSpace(int position, unsigned int spaces);
        void AddChar(char ch);
        virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
        void ClearSelection();
        void ClearAll();
        void ClearDocumentStyle();
        void Cut();
-       void PasteRectangular(int pos, const char *ptr, int len);
+       void PasteRectangular(SelectionPosition pos, const char *ptr, int len);
        virtual void Copy() = 0;
+       virtual void CopyAllowLine();
        virtual bool CanPaste();
        virtual void Paste() = 0;
        void Clear();
@@ -358,7 +381,6 @@ protected:  // ScintillaBase subclass needs access to much of Editor
        virtual void NotifyParent(SCNotification scn) = 0;
        virtual void NotifyStyleToNeeded(int endStyleNeeded);
        void NotifyChar(int ch);
-       void NotifyMove(int position);
        void NotifySavePoint(bool isSavePoint);
        void NotifyModifyAttempt();
        virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
@@ -380,14 +402,14 @@ protected:        // ScintillaBase subclass needs access to much of Editor
        void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
        void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 
-       void PageMove(int direction, selTypes sel=noSel, bool stuttered = false);
+       void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
        void ChangeCaseOfSelection(bool makeUpperCase);
        void LineTranspose();
        void Duplicate(bool forLine);
        virtual void CancelModes();
        void NewLine();
-       void CursorUpOrDown(int direction, selTypes sel=noSel);
-       void ParaUpOrDown(int direction, selTypes sel=noSel);
+       void CursorUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
+       void ParaUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
        int StartEndDisplayLine(int pos, bool start);
        virtual int KeyCommand(unsigned int iMessage);
        virtual int KeyDefault(int /* key */, int /*modifiers*/);
@@ -406,18 +428,16 @@ protected:        // ScintillaBase subclass needs access to much of Editor
 
        virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
        char *CopyRange(int start, int end);
-       void CopySelectionFromRange(SelectionText *ss, int start, int end);
-       void CopySelectionRange(SelectionText *ss);
+       void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
        void CopyRangeToClipboard(int start, int end);
        void CopyText(int length, const char *text);
-       void SetDragPosition(int newPos);
+       void SetDragPosition(SelectionPosition newPos);
        virtual void DisplayCursor(Window::Cursor c);
        virtual bool DragThreshold(Point ptStart, Point ptNow);
        virtual void StartDrag();
-       void DropAt(int position, const char *value, bool moving, bool rectangular);
-       /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
-        * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */
-       int PositionInSelection(int pos);
+       void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
+       /** PositionInSelection returns true if position in selection. */
+       bool PositionInSelection(int pos);
        bool PointInSelection(Point pt);
        bool PointInSelMargin(Point pt);
        void LineSelection(int lineCurrent_, int lineAnchor_);
@@ -439,7 +459,10 @@ protected: // ScintillaBase subclass needs access to much of Editor
        void CheckForChangeOutsidePaint(Range r);
        void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
 
+       void SetAnnotationHeights(int start, int end);
        void SetDocPointer(Document *document);
+       
+       void SetAnnotationVisible(int visible);
 
        void Expand(int &line, bool doExpand);
        void ToggleContraction(int line);
@@ -460,6 +483,10 @@ protected: // ScintillaBase subclass needs access to much of Editor
        void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
        sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 
+       static const char *StringFromEOLMode(int eolMode);
+
+       static sptr_t StringResult(sptr_t lParam, const char *val);
+
 public:
        // Public so the COM thunks can access it.
        bool IsUnicodeMode() const;
@@ -467,6 +494,8 @@ public:
        virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
        // Public so scintilla_set_id can use it.
        int ctrlID;
+       // Public so COM methods for drag and drop can set it.
+       int errorStatus;
        friend class AutoSurface;
        friend class SelectionLineIterator;
 };
index 0344debd78eb506f6b79e7362376d50fd23bd862..098df4dd5bc34ee8765052a8d522969c2571e371 100644 (file)
@@ -10,6 +10,8 @@
 #include <string.h>
 #include <ctype.h>
 
+#include <string>
+
 #include "Platform.h"
 
 #include "Scintilla.h"
@@ -39,7 +41,7 @@ char **WordListsToStrings(WordList *val[]) {
                dim++;
        char **wls = new char * [dim + 1];
        for (int i = 0;i < dim;i++) {
-               SString words;
+               std::string words;
                words = "";
                for (int n = 0; n < val[i]->len; n++) {
                        words += val[i]->words[n];
@@ -172,13 +174,13 @@ LexerLibrary::~LexerLibrary() {
 void LexerLibrary::Release() {
        //TODO maintain a list of lexers created, and delete them!
        LexerMinder *lm;
-       LexerMinder *next;
+       LexerMinder *lmNext;
        lm = first;
        while (NULL != lm) {
-               next = lm->next;
+               lmNext = lm->next;
                delete lm->self;
                delete lm;
-               lm = next;
+               lm = lmNext;
        }
 
        first = NULL;
index 55e127b40ac0575a69655cd80fa04cf1f6ac7e3a..29f42ccf7468d364ebfba3590ab3133a36c432eb 100644 (file)
@@ -40,6 +40,7 @@ public:
        ExternalLexerModule(int language_, LexerFunction fnLexer_, 
                const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){
                strncpy(name, languageName_, sizeof(name));
+               name[sizeof(name)-1] = '\0';
                languageName = name;
        };
        virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
@@ -68,7 +69,7 @@ public:
        void Release();
        
        LexerLibrary    *next;
-       SString                 m_sModuleName;
+       std::string                     m_sModuleName;
 };
 
 /// LexerManager manages external lexers, contains LexerLibrarys.
diff --git a/src/stc/scintilla/src/FontQuality.h b/src/stc/scintilla/src/FontQuality.h
new file mode 100644 (file)
index 0000000..2c8d548
--- /dev/null
@@ -0,0 +1,12 @@
+// Scintilla source code edit control
+/** @file FontQuality.h
+ ** Definitions to control font anti-aliasing.
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#define SC_EFF_QUALITY_MASK            0xF
+#define SC_EFF_QUALITY_DEFAULT           0
+#define SC_EFF_QUALITY_NON_ANTIALIASED   1
+#define SC_EFF_QUALITY_ANTIALIASED       2
+#define SC_EFF_QUALITY_LCD_OPTIMIZED     3
index 139e2b0eab9ed3e9c5050a5aa8babd8117a21325..da9531224aee35f747ece9607bf156f3fa319fab 100644 (file)
@@ -72,7 +72,7 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
                rcBox.top = rcLine.top + 1;
                rcBox.left = rc.left;
                rcBox.right = rc.right;
-               surface->AlphaRectangle(rcBox, 1, fore.allocated, 30, fore.allocated, 50, 0);
+               surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
        } else {        // Either INDIC_PLAIN or unknown
                surface->MoveTo(rc.left, ymid);
                surface->LineTo(rc.right, ymid);
index 2081db544e9b7db8a7b11f46d3d07b4201cae32d..42b56f07e789a928fd99e470eecf8bb350716551 100644 (file)
@@ -19,7 +19,8 @@ public:
        int style;
        bool under;
        ColourPair fore;
-       Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)) {
+       int fillAlpha;
+       Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
        }
        void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
 };
index 29538d57b5aa7dbcfbb20648bc64e39cda7a9d78..5e4de668d04ebf747f196811cb546349a290aa34 100644 (file)
 using namespace Scintilla;
 #endif
 
+/**
+ * Creates an array that points into each word in the string and puts \0 terminators
+ * after each word.
+ */
+static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
+       int prev = '\n';
+       int words = 0;
+       // For rapid determination of whether a character is a separator, build
+       // a look up table.
+       bool wordSeparator[256];
+       for (int i=0;i<256; i++) {
+               wordSeparator[i] = false;
+       }
+       wordSeparator['\r'] = true;
+       wordSeparator['\n'] = true;
+       if (!onlyLineEnds) {
+               wordSeparator[' '] = true;
+               wordSeparator['\t'] = true;
+       }
+       for (int j = 0; wordlist[j]; j++) {
+               int curr = static_cast<unsigned char>(wordlist[j]);
+               if (!wordSeparator[curr] && wordSeparator[prev])
+                       words++;
+               prev = curr;
+       }
+       char **keywords = new char *[words + 1];
+       if (keywords) {
+               words = 0;
+               prev = '\0';
+               size_t slen = strlen(wordlist);
+               for (size_t k = 0; k < slen; k++) {
+                       if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
+                               if (!prev) {
+                                       keywords[words] = &wordlist[k];
+                                       words++;
+                               }
+                       } else {
+                               wordlist[k] = '\0';
+                       }
+                       prev = wordlist[k];
+               }
+               keywords[words] = &wordlist[slen];
+               *len = words;
+       } else {
+               *len = 0;
+       }
+       return keywords;
+}
+
+void WordList::Clear() {
+       if (words) {
+               delete []list;
+               delete []words;
+       }
+       words = 0;
+       list = 0;
+       len = 0;
+       sorted = false;
+}
+
+void WordList::Set(const char *s) {
+       list = new char[strlen(s) + 1];
+       strcpy(list, s);
+       sorted = false;
+       words = ArrayFromWordList(list, &len, onlyLineEnds);
+}
+
+extern "C" int cmpString(const void *a1, const void *a2) {
+       // Can't work out the correct incantation to use modern casts here
+       return strcmp(*(char**)(a1), *(char**)(a2));
+}
+
+static void SortWordList(char **words, unsigned int len) {
+       qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
+             cmpString);
+}
+
+bool WordList::InList(const char *s) {
+       if (0 == words)
+               return false;
+       if (!sorted) {
+               sorted = true;
+               SortWordList(words, len);
+               for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+                       starts[k] = -1;
+               for (int l = len - 1; l >= 0; l--) {
+                       unsigned char indexChar = words[l][0];
+                       starts[indexChar] = l;
+               }
+       }
+       unsigned char firstChar = s[0];
+       int j = starts[firstChar];
+       if (j >= 0) {
+               while ((unsigned char)words[j][0] == firstChar) {
+                       if (s[1] == words[j][1]) {
+                               const char *a = words[j] + 1;
+                               const char *b = s + 1;
+                               while (*a && *a == *b) {
+                                       a++;
+                                       b++;
+                               }
+                               if (!*a && !*b)
+                                       return true;
+                       }
+                       j++;
+               }
+       }
+       j = starts['^'];
+       if (j >= 0) {
+               while (words[j][0] == '^') {
+                       const char *a = words[j] + 1;
+                       const char *b = s;
+                       while (*a && *a == *b) {
+                               a++;
+                               b++;
+                       }
+                       if (!*a)
+                               return true;
+                       j++;
+               }
+       }
+       return false;
+}
+
+/** similar to InList, but word s can be a substring of keyword.
+ * eg. the keyword define is defined as def~ine. This means the word must start
+ * with def to be a keyword, but also defi, defin and define are valid.
+ * The marker is ~ in this case.
+ */
+bool WordList::InListAbbreviated(const char *s, const char marker) {
+       if (0 == words)
+               return false;
+       if (!sorted) {
+               sorted = true;
+               SortWordList(words, len);
+               for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+                       starts[k] = -1;
+               for (int l = len - 1; l >= 0; l--) {
+                       unsigned char indexChar = words[l][0];
+                       starts[indexChar] = l;
+               }
+       }
+       unsigned char firstChar = s[0];
+       int j = starts[firstChar];
+       if (j >= 0) {
+               while (words[j][0] == firstChar) {
+                       bool isSubword = false;
+                       int start = 1;
+                       if (words[j][1] == marker) {
+                               isSubword = true;
+                               start++;
+                       }
+                       if (s[1] == words[j][start]) {
+                               const char *a = words[j] + start;
+                               const char *b = s + 1;
+                               while (*a && *a == *b) {
+                                       a++;
+                                       if (*a == marker) {
+                                               isSubword = true;
+                                               a++;
+                                       }
+                                       b++;
+                               }
+                               if ((!*a || isSubword) && !*b)
+                                       return true;
+                       }
+                       j++;
+               }
+       }
+       j = starts['^'];
+       if (j >= 0) {
+               while (words[j][0] == '^') {
+                       const char *a = words[j] + 1;
+                       const char *b = s;
+                       while (*a && *a == *b) {
+                               a++;
+                               b++;
+                       }
+                       if (!*a)
+                               return true;
+                       j++;
+               }
+       }
+       return false;
+}
+
 const LexerModule *LexerModule::base = 0;
 int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
 
@@ -146,7 +332,6 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmAns1);
        LINK_LEXER(lmAPDL);
        LINK_LEXER(lmAsm);
-       LINK_LEXER(lmASP);
        LINK_LEXER(lmASY);
        LINK_LEXER(lmAU3);
        LINK_LEXER(lmAVE);
@@ -159,6 +344,7 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmClw);
        LINK_LEXER(lmClwNoCase);
        LINK_LEXER(lmCmake);
+       LINK_LEXER(lmCOBOL);
        LINK_LEXER(lmConf);
        LINK_LEXER(lmCPP);
        LINK_LEXER(lmCPPNoCase);
@@ -187,11 +373,15 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmLot);
        LINK_LEXER(lmLout);
        LINK_LEXER(lmLua);
+       LINK_LEXER(lmMagikSF);
        LINK_LEXER(lmMake);
+       LINK_LEXER(lmMarkdown);
        LINK_LEXER(lmMatlab);
        LINK_LEXER(lmMETAPOST);
        LINK_LEXER(lmMMIXAL);
        LINK_LEXER(lmMSSQL);
+       LINK_LEXER(lmMySQL);
+       LINK_LEXER(lmNimrod);
        LINK_LEXER(lmNncrontab);
        LINK_LEXER(lmNsis);
        LINK_LEXER(lmNull);
@@ -200,10 +390,12 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmPascal);
        LINK_LEXER(lmPB);
        LINK_LEXER(lmPerl);
-       LINK_LEXER(lmPHP);
        LINK_LEXER(lmPHPSCRIPT);
        LINK_LEXER(lmPLM);
+       LINK_LEXER(lmPo);
        LINK_LEXER(lmPOV);
+       LINK_LEXER(lmPowerPro);
+       LINK_LEXER(lmPowerShell);
        LINK_LEXER(lmProgress);
        LINK_LEXER(lmProps);
        LINK_LEXER(lmPS);
@@ -214,10 +406,14 @@ int Scintilla_LinkLexers() {
        LINK_LEXER(lmRuby);
        LINK_LEXER(lmScriptol);
        LINK_LEXER(lmSmalltalk);
+       LINK_LEXER(lmSML);
+       LINK_LEXER(lmSorc);
        LINK_LEXER(lmSpecman);
        LINK_LEXER(lmSpice);
        LINK_LEXER(lmSQL);
+       LINK_LEXER(lmTACL);
        LINK_LEXER(lmTADS3);
+       LINK_LEXER(lmTAL);
        LINK_LEXER(lmTCL);
        LINK_LEXER(lmTeX);
        LINK_LEXER(lmVB);
index cedf261f5c9417fd8e11c8640198ddc70afcca48..cfff9279dbf39bb5e548293a7e3225c5fe9f36ec 100644 (file)
@@ -253,11 +253,12 @@ static void ColouriseAU3Doc(unsigned int startPos,
                                //Reset at line end
                                if (sc.atLineEnd) {
                                        ci=0;
-                                       if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
+                                       if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
                                                if (sc.atLineEnd) 
                                                        sc.SetState(SCE_AU3_DEFAULT);
                                                else    
                                                        sc.SetState(SCE_AU3_COMMENTBLOCK);
+                                       }
                                        break;
                                }
                                //skip rest of line when a ; is encountered
index 194b84c516b096d0b0f9221fbdf54be50ec25a83..10e8b76b1ec939365946856193c4b92a1d5704bf 100644 (file)
@@ -2,6 +2,7 @@
 /** @file LexABAQUS.cxx
  ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
  ** By Sergio Lucato.
+ ** Sort of completely rewritten by Gertjan Kloosterman
  **/
 // The License.txt file describes the conditions under which this software may be distributed.
 
@@ -27,7 +28,15 @@ using namespace Scintilla;
 #endif
 
 static inline bool IsAWordChar(const int ch) {
-       return (ch < 0x80 && (isalnum(ch) || ch == '_'));
+       return (ch < 0x80 && (isalnum(ch) || (ch == '_')));
+}
+
+static inline bool IsAKeywordChar(const int ch) {
+       return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
+}
+
+static inline bool IsASetChar(const int ch) {
+       return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
 }
 
 static inline bool IsAnOperator(char ch) {
@@ -41,90 +50,228 @@ static inline bool IsAnOperator(char ch) {
        return false;
 }
 
-static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */,
                             Accessor &styler) {
-
-       int stringStart = ' ';
-
-       WordList &processors = *keywordlists[0];
-       WordList &commands = *keywordlists[1];
-       WordList &slashcommands = *keywordlists[2];
-       WordList &starcommands = *keywordlists[3];
-       WordList &arguments = *keywordlists[4];
-       WordList &functions = *keywordlists[5];
+       enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
+                                         DAT_LINE_VAL, DAT_LINE_COMMA,\
+                                         COMMENT_LINE,\
+                                         ST_ERROR, LINE_END } state ;
 
        // Do not leak onto next line
+       state = LINE_END ;
        initStyle = SCE_ABAQUS_DEFAULT;
        StyleContext sc(startPos, length, initStyle, styler);
 
-       for (; sc.More(); sc.Forward()) {
-               // Determine if the current state should terminate.
-               if (sc.state == SCE_ABAQUS_NUMBER) {
-                       if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
-                               ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
-                               sc.SetState(SCE_ABAQUS_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ABAQUS_COMMENT) {
-                       if (sc.atLineEnd) {
-                               sc.SetState(SCE_ABAQUS_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ABAQUS_COMMENTBLOCK) {
-                       if (sc.atLineEnd) {
-                               if (sc.ch == '\r') {
-                               sc.Forward();
-                               }
-                               sc.ForwardSetState(SCE_ABAQUS_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ABAQUS_STRING) {
-                       if (sc.atLineEnd) {
-                               sc.SetState(SCE_ABAQUS_DEFAULT);
-                       } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
-                               sc.ForwardSetState(SCE_ABAQUS_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ABAQUS_WORD) {
-                       if (!IsAWordChar(sc.ch)) {
-                               char s[100];
-                               sc.GetCurrentLowered(s, sizeof(s));
-                               if (processors.InList(s)) {
-                                       sc.ChangeState(SCE_ABAQUS_PROCESSOR);
-                               } else if (slashcommands.InList(s)) {
-                                       sc.ChangeState(SCE_ABAQUS_SLASHCOMMAND);
-                               } else if (starcommands.InList(s)) {
-                                       sc.ChangeState(SCE_ABAQUS_STARCOMMAND);
-                               } else if (commands.InList(s)) {
-                                       sc.ChangeState(SCE_ABAQUS_COMMAND);
-                               } else if (arguments.InList(s)) {
-                                       sc.ChangeState(SCE_ABAQUS_ARGUMENT);
-                               } else if (functions.InList(s)) {
-                                       sc.ChangeState(SCE_ABAQUS_FUNCTION);
-                               }
-                               sc.SetState(SCE_ABAQUS_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ABAQUS_OPERATOR) {
-                       if (!IsAnOperator(static_cast<char>(sc.ch))) {
-                           sc.SetState(SCE_ABAQUS_DEFAULT);
-                       }
-               }
+       // Things are actually quite simple
+       // we have commentlines
+       // keywordlines and datalines
+       // On a data line there will only be colouring of numbers
+       // a keyword line is constructed as
+       // *word,[ paramname[=paramvalue]]*
+       // if the line ends with a , the keyword line continues onto the new line
 
-               // Determine if a new state should be entered.
-               if (sc.state == SCE_ABAQUS_DEFAULT) {
-                       if (sc.ch == '*' && sc.chNext == '*') {
-                               sc.SetState(SCE_ABAQUS_COMMENTBLOCK);
-                       } else if (sc.ch == '!') {
-                               sc.SetState(SCE_ABAQUS_COMMENT);
-                       } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-                               sc.SetState(SCE_ABAQUS_NUMBER);
-                       } else if (sc.ch == '\'' || sc.ch == '\"') {
-                               sc.SetState(SCE_ABAQUS_STRING);
-                               stringStart = sc.ch;
-                       } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
-                               sc.SetState(SCE_ABAQUS_WORD);
-                       } else if (IsAnOperator(static_cast<char>(sc.ch))) {
-                               sc.SetState(SCE_ABAQUS_OPERATOR);
-                       }
-               }
-       }
-       sc.Complete();
+       for (; sc.More(); sc.Forward()) {
+               switch ( state ) {
+        case KW_LINE_KW :
+            if ( sc.atLineEnd ) {
+                // finished the line in keyword state, switch to LINE_END
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            } else if ( IsAKeywordChar(sc.ch) ) {
+                // nothing changes
+                state = KW_LINE_KW ;
+            } else if ( sc.ch == ',' ) {
+                // Well well we say a comma, arguments *MUST* follow
+                sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                state = KW_LINE_COMMA ;
+            } else {
+                // Flag an error
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            // Done with processing
+            break ;
+        case KW_LINE_COMMA :
+            // acomma on a keywordline was seen
+            if ( IsAKeywordChar(sc.ch)) {
+                sc.SetState(SCE_ABAQUS_ARGUMENT) ;
+                state = KW_LINE_PAR ;
+            } else if ( sc.atLineEnd || (sc.ch == ',') ) {
+                // we remain in keyword mode
+                state = KW_LINE_COMMA ;
+            } else if ( sc.ch == ' ' ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = KW_LINE_COMMA ;
+            } else {
+                // Anything else constitutes an error
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            break ;
+        case KW_LINE_PAR :
+            if ( sc.atLineEnd ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
+                // remain in this state
+                state = KW_LINE_PAR ;
+            } else if ( sc.ch == ',' ) {
+                sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                state = KW_LINE_COMMA ;
+            } else if ( sc.ch == '=' ) {
+                sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                state = KW_LINE_EQ ;
+            } else {
+                // Anything else constitutes an error
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            break ;
+        case KW_LINE_EQ :
+            if ( sc.ch == ' ' ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                // remain in this state
+                state = KW_LINE_EQ ;
+            } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
+                sc.SetState(SCE_ABAQUS_NUMBER) ;
+                state = KW_LINE_VAL ;
+            } else if ( IsAKeywordChar(sc.ch) ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = KW_LINE_VAL ;
+            } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
+                sc.SetState(SCE_ABAQUS_STRING) ;
+                state = KW_LINE_VAL ;
+            } else {
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            break ;
+        case KW_LINE_VAL :
+            if ( sc.atLineEnd ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
+                // nothing changes
+                state = KW_LINE_VAL ;
+            } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
+                    ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
+                    (sc.state == SCE_ABAQUS_NUMBER)) {
+                // remain in number mode
+                state = KW_LINE_VAL ;
+            } else if (sc.state == SCE_ABAQUS_STRING) {
+                // accept everything until a closing quote
+                if ( sc.ch == '\'' || sc.ch == '\"' ) {
+                    sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                    state = KW_LINE_VAL ;
+                }
+            } else if ( sc.ch == ',' ) {
+                sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                state = KW_LINE_COMMA ;
+            } else {
+                // anything else is an error
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            break ;
+        case DAT_LINE_VAL :
+            if ( sc.atLineEnd ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
+                // nothing changes
+                state = DAT_LINE_VAL ;
+            } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
+                    ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
+                    (sc.state == SCE_ABAQUS_NUMBER)) {
+                // remain in number mode
+                state = DAT_LINE_VAL ;
+            } else if (sc.state == SCE_ABAQUS_STRING) {
+                // accept everything until a closing quote
+                if ( sc.ch == '\'' || sc.ch == '\"' ) {
+                    sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                    state = DAT_LINE_VAL ;
+                }
+            } else if ( sc.ch == ',' ) {
+                sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                state = DAT_LINE_COMMA ;
+            } else {
+                // anything else is an error
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            break ;
+        case DAT_LINE_COMMA :
+            // a comma on a data line was seen
+            if ( sc.atLineEnd ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            } else if ( sc.ch == ' ' ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = DAT_LINE_COMMA ;
+            } else if (sc.ch == ',')  {
+                sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                state = DAT_LINE_COMMA ;
+            } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
+                sc.SetState(SCE_ABAQUS_NUMBER) ;
+                state = DAT_LINE_VAL ;
+            } else if ( IsAKeywordChar(sc.ch) ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = DAT_LINE_VAL ;
+            } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
+                sc.SetState(SCE_ABAQUS_STRING) ;
+                state = DAT_LINE_VAL ;
+            } else {
+                sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                state = ST_ERROR ;
+            }
+            break ;
+        case COMMENT_LINE :
+            if ( sc.atLineEnd ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            }
+            break ;
+        case ST_ERROR :
+            if ( sc.atLineEnd ) {
+                sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                state = LINE_END ;
+            }
+            break ;
+        case LINE_END :
+            if ( sc.atLineEnd || sc.ch == ' ' ) {
+                // nothing changes
+                state = LINE_END ;
+            } else if ( sc.ch == '*' ) {
+                if ( sc.chNext == '*' ) {
+                    state = COMMENT_LINE ;
+                    sc.SetState(SCE_ABAQUS_COMMENT) ;
+                } else {
+                    state = KW_LINE_KW ;
+                    sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
+                }
+            } else {
+                // it must be a data line, things are as if we are in DAT_LINE_COMMA
+                if ( sc.ch == ',' ) {
+                    sc.SetState(SCE_ABAQUS_OPERATOR) ;
+                    state = DAT_LINE_COMMA ;
+                } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
+                    sc.SetState(SCE_ABAQUS_NUMBER) ;
+                    state = DAT_LINE_VAL ;
+                } else if ( IsAKeywordChar(sc.ch) ) {
+                    sc.SetState(SCE_ABAQUS_DEFAULT) ;
+                    state = DAT_LINE_VAL ;
+                } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
+                    sc.SetState(SCE_ABAQUS_STRING) ;
+                    state = DAT_LINE_VAL ;
+                } else {
+                    sc.SetState(SCE_ABAQUS_PROCESSOR) ;
+                    state = ST_ERROR ;
+                }
+            }
+            break ;
+                 }
+   }
+   sc.Complete();
 }
 
 //------------------------------------------------------------------------------
@@ -166,85 +313,295 @@ static int LowerCase(int c)
        return c;
 }
 
-static int CheckABAQUSFoldPoint(char const *token, int &level) {
-       if (!strcmp(token, "*step") ||
-               !strcmp(token, "*part") ||
-               !strcmp(token, "*instance") ||
-               !strcmp(token, "*assembly") ||
-               !strcmp(token, "***region") ) {
-               level |= SC_FOLDLEVELHEADERFLAG;
-               return 1;
-       }
-       if (!strcmp(token, "*end step") ||
-               !strcmp(token, "*end part") ||
-               !strcmp(token, "*end instance") ||
-               !strcmp(token, "*end assembly") ||
-               !strcmp(token, "***end region") ) {
-               return -1;
-       }
-       return 0;
+static int LineEnd(int line, Accessor &styler)
+{
+    const int docLines = styler.GetLine(styler.Length() - 1);  // Available last line
+    int eol_pos ;
+    // if the line is the last line, the eol_pos is styler.Length()
+    // eol will contain a new line, or a virtual new line
+    if ( docLines == line )
+        eol_pos = styler.Length() ;
+    else
+        eol_pos = styler.LineStart(line + 1) - 1;
+    return eol_pos ;
+}
+
+static int LineStart(int line, Accessor &styler)
+{
+    return styler.LineStart(line) ;
+}
+
+// LineType
+//
+// bits determines the line type
+// 1  : data line
+// 2  : only whitespace
+// 3  : data line with only whitespace
+// 4  : keyword line
+// 5  : block open keyword line
+// 6  : block close keyword line
+// 7  : keyword line in error
+// 8  : comment line
+static int LineType(int line, Accessor &styler) {
+    int pos = LineStart(line, styler) ;
+    int eol_pos = LineEnd(line, styler) ;
+
+    int c ;
+    char ch = ' ';
+
+    int i = pos ;
+    while ( i < eol_pos ) {
+        c = styler.SafeGetCharAt(i);
+        ch = static_cast<char>(LowerCase(c));
+        // We can say something as soon as no whitespace
+        // was encountered
+        if ( !IsSpace(c) )
+            break ;
+        i++ ;
+    }
+
+    if ( i >= eol_pos ) {
+        // This is a whitespace line, currently
+        // classifies as data line
+        return 3 ;
+    }
+
+    if ( ch != '*' ) {
+        // This is a data line
+        return 1 ;
+    }
+
+    if ( i == eol_pos - 1 ) {
+        // Only a single *, error but make keyword line
+        return 4+3 ;
+    }
+
+    // This means we can have a second character
+    // if that is also a * this means a comment
+    // otherwise it is a keyword.
+    c = styler.SafeGetCharAt(i+1);
+    ch = static_cast<char>(LowerCase(c));
+    if ( ch == '*' ) {
+        return 8 ;
+    }
+
+    // At this point we know this is a keyword line
+    // the character at position i is a *
+    // it is not a comment line
+    char word[256] ;
+    int  wlen = 0;
+
+    word[wlen] = '*' ;
+       wlen++ ;
+
+    i++ ;
+    while ( (i < eol_pos) && (wlen < 255) ) {
+        c = styler.SafeGetCharAt(i);
+        ch = static_cast<char>(LowerCase(c));
+
+        if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
+            break ;
+
+        if ( IsIdentifier(c) ) {
+            word[wlen] = ch ;
+                       wlen++ ;
+               }
+
+        i++ ;
+    }
+
+    word[wlen] = 0 ;
+
+    // Make a comparison
+       if ( !strcmp(word, "*step") ||
+         !strcmp(word, "*part") ||
+         !strcmp(word, "*instance") ||
+         !strcmp(word, "*assembly")) {
+       return 4+1 ;
+    }
+
+       if ( !strcmp(word, "*endstep") ||
+         !strcmp(word, "*endpart") ||
+         !strcmp(word, "*endinstance") ||
+         !strcmp(word, "*endassembly")) {
+       return 4+2 ;
+    }
+
+    return 4 ;
+}
+
+static void SafeSetLevel(int line, int level, Accessor &styler)
+{
+    if ( line < 0 )
+        return ;
+
+    int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
+
+    if ( (level & mask) < 0 )
+        return ;
+
+    if ( styler.LevelAt(line) != level )
+        styler.SetLevel(line, level) ;
 }
 
 static void FoldABAQUSDoc(unsigned int startPos, int length, int,
-       WordList *[], Accessor &styler) {
-
-       int line = styler.GetLine(startPos);
-       int level = styler.LevelAt(line);
-       int go = 0, done = 0;
-       int endPos = startPos + length;
-       char word[256];
-       int wordlen = 0;
-       int i;
-    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-       // Scan for tokens at the start of the line (they may include
-       // whitespace, for tokens like "End Function"
-       for (i = startPos; i < endPos; i++) {
-               int c = styler.SafeGetCharAt(i);
-               if (!done && !go) {
-                       if (wordlen) { // are we scanning a token already?
-                               word[wordlen] = static_cast<char>(LowerCase(c));
-                               if (!IsIdentifier(c)) { // done with token
-                                       word[wordlen] = '\0';
-                                       go = CheckABAQUSFoldPoint(word, level);
-                                       if (!go) {
-                                               // Treat any whitespace as single blank, for
-                                               // things like "End   Function".
-                                               if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
-                                                       word[wordlen] = ' ';
-                                                       if (wordlen < 255)
-                                                               wordlen++;
-                                               }
-                                               else // done with this line
-                                                       done = 1;
-                                       }
-                               } else if (wordlen < 255) {
-                                       wordlen++;
+WordList *[], Accessor &styler) {
+    int startLine = styler.GetLine(startPos) ;
+    int endLine   = styler.GetLine(startPos+length-1) ;
+
+    // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+    // We want to deal with all the cases
+    // To know the correct indentlevel, we need to look back to the
+    // previous command line indentation level
+       // order of formatting keyline datalines commentlines
+    int beginData    = -1 ;
+    int beginComment = -1 ;
+    int prvKeyLine   = startLine ;
+    int prvKeyLineTp =  0 ;
+
+    // Scan until we find the previous keyword line
+    // this will give us the level reference that we need
+    while ( prvKeyLine > 0 ) {
+        prvKeyLine-- ;
+        prvKeyLineTp = LineType(prvKeyLine, styler) ;
+        if ( prvKeyLineTp & 4 )
+            break ;
+    }
+
+    // Determine the base line level of all lines following
+    // the previous keyword
+    // new keyword lines are placed on this level
+    //if ( prvKeyLineTp & 4 ) {
+    int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
+    //}
+
+    // uncomment line below if weird behaviour continues
+    prvKeyLine = -1 ;
+
+    // Now start scanning over the lines.
+    for ( int line = startLine; line <= endLine; line++ ) {
+        int lineType = LineType(line, styler) ;
+
+        // Check for comment line
+        if ( lineType == 8 ) {
+            if ( beginComment < 0 ) {
+                beginComment = line ;
+                       }
+        }
+
+        // Check for data line
+        if ( (lineType == 1) || (lineType == 3) ) {
+            if ( beginData < 0 ) {
+                if ( beginComment >= 0 ) {
+                    beginData = beginComment ;
+                } else {
+                    beginData = line ;
+                }
+            }
+                       beginComment = -1 ;
+               }
+
+        // Check for keywordline.
+        // As soon as a keyword line is encountered, we can set the
+        // levels of everything from the previous keyword line to this one
+        if ( lineType & 4 ) {
+            // this is a keyword, we can now place the previous keyword
+            // all its data lines and the remainder
+
+            // Write comments and data line
+            if ( beginComment < 0 ) {
+                beginComment = line ;
+                       }
+
+            if ( beginData < 0 ) {
+                beginData = beginComment ;
+                               if ( prvKeyLineTp != 5 )
+                                       SafeSetLevel(prvKeyLine, level, styler) ;
+                               else
+                                       SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+            } else {
+                SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+            }
+
+            int datLevel = level + 1 ;
+                       if ( !(prvKeyLineTp & 4) ) {
+                               datLevel = level ;
+                       }
+
+            for ( int ll = beginData; ll < beginComment; ll++ )
+                SafeSetLevel(ll, datLevel, styler) ;
+
+            // The keyword we just found is going to be written at another level
+            // if we have a type 5 and type 6
+            if ( prvKeyLineTp == 5 ) {
+                level += 1 ;
+                       }
+
+            if ( prvKeyLineTp == 6 ) {
+                level -= 1 ;
+                               if ( level < 0 ) {
+                                       level = 0 ;
                                }
-                       } else { // start scanning at first non-whitespace character
-                               if (!IsSpace(c)) {
-                                       if (IsIdentifier(c)) {
-                                               word[0] = static_cast<char>(LowerCase(c));
-                                               wordlen = 1;
-                                       } else // done with this line
-                                               done = 1;
+            }
+
+            for ( int lll = beginComment; lll < line; lll++ )
+                SafeSetLevel(lll, level, styler) ;
+
+            // wrap and reset
+            beginComment = -1 ;
+            beginData    = -1 ;
+            prvKeyLine   = line ;
+            prvKeyLineTp = lineType ;
+        }
+
+    }
+
+    if ( beginComment < 0 ) {
+        beginComment = endLine + 1 ;
+    } else {
+        // We need to find out whether this comment block is followed by
+        // a data line or a keyword line
+        const int docLines = styler.GetLine(styler.Length() - 1);
+
+        for ( int line = endLine + 1; line <= docLines; line++ ) {
+            int lineType = LineType(line, styler) ;
+
+            if ( lineType != 8 ) {
+                               if ( !(lineType & 4) )  {
+                                       beginComment = endLine + 1 ;
                                }
+                break ;
                        }
-               }
-               if (c == '\n') { // line end
-                       if (!done && wordlen == 0 && foldCompact) // line was only space
-                               level |= SC_FOLDLEVELWHITEFLAG;
-                       if (level != styler.LevelAt(line))
-                               styler.SetLevel(line, level);
-                       level += go;
-                       line++;
-                       // reset state
-                       wordlen = 0;
-                       level &= ~SC_FOLDLEVELHEADERFLAG;
-                       level &= ~SC_FOLDLEVELWHITEFLAG;
-                       go = 0;
-                       done = 0;
-               }
+        }
+    }
+
+    if ( beginData < 0 ) {
+        beginData = beginComment ;
+               if ( prvKeyLineTp != 5 )
+                       SafeSetLevel(prvKeyLine, level, styler) ;
+               else
+                       SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+    } else {
+        SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
+    }
+
+    int datLevel = level + 1 ;
+       if ( !(prvKeyLineTp & 4) ) {
+               datLevel = level ;
+       }
+
+    for ( int ll = beginData; ll < beginComment; ll++ )
+        SafeSetLevel(ll, datLevel, styler) ;
+
+       if ( prvKeyLineTp == 5 ) {
+               level += 1 ;
+       }
+
+       if ( prvKeyLineTp == 6 ) {
+               level -= 1 ;
        }
+       for ( int m = beginComment; m <= endLine; m++ )
+        SafeSetLevel(m, level, styler) ;
 }
 
 static const char * const abaqusWordListDesc[] = {
index f6c9e7ee7a853ce08b70b6f2489dcbd3d55b9234..654bfbebad504bffbd1326e7fd3644ef1f1416fd 100644 (file)
@@ -10,6 +10,8 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <string>
+
 #include "Platform.h"
 
 #include "Accessor.h"
@@ -17,7 +19,6 @@
 #include "PropSet.h"
 #include "KeyWords.h"
 #include "SciLexer.h"
-#include "SString.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -62,8 +63,8 @@ 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 bool IsValidIdentifier(const std::string& identifier);
+static bool IsValidNumber(const std::string& number);
 static inline bool IsWordStartCharacter(int ch);
 static inline bool IsWordCharacter(int ch);
 
@@ -117,7 +118,7 @@ static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostroph
        sc.Forward();
        sc.Forward();
 
-       SString identifier;
+       std::string identifier;
 
        while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
                identifier += static_cast<char>(tolower(sc.ch));
@@ -144,7 +145,7 @@ static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostroph
 static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
        apostropheStartsAttribute = true;
 
-       SString number;
+       std::string number;
        sc.SetState(SCE_ADA_NUMBER);
 
        // Get all characters up to a delimiter or a separator, including points, but excluding
@@ -192,7 +193,7 @@ static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostrophe
        apostropheStartsAttribute = true;
        sc.SetState(SCE_ADA_IDENTIFIER);
 
-       SString word;
+       std::string word;
 
        while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
                word += static_cast<char>(tolower(sc.ch));
@@ -321,7 +322,7 @@ static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
        return IsASpace(ch) || IsDelimiterCharacter(ch);
 }
 
-static bool IsValidIdentifier(const SString& identifier) {
+static bool IsValidIdentifier(const std::string& identifier) {
        // First character can't be '_', so initialize the flag to true
        bool lastWasUnderscore = true;
 
@@ -355,8 +356,8 @@ static bool IsValidIdentifier(const SString& identifier) {
        return true;
 }
 
-static bool IsValidNumber(const SString& number) {
-       int hashPos = number.search("#");
+static bool IsValidNumber(const std::string& number) {
+       size_t hashPos = number.find("#");
        bool seenDot = false;
 
        size_t i = 0;
@@ -366,7 +367,7 @@ static bool IsValidNumber(const SString& number) {
                return false; // Just in case
 
        // Decimal number
-       if (hashPos == -1) {
+       if (hashPos == std::string::npos) {
                bool canBeSpecial = false;
 
                for (; i < length; i++) {
index 9dd4df45653256418f273c405b4f41a5ebde4737..17c938420a043e80c0f2bccef6333edaaae5ab88 100644 (file)
@@ -37,8 +37,8 @@ static inline bool IsAWordStart(const int ch) {
                ch == '%' || ch == '@' || ch == '$' || ch == '?');
 }
 
-static inline bool IsAsmOperator(char ch) {
-       if (isalnum(ch))
+static inline bool IsAsmOperator(const int ch) {
+       if ((ch < 0x80) && (isalnum(ch)))
                return false;
        // '.' left out as it is used to make up numbers
        if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
@@ -89,7 +89,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
 
                // Determine if the current state should terminate.
                if (sc.state == SCE_ASM_OPERATOR) {
-                       if (!IsAsmOperator(static_cast<char>(sc.ch))) {
+                       if (!IsAsmOperator(sc.ch)) {
                            sc.SetState(SCE_ASM_DEFAULT);
                        }
                }else if (sc.state == SCE_ASM_NUMBER) {
@@ -149,7 +149,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
                if (sc.state == SCE_ASM_DEFAULT) {
                        if (sc.ch == ';'){
                                sc.SetState(SCE_ASM_COMMENT);
-                       } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+                       } else if (isascii(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && isascii(sc.chNext) && isdigit(sc.chNext)))) {
                                sc.SetState(SCE_ASM_NUMBER);
                        } else if (IsAWordStart(sc.ch)) {
                                sc.SetState(SCE_ASM_IDENTIFIER);
@@ -157,7 +157,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
                                sc.SetState(SCE_ASM_STRING);
                        } else if (sc.ch == '\'') {
                                sc.SetState(SCE_ASM_CHARACTER);
-                       } else if (IsAsmOperator(static_cast<char>(sc.ch))) {
+                       } else if (IsAsmOperator(sc.ch)) {
                                sc.SetState(SCE_ASM_OPERATOR);
                        }
                }
index f0376b9474b010b093a0cb637da72b2f2e208898..5801278becb9f7d5f7860f62fb230b368c3aab5c 100644 (file)
@@ -2,8 +2,8 @@
 /** @file LexBash.cxx
  ** Lexer for Bash.
  **/
-// Copyright 2004-2007 by Neil Hodgson <neilh@scintilla.org>
-// Adapted from LexPerl by Kein-Hong Man <mkh@pl.jaring.my> 2004
+// Copyright 2004-2008 by Neil Hodgson <neilh@scintilla.org>
+// Adapted from LexPerl by Kein-Hong Man 2004
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 
 #include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#define HERE_DELIM_MAX 256
 
 // define this if you want 'invalid octals' to be marked as errors
 // usually, this is not a good idea, permissive lexing is better
 #define BASH_BASE_OCTAL_ERROR  69
 #endif
 
-#define HERE_DELIM_MAX 256
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static inline int translateBashDigit(char ch) {
+static inline int translateBashDigit(int ch) {
        if (ch >= '0' && ch <= '9') {
                return ch - '0';
        } else if (ch >= 'a' && ch <= 'z') {
@@ -53,407 +55,210 @@ static inline int translateBashDigit(char ch) {
        return BASH_BASE_ERROR;
 }
 
-static inline bool isEOLChar(char ch) {
-       return (ch == '\r') || (ch == '\n');
-}
-
-static bool isSingleCharOp(char ch) {
-       char strCharSet[2];
-       strCharSet[0] = ch;
-       strCharSet[1] = '\0';
-       return (NULL != strstr("rwxoRWXOezsfdlpSbctugkTBMACahGLNn", strCharSet));
-}
-
-static inline bool isBashOperator(char ch) {
-       if (ch == '^' || ch == '&' || ch == '\\' || ch == '%' ||
-               ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
-               ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
-               ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
-               ch == '>' || ch == ',' || ch == '/' || ch == '<' ||
-               ch == '?' || ch == '!' || ch == '.' || ch == '~' ||
-               ch == '@')
-               return true;
-       return false;
-}
-
-static int classifyWordBash(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
-       char s[100];
-       for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
-               s[i] = styler[start + i];
-               s[i + 1] = '\0';
-       }
-       char chAttr = SCE_SH_IDENTIFIER;
-       if (keywords.InList(s))
-               chAttr = SCE_SH_WORD;
-       styler.ColourTo(end, chAttr);
-       return chAttr;
-}
-
-static inline int getBashNumberBase(unsigned int start, unsigned int end, Accessor &styler) {
+static inline int getBashNumberBase(char *s) {
+       int i = 0;
        int base = 0;
-       for (unsigned int i = 0; i < end - start + 1 && i < 10; i++) {
-               base = base * 10 + (styler[start + i] - '0');
+       while (*s) {
+               base = base * 10 + (*s++ - '0');
+               i++;
        }
-       if (base > 64 || (end - start) > 1) {
+       if (base > 64 || i > 2) {
                return BASH_BASE_ERROR;
        }
        return base;
 }
 
-static inline bool isEndVar(char ch) {
-       return !isalnum(ch) && ch != '$' && ch != '_';
-}
-
-static inline bool isNonQuote(char ch) {
-       return isalnum(ch) || ch == '_';
-}
-
-static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
-       if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
-               return false;
-       }
-       while (*val) {
-               if (*val != styler[pos++]) {
-                       return false;
-               }
-               val++;
-       }
-       return true;
-}
-
-static char opposite(char ch) {
-       if (ch == '(')
-               return ')';
-       if (ch == '[')
-               return ']';
-       if (ch == '{')
-               return '}';
-       if (ch == '<')
-               return '>';
+static int opposite(int ch) {
+       if (ch == '(') return ')';
+       if (ch == '[') return ']';
+       if (ch == '{') return '}';
+       if (ch == '<') return '>';
        return ch;
 }
 
 static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
-                             WordList *keywordlists[], Accessor &styler) {
-
-       // Lexer for bash often has to backtrack to start of current style to determine
-       // which characters are being used as quotes, how deeply nested is the
-       // start position and what the termination string is for here documents
+                                                        WordList *keywordlists[], Accessor &styler) {
 
        WordList &keywords = *keywordlists[0];
 
-       class HereDocCls {
+       CharacterSet setWordStart(CharacterSet::setAlpha, "_");
+       // note that [+-] are often parts of identifiers in shell scripts
+       CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
+       CharacterSet setBashOperator(CharacterSet::setNone, "^&\\%()-+=|{}[]:;>,*/<?!.~@");
+       CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
+       CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
+       CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
+       CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!");
+       CharacterSet setLeftShift(CharacterSet::setDigits, "=$");
+
+       class HereDocCls {      // Class to manage HERE document elements
        public:
                int State;              // 0: '<<' encountered
                // 1: collect the delimiter
                // 2: here doc text (lines after the delimiter)
-               char Quote;             // the char after '<<'
+               int Quote;              // the char after '<<'
                bool Quoted;            // true if Quote in ('\'','"','`')
                bool Indent;            // indented delimiter (for <<-)
                int DelimiterLength;    // strlen(Delimiter)
                char *Delimiter;        // the Delimiter, 256: sizeof PL_tokenbuf
                HereDocCls() {
                        State = 0;
-            Quote = 0;
-            Quoted = false;
-            Indent = 0;
+                       Quote = 0;
+                       Quoted = false;
+                       Indent = 0;
                        DelimiterLength = 0;
                        Delimiter = new char[HERE_DELIM_MAX];
                        Delimiter[0] = '\0';
                }
+               void Append(int ch) {
+                       Delimiter[DelimiterLength++] = static_cast<char>(ch);
+                       Delimiter[DelimiterLength] = '\0';
+               }
                ~HereDocCls() {
                        delete []Delimiter;
                }
        };
        HereDocCls HereDoc;
 
-       class QuoteCls {
+       class QuoteCls {        // Class to manage quote pairs (simplified vs LexPerl)
                public:
-               int  Rep;
-               int  Count;
-               char Up;
-               char Down;
+               int Count;
+               int Up, Down;
                QuoteCls() {
-                       this->New(1);
-               }
-               void New(int r) {
-                       Rep   = r;
                        Count = 0;
                        Up    = '\0';
                        Down  = '\0';
                }
-               void Open(char u) {
+               void Open(int u) {
                        Count++;
                        Up    = u;
                        Down  = opposite(Up);
                }
+               void Start(int u) {
+                       Count = 0;
+                       Open(u);
+               }
        };
        QuoteCls Quote;
 
-       int state = initStyle;
        int numBase = 0;
-       unsigned int lengthDoc = startPos + length;
+       int digit;
+       unsigned int endPos = startPos + length;
 
-       // If in a long distance lexical state, seek to the beginning to find quote characters
-       // Bash strings can be multi-line with embedded newlines, so backtrack.
-       // Bash numbers have additional state during lexing, so backtrack too.
-       if (state == SCE_SH_HERE_Q) {
+       // Backtrack to beginning of style if required...
+       // If in a long distance lexical state, backtrack to find quote characters
+       if (initStyle == SCE_SH_HERE_Q) {
                while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_SH_HERE_DELIM)) {
                        startPos--;
                }
                startPos = styler.LineStart(styler.GetLine(startPos));
-               state = styler.StyleAt(startPos - 1);
+               initStyle = styler.StyleAt(startPos - 1);
        }
-       if (state == SCE_SH_STRING
-        || state == SCE_SH_BACKTICKS
-        || state == SCE_SH_CHARACTER
-        || state == SCE_SH_NUMBER
-        || state == SCE_SH_IDENTIFIER
-        || state == SCE_SH_COMMENTLINE
-       ) {
-               while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) {
+       // Bash strings can be multi-line with embedded newlines, so backtrack.
+       // Bash numbers have additional state during lexing, so backtrack too.
+       if (initStyle == SCE_SH_STRING
+        || initStyle == SCE_SH_BACKTICKS
+        || initStyle == SCE_SH_CHARACTER
+        || initStyle == SCE_SH_NUMBER
+        || initStyle == SCE_SH_IDENTIFIER
+        || initStyle == SCE_SH_COMMENTLINE) {
+               while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
                        startPos--;
                }
-               state = SCE_SH_DEFAULT;
+               initStyle = SCE_SH_DEFAULT;
        }
 
-       styler.StartAt(startPos);
-       char chPrev = styler.SafeGetCharAt(startPos - 1);
-       if (startPos == 0)
-               chPrev = '\n';
-       char chNext = styler[startPos];
-       styler.StartSegment(startPos);
-
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
-               // if the current character is not consumed due to the completion of an
-               // earlier style, lexing can be restarted via a simple goto
-       restartLexer:
-               chNext = styler.SafeGetCharAt(i + 1);
-               char chNext2 = styler.SafeGetCharAt(i + 2);
-
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       chPrev = ' ';
-                       i += 1;
-                       continue;
-               }
-
-               if ((chPrev == '\r' && ch == '\n')) {   // skip on DOS/Windows
-                       styler.ColourTo(i, state);
-                       chPrev = ch;
-                       continue;
-               }
-
-               if (HereDoc.State == 1 && isEOLChar(ch)) {
-                       // Begin of here-doc (the line after the here-doc delimiter):
-                       // Lexically, the here-doc starts from the next line after the >>, but the
-                       // first line of here-doc seem to follow the style of the last EOL sequence
-                       HereDoc.State = 2;
-                       if (HereDoc.Quoted) {
-                               if (state == SCE_SH_HERE_DELIM) {
-                                       // Missing quote at end of string! We are stricter than bash.
-                                       // Colour here-doc anyway while marking this bit as an error.
-                                       state = SCE_SH_ERROR;
-                               }
-                               styler.ColourTo(i - 1, state);
-                               // HereDoc.Quote always == '\''
-                               state = SCE_SH_HERE_Q;
-                       } else {
-                               styler.ColourTo(i - 1, state);
-                               // always switch
-                               state = SCE_SH_HERE_Q;
-                       }
-               }
-
-               if (state == SCE_SH_DEFAULT) {
-                       if (ch == '\\') {       // escaped character
-                               if (i < lengthDoc - 1)
-                                       i++;
-                               ch = chNext;
-                               chNext = chNext2;
-                               styler.ColourTo(i, SCE_SH_IDENTIFIER);
-                       } else if (isdigit(ch)) {
-                               state = SCE_SH_NUMBER;
-                               numBase = BASH_BASE_DECIMAL;
-                               if (ch == '0') {        // hex,octal
-                                       if (chNext == 'x' || chNext == 'X') {
-                                               numBase = BASH_BASE_HEX;
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
-                                       } else if (isdigit(chNext)) {
-#ifdef PEDANTIC_OCTAL
-                                               numBase = BASH_BASE_OCTAL;
-#else
-                                               numBase = BASH_BASE_HEX;
-#endif
+       StyleContext sc(startPos, endPos - startPos, initStyle, styler);
+
+       for (; sc.More(); sc.Forward()) {
+
+               // Determine if the current state should terminate.
+               switch (sc.state) {
+                       case SCE_SH_OPERATOR:
+                               sc.SetState(SCE_SH_DEFAULT);
+                               break;
+                       case SCE_SH_WORD:
+                               // "." never used in Bash variable names but used in file names
+                               if (!setWord.Contains(sc.ch)) {
+                                       char s[1000];
+                                       sc.GetCurrent(s, sizeof(s));
+                                       if (s[0] != '-' &&      // for file operators
+                                               !keywords.InList(s)) {
+                                               sc.ChangeState(SCE_SH_IDENTIFIER);
                                        }
+                                       sc.SetState(SCE_SH_DEFAULT);
                                }
-                       } else if (iswordstart(ch)) {
-                               state = SCE_SH_WORD;
-                               if (!iswordchar(chNext) && chNext != '+' && chNext != '-') {
-                                       // We need that if length of word == 1!
-                                       // This test is copied from the SCE_SH_WORD handler.
-                                       classifyWordBash(styler.GetStartSegment(), i, keywords, styler);
-                                       state = SCE_SH_DEFAULT;
+                               break;
+                       case SCE_SH_IDENTIFIER:
+                               if (sc.chPrev == '\\') {        // for escaped chars
+                                       sc.ForwardSetState(SCE_SH_DEFAULT);
+                               } else if (!setWord.Contains(sc.ch)) {
+                                       sc.SetState(SCE_SH_DEFAULT);
                                }
-                       } else if (ch == '#') {
-                               state = SCE_SH_COMMENTLINE;
-                       } else if (ch == '\"') {
-                               state = SCE_SH_STRING;
-                               Quote.New(1);
-                               Quote.Open(ch);
-                       } else if (ch == '\'') {
-                               state = SCE_SH_CHARACTER;
-                               Quote.New(1);
-                               Quote.Open(ch);
-                       } else if (ch == '`') {
-                               state = SCE_SH_BACKTICKS;
-                               Quote.New(1);
-                               Quote.Open(ch);
-                       } else if (ch == '$') {
-                               if (chNext == '{') {
-                                       state = SCE_SH_PARAM;
-                                       goto startQuote;
-                               } else if (chNext == '\'') {
-                                       state = SCE_SH_CHARACTER;
-                                       goto startQuote;
-                               } else if (chNext == '"') {
-                                       state = SCE_SH_STRING;
-                                       goto startQuote;
-                               } else if (chNext == '(' && chNext2 == '(') {
-                                       styler.ColourTo(i, SCE_SH_OPERATOR);
-                                       state = SCE_SH_DEFAULT;
-                                       goto skipChar;
-                               } else if (chNext == '(' || chNext == '`') {
-                                       state = SCE_SH_BACKTICKS;
-                               startQuote:
-                                       Quote.New(1);
-                                       Quote.Open(chNext);
-                                       goto skipChar;
-                               } else {
-                                       state = SCE_SH_SCALAR;
-                               skipChar:
-                                       i++;
-                                       ch = chNext;
-                                       chNext = chNext2;
-                               }
-                       } else if (ch == '*') {
-                               if (chNext == '*') {    // exponentiation
-                                       i++;
-                                       ch = chNext;
-                                       chNext = chNext2;
-                               }
-                               styler.ColourTo(i, SCE_SH_OPERATOR);
-                       } else if (ch == '<' && chNext == '<') {
-                               state = SCE_SH_HERE_DELIM;
-                               HereDoc.State = 0;
-                               HereDoc.Indent = false;
-                       } else if (ch == '-'    // file test operators
-                                  && isSingleCharOp(chNext)
-                                  && !isalnum((chNext2 = styler.SafeGetCharAt(i+2)))
-                                  && isspace(chPrev)) {
-                               styler.ColourTo(i + 1, SCE_SH_WORD);
-                               state = SCE_SH_DEFAULT;
-                               i++;
-                               ch = chNext;
-                               chNext = chNext2;
-                       } else if (isBashOperator(ch)) {
-                               styler.ColourTo(i, SCE_SH_OPERATOR);
-                       } else {
-                               // keep colouring defaults to make restart easier
-                               styler.ColourTo(i, SCE_SH_DEFAULT);
-                       }
-               } else if (state == SCE_SH_NUMBER) {
-                       int digit = translateBashDigit(ch);
-                       if (numBase == BASH_BASE_DECIMAL) {
-                               if (ch == '#') {
-                                       numBase = getBashNumberBase(styler.GetStartSegment(), i - 1, styler);
-                                       if (numBase == BASH_BASE_ERROR) // take the rest as comment
-                                               goto numAtEnd;
-                               } else if (!isdigit(ch))
-                                       goto numAtEnd;
-                       } else if (numBase == BASH_BASE_HEX) {
-                               if ((digit < 16) || (digit >= 36 && digit <= 41)) {
-                                       // hex digit 0-9a-fA-F
-                               } else
-                                       goto numAtEnd;
+                               break;
+                       case SCE_SH_NUMBER:
+                               digit = translateBashDigit(sc.ch);
+                               if (numBase == BASH_BASE_DECIMAL) {
+                                       if (sc.ch == '#') {
+                                               char s[10];
+                                               sc.GetCurrent(s, sizeof(s));
+                                               numBase = getBashNumberBase(s);
+                                               if (numBase != BASH_BASE_ERROR)
+                                                       break;
+                                       } else if (IsADigit(sc.ch))
+                                               break;
+                               } else if (numBase == BASH_BASE_HEX) {
+                                       if (IsADigit(sc.ch, 16))
+                                               break;
 #ifdef PEDANTIC_OCTAL
-                       } else if (numBase == BASH_BASE_OCTAL ||
-                                  numBase == BASH_BASE_OCTAL_ERROR) {
-                               if (digit > 7) {
+                               } else if (numBase == BASH_BASE_OCTAL ||
+                                                  numBase == BASH_BASE_OCTAL_ERROR) {
+                                       if (digit <= 7)
+                                               break;
                                        if (digit <= 9) {
-                                                numBase = BASH_BASE_OCTAL_ERROR;
-                                       } else
-                                               goto numAtEnd;
-                               }
-#endif
-                       } else if (numBase == BASH_BASE_ERROR) {
-                               if (digit > 9)
-                                       goto numAtEnd;
-                       } else {        // DD#DDDD number style handling
-                               if (digit != BASH_BASE_ERROR) {
-                                       if (numBase <= 36) {
-                                               // case-insensitive if base<=36
-                                               if (digit >= 36) digit -= 26;
+                                               numBase = BASH_BASE_OCTAL_ERROR;
+                                               break;
                                        }
-                                       if (digit >= numBase) {
+#endif
+                               } else if (numBase == BASH_BASE_ERROR) {
+                                       if (digit <= 9)
+                                               break;
+                               } else {        // DD#DDDD number style handling
+                                       if (digit != BASH_BASE_ERROR) {
+                                               if (numBase <= 36) {
+                                                       // case-insensitive if base<=36
+                                                       if (digit >= 36) digit -= 26;
+                                               }
+                                               if (digit < numBase)
+                                                       break;
                                                if (digit <= 9) {
                                                        numBase = BASH_BASE_ERROR;
-                                               } else
-                                                       goto numAtEnd;
+                                                       break;
+                                               }
                                        }
-                               } else {
-                       numAtEnd:
-                                       if (numBase == BASH_BASE_ERROR
+                               }
+                               // fallthrough when number is at an end or error
+                               if (numBase == BASH_BASE_ERROR
 #ifdef PEDANTIC_OCTAL
-                                           || numBase == BASH_BASE_OCTAL_ERROR
+                                       || numBase == BASH_BASE_OCTAL_ERROR
 #endif
-                                           )
-                                               state = SCE_SH_ERROR;
-                                       styler.ColourTo(i - 1, state);
-                                       state = SCE_SH_DEFAULT;
-                                       goto restartLexer;
+                               ) {
+                                       sc.ChangeState(SCE_SH_ERROR);
                                }
-                       }
-               } else if (state == SCE_SH_WORD) {
-                       if (!iswordchar(chNext) && chNext != '+' && chNext != '-') {
-                               // "." never used in Bash variable names
-                               // but used in file names
-                               classifyWordBash(styler.GetStartSegment(), i, keywords, styler);
-                               state = SCE_SH_DEFAULT;
-                               ch = ' ';
-                       }
-               } else if (state == SCE_SH_IDENTIFIER) {
-                       if (!iswordchar(chNext) && chNext != '+' && chNext != '-') {
-                               styler.ColourTo(i, SCE_SH_IDENTIFIER);
-                               state = SCE_SH_DEFAULT;
-                               ch = ' ';
-                       }
-               } else {
-                       if (state == SCE_SH_COMMENTLINE) {
-                               if (ch == '\\' && isEOLChar(chNext)) {
+                               sc.SetState(SCE_SH_DEFAULT);
+                               break;
+                       case SCE_SH_COMMENTLINE:
+                               if (sc.ch == '\\' && (sc.chNext == '\r' || sc.chNext == '\n')) {
                                        // comment continuation
-                                       if (chNext == '\r' && chNext2 == '\n') {
-                                               i += 2;
-                                               ch = styler.SafeGetCharAt(i);
-                                               chNext = styler.SafeGetCharAt(i + 1);
-                                       } else {
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
+                                       sc.Forward();
+                                       if (sc.ch == '\r' && sc.chNext == '\n') {
+                                               sc.Forward();
                                        }
-                               } else if (isEOLChar(ch)) {
-                                       styler.ColourTo(i - 1, state);
-                                       state = SCE_SH_DEFAULT;
-                                       goto restartLexer;
-                               } else if (isEOLChar(chNext)) {
-                                       styler.ColourTo(i, state);
-                                       state = SCE_SH_DEFAULT;
+                               } else if (sc.atLineEnd) {
+                                       sc.ForwardSetState(SCE_SH_DEFAULT);
                                }
-                       } else if (state == SCE_SH_HERE_DELIM) {
-                               //
+                               break;
+                       case SCE_SH_HERE_DELIM:
                                // From Bash info:
                                // ---------------
                                // Specifier format is: <<[-]WORD
@@ -461,150 +266,198 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
                                // Whitespace acceptable after <<[-] operator
                                //
                                if (HereDoc.State == 0) { // '<<' encountered
-                                       HereDoc.State = 1;
-                                       HereDoc.Quote = chNext;
+                                       HereDoc.Quote = sc.chNext;
                                        HereDoc.Quoted = false;
                                        HereDoc.DelimiterLength = 0;
                                        HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
-                                       if (chNext == '\'' || chNext == '\"') { // a quoted here-doc delimiter (' or ")
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
+                                       if (sc.chNext == '\'' || sc.chNext == '\"') {   // a quoted here-doc delimiter (' or ")
+                                               sc.Forward();
                                                HereDoc.Quoted = true;
-                                       } else if (!HereDoc.Indent && chNext == '-') {  // <<- indent case
+                                               HereDoc.State = 1;
+                                       } else if (!HereDoc.Indent && sc.chNext == '-') {       // <<- indent case
                                                HereDoc.Indent = true;
-                                               HereDoc.State = 0;
-                                       } else if (isalpha(chNext) || chNext == '_' || chNext == '\\'
-                                               || chNext == '-' || chNext == '+' || chNext == '!') {
+                                       } else if (setHereDoc.Contains(sc.chNext)) {
                                                // an unquoted here-doc delimiter, no special handling
-                        // TODO check what exactly bash considers part of the delim
-                                       } else if (chNext == '<') {     // HERE string <<<
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
-                                               styler.ColourTo(i, SCE_SH_HERE_DELIM);
-                                               state = SCE_SH_DEFAULT;
-                                               HereDoc.State = 0;
-                                       } else if (isspacechar(chNext)) {
+                                               // TODO check what exactly bash considers part of the delim
+                                               HereDoc.State = 1;
+                                       } else if (sc.chNext == '<') {  // HERE string <<<
+                                               sc.Forward();
+                                               sc.ForwardSetState(SCE_SH_DEFAULT);
+                                       } else if (IsASpace(sc.chNext)) {
                                                // eat whitespace
-                                               HereDoc.State = 0;
-                                       } else if (isdigit(chNext) || chNext == '=' || chNext == '$') {
+                                       } else if (setLeftShift.Contains(sc.chNext)) {
                                                // left shift << or <<= operator cases
-                                               styler.ColourTo(i, SCE_SH_OPERATOR);
-                                               state = SCE_SH_DEFAULT;
-                                               HereDoc.State = 0;
+                                               sc.ChangeState(SCE_SH_OPERATOR);
+                                               sc.ForwardSetState(SCE_SH_DEFAULT);
                                        } else {
                                                // symbols terminates; deprecated zero-length delimiter
+                                               HereDoc.State = 1;
                                        }
                                } else if (HereDoc.State == 1) { // collect the delimiter
                                        if (HereDoc.Quoted) { // a quoted here-doc delimiter
-                                               if (ch == HereDoc.Quote) { // closing quote => end of delimiter
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_SH_DEFAULT;
+                                               if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
+                                                       sc.ForwardSetState(SCE_SH_DEFAULT);
                                                } else {
-                                                       if (ch == '\\' && chNext == HereDoc.Quote) { // escaped quote
-                                                               i++;
-                                                               ch = chNext;
-                                                               chNext = chNext2;
+                                                       if (sc.ch == '\\' && sc.chNext == HereDoc.Quote) { // escaped quote
+                                                               sc.Forward();
                                                        }
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+                                                       HereDoc.Append(sc.ch);
                                                }
                                        } else { // an unquoted here-doc delimiter
-                                               if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+' || ch == '!') {
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
-                                               } else if (ch == '\\') {
+                                               if (setHereDoc2.Contains(sc.ch)) {
+                                                       HereDoc.Append(sc.ch);
+                                               } else if (sc.ch == '\\') {
                                                        // skip escape prefix
                                                } else {
-                                                       styler.ColourTo(i - 1, state);
-                                                       state = SCE_SH_DEFAULT;
-                                                       goto restartLexer;
+                                                       sc.SetState(SCE_SH_DEFAULT);
                                                }
                                        }
-                                       if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_SH_ERROR;
-                                               goto restartLexer;
+                                       if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {    // force blowup
+                                               sc.SetState(SCE_SH_ERROR);
+                                               HereDoc.State = 0;
                                        }
                                }
-                       } else if (HereDoc.State == 2) {
-                               // state == SCE_SH_HERE_Q
-                               if (isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
-                                       if (!HereDoc.Indent && isEOLChar(chPrev)) {
-                                       endHereDoc:
-                                               // standard HERE delimiter
-                                               i += HereDoc.DelimiterLength;
-                                               chPrev = styler.SafeGetCharAt(i - 1);
-                                               ch = styler.SafeGetCharAt(i);
-                                               if (isEOLChar(ch)) {
-                                                       styler.ColourTo(i - 1, state);
-                                                       state = SCE_SH_DEFAULT;
-                                                       HereDoc.State = 0;
-                                                       goto restartLexer;
-                                               }
-                                               chNext = styler.SafeGetCharAt(i + 1);
-                                       } else if (HereDoc.Indent) {
-                                               // indented HERE delimiter
-                                               unsigned int bk = (i > 0)? i - 1: 0;
-                                               while (i > 0) {
-                                                       ch = styler.SafeGetCharAt(bk--);
-                                                       if (isEOLChar(ch)) {
-                                                               goto endHereDoc;
-                                                       } else if (!isspacechar(ch)) {
-                                                               break;  // got leading non-whitespace
-                                                       }
+                               break;
+                       case SCE_SH_HERE_Q:
+                               // HereDoc.State == 2
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_SH_HERE_Q);
+                                       int prefixws = 0;
+                                       while (IsASpace(sc.ch) && !sc.atLineEnd) {      // whitespace prefix
+                                               sc.Forward();
+                                               prefixws++;
+                                       }
+                                       if (prefixws > 0)
+                                               sc.SetState(SCE_SH_HERE_Q);
+                                       while (!sc.atLineEnd) {
+                                               sc.Forward();
+                                       }
+                                       char s[HERE_DELIM_MAX];
+                                       sc.GetCurrent(s, sizeof(s));
+                                       if (sc.LengthCurrent() == 0)
+                                               break;
+                                       if (s[strlen(s) - 1] == '\r')
+                                               s[strlen(s) - 1] = '\0';
+                                       if (strcmp(HereDoc.Delimiter, s) == 0) {
+                                               if ((prefixws > 0 && HereDoc.Indent) || // indentation rule
+                                                       (prefixws == 0 && !HereDoc.Indent)) {
+                                                       sc.SetState(SCE_SH_DEFAULT);
+                                                       break;
                                                }
                                        }
                                }
-                       } else if (state == SCE_SH_SCALAR) {    // variable names
-                               if (isEndVar(ch)) {
-                                       if ((state == SCE_SH_SCALAR)
-                                           && i == (styler.GetStartSegment() + 1)) {
+                               break;
+                       case SCE_SH_SCALAR:     // variable names
+                               if (!setParam.Contains(sc.ch)) {
+                                       if (sc.LengthCurrent() == 1) {
                                                // Special variable: $(, $_ etc.
-                                               styler.ColourTo(i, state);
-                                               state = SCE_SH_DEFAULT;
+                                               sc.ForwardSetState(SCE_SH_DEFAULT);
                                        } else {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_SH_DEFAULT;
-                                               goto restartLexer;
+                                               sc.SetState(SCE_SH_DEFAULT);
                                        }
                                }
-                       } else if (state == SCE_SH_STRING
-                               || state == SCE_SH_CHARACTER
-                               || state == SCE_SH_BACKTICKS
-                               || state == SCE_SH_PARAM
-                               ) {
-                               if (!Quote.Down && !isspacechar(ch)) {
-                                       Quote.Open(ch);
-                               } else if (ch == '\\' && Quote.Up != '\\') {
-                                       i++;
-                                       ch = chNext;
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               } else if (ch == Quote.Down) {
+                               break;
+                       case SCE_SH_STRING:     // delimited styles
+                       case SCE_SH_CHARACTER:
+                       case SCE_SH_BACKTICKS:
+                       case SCE_SH_PARAM:
+                               if (sc.ch == '\\' && Quote.Up != '\\') {
+                                       sc.Forward();
+                               } else if (sc.ch == Quote.Down) {
                                        Quote.Count--;
                                        if (Quote.Count == 0) {
-                                               Quote.Rep--;
-                                               if (Quote.Rep <= 0) {
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_SH_DEFAULT;
-                                                       ch = ' ';
-                                               }
-                                               if (Quote.Up == Quote.Down) {
-                                                       Quote.Count++;
-                                               }
+                                               sc.ForwardSetState(SCE_SH_DEFAULT);
                                        }
-                               } else if (ch == Quote.Up) {
+                               } else if (sc.ch == Quote.Up) {
                                        Quote.Count++;
                                }
+                               break;
+               }
+
+               // Must check end of HereDoc state 1 before default state is handled
+               if (HereDoc.State == 1 && sc.atLineEnd) {
+                       // Begin of here-doc (the line after the here-doc delimiter):
+                       // Lexically, the here-doc starts from the next line after the >>, but the
+                       // first line of here-doc seem to follow the style of the last EOL sequence
+                       HereDoc.State = 2;
+                       if (HereDoc.Quoted) {
+                               if (sc.state == SCE_SH_HERE_DELIM) {
+                                       // Missing quote at end of string! We are stricter than bash.
+                                       // Colour here-doc anyway while marking this bit as an error.
+                                       sc.ChangeState(SCE_SH_ERROR);
+                               }
+                               // HereDoc.Quote always == '\''
                        }
+                       sc.SetState(SCE_SH_HERE_Q);
                }
-               if (state == SCE_SH_ERROR) {
-                       break;
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_SH_DEFAULT) {
+                       if (sc.ch == '\\') {    // escaped character
+                               sc.SetState(SCE_SH_IDENTIFIER);
+                       } else if (IsADigit(sc.ch)) {
+                               sc.SetState(SCE_SH_NUMBER);
+                               numBase = BASH_BASE_DECIMAL;
+                               if (sc.ch == '0') {     // hex,octal
+                                       if (sc.chNext == 'x' || sc.chNext == 'X') {
+                                               numBase = BASH_BASE_HEX;
+                                               sc.Forward();
+                                       } else if (IsADigit(sc.chNext)) {
+#ifdef PEDANTIC_OCTAL
+                                               numBase = BASH_BASE_OCTAL;
+#else
+                                               numBase = BASH_BASE_HEX;
+#endif
+                                       }
+                               }
+                       } else if (setWordStart.Contains(sc.ch)) {
+                               sc.SetState(SCE_SH_WORD);
+                       } else if (sc.ch == '#') {
+                               sc.SetState(SCE_SH_COMMENTLINE);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_SH_STRING);
+                               Quote.Start(sc.ch);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_SH_CHARACTER);
+                               Quote.Start(sc.ch);
+                       } else if (sc.ch == '`') {
+                               sc.SetState(SCE_SH_BACKTICKS);
+                               Quote.Start(sc.ch);
+                       } else if (sc.ch == '$') {
+                               sc.SetState(SCE_SH_SCALAR);
+                               sc.Forward();
+                               if (sc.ch == '{') {
+                                       sc.ChangeState(SCE_SH_PARAM);
+                               } else if (sc.ch == '\'') {
+                                       sc.ChangeState(SCE_SH_CHARACTER);
+                               } else if (sc.ch == '"') {
+                                       sc.ChangeState(SCE_SH_STRING);
+                               } else if (sc.ch == '(' || sc.ch == '`') {
+                                       sc.ChangeState(SCE_SH_BACKTICKS);
+                                       if (sc.chNext == '(') { // $(( is lexed as operator
+                                               sc.ChangeState(SCE_SH_OPERATOR);
+                                       }
+                               } else {
+                                       continue;       // scalar has no delimiter pair
+                               }
+                               // fallthrough, open delim for $[{'"(`]
+                               Quote.Start(sc.ch);
+                       } else if (sc.Match('<', '<')) {
+                               sc.SetState(SCE_SH_HERE_DELIM);
+                               HereDoc.State = 0;
+                               HereDoc.Indent = false;
+                       } else if (sc.ch == '-' &&      // one-char file test operators
+                                          setSingleCharOp.Contains(sc.chNext) &&
+                                          !setWord.Contains(sc.GetRelative(2)) &&
+                                          IsASpace(sc.chPrev)) {
+                               sc.SetState(SCE_SH_WORD);
+                               sc.Forward();
+                       } else if (setBashOperator.Contains(sc.ch)) {
+                               sc.SetState(SCE_SH_OPERATOR);
+                       }
                }
-               chPrev = ch;
        }
-       styler.ColourTo(lengthDoc - 1, state);
+       sc.Complete();
 }
 
 static bool IsCommentLine(int line, Accessor &styler) {
@@ -621,7 +474,7 @@ static bool IsCommentLine(int line, Accessor &styler) {
 }
 
 static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
-                            Accessor &styler) {
+                                               Accessor &styler) {
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
        unsigned int endPos = startPos + length;
@@ -637,16 +490,16 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
                int style = styleNext;
                styleNext = styler.StyleAt(i + 1);
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-        // Comment folding
+               // Comment folding
                if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
-        {
-            if (!IsCommentLine(lineCurrent - 1, styler)
-                && IsCommentLine(lineCurrent + 1, styler))
-                levelCurrent++;
-            else if (IsCommentLine(lineCurrent - 1, styler)
-                     && !IsCommentLine(lineCurrent+1, styler))
-                levelCurrent--;
-        }
+               {
+                       if (!IsCommentLine(lineCurrent - 1, styler)
+                               && IsCommentLine(lineCurrent + 1, styler))
+                               levelCurrent++;
+                       else if (IsCommentLine(lineCurrent - 1, styler)
+                                        && !IsCommentLine(lineCurrent + 1, styler))
+                               levelCurrent--;
+               }
                if (style == SCE_SH_OPERATOR) {
                        if (ch == '{') {
                                levelCurrent++;
diff --git a/src/stc/scintilla/src/LexCOBOL.cxx b/src/stc/scintilla/src/LexCOBOL.cxx
new file mode 100644 (file)
index 0000000..d061d5c
--- /dev/null
@@ -0,0 +1,368 @@
+// Scintilla source code edit control
+/** @file LexCOBOL.cxx
+ ** Lexer for COBOL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to COBOL
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#define IN_DIVISION 0x01
+#define IN_DECLARATIVES 0x02
+#define IN_SECTION 0x04
+#define IN_PARAGRAPH 0x08
+#define IN_FLAGS 0xF
+#define NOT_HEADER 0x10
+
+inline bool isCOBOLoperator(char ch)
+    {
+    return isoperator(ch);
+    }
+
+inline bool isCOBOLwordchar(char ch)
+    {
+    return isascii(ch) && (isalnum(ch) || ch == '-');
+
+    }
+
+inline bool isCOBOLwordstart(char ch)
+    {
+    return isascii(ch) && isalnum(ch);
+    }
+
+static int CountBits(int nBits)
+       {
+       int count = 0;
+       for (int i = 0; i < 32; ++i)
+               {
+               count += nBits & 1;
+               nBits >>= 1;
+               }
+       return count;
+       }
+
+static void getRange(unsigned int start,
+        unsigned int end,
+        Accessor &styler,
+        char *s,
+        unsigned int len) {
+    unsigned int i = 0;
+    while ((i < end - start + 1) && (i < len-1)) {
+        s[i] = static_cast<char>(tolower(styler[start + i]));
+        i++;
+    }
+    s[i] = '\0';
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr) {
+    styler.ColourTo(end, attr);
+}
+
+
+static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
+    int ret = 0;
+
+    WordList& a_keywords = *keywordlists[0];
+    WordList& b_keywords = *keywordlists[1];
+    WordList& c_keywords = *keywordlists[2];
+
+    char s[100];
+    getRange(start, end, styler, s, sizeof(s));
+
+    char chAttr = SCE_C_IDENTIFIER;
+    if (isdigit(s[0]) || (s[0] == '.')) {
+        chAttr = SCE_C_NUMBER;
+               char *p = s + 1;
+               while (*p) {
+                       if (!isdigit(*p) && isCOBOLwordchar(*p)) {
+                               chAttr = SCE_C_IDENTIFIER;
+                           break;
+                       }
+                       ++p;
+               }
+    }
+    else {
+        if (a_keywords.InList(s)) {
+            chAttr = SCE_C_WORD;
+        }
+        else if (b_keywords.InList(s)) {
+            chAttr = SCE_C_WORD2;
+        }
+        else if (c_keywords.InList(s)) {
+            chAttr = SCE_C_UUID;
+        }
+    }
+    if (*bAarea) {
+        if (strcmp(s, "division") == 0) {
+            ret = IN_DIVISION;
+                       // we've determined the containment, anything else is just ignored for those purposes
+                       *bAarea = false;
+               } else if (strcmp(s, "declaratives") == 0) {
+            ret = IN_DIVISION | IN_DECLARATIVES;
+                       if (nContainment & IN_DECLARATIVES)
+                               ret |= NOT_HEADER | IN_SECTION;
+                       // we've determined the containment, anything else is just ignored for those purposes
+                       *bAarea = false;
+               } else if (strcmp(s, "section") == 0) {
+            ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;
+                       // we've determined the containment, anything else is just ignored for those purposes
+                       *bAarea = false;
+               } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) {
+            ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;
+               } else {
+                       ret = nContainment | IN_PARAGRAPH;
+        }
+    }
+    ColourTo(styler, end, chAttr);
+    return ret;
+}
+
+static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+    Accessor &styler) {
+
+    styler.StartAt(startPos);
+
+    int state = initStyle;
+    if (state == SCE_C_CHARACTER)   // Does not leak onto next line
+        state = SCE_C_DEFAULT;
+    char chPrev = ' ';
+    char chNext = styler[startPos];
+    unsigned int lengthDoc = startPos + length;
+
+    int nContainment;
+
+    int currentLine = styler.GetLine(startPos);
+    if (currentLine > 0) {
+        styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+        nContainment = styler.GetLineState(currentLine);
+               nContainment &= ~NOT_HEADER;
+    } else {
+        styler.SetLineState(currentLine, 0);
+        nContainment = 0;
+    }
+
+    styler.StartSegment(startPos);
+    bool bNewLine = true;
+    bool bAarea = !isspacechar(chNext);
+       int column = 0;
+    for (unsigned int i = startPos; i < lengthDoc; i++) {
+        char ch = chNext;
+
+        chNext = styler.SafeGetCharAt(i + 1);
+
+               ++column;
+
+        if (bNewLine) {
+                       column = 0;
+        }
+               if (column <= 1 && !bAarea) {
+                       bAarea = !isspacechar(ch);
+                       }
+        bool bSetNewLine = false;
+        if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+            // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+            // Avoid triggering two times on Dos/Win
+            // End of line
+            if (state == SCE_C_CHARACTER) {
+                ColourTo(styler, i, state);
+                state = SCE_C_DEFAULT;
+            }
+            styler.SetLineState(currentLine, nContainment);
+            currentLine++;
+            bSetNewLine = true;
+                       if (nContainment & NOT_HEADER)
+                               nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);
+        }
+
+        if (styler.IsLeadByte(ch)) {
+            chNext = styler.SafeGetCharAt(i + 2);
+            chPrev = ' ';
+            i += 1;
+            continue;
+        }
+
+        if (state == SCE_C_DEFAULT) {
+            if (isCOBOLwordstart(ch) || (ch == '$' && isalpha(chNext))) {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_IDENTIFIER;
+            } else if (column == 0 && ch == '*' && chNext != '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTLINE;
+            } else if (column == 0 && ch == '/' && chNext != '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTLINE;
+            } else if (column == 0 && ch == '*' && chNext == '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTDOC;
+            } else if (column == 0 && ch == '/' && chNext == '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTDOC;
+            } else if (ch == '"') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_STRING;
+            } else if (ch == '\'') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_CHARACTER;
+            } else if (ch == '?' && column == 0) {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_PREPROCESSOR;
+            } else if (isCOBOLoperator(ch)) {
+                ColourTo(styler, i-1, state);
+                ColourTo(styler, i, SCE_C_OPERATOR);
+            }
+        } else if (state == SCE_C_IDENTIFIER) {
+            if (!isCOBOLwordchar(ch)) {
+                int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
+
+                if(lStateChange != 0) {
+                    styler.SetLineState(currentLine, lStateChange);
+                    nContainment = lStateChange;
+                }
+
+                state = SCE_C_DEFAULT;
+                chNext = styler.SafeGetCharAt(i + 1);
+                if (ch == '"') {
+                    state = SCE_C_STRING;
+                } else if (ch == '\'') {
+                    state = SCE_C_CHARACTER;
+                } else if (isCOBOLoperator(ch)) {
+                    ColourTo(styler, i, SCE_C_OPERATOR);
+                }
+            }
+        } else {
+            if (state == SCE_C_PREPROCESSOR) {
+                if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+                    ColourTo(styler, i-1, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_COMMENT) {
+                if (ch == '\r' || ch == '\n') {
+                    ColourTo(styler, i, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_COMMENTDOC) {
+                if (ch == '\r' || ch == '\n') {
+                    if (((i > styler.GetStartSegment() + 2) || (
+                        (initStyle == SCE_C_COMMENTDOC) &&
+                        (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+                            ColourTo(styler, i, state);
+                            state = SCE_C_DEFAULT;
+                    }
+                }
+            } else if (state == SCE_C_COMMENTLINE) {
+                if (ch == '\r' || ch == '\n') {
+                    ColourTo(styler, i-1, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_STRING) {
+                if (ch == '"') {
+                    ColourTo(styler, i, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_CHARACTER) {
+                if (ch == '\'') {
+                    ColourTo(styler, i, state);
+                    state = SCE_C_DEFAULT;
+                }
+            }
+        }
+        chPrev = ch;
+        bNewLine = bSetNewLine;
+               if (bNewLine)
+                       {
+                       bAarea = false;
+                       }
+    }
+    ColourTo(styler, lengthDoc - 1, state);
+}
+
+static void FoldCOBOLDoc(unsigned int startPos, int length, int, WordList *[],
+                            Accessor &styler) {
+    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+    unsigned int endPos = startPos + length;
+    int visibleChars = 0;
+    int lineCurrent = styler.GetLine(startPos);
+    int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;
+    char chNext = styler[startPos];
+
+    bool bNewLine = true;
+    bool bAarea = !isspacechar(chNext);
+       int column = 0;
+       bool bComment = false;
+    for (unsigned int i = startPos; i < endPos; i++) {
+        char ch = chNext;
+        chNext = styler.SafeGetCharAt(i + 1);
+               ++column;
+
+        if (bNewLine) {
+                       column = 0;
+                       bComment = (ch == '*' || ch == '/' || ch == '?');
+        }
+               if (column <= 1 && !bAarea) {
+                       bAarea = !isspacechar(ch);
+                       }
+        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+        if (atEOL) {
+                       int nContainment = styler.GetLineState(lineCurrent);
+            int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;
+                       if (bAarea && !bComment)
+                               --lev;
+            if (visibleChars == 0 && foldCompact)
+                lev |= SC_FOLDLEVELWHITEFLAG;
+            if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)
+                lev |= SC_FOLDLEVELHEADERFLAG;
+            if (lev != styler.LevelAt(lineCurrent)) {
+                styler.SetLevel(lineCurrent, lev);
+            }
+                       if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {
+                               // this level is at the same level or less than the previous line
+                               // therefore these is nothing for the previous header to collapse, so remove the header
+                               styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
+                       }
+            levelPrev = lev;
+            visibleChars = 0;
+                       bAarea = false;
+            bNewLine = true;
+            lineCurrent++;
+        } else {
+            bNewLine = false;
+        }
+
+
+        if (!isspacechar(ch))
+            visibleChars++;
+    }
+
+    // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+    int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+    styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const COBOLWordListDesc[] = {
+    "A Keywords",
+    "B Keywords",
+    "Extended Keywords",
+    0
+};
+
+LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);
index bf351280fe17cdee46e2cfd1c35ec6c67677cd68..9577afbdaf38a947f5ae197e1db63a30f198d0cc 100644 (file)
@@ -58,15 +58,21 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
        WordList &keywords3 = *keywordlists[2];
        WordList &keywords4 = *keywordlists[3];
 
+       // property styling.within.preprocessor
+       //      For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) 
+       //      or only from the initial # to the end of the command word(1). 
        bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
 
        CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
        CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
 
-       CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]");
+       CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
 
        CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
        CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+       // property lexer.cpp.allow.dollars
+       //      Set to 0 to disallow the '$' character in identifiers with the cpp lexer. 
        if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
                setWordStart.Add('$');
                setWord.Add('$');
@@ -77,6 +83,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
        bool lastWordWasUUID = false;
        int styleBeforeDCKeyword = SCE_C_DEFAULT;
        bool continuationLine = false;
+       bool isIncludePreprocessor = false;
 
        if (initStyle == SCE_C_PREPROCESSOR) {
                // Set continuationLine if last character of previous line is '\'
@@ -118,6 +125,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                        // if different sets of lines lexed.
                        visibleChars = 0;
                        lastWordWasUUID = false;
+                       isIncludePreprocessor = false;
                }
 
                // Handle line continuation generically.
@@ -230,6 +238,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                        case SCE_C_STRING:
                                if (sc.atLineEnd) {
                                        sc.ChangeState(SCE_C_STRINGEOL);
+                               } else if (isIncludePreprocessor) {
+                                       if (sc.ch == '>') {
+                                               sc.ForwardSetState(SCE_C_DEFAULT);
+                                               isIncludePreprocessor = false;
+                                       }
                                } else if (sc.ch == '\\') {
                                        if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
                                                sc.Forward();
@@ -321,6 +334,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                sc.SetState(SCE_C_REGEX);       // JavaScript's RegEx
                        } else if (sc.ch == '\"') {
                                sc.SetState(SCE_C_STRING);
+                               isIncludePreprocessor = false;  // ensure that '>' won't end the string
+                       } else if (isIncludePreprocessor && sc.ch == '<') {
+                               sc.SetState(SCE_C_STRING);
                        } else if (sc.ch == '\'') {
                                sc.SetState(SCE_C_CHARACTER);
                        } else if (sc.ch == '#' && visibleChars == 0) {
@@ -332,6 +348,8 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
                                } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
                                if (sc.atLineEnd) {
                                        sc.SetState(SCE_C_DEFAULT);
+                               } else if (sc.Match("include")) {
+                                       isIncludePreprocessor = true;
                                }
                        } else if (isoperator(static_cast<char>(sc.ch))) {
                                sc.SetState(SCE_C_OPERATOR);
@@ -359,10 +377,24 @@ static bool IsStreamCommentStyle(int style) {
 // and to make it possible to fiddle the current level for "} else {".
 static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
                                           WordList *[], Accessor &styler) {
+
+       // property fold.comment
+       //      This option enables folding multi-line comments and explicit fold points when using the C++ lexer. 
+       //      Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} 
+       //      at the end of a section that should fold. 
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+       // property fold.preprocessor
+       //      This option enables folding preprocessor directives when using the C++ lexer. 
+       //      Includes C#'s explicit #region and #endregion folding directives. 
        bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+       // property fold.at.else 
+       //      This option enables C++ folding on a "} else {" line of an if statement. 
        bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+
        unsigned int endPos = startPos + length;
        int visibleChars = 0;
        int lineCurrent = styler.GetLine(startPos);
@@ -424,7 +456,9 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
                                levelNext--;
                        }
                }
-               if (atEOL) {
+               if (!IsASpace(ch))
+                       visibleChars++;
+               if (atEOL || (i == endPos-1)) {
                        int levelUse = levelCurrent;
                        if (foldAtElse) {
                                levelUse = levelMinCurrent;
@@ -440,10 +474,12 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
                        lineCurrent++;
                        levelCurrent = levelNext;
                        levelMinCurrent = levelCurrent;
+                       if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+                               // There is an empty line at end of file so give it same level and empty
+                               styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+                       }
                        visibleChars = 0;
                }
-               if (!IsASpace(ch))
-                       visibleChars++;
        }
 }
 
index f5c112d6f1501815d02559fe5af177951e000e92..3b139cdcddfa22982c3ed48b86afbb836c7f4b54 100644 (file)
@@ -28,11 +28,16 @@ using namespace Scintilla;
 
 
 static inline bool IsAWordChar(const unsigned int ch) {
-       return (isalnum(ch) || ch == '-' || ch == '_' || ch >= 161); // _ is not in fact correct CSS word-character
+       /* FIXME:
+        * The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars.
+        * Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee
+        * that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher
+        */
+       return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
 }
 
-inline bool IsCssOperator(const char ch) {
-       if (!isalnum(ch) &&
+inline bool IsCssOperator(const int ch) {
+       if (!((ch < 0x80) && isalnum(ch)) &&
                (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' ||
                 ch == '.' || ch == '#' || ch == '!' || ch == '@' ||
                 /* CSS2 */
@@ -44,15 +49,21 @@ inline bool IsCssOperator(const char ch) {
 }
 
 static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
-       WordList &keywords = *keywordlists[0];
+       WordList &css1Props = *keywordlists[0];
        WordList &pseudoClasses = *keywordlists[1];
-       WordList &keywords2 = *keywordlists[2];
+       WordList &css2Props = *keywordlists[2];
+       WordList &css3Props = *keywordlists[3];
+       WordList &pseudoElements = *keywordlists[4];
+       WordList &exProps = *keywordlists[5];
+       WordList &exPseudoClasses = *keywordlists[6];
+       WordList &exPseudoElements = *keywordlists[7];
 
        StyleContext sc(startPos, length, initStyle, styler);
 
        int lastState = -1; // before operator
        int lastStateC = -1; // before comment
        int op = ' '; // last operator
+       int opPrev = ' '; // last operator
 
        for (; sc.More(); sc.Forward()) {
                if (sc.state == SCE_CSS_COMMENT && sc.Match('*', '/')) {
@@ -64,6 +75,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                                        if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) {
                                                if (lastStateC == SCE_CSS_OPERATOR) {
                                                        op = styler.SafeGetCharAt(i-1);
+                                                       opPrev = styler.SafeGetCharAt(i-2);
                                                        while (--i) {
                                                                lastState = styler.StyleAt(i-1);
                                                                if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
@@ -100,6 +112,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                        if (op == ' ') {
                                unsigned int i = startPos;
                                op = styler.SafeGetCharAt(i-1);
+                               opPrev = styler.SafeGetCharAt(i-2);
                                while (--i) {
                                        lastState = styler.StyleAt(i-1);
                                        if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT)
@@ -111,19 +124,15 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                                if (lastState == SCE_CSS_DEFAULT)
                                        sc.SetState(SCE_CSS_DIRECTIVE);
                                break;
-                       case '*':
-                               if (lastState == SCE_CSS_DEFAULT)
-                                       sc.SetState(SCE_CSS_TAG);
-                               break;
                        case '>':
                        case '+':
-                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_CLASS
-                                       || lastState == SCE_CSS_ID || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+                                       lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
                                        sc.SetState(SCE_CSS_DEFAULT);
                                break;
                        case '[':
-                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_DEFAULT ||
-                                       lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+                                       lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
                                        sc.SetState(SCE_CSS_ATTRIBUTE);
                                break;
                        case ']':
@@ -138,27 +147,44 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                                break;
                        case '}':
                                if (lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_VALUE || lastState == SCE_CSS_IMPORTANT ||
-                                       lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2)
+                                       lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 || lastState == SCE_CSS_IDENTIFIER3)
                                        sc.SetState(SCE_CSS_DEFAULT);
                                break;
+                       case '(':
+                               if (lastState == SCE_CSS_PSEUDOCLASS)
+                                       sc.SetState(SCE_CSS_TAG);
+                               else if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)
+                                       sc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS);
+                               break;
+                       case ')':
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+                                       lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
+                                       lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
+                                       sc.SetState(SCE_CSS_TAG);
+                               break;
                        case ':':
-                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_DEFAULT ||
-                                       lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+                                       lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
+                                       lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT)
                                        sc.SetState(SCE_CSS_PSEUDOCLASS);
-                               else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 || lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
+                               else if (lastState == SCE_CSS_IDENTIFIER || lastState == SCE_CSS_IDENTIFIER2 ||
+                                       lastState == SCE_CSS_IDENTIFIER3 || lastState == SCE_CSS_EXTENDED_IDENTIFIER ||
+                                       lastState == SCE_CSS_UNKNOWN_IDENTIFIER)
                                        sc.SetState(SCE_CSS_VALUE);
                                break;
                        case '.':
-                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_DEFAULT ||
-                                       lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+                                       lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
                                        sc.SetState(SCE_CSS_CLASS);
                                break;
                        case '#':
-                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_DEFAULT ||
-                                       lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
+                               if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID ||
+                                       lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS)
                                        sc.SetState(SCE_CSS_ID);
                                break;
                        case ',':
+                       case '|':
+                       case '~':
                                if (lastState == SCE_CSS_TAG)
                                        sc.SetState(SCE_CSS_DEFAULT);
                                break;
@@ -181,11 +207,19 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                        continue;
                }
 
+               if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) {
+                       sc.SetState(SCE_CSS_TAG);
+                       continue;
+               }
+
                if (IsAWordChar(sc.chPrev) && (
-                       sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2
-                       || sc.state == SCE_CSS_UNKNOWN_IDENTIFIER
-                       || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
-                       || sc.state == SCE_CSS_IMPORTANT
+                       sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 ||
+                       sc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER ||
+                       sc.state == SCE_CSS_UNKNOWN_IDENTIFIER ||
+                       sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
+                       sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
+                       sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
+                       sc.state == SCE_CSS_IMPORTANT
                )) {
                        char s[100];
                        sc.GetCurrentLowered(s, sizeof(s));
@@ -194,27 +228,36 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                                s2++;
                        switch (sc.state) {
                        case SCE_CSS_IDENTIFIER:
-                               if (!keywords.InList(s2)) {
-                                       if (keywords2.InList(s2)) {
-                                               sc.ChangeState(SCE_CSS_IDENTIFIER2);
-                                       } else {
-                                               sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
-                                       }
-                               }
-                               break;
+                       case SCE_CSS_IDENTIFIER2:
+                       case SCE_CSS_IDENTIFIER3:
+                       case SCE_CSS_EXTENDED_IDENTIFIER:
                        case SCE_CSS_UNKNOWN_IDENTIFIER:
-                               if (keywords.InList(s2))
+                               if (css1Props.InList(s2))
                                        sc.ChangeState(SCE_CSS_IDENTIFIER);
-                               else if (keywords2.InList(s2))
+                               else if (css2Props.InList(s2))
                                        sc.ChangeState(SCE_CSS_IDENTIFIER2);
+                               else if (css3Props.InList(s2))
+                                       sc.ChangeState(SCE_CSS_IDENTIFIER3);
+                               else if (exProps.InList(s2))
+                                       sc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER);
+                               else
+                                       sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER);
                                break;
                        case SCE_CSS_PSEUDOCLASS:
-                               if (!pseudoClasses.InList(s2))
-                                       sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
-                               break;
+                       case SCE_CSS_PSEUDOELEMENT:
+                       case SCE_CSS_EXTENDED_PSEUDOCLASS:
+                       case SCE_CSS_EXTENDED_PSEUDOELEMENT:
                        case SCE_CSS_UNKNOWN_PSEUDOCLASS:
-                               if (pseudoClasses.InList(s2))
+                               if (op == ':' && opPrev != ':' && pseudoClasses.InList(s2))
                                        sc.ChangeState(SCE_CSS_PSEUDOCLASS);
+                               else if (opPrev == ':' && pseudoElements.InList(s2))
+                                       sc.ChangeState(SCE_CSS_PSEUDOELEMENT);
+                               else if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2))
+                                       sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS);
+                               else if (opPrev == ':' && exPseudoElements.InList(s2))
+                                       sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT);
+                               else
+                                       sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS);
                                break;
                        case SCE_CSS_IMPORTANT:
                                if (strcmp(s2, "important") != 0)
@@ -223,7 +266,14 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                        }
                }
 
-               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))
+               if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && (
+                       sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID ||
+                       (sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */
+                               sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
+                               sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
+                               sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
+                       ))
+               ))
                        sc.SetState(SCE_CSS_TAG);
 
                if (sc.Match('/', '*')) {
@@ -232,7 +282,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                        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))
+               } else if (IsCssOperator(sc.ch)
                        && (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
                        && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
                        && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
@@ -241,6 +291,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
                                lastState = sc.state;
                        sc.SetState(SCE_CSS_OPERATOR);
                        op = sc.ch;
+                       opPrev = sc.chPrev;
                }
        }
 
@@ -298,9 +349,14 @@ static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Acc
 }
 
 static const char * const cssWordListDesc[] = {
-       "CSS1 Keywords",
-       "Pseudo classes",
-       "CSS2 Keywords",
+       "CSS1 Properties",
+       "Pseudo-classes",
+       "CSS2 Properties",
+       "CSS3 Properties",
+       "Pseudo-elements",
+       "Browser-Specific CSS Properties",
+       "Browser-Specific Pseudo-classes",
+       "Browser-Specific Pseudo-elements",
        0
 };
 
index 539eee0de7b5310ae8cea5b38589f6e827c6c361..0d11622593880d9ef23480fbcb4a5af3af0e0a32 100644 (file)
@@ -2,7 +2,7 @@
 /** @file LexCaml.cxx
  ** Lexer for Objective Caml.
  **/
-// Copyright 2005 by Robert Roessler <robertr@rftp.com>
+// Copyright 2005-2009 by Robert Roessler <robertr@rftp.com>
 // The License.txt file describes the conditions under which this software may be distributed.
 /*     Release History
        20050204 Initial release.
@@ -15,6 +15,7 @@
        20051125 Added 2nd "optional" keywords class.
        20051129 Support "magic" (read-only) comments for RCaml.
        20051204 Swtich to using StyleContext infrastructure.
+       20090629 Add full Standard ML '97 support.
 */
 
 #include <stdlib.h>
@@ -26,6 +27,7 @@
 #include "Platform.h"
 
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 #include "KeyWords.h"
@@ -35,7 +37,6 @@
 //     Since the Microsoft __iscsym[f] funcs are not ANSI...
 inline int  iscaml(int c) {return isalnum(c) || c == '_';}
 inline int iscamlf(int c) {return isalpha(c) || c == '_';}
-inline int iscamld(int c) {return isdigit(c) || c == '_';}
 
 static const int baseT[24] = {
        0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* A - L */
@@ -143,7 +144,7 @@ static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
        int initStyle, char *words[], WindowID window, char *props)
 {
        // create and initialize a WindowAccessor (including contained PropSet)
-       PropSet ps;
+       PropSetSimple ps;
        ps.SetMultiple(props);
        WindowAccessor wa(window, ps);
        // create and initialize WordList(s)
@@ -179,25 +180,27 @@ void ColouriseCamlDoc(
 {
        // initialize styler
        StyleContext sc(startPos, length, initStyle, styler);
-       // set up [initial] state info (terminating states that shouldn't "bleed")
-       int nesting = 0;
-       if (sc.state < SCE_CAML_STRING)
-               sc.state = SCE_CAML_DEFAULT;
-       if (sc.state >= SCE_CAML_COMMENT)
-               nesting = (sc.state & 0x0f) - SCE_CAML_COMMENT;
 
        int chBase = 0, chToken = 0, chLit = 0;
        WordList& keywords  = *keywordlists[0];
        WordList& keywords2 = *keywordlists[1];
        WordList& keywords3 = *keywordlists[2];
+       const bool isSML = keywords.InList("andalso");
        const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
 
+       // set up [initial] state info (terminating states that shouldn't "bleed")
+       const int state_ = sc.state & 0x0f;
+       if (state_ <= SCE_CAML_CHAR
+               || (isSML && state_ == SCE_CAML_STRING))
+               sc.state = SCE_CAML_DEFAULT;
+       int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;
+
        // foreach char in range...
        while (sc.More()) {
                // set up [per-char] state info
-               int state2 = -1;                // (ASSUME no state change)
+               int state2 = -1;                                // (ASSUME no state change)
                int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
-               bool advance = true;    // (ASSUME scanner "eats" 1 char)
+               bool advance = true;                    // (ASSUME scanner "eats" 1 char)
 
                // step state machine
                switch (sc.state & 0x0f) {
@@ -206,25 +209,38 @@ void ColouriseCamlDoc(
                        // it's wide open; what do we have?
                        if (iscamlf(sc.ch))
                                state2 = SCE_CAML_IDENTIFIER;
-                       else if (sc.Match('`') && iscamlf(sc.chNext))
+                       else if (!isSML && sc.Match('`') && iscamlf(sc.chNext))
                                state2 = SCE_CAML_TAGNAME;
-                       else if (sc.Match('#') && isdigit(sc.chNext))
+                       else if (!isSML && sc.Match('#') && isdigit(sc.chNext))
                                state2 = SCE_CAML_LINENUM;
                        else if (isdigit(sc.ch)) {
+                               // it's a number, assume base 10
                                state2 = SCE_CAML_NUMBER, chBase = 10;
-                               if (sc.Match('0') && strchr("bBoOxX", sc.chNext))
-                                       chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
-                       } else if (sc.Match('\''))      /* (char literal?) */
+                               if (sc.Match('0')) {
+                                       // there MAY be a base specified...
+                                       const char* baseC = "bBoOxX";
+                                       if (isSML) {
+                                               if (sc.chNext == 'w')
+                                                       sc.Forward();   // (consume SML "word" indicator)
+                                               baseC = "x";
+                                       }
+                                       // ... change to specified base AS REQUIRED
+                                       if (strchr(baseC, sc.chNext))
+                                               chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
+                               }
+                       } else if (!isSML && sc.Match('\''))    // (Caml char literal?)
                                state2 = SCE_CAML_CHAR, chLit = 0;
-                       else if (sc.Match('\"'))
+                       else if (isSML && sc.Match('#', '"'))   // (SML char literal?)
+                               state2 = SCE_CAML_CHAR, sc.Forward();
+                       else if (sc.Match('"'))
                                state2 = SCE_CAML_STRING;
                        else if (sc.Match('(', '*'))
-                               state2 = SCE_CAML_COMMENT,
-                                       sc.ch = ' ',    // (make SURE "(*)" isn't seen as a closed comment)
-                                       sc.Forward();
-                       else if (strchr("!?~"           /* Caml "prefix-symbol" */
-                                       "=<>@^|&+-*/$%"         /* Caml "infix-symbol" */
-                                       "()[]{};,:.#", sc.ch))  /* Caml "bracket" or ;,:.# */
+                               state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...
+                       else if (strchr("!?~"                   /* Caml "prefix-symbol" */
+                                       "=<>@^|&+-*/$%"                 /* Caml "infix-symbol" */
+                                       "()[]{};,:.#", sc.ch)   // Caml "bracket" or ;,:.#
+                                                                                       // SML "extra" ident chars
+                               || (isSML && (sc.Match('\\') || sc.Match('`'))))
                                state2 = SCE_CAML_OPERATOR;
                        break;
 
@@ -273,9 +289,12 @@ void ColouriseCamlDoc(
                case SCE_CAML_OPERATOR: {
                        // [try to] interpret as [additional] operator char
                        const char* o = 0;
-                       if (iscaml(sc.ch) || isspace(sc.ch)                /* ident or whitespace */
-                               || (o = strchr(")]};,\'\"`#", sc.ch),o)/* "termination" chars */
-                               || !strchr("!$%&*+-./:<=>?@^|~", sc.ch)/* "operator" chars */) {
+                       if (iscaml(sc.ch) || isspace(sc.ch)                     // ident or whitespace
+                               || (o = strchr(")]};,\'\"#", sc.ch),o)  // "termination" chars
+                               || (!isSML && sc.Match('`'))                    // Caml extra term char
+                               || (!strchr("!$%&*+-./:<=>?@^|~", sc.ch)// "operator" chars
+                                                                                                               // SML extra ident chars
+                                       && !(isSML && (sc.Match('\\') || sc.Match('`'))))) {
                                // check for INCLUSIVE termination
                                if (o && strchr(")]};,", sc.ch)) {
                                        if ((sc.Match(')') && sc.chPrev == '(')
@@ -292,24 +311,27 @@ void ColouriseCamlDoc(
 
                case SCE_CAML_NUMBER:
                        // [try to] interpret as [additional] numeric literal char
-                       // N.B. - improperly accepts "extra" digits in base 2 or 8 literals
-                       if (iscamld(sc.ch) || IsADigit(sc.ch, chBase))
+                       if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))
                                break;
                        // how about an integer suffix?
-                       if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
-                               && (iscamld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))
+                       if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))
+                               && (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))
                                break;
                        // or a floating-point literal?
                        if (chBase == 10) {
                                // with a decimal point?
-                               if (sc.Match('.') && iscamld(sc.chPrev))
+                               if (sc.Match('.')
+                                       && ((!isSML && sc.chPrev == '_')
+                                               || IsADigit(sc.chPrev, chBase)))
                                        break;
                                // with an exponent? (I)
                                if ((sc.Match('e') || sc.Match('E'))
-                                       && (iscamld(sc.chPrev) || sc.chPrev == '.'))
+                                       && ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))
+                                               || IsADigit(sc.chPrev, chBase)))
                                        break;
                                // with an exponent? (II)
-                               if ((sc.Match('+') || sc.Match('-'))
+                               if (((!isSML && (sc.Match('+') || sc.Match('-')))
+                                               || (isSML && sc.Match('~')))
                                        && (sc.chPrev == 'e' || sc.chPrev == 'E'))
                                        break;
                        }
@@ -318,29 +340,56 @@ void ColouriseCamlDoc(
                        break;
 
                case SCE_CAML_CHAR:
-                       // [try to] interpret as [additional] char literal char
-                       if (sc.Match('\\')) {
-                               chLit = 1;      // (definitely IS a char literal)
-                               if (sc.chPrev == '\\')
-                                       sc.ch = ' ';    // (so termination test isn't fooled)
+                       if (!isSML) {
+                               // [try to] interpret as [additional] char literal char
+                               if (sc.Match('\\')) {
+                                       chLit = 1;      // (definitely IS a char literal)
+                                       if (sc.chPrev == '\\')
+                                               sc.ch = ' ';    // (...\\')
+                               // should we be terminating - one way or another?
+                               } else if ((sc.Match('\'') && sc.chPrev != '\\')
+                                       || sc.atLineEnd) {
+                                       state2 = SCE_CAML_DEFAULT;
+                                       if (sc.Match('\''))
+                                               chColor++;
+                                       else
+                                               sc.ChangeState(SCE_CAML_IDENTIFIER);
+                               // ... maybe a char literal, maybe not
+                               } else if (chLit < 1 && sc.currentPos - chToken >= 2)
+                                       sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
+                               break;
+                       }/* else
+                               // fall through for SML char literal (handle like string) */
+
+               case SCE_CAML_STRING:
+                       // [try to] interpret as [additional] [SML char/] string literal char
+                       if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext))
+                               state2 = SCE_CAML_WHITE;
+                       else if (sc.Match('\\') && sc.chPrev == '\\')
+                               sc.ch = ' ';    // (...\\")
                        // should we be terminating - one way or another?
-                       } else if ((sc.Match('\'') && sc.chPrev != '\\') || sc.atLineEnd) {
+                       else if ((sc.Match('"') && sc.chPrev != '\\')
+                               || (isSML && sc.atLineEnd)) {
                                state2 = SCE_CAML_DEFAULT;
-                               if (sc.Match('\''))
+                               if (sc.Match('"'))
                                        chColor++;
-                               else
-                                       sc.ChangeState(SCE_CAML_IDENTIFIER);
-                       // ... maybe a char literal, maybe not
-                       } else if (chLit < 1 && sc.currentPos - chToken >= 2)
-                               sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
+                       }
                        break;
 
-               case SCE_CAML_STRING:
-                       // [try to] interpret as [additional] string literal char
-                       if (sc.Match('\\') && sc.chPrev == '\\')
-                               sc.ch = ' ';    // (so '\\' doesn't cause us trouble)
-                       else if (sc.Match('\"') && sc.chPrev != '\\')
-                               state2 = SCE_CAML_DEFAULT, chColor++;
+               case SCE_CAML_WHITE:
+                       // [try to] interpret as [additional] SML embedded whitespace char
+                       if (sc.Match('\\')) {
+                               // style this puppy NOW...
+                               state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++,
+                                       styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();
+                               // ... then backtrack to determine original SML literal type
+                               int p = chColor - 2;
+                               for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;
+                               if (p >= 0)
+                                       state2 = static_cast<int>(styler.StyleAt(p));
+                               // take care of state change NOW
+                               sc.ChangeState(state2), state2 = -1;
+                       }
                        break;
 
                case SCE_CAML_COMMENT:
@@ -350,8 +399,7 @@ void ColouriseCamlDoc(
                        // we're IN a comment - does this start a NESTED comment?
                        if (sc.Match('(', '*'))
                                state2 = sc.state + 1, chToken = sc.currentPos,
-                                       sc.ch = ' ',    // (make SURE "(*)" isn't seen as a closed comment)
-                                       sc.Forward(), nesting++;
+                                       sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;
                        // [try to] interpret as [additional] comment char
                        else if (sc.Match(')') && sc.chPrev == '*') {
                                if (nesting)
@@ -366,7 +414,7 @@ void ColouriseCamlDoc(
                        break;
                }
 
-               // handle state change and char coloring as required
+               // handle state change and char coloring AS REQUIRED
                if (state2 >= 0)
                        styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
                // move to next char UNLESS re-scanning current char
index f63eb399f7441afad883a6ba867a57bad9b79706..1f51f474e80740aad4eedc85ce30da5d9db73f87 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "KeyWords.h"
index 95be129d59d1191b8bb648342290612c130e5670..4c4bcb343e81bc5a824f3013d411fc6d510abf4b 100644 (file)
 using namespace Scintilla;
 #endif
 
-/*/ Nested comments require keeping the value of the nesting level for every
-    position in the document.  But since scintilla always styles line by line,
-    we only need to store one value per line. The non-negative number indicates
-    nesting level at the end of the line.
-/*/
+/* Nested comments require keeping the value of the nesting level for every
+   position in the document.  But since scintilla always styles line by line,
+   we only need to store one value per line. The non-negative number indicates
+   nesting level at the end of the line.
+*/
 
-// We use custom qualifiers since it is not clear what D allows.
+// Underscore, letter, digit and universal alphas from C99 Appendix D.
 
 static bool IsWordStart(int ch) {
-       return isascii(ch) && (isalpha(ch) || ch == '_');
+       return (isascii(ch) && (isalpha(ch) || ch == '_')) || !isascii(ch);
 }
 
 static bool IsWord(int ch) {
-       return isascii(ch) && (isalnum(ch) || ch == '_');
+       return (isascii(ch) && (isalnum(ch) || ch == '_')) || !isascii(ch);
 }
 
 static bool IsDoxygen(int ch) {
@@ -51,308 +51,349 @@ static bool IsDoxygen(int ch) {
        return false;
 }
 
+static bool IsStringSuffix(int ch) {
+       return ch == 'c' || ch == 'w' || ch == 'd';
+}
 
-static void ColouriseDoc(unsigned int startPos, int length, int initStyle, 
-    WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
 
-    WordList &keywords = *keywordlists[0];
-    WordList &keywords2 = *keywordlists[1];
-    WordList &keywords3 = *keywordlists[2];
-    WordList &keywords4 = *keywordlists[3];
+static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
+       WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
 
-    int styleBeforeDCKeyword = SCE_D_DEFAULT;
+       WordList &keywords  = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2]; //doxygen
+       WordList &keywords4 = *keywordlists[3];
+       WordList &keywords5 = *keywordlists[4];
+       WordList &keywords6 = *keywordlists[5];
+       WordList &keywords7 = *keywordlists[6];
 
-    StyleContext sc(startPos, length, initStyle, styler);
+       int styleBeforeDCKeyword = SCE_D_DEFAULT;
 
-    int curLine = styler.GetLine(startPos);
-    int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
+       StyleContext sc(startPos, length, initStyle, styler);
 
-    for (; sc.More(); sc.Forward()) {
+       int curLine = styler.GetLine(startPos);
+       int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
+       bool numFloat = false; // Float literals have '+' and '-' signs
+       bool numHex = false;
 
-        if (sc.atLineStart) {
-            if (sc.state == SCE_D_STRING) {
-                // Prevent SCE_D_STRINGEOL from leaking back to previous line which
-                // ends with a line continuation by locking in the state upto this position.
-                sc.SetState(SCE_D_STRING);
-            }
-            curLine = styler.GetLine(sc.currentPos);
-            styler.SetLineState(curLine, curNcLevel);
-        }
+       for (; sc.More(); sc.Forward()) {
 
-        // Handle line continuation generically.
-        if (sc.ch == '\\') {
-            if (sc.chNext == '\n' || sc.chNext == '\r') {
-                sc.Forward();
-                if (sc.ch == '\r' && sc.chNext == '\n') {
-                    sc.Forward();
-                }
-                continue;
-            }
-        }
+               if (sc.atLineStart) {
+                       curLine = styler.GetLine(sc.currentPos);
+                       styler.SetLineState(curLine, curNcLevel);
+               }
 
-        // Determine if the current state should terminate.
-        switch (sc.state) {
-            case SCE_D_OPERATOR:
-                sc.SetState(SCE_D_DEFAULT);
-                break;
-            case SCE_D_NUMBER:
-                // We accept almost anything because of hex. and number suffixes
-                if (!IsWord(sc.ch) && sc.ch != '.') {
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_IDENTIFIER:
-                if (!IsWord(sc.ch)) {
-                    char s[1000];
-                    if (caseSensitive) {
-                        sc.GetCurrent(s, sizeof(s));
-                    } else {
-                        sc.GetCurrentLowered(s, sizeof(s));
-                    }
-                    if (keywords.InList(s)) {
-                        sc.ChangeState(SCE_D_WORD);
-                    } else if (keywords2.InList(s)) {
-                        sc.ChangeState(SCE_D_WORD2);
-                    } else if (keywords4.InList(s)) {
-                        sc.ChangeState(SCE_D_TYPEDEF);
-                    }
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_COMMENT:
-                if (sc.Match('*', '/')) {
-                    sc.Forward();
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_COMMENTDOC:
-                if (sc.Match('*', '/')) {
-                    sc.Forward();
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
-                    // Verify that we have the conditions to mark a comment-doc-keyword
-                    if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
-                        styleBeforeDCKeyword = SCE_D_COMMENTDOC;
-                        sc.SetState(SCE_D_COMMENTDOCKEYWORD);
-                    }
-                }
-                break;
-            case SCE_D_COMMENTLINE:
-                if (sc.atLineStart) {
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_COMMENTLINEDOC:
-                if (sc.atLineStart) {
-                    sc.SetState(SCE_D_DEFAULT);
-                } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
-                    // Verify that we have the conditions to mark a comment-doc-keyword
-                    if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
-                        styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
-                        sc.SetState(SCE_D_COMMENTDOCKEYWORD);
-                    }
-                }
-                break;
-            case SCE_D_COMMENTDOCKEYWORD:
-                if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
-                    sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
-                    sc.Forward();
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                } else if (!IsDoxygen(sc.ch)) {
-                    char s[100];
-                    if (caseSensitive) {
-                        sc.GetCurrent(s, sizeof(s));
-                    } else {
-                        sc.GetCurrentLowered(s, sizeof(s));
-                    }
-                    if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
-                        sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
-                    }
-                    sc.SetState(styleBeforeDCKeyword);
-                }
-                break;
-            case SCE_D_COMMENTNESTED:
-                if (sc.Match('+', '/')) {
-                    if (curNcLevel > 0)
-                        curNcLevel -= 1;
-                    curLine = styler.GetLine(sc.currentPos);
-                    styler.SetLineState(curLine, curNcLevel);
-                    sc.Forward();
-                    if (curNcLevel == 0) {
-                        sc.ForwardSetState(SCE_D_DEFAULT);
-                   }
-                }
-                else if (sc.Match('/','+')) {
-                    curNcLevel += 1;
-                    curLine = styler.GetLine(sc.currentPos);
-                    styler.SetLineState(curLine, curNcLevel);
-                    sc.Forward();
-                }
-                break;
-            case SCE_D_STRING:
-                if (sc.atLineEnd) {
-                    sc.ChangeState(SCE_D_STRINGEOL);
-                } else if (sc.ch == '\\') {
-                    if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
-                        sc.Forward();
-                    }
-                } else if (sc.ch == '\"') {
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_CHARACTER:
-                if (sc.atLineEnd) {
-                    sc.ChangeState(SCE_D_STRINGEOL);
-                } else if (sc.ch == '\\') {
-                    if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
-                        sc.Forward();
-                    }
-                } else if (sc.ch == '\'') {
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_STRINGEOL:
-                if (sc.atLineStart) {
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-        }
+               // Determine if the current state should terminate.
+               switch (sc.state) {
+                       case SCE_D_OPERATOR:
+                               sc.SetState(SCE_D_DEFAULT);
+                               break;
+                       case SCE_D_NUMBER:
+                               // We accept almost anything because of hex. and number suffixes
+                               if (isascii(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {
+                                       continue;
+                               } else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {
+                                       // Don't parse 0..2 as number.
+                                       numFloat=true;
+                                       continue;
+                               } else if ( ( sc.ch == '-' || sc.ch == '+' ) && (               /*sign and*/
+                                       ( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/
+                                       ( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) {          /*hex*/
+                                       // Parse exponent sign in float literals: 2e+10 0x2e+10
+                                       continue;
+                               } else {
+                                       sc.SetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_IDENTIFIER:
+                               if (!IsWord(sc.ch)) {
+                                       char s[1000];
+                                       if (caseSensitive) {
+                                               sc.GetCurrent(s, sizeof(s));
+                                       } else {
+                                               sc.GetCurrentLowered(s, sizeof(s));
+                                       }
+                                       if (keywords.InList(s)) {
+                                               sc.ChangeState(SCE_D_WORD);
+                                       } else if (keywords2.InList(s)) {
+                                               sc.ChangeState(SCE_D_WORD2);
+                                       } else if (keywords4.InList(s)) {
+                                               sc.ChangeState(SCE_D_TYPEDEF);
+                                       } else if (keywords5.InList(s)) {
+                                               sc.ChangeState(SCE_D_WORD5);
+                                       } else if (keywords6.InList(s)) {
+                                               sc.ChangeState(SCE_D_WORD6);
+                                       } else if (keywords7.InList(s)) {
+                                               sc.ChangeState(SCE_D_WORD7);
+                                       }
+                                       sc.SetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_COMMENT:
+                               if (sc.Match('*', '/')) {
+                                       sc.Forward();
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_COMMENTDOC:
+                               if (sc.Match('*', '/')) {
+                                       sc.Forward();
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+                                       // Verify that we have the conditions to mark a comment-doc-keyword
+                                       if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+                                               styleBeforeDCKeyword = SCE_D_COMMENTDOC;
+                                               sc.SetState(SCE_D_COMMENTDOCKEYWORD);
+                                       }
+                               }
+                               break;
+                       case SCE_D_COMMENTLINE:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_COMMENTLINEDOC:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_D_DEFAULT);
+                               } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+                                       // Verify that we have the conditions to mark a comment-doc-keyword
+                                       if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+                                               styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
+                                               sc.SetState(SCE_D_COMMENTDOCKEYWORD);
+                                       }
+                               }
+                               break;
+                       case SCE_D_COMMENTDOCKEYWORD:
+                               if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
+                                       sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
+                                       sc.Forward();
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               } else if (!IsDoxygen(sc.ch)) {
+                                       char s[100];
+                                       if (caseSensitive) {
+                                               sc.GetCurrent(s, sizeof(s));
+                                       } else {
+                                               sc.GetCurrentLowered(s, sizeof(s));
+                                       }
+                                       if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+                                               sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
+                                       }
+                                       sc.SetState(styleBeforeDCKeyword);
+                               }
+                               break;
+                       case SCE_D_COMMENTNESTED:
+                               if (sc.Match('+', '/')) {
+                                       if (curNcLevel > 0)
+                                               curNcLevel -= 1;
+                                       curLine = styler.GetLine(sc.currentPos);
+                                       styler.SetLineState(curLine, curNcLevel);
+                                       sc.Forward();
+                                       if (curNcLevel == 0) {
+                                               sc.ForwardSetState(SCE_D_DEFAULT);
+                                       }
+                               } else if (sc.Match('/','+')) {
+                                       curNcLevel += 1;
+                                       curLine = styler.GetLine(sc.currentPos);
+                                       styler.SetLineState(curLine, curNcLevel);
+                                       sc.Forward();
+                               }
+                               break;
+                       case SCE_D_STRING:
+                               if (sc.ch == '\\') {
+                                       if (sc.chNext == '"' || sc.chNext == '\\') {
+                                               sc.Forward();
+                                       }
+                               } else if (sc.ch == '"') {
+                                       if(IsStringSuffix(sc.chNext))
+                                               sc.Forward();
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_CHARACTER:
+                               if (sc.atLineEnd) {
+                                       sc.ChangeState(SCE_D_STRINGEOL);
+                               } else if (sc.ch == '\\') {
+                                       if (sc.chNext == '\'' || sc.chNext == '\\') {
+                                               sc.Forward();
+                                       }
+                               } else if (sc.ch == '\'') {
+                                       // Char has no suffixes
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_STRINGEOL:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_STRINGB:
+                               if (sc.ch == '`') {
+                                       if(IsStringSuffix(sc.chNext))
+                                               sc.Forward();
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               }
+                               break;
+                       case SCE_D_STRINGR:
+                               if (sc.ch == '"') {
+                                       if(IsStringSuffix(sc.chNext))
+                                               sc.Forward();
+                                       sc.ForwardSetState(SCE_D_DEFAULT);
+                               }
+                               break;
+               }
 
-        // Determine if a new state should be entered.
-        if (sc.state == SCE_D_DEFAULT) {
-            if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-                    sc.SetState(SCE_D_NUMBER);
-            } else if (IsWordStart(sc.ch)) {
-                    sc.SetState(SCE_D_IDENTIFIER);
-            } else if (sc.Match('/','+')) {
-                curNcLevel += 1;
-               curLine = styler.GetLine(sc.currentPos);
-                styler.SetLineState(curLine, curNcLevel);
-                sc.SetState(SCE_D_COMMENTNESTED);
-                sc.Forward();
-            } else if (sc.Match('/', '*')) {
-                if (sc.Match("/**") || sc.Match("/*!")) {   // Support of Qt/Doxygen doc. style
-                    sc.SetState(SCE_D_COMMENTDOC);
-                } else {
-                    sc.SetState(SCE_D_COMMENT);
-                }
-                sc.Forward();   // Eat the * so it isn't used for the end of the comment
-            } else if (sc.Match('/', '/')) {
-                if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
-                    // Support of Qt/Doxygen doc. style
-                    sc.SetState(SCE_D_COMMENTLINEDOC);
-                else
-                    sc.SetState(SCE_D_COMMENTLINE);
-            } else if (sc.ch == '\"') {
-                sc.SetState(SCE_D_STRING);
-            } else if (sc.ch == '\'') {
-                sc.SetState(SCE_D_CHARACTER);
-            } else if (isoperator(static_cast<char>(sc.ch))) {
-                sc.SetState(SCE_D_OPERATOR);
-            }
-        }
-    }
-    sc.Complete();
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_D_DEFAULT) {
+                       if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_D_NUMBER);
+                               numFloat = sc.ch == '.';
+                               // Remember hex literal
+                               numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );
+                       } else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')
+                               && sc.chNext == '"' ) {
+                               // Limited support for hex and delimited strings: parse as r""
+                               sc.SetState(SCE_D_STRINGR);
+                               sc.Forward();
+                       } else if (IsWordStart(sc.ch) || sc.ch == '$') {
+                               sc.SetState(SCE_D_IDENTIFIER);
+                       } else if (sc.Match('/','+')) {
+                               curNcLevel += 1;
+                               curLine = styler.GetLine(sc.currentPos);
+                               styler.SetLineState(curLine, curNcLevel);
+                               sc.SetState(SCE_D_COMMENTNESTED);
+                               sc.Forward();
+                       } else if (sc.Match('/', '*')) {
+                               if (sc.Match("/**") || sc.Match("/*!")) {   // Support of Qt/Doxygen doc. style
+                                       sc.SetState(SCE_D_COMMENTDOC);
+                               } else {
+                                       sc.SetState(SCE_D_COMMENT);
+                               }
+                               sc.Forward();   // Eat the * so it isn't used for the end of the comment
+                       } else if (sc.Match('/', '/')) {
+                               if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
+                                       // Support of Qt/Doxygen doc. style
+                                       sc.SetState(SCE_D_COMMENTLINEDOC);
+                               else
+                                       sc.SetState(SCE_D_COMMENTLINE);
+                       } else if (sc.ch == '"') {
+                               sc.SetState(SCE_D_STRING);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_D_CHARACTER);
+                       } else if (sc.ch == '`') {
+                               sc.SetState(SCE_D_STRINGB);
+                       } else if (isoperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_D_OPERATOR);
+                               if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator
+                       }
+               }
+       }
+       sc.Complete();
 }
 
 static bool IsStreamCommentStyle(int style) {
-    return style == SCE_D_COMMENT ||
-        style == SCE_D_COMMENTDOC ||
-        style == SCE_D_COMMENTDOCKEYWORD ||
-        style == SCE_D_COMMENTDOCKEYWORDERROR;
+       return style == SCE_D_COMMENT ||
+               style == SCE_D_COMMENTDOC ||
+               style == SCE_D_COMMENTDOCKEYWORD ||
+               style == SCE_D_COMMENTDOCKEYWORDERROR;
 }
 
 // Store both the current line's fold level and the next lines in the
 // level store to make it easy to pick up with each increment
 // and to make it possible to fiddle the current level for "} else {".
 static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) {
-    bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-    bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+       // property lexer.d.fold.at.else
+       //  This option enables D folding on a "} else {" line of an if statement.
+       bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
                styler.GetPropertyInt("fold.at.else", 0)) != 0;
-    unsigned int endPos = startPos + length;
-    int visibleChars = 0;
-    int lineCurrent = styler.GetLine(startPos);
-    int levelCurrent = SC_FOLDLEVELBASE;
-    if (lineCurrent > 0)
-        levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
-    int levelMinCurrent = levelCurrent;
-    int levelNext = levelCurrent;
-    char chNext = styler[startPos];
-    int styleNext = styler.StyleAt(startPos);
-    int style = initStyle;
-    for (unsigned int i = startPos; i < endPos; i++) {
-        char ch = chNext;
-        chNext = styler.SafeGetCharAt(i + 1);
-        int stylePrev = style;
-        style = styleNext;
-        styleNext = styler.StyleAt(i + 1);
-        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-        if (foldComment && IsStreamCommentStyle(style)) {
-            if (!IsStreamCommentStyle(stylePrev)) {
-                levelNext++;
-            } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
-                // Comments don't end at end of line and the next character may be unstyled.
-                levelNext--;
-            }
-        }
-        if (style == SCE_D_OPERATOR) {
-            if (ch == '{') {
-                // Measure the minimum before a '{' to allow
-                // folding on "} else {"
-                if (levelMinCurrent > levelNext) {
-                    levelMinCurrent = levelNext;
-                }
-                levelNext++;
-            } else if (ch == '}') {
-                levelNext--;
-            }
-        }
-        if (atEOL) {
-            if (foldComment) { // Handle nested comments
-               int nc;
-                nc =  styler.GetLineState(lineCurrent);
-                nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
-                levelNext += nc;
-           }
-            int levelUse = levelCurrent;
-            if (foldAtElse) {
-                levelUse = levelMinCurrent;
-            }
-            int lev = levelUse | levelNext << 16;
-            if (visibleChars == 0 && foldCompact)
-                lev |= SC_FOLDLEVELWHITEFLAG;
-            if (levelUse < levelNext)
-                lev |= SC_FOLDLEVELHEADERFLAG;
-            if (lev != styler.LevelAt(lineCurrent)) {
-                styler.SetLevel(lineCurrent, lev);
-            }
-            lineCurrent++;
-            levelCurrent = levelNext;
-            levelMinCurrent = levelCurrent;
-            visibleChars = 0;
-        }
-        if (!IsASpace(ch))
-            visibleChars++;
-    }
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelCurrent = SC_FOLDLEVELBASE;
+       if (lineCurrent > 0)
+               levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+       int levelMinCurrent = levelCurrent;
+       int levelNext = levelCurrent;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (foldComment && IsStreamCommentStyle(style)) {
+                       if (!IsStreamCommentStyle(stylePrev)) {
+                               levelNext++;
+                       } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+                               // Comments don't end at end of line and the next character may be unstyled.
+                               levelNext--;
+                       }
+               }
+               if (style == SCE_D_OPERATOR) {
+                       if (ch == '{') {
+                               // Measure the minimum before a '{' to allow
+                               // folding on "} else {"
+                               if (levelMinCurrent > levelNext) {
+                                       levelMinCurrent = levelNext;
+                               }
+                               levelNext++;
+                       } else if (ch == '}') {
+                               levelNext--;
+                       }
+               }
+               if (atEOL) {
+                       if (foldComment) {  // Handle nested comments
+                               int nc;
+                               nc =  styler.GetLineState(lineCurrent);
+                               nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
+                               levelNext += nc;
+                       }
+                       int levelUse = levelCurrent;
+                       if (foldAtElse) {
+                               levelUse = levelMinCurrent;
+                       }
+                       int lev = levelUse | levelNext << 16;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if (levelUse < levelNext)
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelCurrent = levelNext;
+                       levelMinCurrent = levelCurrent;
+                       visibleChars = 0;
+               }
+               if (!IsASpace(ch))
+                       visibleChars++;
+       }
 }
 
 static void FoldDDoc(unsigned int startPos, int length, int initStyle,
-    WordList *[], Accessor &styler) {
-        FoldDoc(startPos, length, initStyle, styler);
+       WordList *[], Accessor &styler) {
+               FoldDoc(startPos, length, initStyle, styler);
 }
 
 static const char * const dWordLists[] = {
-            "Primary keywords and identifiers",
-            "Secondary keywords and identifiers",
-            "Documentation comment keywords",
-            "Type definitions and aliases",
-            0,
-        };
+                       "Primary keywords and identifiers",
+                       "Secondary keywords and identifiers",
+                       "Documentation comment keywords",
+                       "Type definitions and aliases",
+                       "Keywords 5",
+                       "Keywords 6",
+                       "Keywords 7",
+                       0,
+               };
 
-static void ColouriseDDoc(unsigned int startPos, int length, 
-    int initStyle, WordList *keywordlists[], Accessor &styler) {
-        ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
+static void ColouriseDDoc(unsigned int startPos, int length,
+       int initStyle, WordList *keywordlists[], Accessor &styler) {
+               ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
 }
 
 LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);
index d56f78528715f6f184ab0e7de5754623b2463307..45577bda4c4e71d0b07fe8b1e533debeb96ce0d8 100644 (file)
@@ -1,10 +1,12 @@
 // Scintilla source code edit control
+// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
 /** @file LexErlang.cxx
  ** Lexer for Erlang.
- ** Written by Peter-Henry Mander, based on Matlab lexer by Jose' Fonseca
+ ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com)
+ ** Originally wrote by Peter-Henry Mander, 
+ ** based on Matlab lexer 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.
 
 #include <stdlib.h>
 #include <string.h>
@@ -13,7 +15,6 @@
 #include <stdarg.h>
 
 #include "Platform.h"
-
 #include "PropSet.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 using namespace Scintilla;
 #endif
 
-/*
-   TODO:
-   o  _Param should be a new lexical type
-*/
-
 static int is_radix(int radix, int ch) {
-   int digit;
-   if ( 16 < radix || 2 > radix ) {
-      return 0;
-   }
-   if ( isdigit(ch) ) {
-      digit = ch - '0';
-   } else if ( isxdigit(ch) ) {
-      digit = toupper(ch) - 'A' + 10;
-   } else {
-      return 0;
-   }
-   if ( digit < radix ) {
-      return 1;
-   } else {
-      return 0;
-   }
+       int digit;
+
+       if (36 < radix || 2 > radix)
+               return 0;
+
+       if (isdigit(ch)) {
+               digit = ch - '0';
+       } else if (isalnum(ch)) {
+               digit = toupper(ch) - 'A' + 10;
+       } else {
+               return 0;
+       }
+
+       return (digit < radix);
 }
 
 typedef enum {
-   STATE_NULL,
-   ATOM_UNQUOTED,
-   ATOM_QUOTED,
-   ATOM_FUN_NAME,
-   NODE_NAME_UNQUOTED,
-   NODE_NAME_QUOTED,
-   MACRO_START,
-   MACRO_UNQUOTED,
-   MACRO_QUOTED,
-   RECORD_START,
-   RECORD_UNQUOTED,
-   RECORD_QUOTED,
-   NUMERAL_START,
-   NUMERAL_SIGNED,
-   NUMERAL_RADIX_LITERAL,
-   NUMERAL_SPECULATIVE_MANTISSA,
-   NUMERAL_FLOAT_MANTISSA,
-   NUMERAL_FLOAT_EXPONENT,
-   NUMERAL_FLOAT_SIGNED_EXPONENT,
-   PARSE_ERROR
+       STATE_NULL,
+       COMMENT,
+       COMMENT_FUNCTION,
+       COMMENT_MODULE,
+       COMMENT_DOC,
+       COMMENT_DOC_MACRO,
+       ATOM_UNQUOTED,
+       ATOM_QUOTED,
+       NODE_NAME_UNQUOTED,
+       NODE_NAME_QUOTED,
+       MACRO_START,
+       MACRO_UNQUOTED,
+       MACRO_QUOTED,
+       RECORD_START,
+       RECORD_UNQUOTED,
+       RECORD_QUOTED,
+       NUMERAL_START,
+       NUMERAL_BASE_VALUE,
+       NUMERAL_FLOAT,
+       NUMERAL_EXPONENT,
+       PREPROCESSOR
 } atom_parse_state_t;
 
+static inline bool IsAWordChar(const int ch) {
+       return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_');
+}
+
 static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
-                               WordList *keywordlists[], Accessor &styler) {
+                                                               WordList *keywordlists[], Accessor &styler) {
 
-       WordList &keywords = *keywordlists[0];
+       StyleContext sc(startPos, length, initStyle, styler);
+       WordList &reservedWords = *keywordlists[0];
+       WordList &erlangBIFs = *keywordlists[1];
+       WordList &erlangPreproc = *keywordlists[2];
+       WordList &erlangModulesAtt = *keywordlists[3];
+       WordList &erlangDoc = *keywordlists[4];
+       WordList &erlangDocMacro = *keywordlists[5];
+       int radix_digits = 0;
+       int exponent_digits = 0;
+       atom_parse_state_t parse_state = STATE_NULL;
+       atom_parse_state_t old_parse_state = STATE_NULL;
+       bool to_late_to_comment = false;
+       char cur[100];
+       int old_style = SCE_ERLANG_DEFAULT;
 
        styler.StartAt(startPos);
 
-       StyleContext sc(startPos, length, initStyle, styler);
-   atom_parse_state_t parse_state = STATE_NULL;
-   int radix_digits = 0;
-   int exponent_digits = 0;
        for (; sc.More(); sc.Forward()) {
-      if ( STATE_NULL != parse_state ) {
-         switch (parse_state) {
-         case STATE_NULL:
-                               sc.SetState(SCE_ERLANG_DEFAULT);
-            break;
-         case ATOM_UNQUOTED:
-            if ( '@' == sc.ch ){
-               parse_state = NODE_NAME_UNQUOTED;
-            } else if ( !isalnum(sc.ch) && sc.ch != '_' ) {
-               char s[100];
-               sc.GetCurrent(s, sizeof(s));
-               if (keywords.InList(s)) {
-                  sc.ChangeState(SCE_ERLANG_KEYWORD);
-                  sc.SetState(SCE_ERLANG_DEFAULT);
-                  parse_state = STATE_NULL;
-               } else {
-                  if ( '/' == sc.ch ) {
-                     parse_state = ATOM_FUN_NAME;
-                  } else {
-                     sc.ChangeState(SCE_ERLANG_ATOM);
-                     sc.SetState(SCE_ERLANG_DEFAULT);
-                     parse_state = STATE_NULL;
-                  }
-               }
-            }
-            break;
-         case ATOM_QUOTED:
-            if ( '@' == sc.ch ){
-               parse_state = NODE_NAME_QUOTED;
-            } else if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
-               sc.ChangeState(SCE_ERLANG_ATOM);
-               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case ATOM_FUN_NAME:
-            if ( !isdigit(sc.ch) ) {
-               sc.ChangeState(SCE_ERLANG_FUNCTION_NAME);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case NODE_NAME_QUOTED:
-            if ( '@' == sc.ch ) {
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            } else if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
-               sc.ChangeState(SCE_ERLANG_NODE_NAME);
-               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case NODE_NAME_UNQUOTED:
-            if ( '@' == sc.ch ) {
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            } else if ( !isalnum(sc.ch) && sc.ch != '_' ) {
-               sc.ChangeState(SCE_ERLANG_NODE_NAME);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case RECORD_START:
-            if ( '\'' == sc.ch ) {
-               parse_state = RECORD_QUOTED;
-            } else if (isalpha(sc.ch) && islower(sc.ch)) {
-               parse_state = RECORD_UNQUOTED;
-            } else { // error
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case RECORD_QUOTED:
-            if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
-               sc.ChangeState(SCE_ERLANG_RECORD);
-               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case RECORD_UNQUOTED:
-            if ( !isalpha(sc.ch) && '_' != sc.ch ) {
-               sc.ChangeState(SCE_ERLANG_RECORD);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case MACRO_START:
-            if ( '\'' == sc.ch ) {
-               parse_state = MACRO_QUOTED;
-            } else if (isalpha(sc.ch)) {
-               parse_state = MACRO_UNQUOTED;
-            } else { // error
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case MACRO_UNQUOTED:
-            if ( !isalpha(sc.ch) && '_' != sc.ch ) {
-               sc.ChangeState(SCE_ERLANG_MACRO);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case MACRO_QUOTED:
-            if ( '\'' == sc.ch && '\\' != sc.chPrev ) {
-               sc.ChangeState(SCE_ERLANG_MACRO);
-               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case NUMERAL_START:
-            if ( isdigit(sc.ch) ) {
-               radix_digits *= 10;
-               radix_digits += sc.ch - '0'; // Assuming ASCII here!
-            } else if ( '#' == sc.ch ) {
-               if ( 2 > radix_digits || 16 < radix_digits) {
-                  sc.SetState(SCE_ERLANG_DEFAULT);
-                  parse_state = STATE_NULL;
-               } else {
-                  parse_state = NUMERAL_RADIX_LITERAL;
-               }
-            } else if ( '.' == sc.ch && isdigit(sc.chNext)) {
-               radix_digits = 0;
-               parse_state = NUMERAL_FLOAT_MANTISSA;
-            } else if ( 'e' == sc.ch || 'E' == sc.ch ) {
-               exponent_digits = 0;
-               parse_state = NUMERAL_FLOAT_EXPONENT;
-            } else {
-               radix_digits = 0;
-               sc.ChangeState(SCE_ERLANG_NUMBER);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case NUMERAL_RADIX_LITERAL:
-            if ( !is_radix(radix_digits,sc.ch) ) {
-               radix_digits = 0;
-               if ( !isalnum(sc.ch) ) {
-                  sc.ChangeState(SCE_ERLANG_NUMBER);
-               }
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case NUMERAL_FLOAT_MANTISSA:
-            if ( 'e' == sc.ch || 'E' == sc.ch ) {
-               exponent_digits = 0;
-               parse_state = NUMERAL_FLOAT_EXPONENT;
-            } else if ( !isdigit(sc.ch) ) {
-               sc.ChangeState(SCE_ERLANG_NUMBER);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            }
-            break;
-         case NUMERAL_FLOAT_EXPONENT:
-            if ( '-' == sc.ch || '+' == sc.ch ) {
-               parse_state = NUMERAL_FLOAT_SIGNED_EXPONENT;
-            } else if ( !isdigit(sc.ch) ) {
-               if ( 0 < exponent_digits ) {
-                  sc.ChangeState(SCE_ERLANG_NUMBER);
-               }
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            } else {
-               ++exponent_digits;
-            }
-            break;
-         case NUMERAL_FLOAT_SIGNED_EXPONENT:
-            if ( !isdigit(sc.ch) ) {
-               if ( 0 < exponent_digits ) {
-                  sc.ChangeState(SCE_ERLANG_NUMBER);
-               }
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            } else {
-               ++exponent_digits;
-            }
-            break;
-         case NUMERAL_SIGNED:
-            if ( !isdigit(sc.ch) ) {
-               sc.ChangeState(SCE_ERLANG_NUMBER);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            } else if ( '.' == sc.ch ) {
-               parse_state = NUMERAL_FLOAT_MANTISSA;
-            }
-            break;
-         case NUMERAL_SPECULATIVE_MANTISSA:
-            if ( !isdigit(sc.ch) ) {
-               sc.ChangeState(SCE_ERLANG_OPERATOR);
-               sc.SetState(SCE_ERLANG_DEFAULT);
-               parse_state = STATE_NULL;
-            } else {
-               parse_state = NUMERAL_FLOAT_MANTISSA;
-            }
-            break;
-         case PARSE_ERROR:
-                               sc.SetState(SCE_ERLANG_DEFAULT);
-            parse_state = STATE_NULL;
-            break;
-         }
-      } else if (sc.state == SCE_ERLANG_OPERATOR) {
-                       if (sc.chPrev == '.') {
-                               if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
-                                       sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-                               } else if (sc.ch == '\'') {
-                                       sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-                               } else {
-                                       sc.SetState(SCE_ERLANG_DEFAULT);
+               int style = SCE_ERLANG_DEFAULT;
+               if (STATE_NULL != parse_state) {
+
+                       switch (parse_state) {
+
+                               case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;
+
+                       /* COMMENTS ------------------------------------------------------*/
+                               case COMMENT : {
+                                       if (sc.ch != '%') {
+                                               to_late_to_comment = true;
+                                       } else if (!to_late_to_comment && sc.ch == '%') {
+                                               // Switch to comment level 2 (Function)
+                                               sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
+                                               old_style = SCE_ERLANG_COMMENT_FUNCTION;
+                                               parse_state = COMMENT_FUNCTION;
+                                               sc.Forward();
+                                       }
                                }
-                       } else {
-                               sc.SetState(SCE_ERLANG_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ERLANG_VARIABLE) {
-                       if (!isalnum(sc.ch) && sc.ch != '_') {
-            sc.SetState(SCE_ERLANG_DEFAULT);
-                       }
-               } else if (sc.state == SCE_ERLANG_STRING) {
-                       if (sc.ch == '\"' && sc.chPrev != '\\') {
-                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                               // V--- Falling through!
+                               case COMMENT_FUNCTION : {
+                                       if (sc.ch != '%') {
+                                               to_late_to_comment = true;
+                                       } else if (!to_late_to_comment && sc.ch == '%') {
+                                               // Switch to comment level 3 (Module)
+                                               sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
+                                               old_style = SCE_ERLANG_COMMENT_MODULE;
+                                               parse_state = COMMENT_MODULE;
+                                               sc.Forward();
+                                       }
+                               }
+                               // V--- Falling through!
+                               case COMMENT_MODULE : {
+                                       if (parse_state != COMMENT) {
+                                               // Search for comment documentation
+                                               if (sc.chNext == '@') {
+                                                       old_parse_state = parse_state;
+                                                       parse_state = ('{' == sc.ch)
+                                                                                       ? COMMENT_DOC_MACRO
+                                                                                       : COMMENT_DOC;
+                                                       sc.ForwardSetState(sc.state);
+                                               }
+                                       }
+
+                                       // All comments types fall here.
+                                       if (sc.atLineEnd) {
+                                               to_late_to_comment = false;
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                               case COMMENT_DOC :
+                               // V--- Falling through!
+                               case COMMENT_DOC_MACRO : {
+
+                                       if (!isalnum(sc.ch)) {
+                                               // Try to match documentation comment
+                                               sc.GetCurrent(cur, sizeof(cur));
+
+                                               if (parse_state == COMMENT_DOC_MACRO 
+                                                       && erlangDocMacro.InList(cur)) {
+                                                               sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
+                                                               while (sc.ch != '}' && !sc.atLineEnd)
+                                                                       sc.Forward();
+                                               } else if (erlangDoc.InList(cur)) {
+                                                       sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
+                                               } else {
+                                                       sc.ChangeState(old_style);
+                                               }
+
+                                               // Switch back to old state
+                                               sc.SetState(old_style);
+                                               parse_state = old_parse_state;
+                                       }
+
+                                       if (sc.atLineEnd) {
+                                               to_late_to_comment = false;
+                                               sc.ChangeState(old_style);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* -------------------------------------------------------------- */
+                       /* Atoms ---------------------------------------------------------*/
+                               case ATOM_UNQUOTED : {
+                                       if ('@' == sc.ch){
+                                               parse_state = NODE_NAME_UNQUOTED;
+                                       } else if (sc.ch == ':') {
+                                               // Searching for module name
+                                               if (sc.chNext == ' ') {
+                                                       // error
+                                                       sc.ChangeState(SCE_ERLANG_UNKNOWN);
+                                                       parse_state = STATE_NULL;
+                                               } else {
+                                                       sc.Forward();
+                                                       if (isalnum(sc.ch))  {
+                                                               sc.GetCurrent(cur, sizeof(cur));
+                                                               sc.ChangeState(SCE_ERLANG_MODULES);
+                                                               sc.SetState(SCE_ERLANG_MODULES);
+                                                       }
+                                               }
+                                       } else if (!IsAWordChar(sc.ch)) {
+
+                                               sc.GetCurrent(cur, sizeof(cur));
+                                               if (reservedWords.InList(cur)) {
+                                                       style = SCE_ERLANG_KEYWORD;
+                                               } else if (erlangBIFs.InList(cur)
+                                                                       && strcmp(cur,"erlang:")){
+                                                       style = SCE_ERLANG_BIFS;
+                                               } else if (sc.ch == '(' || '/' == sc.ch){
+                                                       style = SCE_ERLANG_FUNCTION_NAME;
+                                               } else {
+                                                       style = SCE_ERLANG_ATOM;
+                                               }
+
+                                               sc.ChangeState(style);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+
+                               } break;
+
+                               case ATOM_QUOTED : {
+                                       if ( '@' == sc.ch ){
+                                               parse_state = NODE_NAME_QUOTED;
+                                       } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
+                                               sc.ChangeState(SCE_ERLANG_ATOM);
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* -------------------------------------------------------------- */
+                       /* Node names ----------------------------------------------------*/
+                               case NODE_NAME_UNQUOTED : {
+                                       if ('@' == sc.ch) {
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       } else if (!IsAWordChar(sc.ch)) {
+                                               sc.ChangeState(SCE_ERLANG_NODE_NAME);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                               case NODE_NAME_QUOTED : {
+                                       if ('@' == sc.ch) {
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
+                                               sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* -------------------------------------------------------------- */
+                       /* Records -------------------------------------------------------*/
+                               case RECORD_START : {
+                                       if ('\'' == sc.ch) {
+                                               parse_state = RECORD_QUOTED;
+                                       } else if (isalpha(sc.ch) && islower(sc.ch)) {
+                                               parse_state = RECORD_UNQUOTED;
+                                       } else { // error
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                               case RECORD_UNQUOTED : {
+                                       if (!IsAWordChar(sc.ch)) {
+                                               sc.ChangeState(SCE_ERLANG_RECORD);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                               case RECORD_QUOTED : {
+                                       if ('\'' == sc.ch && '\\' != sc.chPrev) {
+                                               sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* -------------------------------------------------------------- */
+                       /* Macros --------------------------------------------------------*/
+                               case MACRO_START : {
+                                       if ('\'' == sc.ch) {
+                                               parse_state = MACRO_QUOTED;
+                                       } else if (isalpha(sc.ch)) {
+                                               parse_state = MACRO_UNQUOTED;
+                                       } else { // error
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                               case MACRO_UNQUOTED : {
+                                       if (!IsAWordChar(sc.ch)) {
+                                               sc.ChangeState(SCE_ERLANG_MACRO);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                               case MACRO_QUOTED : {
+                                       if ('\'' == sc.ch && '\\' != sc.chPrev) {
+                                               sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* -------------------------------------------------------------- */
+                       /* Numerics ------------------------------------------------------*/
+                       /* Simple integer */
+                               case NUMERAL_START : {
+                                       if (isdigit(sc.ch)) {
+                                               radix_digits *= 10;
+                                               radix_digits += sc.ch - '0'; // Assuming ASCII here!
+                                       } else if ('#' == sc.ch) {
+                                               if (2 > radix_digits || 36 < radix_digits) {
+                                                       sc.SetState(SCE_ERLANG_DEFAULT);
+                                                       parse_state = STATE_NULL;
+                                               } else {
+                                                       parse_state = NUMERAL_BASE_VALUE;
+                                               }
+                                       } else if ('.' == sc.ch && isdigit(sc.chNext)) {
+                                               radix_digits = 0;
+                                               parse_state = NUMERAL_FLOAT;
+                                       } else if ('e' == sc.ch || 'E' == sc.ch) {
+                                               exponent_digits = 0;
+                                               parse_state = NUMERAL_EXPONENT;
+                                       } else {
+                                               radix_digits = 0;
+                                               sc.ChangeState(SCE_ERLANG_NUMBER);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* Integer in other base than 10 (x#yyy) */
+                               case NUMERAL_BASE_VALUE : {
+                                       if (!is_radix(radix_digits,sc.ch)) {
+                                               radix_digits = 0;
+                               
+                                               if (!isalnum(sc.ch))
+                                                       sc.ChangeState(SCE_ERLANG_NUMBER);
+
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* Float (x.yyy) */
+                               case NUMERAL_FLOAT : {
+                                       if ('e' == sc.ch || 'E' == sc.ch) {
+                                               exponent_digits = 0;
+                                               parse_state = NUMERAL_EXPONENT;
+                                       } else if (!isdigit(sc.ch)) {
+                                               sc.ChangeState(SCE_ERLANG_NUMBER);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
+                       /* Exponent, either integer or float (xEyy, x.yyEzzz) */
+                               case NUMERAL_EXPONENT : {
+                                       if (('-' == sc.ch || '+' == sc.ch)
+                                                       && (isdigit(sc.chNext))) {
+                                               sc.Forward();
+                                       } else if (!isdigit(sc.ch)) {
+                                               if (0 < exponent_digits)
+                                                       sc.ChangeState(SCE_ERLANG_NUMBER);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       } else {
+                                               ++exponent_digits;
+                                       }
+                               } break;
+
+                       /* -------------------------------------------------------------- */
+                       /* Preprocessor --------------------------------------------------*/
+                               case PREPROCESSOR : {
+                                       if (!IsAWordChar(sc.ch)) {
+                                               
+                                               sc.GetCurrent(cur, sizeof(cur));
+                                               if (erlangPreproc.InList(cur)) {
+                                                       style = SCE_ERLANG_PREPROC;
+                                               } else if (erlangModulesAtt.InList(cur)) {
+                                                       style = SCE_ERLANG_MODULES_ATT;
+                                               }
+
+                                               sc.ChangeState(style);
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                               parse_state = STATE_NULL;
+                                       }
+                               } break;
+
                        }
-               } else if (sc.state == SCE_ERLANG_COMMENT ) {
-                       if (sc.atLineEnd) {
-                               sc.SetState(SCE_ERLANG_DEFAULT);
+
+               } /* End of : STATE_NULL != parse_state */
+               else
+               {
+                       switch (sc.state) {
+                               case SCE_ERLANG_VARIABLE : {
+                                       if (!IsAWordChar(sc.ch))
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                               } break;
+                               case SCE_ERLANG_STRING : {
+                                        if (sc.ch == '\"' && sc.chPrev != '\\')
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                               } break;
+                               case SCE_ERLANG_COMMENT : {
+                                        if (sc.atLineEnd)
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                               } break;
+                               case SCE_ERLANG_CHARACTER : {
+                                       if (sc.chPrev == '\\') {
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                       } else if (sc.ch != '\\') {
+                                               sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                       }
+                               } break;
+                               case SCE_ERLANG_OPERATOR : {
+                                       if (sc.chPrev == '.') {
+                                               if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' 
+                                                       || sc.ch == '^') {
+                                                       sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                               } else if (sc.ch == '\'') {
+                                                       sc.ForwardSetState(SCE_ERLANG_DEFAULT);
+                                               } else {
+                                                       sc.SetState(SCE_ERLANG_DEFAULT);
+                                               }
+                                       } else {
+                                               sc.SetState(SCE_ERLANG_DEFAULT);
+                                       }
+                               } break;
                        }
-      } else if (sc.state == SCE_ERLANG_CHARACTER ) {
-         if ( sc.chPrev == '\\' ) {
-            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-         } else if ( sc.ch != '\\' ) {
-            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
-         }
-      }
+               }
 
                if (sc.state == SCE_ERLANG_DEFAULT) {
-                       if (sc.ch == '%') {
-                               sc.SetState(SCE_ERLANG_COMMENT);
-                       } else if (sc.ch == '\"') {
-            sc.SetState(SCE_ERLANG_STRING);
-         } else if (sc.ch == '#') {
-            parse_state = RECORD_START;
-                               sc.SetState(SCE_ERLANG_UNKNOWN);
-         } else if (sc.ch == '?') {
-            parse_state = MACRO_START;
-                               sc.SetState(SCE_ERLANG_UNKNOWN);
-         } else if (sc.ch == '$') {
-                               sc.SetState(SCE_ERLANG_CHARACTER);
-         } else if (sc.ch == '\'') {
-            parse_state = ATOM_QUOTED;
-                               sc.SetState(SCE_ERLANG_UNKNOWN);
-                       } else if ( isdigit(sc.ch) ) {
-            parse_state = NUMERAL_START;
-            radix_digits = sc.ch - '0';
-                               sc.SetState(SCE_ERLANG_UNKNOWN);
-         } else if ( '.' == sc.ch ) {
-            parse_state = NUMERAL_SPECULATIVE_MANTISSA;
-                               sc.SetState(SCE_ERLANG_UNKNOWN);
-                       } else if (isalpha(sc.ch) && isupper(sc.ch)) {
-                               sc.SetState(SCE_ERLANG_VARIABLE);
-                       } else if (isalpha(sc.ch)) {
-            parse_state = ATOM_UNQUOTED;
-                               sc.SetState(SCE_ERLANG_UNKNOWN);
-                       } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '\\') {
-                               sc.SetState(SCE_ERLANG_OPERATOR);
+                       bool no_new_state = false;
+
+                       switch (sc.ch) {
+                               case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
+                               case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
+                               case '%' : {
+                                       parse_state = COMMENT;
+                                       sc.SetState(SCE_ERLANG_COMMENT);
+                               } break;
+                               case '#' : {
+                                       parse_state = RECORD_START;
+                                       sc.SetState(SCE_ERLANG_UNKNOWN);
+                               } break;
+                               case '?' : {
+                                       parse_state = MACRO_START;
+                                       sc.SetState(SCE_ERLANG_UNKNOWN);
+                               } break;
+                               case '\'' : {
+                                       parse_state = ATOM_QUOTED;
+                                       sc.SetState(SCE_ERLANG_UNKNOWN);
+                               } break;
+                               case '+' :
+                               case '-' : {
+                                       if (IsADigit(sc.chNext)) {
+                                               parse_state = NUMERAL_START;
+                                               radix_digits = 0;
+                                               sc.SetState(SCE_ERLANG_UNKNOWN);
+                                       } else if (sc.ch != '+') {
+                                               parse_state = PREPROCESSOR;
+                                               sc.SetState(SCE_ERLANG_UNKNOWN);
+                                       }
+                               } break;
+                               default : no_new_state = true;
+                       }
+
+                       if (no_new_state) {
+                               if (isdigit(sc.ch)) {
+                                       parse_state = NUMERAL_START;
+                                       radix_digits = sc.ch - '0';
+                                       sc.SetState(SCE_ERLANG_UNKNOWN);
+                               } else if (isupper(sc.ch) || '_' == sc.ch) {
+                                       sc.SetState(SCE_ERLANG_VARIABLE);
+                               } else if (isalpha(sc.ch)) {
+                                       parse_state = ATOM_UNQUOTED;
+                                       sc.SetState(SCE_ERLANG_UNKNOWN);
+                               } else if (isoperator(static_cast<char>(sc.ch))
+                                                       || sc.ch == '\\') {
+                                       sc.SetState(SCE_ERLANG_OPERATOR);
+                               }
                        }
                }
+
        }
        sc.Complete();
 }
 
-static int ClassifyFoldPointErlang(
-   Accessor &styler,
-   int styleNext,
-   int keyword_start
+static int ClassifyErlangFoldPoint(
+       Accessor &styler,
+       int styleNext,
+       int keyword_start
 ) {
        int lev = 0;
-   if ( styler.Match(keyword_start,"case")
-      || (
-            styler.Match(keyword_start,"fun")
-         && SCE_ERLANG_FUNCTION_NAME != styleNext)
-      || styler.Match(keyword_start,"if")
-      || styler.Match(keyword_start,"query")
-      || styler.Match(keyword_start,"receive")
-   ) {
-      ++lev;
-   } else if ( styler.Match(keyword_start,"end") ) {
-      --lev;
-   }
+       if (styler.Match(keyword_start,"case")
+               || (
+                       styler.Match(keyword_start,"fun")
+                       && (SCE_ERLANG_FUNCTION_NAME != styleNext)
+                       )
+               || styler.Match(keyword_start,"if")
+               || styler.Match(keyword_start,"query")
+               || styler.Match(keyword_start,"receive")
+       ) {
+               ++lev;
+       } else if (styler.Match(keyword_start,"end")) {
+               --lev;
+       }
+
        return lev;
 }
 
-
 static void FoldErlangDoc(
-   unsigned int startPos, int length, int initStyle,
-   WordList** /*keywordlists*/, Accessor &styler
+       unsigned int startPos, int length, int initStyle,
+       WordList** /*keywordlists*/, Accessor &styler
 ) {
        unsigned int endPos = startPos + length;
-       //~ int visibleChars = 0;
-       int lineCurrent = styler.GetLine(startPos);
-       int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
-       int levelCurrent = levelPrev;
-       char chNext = styler.SafeGetCharAt(startPos);
+       int currentLine = styler.GetLine(startPos);
+       int lev;
+       int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
+       int currentLevel = previousLevel;
        int styleNext = styler.StyleAt(startPos);
        int style = initStyle;
+       int stylePrev;
        int keyword_start = 0;
-
-   bool fold_keywords = true;
-   bool fold_comments = true;
-   bool fold_braces = true;
-   bool fold_function_clauses = false;
-   bool fold_clauses = false;
-
-   //int clause_level = 0;
+       char ch;
+       char chNext = styler.SafeGetCharAt(startPos);
+       bool atEOL;
 
        for (unsigned int i = startPos; i < endPos; i++) {
-               char ch = chNext;
+               ch = chNext;
                chNext = styler.SafeGetCharAt(i + 1);
-               int stylePrev = style;
+
+               // Get styles
+               stylePrev = style;
                style = styleNext;
                styleNext = styler.StyleAt(i + 1);
-               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
-      if ( (stylePrev != SCE_ERLANG_KEYWORD) && (style == SCE_ERLANG_KEYWORD) ) {
-         keyword_start = i;
-      }
-      if ( fold_keywords ) {
-         if ( (stylePrev == SCE_ERLANG_KEYWORD)
-            && (style != SCE_ERLANG_KEYWORD)
-            && (style != SCE_ERLANG_ATOM)
-         ) {
-            levelCurrent += ClassifyFoldPointErlang(styler,styleNext,keyword_start);
-         }
-      }
-
-      if ( fold_comments ) {
-         if (style == SCE_ERLANG_COMMENT) {
-            if ((ch == '%') && (chNext == '{')) {
-               levelCurrent++;
-            } else if ((ch == '%') && (chNext == '}')) {
-               levelCurrent--;
-            }
-         }
-      }
-
-      if ( fold_function_clauses ) {
-         if ( (SC_FOLDLEVELBASE == levelCurrent) /*&& (style == SCE_ERLANG_OPERATOR)*/ ) {
-            if ( (ch == '-') && (chNext == '>')) {
-               //~ fprintf(stderr,"levelCurrent=%d\n", levelCurrent);
-               //++clause_level;
-               //~ if ( 0 < clause_level )
-                  ++levelCurrent;
-            }
-         }
-         //~ if (  (stylePrev != SCE_ERLANG_RECORD)
-            //~ && (style != SCE_ERLANG_NUMBER)
-            //~ && (style != SCE_ERLANG_STRING)
-            //~ && (style != SCE_ERLANG_COMMENT)
-         //~ ) {
-            if ( (SC_FOLDLEVELBASE+1 == levelCurrent) && (ch == '.') ) {
-               //--clause_level;
-               //~ if ( 0 == clause_level )
-                  --levelCurrent;
-            }
-         //~ }
-      }
-
-      if ( fold_clauses ) {
-         if ( (0 < levelCurrent) && (style == SCE_ERLANG_OPERATOR) ) {
-            if ((ch == '-') && (chNext == '>')) {
-               levelCurrent++;
-            }
-            if ( (ch == ';') ) {
-               levelCurrent--;
-            }
-         }
-         if ( (stylePrev != SCE_ERLANG_RECORD)
-            && (style != SCE_ERLANG_NUMBER)
-            && (style != SCE_ERLANG_STRING)
-            && (style != SCE_ERLANG_COMMENT)
-         ) {
-            if ( (ch == '.') ) {
-               levelCurrent--;
-            }
-         }
-         if (  (stylePrev == SCE_ERLANG_KEYWORD)
-            && (style != SCE_ERLANG_KEYWORD)
-            && (style != SCE_ERLANG_ATOM)
-            && (
-               styler.Match(keyword_start,"end") // 'end' counted twice if fold_keywords too
-               || styler.Match(keyword_start,"after") )
-         ) {
-            levelCurrent--;
-         }
-      }
-
-      if ( fold_braces ) {
-         if (style == SCE_ERLANG_OPERATOR) {
-            if ( (ch == '{') || (ch == '(') || (ch == '[') ) {
-               levelCurrent++;
-            } else if ( (ch == '}') || (ch == ')') || (ch == ']') ) {
-               levelCurrent--;
-            }
-         }
-      }
+               atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');
+
+               if (stylePrev != SCE_ERLANG_KEYWORD
+                       && style == SCE_ERLANG_KEYWORD) {
+                       keyword_start = i;
+               }
+
+               // Fold on keywords
+               if (stylePrev == SCE_ERLANG_KEYWORD
+                       && style != SCE_ERLANG_KEYWORD
+                       && style != SCE_ERLANG_ATOM
+               ) {
+                       currentLevel += ClassifyErlangFoldPoint(styler,
+                                                                                                       styleNext,
+                                                                                                       keyword_start);
+               }
+
+               // Fold on comments
+               if (style == SCE_ERLANG_COMMENT
+                       || style == SCE_ERLANG_COMMENT_MODULE
+                       || style == SCE_ERLANG_COMMENT_FUNCTION) {
+
+                       if (ch == '%' && chNext == '{') {
+                               currentLevel++;
+                       } else if (ch == '%' && chNext == '}') {
+                               currentLevel--;
+                       }
+               }
+
+               // Fold on braces
+               if (style == SCE_ERLANG_OPERATOR) {
+                       if (ch == '{' || ch == '(' || ch == '[') {
+                               currentLevel++;
+                       } else if (ch == '}' || ch == ')' || ch == ']') {
+                               currentLevel--;
+                       }
+               }
+
 
                if (atEOL) {
-                       int lev = levelPrev;
-                       //~ if (visibleChars == 0 && foldCompact)
-                               //~ lev |= SC_FOLDLEVELWHITEFLAG;
-                       //~ if ((levelCurrent > levelPrev) && (visibleChars > 0))
-                       if ((levelCurrent > levelPrev)) {
+                       lev = previousLevel;
+
+                       if (currentLevel > previousLevel)
                                lev |= SC_FOLDLEVELHEADERFLAG;
-         }
-                       if (lev != styler.LevelAt(lineCurrent)) {
-                               styler.SetLevel(lineCurrent, lev);
-                       }
-                       lineCurrent++;
-                       levelPrev = levelCurrent;
-                       //~ visibleChars = 0;
+
+                       if (lev != styler.LevelAt(currentLine))
+                               styler.SetLevel(currentLine, lev);
+
+                       currentLine++;
+                       previousLevel = currentLevel;
                }
-               //~ 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);
+       styler.SetLevel(currentLine,
+                                       previousLevel
+                                       | (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
 }
 
 static const char * const erlangWordListDesc[] = {
-       "Keywords",
+       "Erlang Reserved words",
+       "Erlang BIFs",
+       "Erlang Preprocessor",
+       "Erlang Module Attributes",
+       "Erlang Documentation",
+       "Erlang Documentation Macro",
        0
 };
 
 LexerModule lmErlang(
-   SCLEX_ERLANG,
-   ColouriseErlangDoc,
-   "erlang",
-   FoldErlangDoc,
-   erlangWordListDesc);
-
+       SCLEX_ERLANG,
+       ColouriseErlangDoc,
+       "erlang",
+       FoldErlangDoc,
+       erlangWordListDesc);
index f097b0e00a1e2b9febac6cc8341e9b1a40d35537..e52543fa552da9e9b1a6c396a08a439981f5a089 100644 (file)
@@ -1,10 +1,8 @@
 // Scintilla source code edit control
-/** @file LexCrontab.cxx
- ** Lexer to use with extended crontab files used by a powerful
- ** Windows scheduler/event monitor/automation manager nnCron.
- ** (http://nemtsev.eserv.ru/)
+/** @file LexForth.cxx
+ ** Lexer for FORTH
  **/
-// 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 <stdlib.h>
@@ -17,6 +15,7 @@
 
 #include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 using namespace Scintilla;
 #endif
 
-bool is_whitespace(int ch){
-    return ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ';
+static inline bool IsAWordChar(int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+               ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
+               ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
+               ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
+               ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
+               ch == ')' );
 }
 
-bool is_blank(int ch){
-    return ch == '\t' || ch == ' ';
+static inline bool IsAWordStart(int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
 }
-//#define FORTH_DEBUG
-#ifdef FORTH_DEBUG
-static FILE *f_debug;
-#define log(x)  fputs(f_debug,x);
-#else
-#define log(x)
-#endif
-
-#define STATE_LOCALE
-#define BL ' '
 
-static Accessor *st;
-static int cur_pos,pos1,pos2,pos0,lengthDoc;
-char *buffer;
-
-char getChar(bool is_bl){
-    char ch=st->SafeGetCharAt(cur_pos);
-    if(is_bl) if(is_whitespace(ch)) ch=BL;
-    return ch;
+static inline bool IsANumChar(int ch) {
+       return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
 }
 
-char getCharBL(){
-    char ch=st->SafeGetCharAt(cur_pos);
-    return ch;
-}
-bool is_eol(char ch){
-    return ch=='\n' || ch=='\r';
-}
-
-int parse(char ch, bool skip_eol){
-// pos1 - start pos of word
-// pos2 - pos after of word
-// pos0 - start pos
-    char c=0;
-    int len;
-    bool is_bl=ch==BL;
-    pos0=pos1=pos2=cur_pos;
-    for(;cur_pos<lengthDoc && (c=getChar(is_bl))==ch; cur_pos++){
-        if(is_eol(c) && !skip_eol){
-            pos2=pos1;
-            return 0;
-        }
-    }
-    pos1=cur_pos;
-    pos2=pos1;
-    if(cur_pos==lengthDoc) return 0;
-    for(len=0;cur_pos<lengthDoc && (c=getChar(is_bl))!=ch; cur_pos++){
-        if(is_eol(c) && !skip_eol) break;
-        pos2++;
-        buffer[len++]=c;
-    }
-    if(c==ch) pos2--;
-    buffer[len]='\0';
-#ifdef FORTH_DEBUG
-    fprintf(f_debug,"parse: %c %s\n",ch,buffer);
-#endif
-    return len;
+static inline bool IsASpaceChar(int ch) {
+       return (ch < 0x80) && isspace(ch);
 }
 
-bool _is_number(char *s,int base){
-    for(;*s;s++){
-        int digit=((int)*s)-(int)'0';
-#ifdef FORTH_DEBUG
-    fprintf(f_debug,"digit: %c %d\n",*s,digit);
-#endif
-        if(digit>9 && base>10) digit-=7;
-        if(digit<0) return false;
-        if(digit>=base) return false;
-    }
-    return true;
-}
-
-bool is_number(char *s){
-    if(strncmp(s,"0x",2)==0) return _is_number(s+2,16);
-    return _is_number(s,10);
-}
-
-static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
-{
-    st=&styler;
-    cur_pos=startPos;
-    lengthDoc = startPos + length;
-    buffer = new char[length];
-
-#ifdef FORTH_DEBUG
-    f_debug=fopen("c:\\sci.log","at");
-#endif
+static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
+                            Accessor &styler) {
 
     WordList &control = *keywordLists[0];
     WordList &keyword = *keywordLists[1];
@@ -127,226 +55,122 @@ static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *
     WordList &preword2 = *keywordLists[4];
     WordList &strings = *keywordLists[5];
 
-    // go through all provided text segment
-    // using the hand-written state machine shown below
-    styler.StartAt(startPos);
-    styler.StartSegment(startPos);
-    while(parse(BL,true)!=0){
-        if(pos0!=pos1){
-            styler.ColourTo(pos0,SCE_FORTH_DEFAULT);
-            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
-        }
-        if(strcmp("\\",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_COMMENT);
-            parse(1,false);
-            styler.ColourTo(pos2,SCE_FORTH_COMMENT);
-        }else if(strcmp("(",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_COMMENT);
-            parse(')',true);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_COMMENT);
-        }else if(strcmp("[",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_STRING);
-            parse(']',true);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_STRING);
-        }else if(strcmp("{",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_LOCALE);
-            parse('}',false);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_LOCALE);
-        }else if(strings.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_STRING);
-            parse('"',false);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_STRING);
-        }else if(control.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_CONTROL);
-            styler.ColourTo(pos2,SCE_FORTH_CONTROL);
-        }else if(keyword.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_KEYWORD);
-            styler.ColourTo(pos2,SCE_FORTH_KEYWORD);
-        }else if(defword.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_KEYWORD);
-            styler.ColourTo(pos2,SCE_FORTH_KEYWORD);
-            parse(BL,false);
-            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
-            styler.ColourTo(pos1,SCE_FORTH_DEFWORD);
-            styler.ColourTo(pos2,SCE_FORTH_DEFWORD);
-        }else if(preword1.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_PREWORD1);
-            parse(BL,false);
-            styler.ColourTo(pos2,SCE_FORTH_PREWORD1);
-        }else if(preword2.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_PREWORD2);
-            parse(BL,false);
-            styler.ColourTo(pos2,SCE_FORTH_PREWORD2);
-            parse(BL,false);
-            styler.ColourTo(pos1,SCE_FORTH_STRING);
-            styler.ColourTo(pos2,SCE_FORTH_STRING);
-        }else if(is_number(buffer)){
-            styler.ColourTo(pos1,SCE_FORTH_NUMBER);
-            styler.ColourTo(pos2,SCE_FORTH_NUMBER);
-        }
-    }
-#ifdef FORTH_DEBUG
-    fclose(f_debug);
-#endif
-    delete []buffer;
-    return;
-/*
-                        if(control.InList(buffer)) {
-                            styler.ColourTo(i,SCE_FORTH_CONTROL);
-                        } else if(keyword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
-                        } else if(defword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
-//                            prev_state=SCE_FORTH_DEFWORD
-                        } else if(preword1.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
-//                            state=SCE_FORTH_PREWORD1;
-                        } else if(preword2.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
-                         } else {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
-                        }
-*/
-/*
-    chPrev=' ';
-    for (int i = startPos; i < lengthDoc; i++) {
-        char ch = chNext;
-        chNext = styler.SafeGetCharAt(i + 1);
-        if(i!=startPos) chPrev=styler.SafeGetCharAt(i - 1);
-
-        if (styler.IsLeadByte(ch)) {
-            chNext = styler.SafeGetCharAt(i + 2);
-            i++;
-            continue;
-        }
-#ifdef FORTH_DEBUG
-        fprintf(f_debug,"%c %d ",ch,state);
-#endif
-        switch(state) {
-            case SCE_FORTH_DEFAULT:
-                if(is_whitespace(ch)) {
-                    // whitespace is simply ignored here...
-                    styler.ColourTo(i,SCE_FORTH_DEFAULT);
-                    break;
-                } else if( ch == '\\' && is_blank(chNext)) {
-                    // signals the start of an one line comment...
-                    state = SCE_FORTH_COMMENT;
-                    styler.ColourTo(i,SCE_FORTH_COMMENT);
-                } else if( is_whitespace(chPrev) &&  ch == '(' &&  is_whitespace(chNext)) {
-                    // signals the start of a plain comment...
-                    state = SCE_FORTH_COMMENT_ML;
-                    styler.ColourTo(i,SCE_FORTH_COMMENT_ML);
-                } else if( isdigit(ch) ) {
-                    // signals the start of a number
-                    bufferCount = 0;
-                    buffer[bufferCount++] = ch;
-                    state = SCE_FORTH_NUMBER;
-                } else if( !is_whitespace(ch)) {
-                    // signals the start of an identifier
-                    bufferCount = 0;
-                    buffer[bufferCount++] = ch;
-                    state = SCE_FORTH_IDENTIFIER;
-                } else {
-                    // style it the default style..
-                    styler.ColourTo(i,SCE_FORTH_DEFAULT);
-                }
-                break;
-
-            case SCE_FORTH_COMMENT:
-                // if we find a newline here,
-                // we simply go to default state
-                // else continue to work on it...
-                if( ch == '\n' || ch == '\r' ) {
-                    state = SCE_FORTH_DEFAULT;
-                } else {
-                    styler.ColourTo(i,SCE_FORTH_COMMENT);
-                }
-                break;
-
-            case SCE_FORTH_COMMENT_ML:
-                if( ch == ')') {
-                    state = SCE_FORTH_DEFAULT;
-                } else {
-                    styler.ColourTo(i+1,SCE_FORTH_COMMENT_ML);
-                }
-                break;
-
-            case SCE_FORTH_IDENTIFIER:
-                // stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
-                if( !is_whitespace(ch) ) {
-                    buffer[bufferCount++] = ch;
-                } else {
-                    state = SCE_FORTH_DEFAULT;
-                    buffer[bufferCount] = '\0';
-#ifdef FORTH_DEBUG
-        fprintf(f_debug,"\nid %s\n",buffer);
-#endif
-
-                    // check if the buffer contains a keyword,
-                    // and highlight it if it is a keyword...
-//                    switch(prev_state)
-//                    case SCE_FORTH_DEFAULT:
-                        if(control.InList(buffer)) {
-                            styler.ColourTo(i,SCE_FORTH_CONTROL);
-                        } else if(keyword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
-                        } else if(defword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
-//                            prev_state=SCE_FORTH_DEFWORD
-                        } else if(preword1.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
-//                            state=SCE_FORTH_PREWORD1;
-                        } else if(preword2.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
-                         } else {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
-                        }
-//                        break;
-//                    case
-
-                    // push back the faulty character
-                    chNext = styler[i--];
-                }
-                break;
-
-            case SCE_FORTH_NUMBER:
-                // stay  in CONF_NUMBER state until we find a non-numeric
-                if( isdigit(ch) ) {
-                    buffer[bufferCount++] = ch;
-                } else {
-                    state = SCE_FORTH_DEFAULT;
-                    buffer[bufferCount] = '\0';
-                    // Colourize here... (normal number)
-                    styler.ColourTo(i-1,SCE_FORTH_NUMBER);
-                    // push back a character
-                    chNext = styler[i--];
-                }
-                break;
-        }
-    }
-#ifdef FORTH_DEBUG
-    fclose(f_debug);
-#endif
-    delete []buffer;
-*/
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       for (; sc.More(); sc.Forward())
+       {
+               // Determine if the current state should terminate.
+               if (sc.state == SCE_FORTH_COMMENT) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_FORTH_DEFAULT);
+                       }
+               }else if (sc.state == SCE_FORTH_COMMENT_ML) {
+                       if (sc.ch == ')') {
+                               sc.ForwardSetState(SCE_FORTH_DEFAULT);
+                       }
+               }else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
+                       // handle numbers here too, because what we thought was a number might
+                       // turn out to be a keyword e.g. 2DUP
+                       if (IsASpaceChar(sc.ch) ) {
+                               char s[100];
+                               sc.GetCurrentLowered(s, sizeof(s));
+                               int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
+                               if (control.InList(s)) {
+                                       sc.ChangeState(SCE_FORTH_CONTROL);
+                               } else if (keyword.InList(s)) {
+                                       sc.ChangeState(SCE_FORTH_KEYWORD);
+                               } else if (defword.InList(s)) {
+                                       sc.ChangeState(SCE_FORTH_DEFWORD);
+                               }  else if (preword1.InList(s)) {
+                                       sc.ChangeState(SCE_FORTH_PREWORD1);
+                               } else if (preword2.InList(s)) {
+                                       sc.ChangeState(SCE_FORTH_PREWORD2);
+                               } else if (strings.InList(s)) {
+                                       sc.ChangeState(SCE_FORTH_STRING);
+                                       newState = SCE_FORTH_STRING;
+                               }
+                               sc.SetState(newState);
+                       }
+                       if (sc.state == SCE_FORTH_NUMBER) {
+                               if (IsASpaceChar(sc.ch)) {
+                                       sc.SetState(SCE_FORTH_DEFAULT);
+                               } else if (!IsANumChar(sc.ch)) {
+                                       sc.ChangeState(SCE_FORTH_IDENTIFIER);
+                               }
+                       }
+               }else if (sc.state == SCE_FORTH_STRING) {
+                       if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_FORTH_DEFAULT);
+                       }
+               }else if (sc.state == SCE_FORTH_LOCALE) {
+                       if (sc.ch == '}') {
+                               sc.ForwardSetState(SCE_FORTH_DEFAULT);
+                       }
+               }else if (sc.state == SCE_FORTH_DEFWORD) {
+                       if (IsASpaceChar(sc.ch)) {
+                               sc.SetState(SCE_FORTH_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_FORTH_DEFAULT) {
+                       if (sc.ch == '\\'){
+                               sc.SetState(SCE_FORTH_COMMENT);
+                       } else if (sc.ch == '(' &&
+                                       (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
+                                       (sc.atLineEnd   || IsASpaceChar(sc.chNext))) {
+                               sc.SetState(SCE_FORTH_COMMENT_ML);
+                       } else if (     (sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
+                               // number starting with $ is a hex number
+                               sc.SetState(SCE_FORTH_NUMBER);
+                               while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
+                                       sc.Forward();
+                       } else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
+                               // number starting with % is binary
+                               sc.SetState(SCE_FORTH_NUMBER);
+                               while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
+                                       sc.Forward();
+                       } else if (     isascii(sc.ch) && 
+                                               (isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
+                                       ){
+                               sc.SetState(SCE_FORTH_NUMBER);
+                       } else if (IsAWordStart(sc.ch)) {
+                               sc.SetState(SCE_FORTH_IDENTIFIER);
+                       } else if (sc.ch == '{') {
+                               sc.SetState(SCE_FORTH_LOCALE);
+                       } else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
+                               // highlight word definitions e.g.  : GCD ( n n -- n ) ..... ;
+                               //                                  ^ ^^^
+                               sc.SetState(SCE_FORTH_DEFWORD);
+                               while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
+                                       sc.Forward();
+                       } else if (sc.ch == ';' &&
+                                       (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
+                                       (sc.atLineEnd   || IsASpaceChar(sc.chNext))     ) {
+                               // mark the ';' that ends a word
+                               sc.SetState(SCE_FORTH_DEFWORD);
+                               sc.ForwardSetState(SCE_FORTH_DEFAULT);
+                       }
+               }
+
+       }
+       sc.Complete();
 }
 
 static void FoldForthDoc(unsigned int, int, int, WordList *[],
-                       Accessor &) {
+                                               Accessor &) {
 }
 
 static const char * const forthWordLists[] = {
-            "control keywords",
-            "keywords",
-            "definition words",
-            "prewords with one argument",
-            "prewords with two arguments",
-            "string definition keywords",
-            0,
-        };
-
-LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth",FoldForthDoc,forthWordLists);
+                       "control keywords",
+                       "keywords",
+                       "definition words",
+                       "prewords with one argument",
+                       "prewords with two arguments",
+                       "string definition keywords",
+                       0,
+               };
+
+LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
+
+                
index c68c5b62fa955f43ab76100554bd2e2a781b0712..0b3f2777c9027d6237504d5eda635212a4bdb003 100644 (file)
@@ -83,8 +83,16 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
                // Handle the fix format generically
                int toLineStart = sc.currentPos - posLineStart;
                if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
-                       if (toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') {
-                               sc.SetState(SCE_F_COMMENT);
+                       if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
+                if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
+                    sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
+                    sc.MatchIgnoreCase("cms$")  || sc.MatchIgnoreCase("*ms$")  || sc.MatchIgnoreCase("!ms$")  ||
+                    sc.chNext == '$') {
+                    sc.SetState(SCE_F_PREPROCESSOR);
+                               } else {
+                                       sc.SetState(SCE_F_COMMENT);
+                               }
+
                                while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
                        } else if (toLineStart > 72) {
                                sc.SetState(SCE_F_COMMENT);
@@ -198,7 +206,8 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
                // Determine if a new state should be entered.
                if (sc.state == SCE_F_DEFAULT) {
                        if (sc.ch == '!') {
-                               if (sc.chNext == '$') {
+                if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
+                    sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
                                        sc.SetState(SCE_F_PREPROCESSOR);
                                } else {
                                        sc.SetState(SCE_F_COMMENT);
@@ -243,7 +252,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
                                lev = 0;
                        else
                                lev = 1;
-       } else if (strcmp(s, "end") == 0 && chNextNonBlank != '='
+       } else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
                || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
                || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
                || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
diff --git a/src/stc/scintilla/src/LexGen.py b/src/stc/scintilla/src/LexGen.py
new file mode 100644 (file)
index 0000000..571332e
--- /dev/null
@@ -0,0 +1,288 @@
+# LexGen.py - implemented 2002 by Neil Hodgson neilh@scintilla.org
+# Released to the public domain.
+
+# Regenerate the Scintilla and SciTE source files that list
+# all the lexers and all the properties files.
+# Should be run whenever a new lexer is added or removed.
+# Requires Python 2.4 or later
+# Most files are regenerated in place with templates stored in comments.
+# The VS .NET project file is generated into a different file as the
+# VS .NET environment will not retain comments when modifying the file.
+# The files are copied to a string apart from sections between a
+# ++Autogenerated comment and a --Autogenerated comment which is
+# generated by the CopyWithInsertion function. After the whole
+# string is instantiated, it is compared with the target file and
+# if different the file is rewritten.
+# Does not regenerate the Visual C++ 6 project files but does the VS .NET
+# project file.
+
+import string
+import sys
+import os
+import glob
+
+# EOL constants
+CR = "\r"
+LF = "\n"
+CRLF = "\r\n"
+if sys.platform == "win32":
+    NATIVE = CRLF
+else:
+    # Yes, LF is the native EOL even on Mac OS X. CR is just for
+    # Mac OS <=9 (a.k.a. "Mac Classic")
+    NATIVE = LF
+
+# Automatically generated sections contain start and end comments,
+# a definition line and the results.
+# The results are replaced by regenerating based on the definition line.
+# The definition line is a comment prefix followed by "**".
+# If there is a digit after the ** then this indicates which list to use
+# and the digit and next character are not part of the definition
+# Backslash is used as an escape within the definition line.
+# The part between \( and \) is repeated for each item in the list.
+# \* is replaced by each list item. \t, and \n are tab and newline.
+def CopyWithInsertion(input, commentPrefix, retainDefs, eolType, *lists):
+    copying = 1
+    listid = 0
+    output = []
+    for line in input.splitlines(0):
+        isStartGenerated = line.startswith(commentPrefix + "++Autogenerated")
+        if copying and not isStartGenerated:
+            output.append(line)
+        if isStartGenerated:
+            if retainDefs:
+                output.append(line)
+            copying = 0
+            definition = ""
+        elif not copying and line.startswith(commentPrefix + "**"):
+            if retainDefs:
+                output.append(line)
+            definition = line[len(commentPrefix + "**"):]
+            if (commentPrefix == "<!--") and (" -->" in definition):
+                definition = definition.replace(" -->", "")
+            listid = 0
+            if definition[0] in string.digits:
+                listid = int(definition[:1])
+                definition = definition[2:]
+            # Hide double slashes as a control character
+            definition = definition.replace("\\\\", "\001")
+            # Do some normal C style transforms
+            definition = definition.replace("\\n", "\n")
+            definition = definition.replace("\\t", "\t")
+            # Get the doubled backslashes back as single backslashes
+            definition = definition.replace("\001", "\\")
+            startRepeat = definition.find("\\(")
+            endRepeat = definition.find("\\)")
+            intro = definition[:startRepeat]
+            out = ""
+            if intro.endswith("\n"):
+                pos = 0
+            else:
+                pos = len(intro)
+            out += intro
+            middle = definition[startRepeat+2:endRepeat]
+            for i in lists[listid]:
+                item = middle.replace("\\*", i)
+                if pos and (pos + len(item) >= 80):
+                    out += "\\\n"
+                    pos = 0
+                out += item
+                pos += len(item)
+                if item.endswith("\n"):
+                    pos = 0
+            outro = definition[endRepeat+2:]
+            out += outro
+            out = out.replace("\n", eolType) # correct EOLs in generated content
+            output.append(out)
+        elif line.startswith(commentPrefix + "--Autogenerated"):
+            copying = 1
+            if retainDefs:
+                output.append(line)
+    output = [line.rstrip(" \t") for line in output] # trim trailing whitespace
+    return eolType.join(output) + eolType
+
+def UpdateFile(filename, updated):
+    """ If the file is different to updated then copy updated
+    into the file else leave alone so CVS and make don't treat
+    it as modified. """
+    try:
+        infile = open(filename, "rb")
+    except IOError:    # File is not there yet
+        out = open(filename, "wb")
+        out.write(updated.encode('utf-8'))
+        out.close()
+        print("New %s" % filename)
+        return
+    original = infile.read()
+    infile.close()
+    original = original.decode('utf-8')
+    if updated != original:
+        os.unlink(filename)
+        out = open(filename, "wb")
+        out.write(updated.encode('utf-8'))
+        out.close()
+        print("Changed %s " % filename)
+    #~ else:
+        #~ print "Unchanged", filename
+
+def Generate(inpath, outpath, commentPrefix, eolType, *lists):
+    """Generate 'outpath' from 'inpath'.
+
+        "eolType" indicates the type of EOLs to use in the generated
+            file. It should be one of following constants: LF, CRLF,
+            CR, or NATIVE.
+    """
+    #print "generate '%s' -> '%s' (comment prefix: %r, eols: %r)"\
+    #      % (inpath, outpath, commentPrefix, eolType)
+    try:
+        infile = open(inpath, "rb")
+    except IOError:
+        print("Can not open %s" % inpath)
+        return
+    original = infile.read()
+    infile.close()
+    original = original.decode('utf-8')
+    updated = CopyWithInsertion(original, commentPrefix,
+        inpath == outpath, eolType, *lists)
+    UpdateFile(outpath, updated)
+
+def Regenerate(filename, commentPrefix, eolType, *lists):
+    """Regenerate the given file.
+
+        "eolType" indicates the type of EOLs to use in the generated
+            file. It should be one of following constants: LF, CRLF,
+            CR, or NATIVE.
+    """
+    Generate(filename, filename, commentPrefix, eolType, *lists)
+
+def FindModules(lexFile):
+    modules = []
+    f = open(lexFile)
+    for l in f.readlines():
+        if l.startswith("LexerModule"):
+            l = l.replace("(", " ")
+            modules.append(l.split()[1])
+    return modules
+
+knownIrregularProperties = [
+    "fold",
+    "styling.within.preprocessor",
+    "tab.timmy.whinge.level",
+    "asp.default.language",
+    "html.tags.case.sensitive",
+    "ps.level",
+    "ps.tokenize",
+    "sql.backslash.escapes",
+    "nsis.uservars",
+    "nsis.ignorecase"
+]
+
+def FindProperties(lexFile):
+    properties = {}
+    f = open(lexFile)
+    for l in f.readlines():
+        if "GetProperty" in l:
+            l = l.strip()
+            if not l.startswith("//"): # Drop comments
+                propertyName = l.split("\"")[1]
+                if propertyName.lower() == propertyName:
+                    # Only allow lower case property names
+                    if propertyName in knownIrregularProperties or \
+                        propertyName.startswith("fold.") or \
+                        propertyName.startswith("lexer."):
+                        properties[propertyName] = 1
+    return properties
+
+def FindPropertyDocumentation(lexFile):
+    documents = {}
+    f = open(lexFile)
+    name = ""
+    for l in f.readlines():
+        l = l.strip()
+        if "// property " in l:
+            propertyName = l.split()[2]
+            if propertyName.lower() == propertyName:
+                # Only allow lower case property names
+                name = propertyName
+                documents[name] = ""
+        elif name:
+            if l.startswith("//"):
+                if documents[name]:
+                    documents[name] += " "
+                documents[name] += l[2:].strip()
+            else:
+                name = ""
+    return documents
+
+def ciCompare(a,b):
+    return cmp(a.lower(), b.lower())
+
+def ciKey(a):
+    return a.lower()
+    
+def sortListInsensitive(l):
+    try:    # Try key function
+        l.sort(key=ciKey)
+    except TypeError:    # Earlier version of Python, so use comparison function
+        l.sort(ciCompare)
+
+def RegenerateAll():
+    root="../../"
+
+    # Find all the lexer source code files
+    lexFilePaths = glob.glob(root + "scintilla/src/Lex*.cxx")
+    sortListInsensitive(lexFilePaths)
+    lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
+    print(lexFiles)
+    lexerModules = []
+    lexerProperties = {}
+    propertyDocuments = {}
+    for lexFile in lexFilePaths:
+        lexerModules.extend(FindModules(lexFile))
+        for k in FindProperties(lexFile).keys():
+            lexerProperties[k] = 1
+        documents = FindPropertyDocumentation(lexFile)
+        for k in documents.keys():
+            propertyDocuments[k] = documents[k]
+    sortListInsensitive(lexerModules)
+    del lexerProperties["fold.comment.python"]
+    lexerProperties = list(lexerProperties.keys())
+    sortListInsensitive(lexerProperties)
+
+    # Generate HTML to document each property
+    # This is done because tags can not be safely put inside comments in HTML
+    documentProperties = list(propertyDocuments.keys())
+    sortListInsensitive(documentProperties)
+    propertiesHTML = []
+    for k in documentProperties:
+        propertiesHTML.append("\t<tr>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" % 
+            (k, propertyDocuments[k]))
+        
+    # Find all the SciTE properties files
+    otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"]
+    if os.path.exists(root + "scite"):
+        propFilePaths = glob.glob(root + "scite/src/*.properties")
+        sortListInsensitive(propFilePaths)
+        propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps]
+        sortListInsensitive(propFiles)
+        print(propFiles)
+
+    Regenerate(root + "scintilla/src/KeyWords.cxx", "//", NATIVE, lexerModules)
+    Regenerate(root + "scintilla/win32/makefile", "#", NATIVE, lexFiles)
+    Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
+    Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
+    # Use Unix EOLs for gtk Makefiles so they work for Linux users when
+    # extracted from the Scintilla source ZIP (typically created on
+    # Windows).
+    Regenerate(root + "scintilla/gtk/makefile", "#", LF, lexFiles)
+    Regenerate(root + "scintilla/gtk/scintilla.mak", "#", NATIVE, lexFiles)
+    Regenerate(root + "scintilla/macosx/makefile", "#", LF, lexFiles)
+    if os.path.exists(root + "scite"):
+        Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
+        Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)
+        Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties)
+        Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", NATIVE, propertiesHTML)
+        Generate(root + "scite/boundscheck/vcproj.gen",
+         root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
+
+RegenerateAll()
index 9b8d5dc92339065959e78d6b0caf076e136b72de..6038326e3eea86bff63c7753a25b81ac43cbeafa 100644 (file)
@@ -29,7 +29,7 @@ using namespace Scintilla;
 #define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
 #define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
 
-enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock };
+enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };
 enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
 
 static inline bool IsAWordChar(const int ch) {
@@ -69,6 +69,22 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
        s[i] = '\0';
 }
 
+static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
+
+       size_t i = 0;
+       for (; i < sLen-1; i++) {
+               char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
+               if ((i == 0) && !IsAWordStart(ch))
+                       break;
+               if ((i > 0) && !IsAWordChar(ch)) 
+                       break;
+               s[i] = ch;
+       }
+       s[i] = '\0';
+       
+       return s;
+}
+
 static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
        char s[100];
        GetTextSegment(styler, start, end, s, sizeof(s));
@@ -249,7 +265,7 @@ static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &k
 
 static int classifyTagHTML(unsigned int start, unsigned int end,
                            WordList &keywords, Accessor &styler, bool &tagDontFold,
-                          bool caseSensitive, bool isXml) {
+                          bool caseSensitive, bool isXml, bool allowScripts) {
        char s[30 + 2];
        // Copy after the '<'
        unsigned int i = 0;
@@ -268,31 +284,41 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
        // if the current language is XML, I can fold any tag
        // if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)
        //...to find it in the list of no-container-tags
-       tagDontFold = (!isXml) && (NULL != strstr("meta link img area br hr input ",s));
+       tagDontFold = (!isXml) && (NULL != strstr("meta link img area br hr input ", s));
 
        //now we can remove the trailing space
        s[i] = '\0';
 
-       bool isScript = false;
+       // No keywords -> all are known
        char chAttr = SCE_H_TAGUNKNOWN;
        if (s[0] == '!') {
                chAttr = SCE_H_SGML_DEFAULT;
-       } else if (s[0] == '/') {       // Closing tag
-               if (keywords.InList(s + 1))
-                       chAttr = SCE_H_TAG;
-       } else {
-               if (keywords.InList(s)) {
-                       chAttr = SCE_H_TAG;
-                       isScript = 0 == strcmp(s, "script");
-               }
-       }
-       if ((chAttr == SCE_H_TAGUNKNOWN) && !keywords) {
-               // No keywords -> all are known
+       } else if (!keywords || keywords.InList(s)) {
                chAttr = SCE_H_TAG;
-               isScript = 0 == strcmp(s, "script");
        }
        styler.ColourTo(end, chAttr);
-       return isScript ? SCE_H_SCRIPT : chAttr;
+       if (chAttr == SCE_H_TAG) {
+               if (allowScripts && 0 == strcmp(s, "script")) {
+                       // check to see if this is a self-closing tag by sniffing ahead
+                       bool isSelfClose = false;
+                       for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
+                               char ch = styler.SafeGetCharAt(cPos, '\0');
+                               if (ch == '\0' || ch == '>')
+                                       break;
+                               else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') {
+                                       isSelfClose = true;
+                                       break;
+                               }
+                       }
+
+                       // do not enter a script state if the tag self-closed
+                       if (!isSelfClose)
+                               chAttr = SCE_H_SCRIPT;
+               } else if (!isXml && 0 == strcmp(s, "comment")) {
+                       chAttr = SCE_H_COMMENT;
+               }
+       }
+       return chAttr;
 }
 
 static void classifyWordHTJS(unsigned int start, unsigned int end,
@@ -411,6 +437,9 @@ static int StateForScript(script_type scriptLanguage) {
        case eScriptSGML:
                Result = SCE_H_SGML_DEFAULT;
                break;
+       case eScriptComment:
+               Result = SCE_H_COMMENT;
+               break;
        default :
                Result = SCE_HJ_START;
                break;
@@ -461,6 +490,23 @@ static bool isOKBeforeRE(int ch) {
        return (ch == '(') || (ch == '=') || (ch == ',');
 }
 
+static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
+       if (strlen(blockType) == 0) {
+               return ((ch == '%') && (chNext == '>'));
+       } else if ((0 == strcmp(blockType, "inherit")) ||
+                          (0 == strcmp(blockType, "namespace")) || 
+                          (0 == strcmp(blockType, "include")) ||
+                          (0 == strcmp(blockType, "page"))) {
+               return ((ch == '/') && (chNext == '>'));
+       } else if (0 == strcmp(blockType, "%")) {
+               return isLineEnd(ch);
+       } else if (0 == strcmp(blockType, "{")) {
+               return ch == '}';
+       } else {
+               return (ch == '>');
+       }
+}
+
 static bool isPHPStringState(int state) {
        return
            (state == SCE_HPHP_HSTRING) ||
@@ -469,19 +515,51 @@ static bool isPHPStringState(int state) {
            (state == SCE_HPHP_COMPLEX_VARIABLE);
 }
 
-static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
+static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler, bool &isSimpleString) {
        int j;
+       const int beginning = i - 1;
+       bool isValidSimpleString = false;
+
        while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
                i++;
-       phpStringDelimiter[0] = '\n';
-       for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
+
+       char ch = styler.SafeGetCharAt(i);
+       const char chNext = styler.SafeGetCharAt(i + 1);
+       if (!IsPhpWordStart(ch)) {
+               if (ch == '\'' && IsPhpWordStart(chNext)) {
+                       i++;
+                       ch = chNext;
+                       isSimpleString = true;
+               } else {
+                       phpStringDelimiter[0] = '\0';
+                       return beginning;
+               }
+       }
+       phpStringDelimiter[0] = ch;
+       i++;
+
+       for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) {
+               if (!IsPhpWordChar(styler[j])) {
+                       if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) {
+                               isValidSimpleString = true;
+                               j++;
+                               break;
+                       } else {
+                               phpStringDelimiter[0] = '\0';
+                               return beginning;
+                       }
+               }
                if (j - i < phpStringDelimiterSize - 2)
                        phpStringDelimiter[j-i+1] = styler[j];
                else
                        i++;
        }
-       phpStringDelimiter[j-i+1] = '\0';
-       return j;
+       if (isSimpleString && !isValidSimpleString) {
+               phpStringDelimiter[0] = '\0';
+               return beginning;
+       }
+       phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0';
+       return j - 1;
 }
 
 static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
@@ -497,10 +575,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
        char prevWord[200];
        prevWord[0] = '\0';
+       char nextWord[200];
+       nextWord[0] = '\0';
        char phpStringDelimiter[200]; // PHP is not limited in length, we are
        phpStringDelimiter[0] = '\0';
        int StateToPrint = initStyle;
        int state = stateForPrintState(StateToPrint);
+       char makoBlockType[200];
+       makoBlockType[0] = '\0';
 
        // If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
        if (InTagState(state)) {
@@ -510,11 +592,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                }
                state = SCE_H_DEFAULT;
        }
-       // String can be heredoc, must find a delimiter first
-       while (startPos > 0 && isPHPStringState(state) && state != SCE_HPHP_SIMPLESTRING) {
-               startPos--;
-               length++;
-               state = styler.StyleAt(startPos);
+       // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
+       if (isPHPStringState(state)) {
+               while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
+                       startPos--;
+                       length++;
+                       state = styler.StyleAt(startPos);
+               }
+               if (startPos == 0)
+                       state = SCE_H_DEFAULT;
        }
        styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
 
@@ -525,6 +611,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        } else {
                // Default client and ASP scripting language is JavaScript
                lineState = eScriptJS << 8;
+
+               // property asp.default.language 
+               //      Script in ASP code is initially assumed to be in JavaScript. 
+               //      To change this to VBScript set asp.default.language to 2. Python is 3.
                lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
        }
        script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
@@ -536,13 +626,48 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
 
        script_type scriptLanguage = ScriptOfState(state);
+       // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
+       if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
+               scriptLanguage = eScriptComment;
+       }
 
+       // property fold.html 
+       //      Folding is turned on or off for HTML and XML files with this option. 
+       //      The fold option must also be on for folding to occur.
        const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
+
        const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
+
+       // property fold.html.preprocessor 
+       //      Folding is turned on or off for scripts embedded in HTML files with this option. 
+       //      The default is on.
        const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
+
        const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+       // property fold.hypertext.comment 
+       //      Allow folding for comments in scripts embedded in HTML. 
+       //      The default is off. 
+       const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
+
+       // property fold.hypertext.heredoc 
+       //      Allow folding for heredocs in scripts embedded in HTML. 
+       //      The default is off.  
+       const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
+
+       // property html.tags.case.sensitive 
+       //      For XML and HTML, setting this property to 1 will make tags match in a case 
+       //      sensitive way which is the expected behaviour for XML and XHTML. 
        const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
 
+       // property lexer.xml.allow.scripts 
+       //      Set to 0 to disable scripts in XML.  
+       const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
+
+       // property lexer.html.mako 
+       //      Set to 1 to enable the mako template language.  
+       const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
+
        const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
        const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
        const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
@@ -550,6 +675,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
        int levelCurrent = levelPrev;
        int visibleChars = 0;
+       int lineStartVisibleChars = 0;
 
        int chPrev = ' ';
        int ch = ' ';
@@ -590,6 +716,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 
                if ((!IsASpace(ch) || !foldCompact) && fold)
                        visibleChars++;
+               if (!IsASpace(ch))
+                       lineStartVisibleChars++;
 
                // decide what is the current state to print (depending of the script tag)
                StateToPrint = statePrintForState(state, inScriptType);
@@ -604,9 +732,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                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;
+                                       if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
+                                               levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
                                        }
+                               } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
+                                       levelCurrent--;
                                }
                                break;
                        case eScriptPython:
@@ -656,6 +786,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                levelPrev = levelCurrent;
                        }
                        lineCurrent++;
+                       lineStartVisibleChars = 0;
                        styler.SetLineState(lineCurrent,
                                            ((inScriptType & 0x03) << 0) |
                                            ((tagOpened & 0x01) << 2) |
@@ -665,6 +796,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                            ((beforePreProc & 0xFF) << 12));
                }
 
+               // Allow falling through to mako handling code if newline is going to end a block
+               if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
+                       (!isMako || (0 != strcmp(makoBlockType, "%")))) {
+               }
+               
                // generic end of script processing
                else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
                        // Check if it's the end of the script tag (or any other HTML tag)
@@ -686,19 +822,22 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        case SCE_HP_STRING:
                        case SCE_HP_TRIPLE:
                        case SCE_HP_TRIPLEDOUBLE:
+                       case SCE_HPHP_HSTRING:
+                       case SCE_HPHP_SIMPLESTRING:
+                       case SCE_HPHP_COMMENT:
+                       case SCE_HPHP_COMMENTLINE:
                                break;
                        default :
                                // check if the closing tag is a script tag
-                               if (state == SCE_HJ_COMMENTLINE || isXml) {
-                                       char tag[7]; // room for the <script> tag
-                                       int j = 0;
-                                       char chr = styler.SafeGetCharAt(i+2);
-                                       while (j < 6 && !IsASpace(chr)) {
-                                               tag[j++] = static_cast<char>(MakeLowerCase(chr));
-                                               chr = styler.SafeGetCharAt(i+2+j);
-                                       }
-                                       tag[j] = '\0';
-                                       if (strcmp(tag, "script") != 0) break;
+                               if (const char *tag =
+                                               state == SCE_HJ_COMMENTLINE || isXml ? "script" :
+                                               state == SCE_H_COMMENT ? "comment" : 0) {
+                                       int j = i + 2;
+                                       int chr;
+                                       do {
+                                               chr = static_cast<int>(*tag++);
+                                       } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++)));
+                                       if (chr != 0) break;
                                }
                                // closing tag of the script (it's a closing HTML tag anyway)
                                styler.ColourTo(i - 1, StateToPrint);
@@ -721,13 +860,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                         (ch == '<') &&
                         (chNext == '?') &&
                                 !IsScriptCommentState(state) ) {
-                       scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 10, eScriptPHP);
+                       scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
                        if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
                        styler.ColourTo(i - 1, StateToPrint);
                        beforePreProc = state;
                        i++;
                        visibleChars++;
-                       i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 10);
+                       i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6);
                        if (scriptLanguage == eScriptXML)
                                styler.ColourTo(i, SCE_H_XMLSTART);
                        else
@@ -746,8 +885,54 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        continue;
                }
 
+               // handle the start Mako template Python code
+               else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') || 
+                                                                                                                        (lineStartVisibleChars == 1 && ch == '%') ||
+                                                                                                                        (ch == '$' && chNext == '{') ||
+                                                                                                                        (ch == '<' && chNext == '/' && chNext2 == '%'))) {
+                       if (ch == '%')
+                               strcpy(makoBlockType, "%");
+                       else if (ch == '$') 
+                               strcpy(makoBlockType, "{");
+                       else if (chNext == '/')
+                               GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
+                       else
+                               GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType));
+                       styler.ColourTo(i - 1, StateToPrint);
+                       beforePreProc = state;
+                       if (inScriptType == eNonHtmlScript)
+                               inScriptType = eNonHtmlScriptPreProc;
+                       else
+                               inScriptType = eNonHtmlPreProc;
+
+                       if (chNext == '/') {
+                               i += 2;
+                               visibleChars += 2;
+                       } else if (ch != '%') {
+                               i++;
+                               visibleChars++;
+                       }
+                       state = SCE_HP_START;
+                       scriptLanguage = eScriptPython;
+                       styler.ColourTo(i, SCE_H_ASP);
+                       if (foldHTMLPreprocessor && ch == '<')
+                               levelCurrent++;
+                               
+                       if (ch != '%' && ch != '$') {
+                               i += strlen(makoBlockType);
+                               visibleChars += strlen(makoBlockType);
+                               if (keywords4.InList(makoBlockType))
+                                       styler.ColourTo(i, SCE_HP_WORD);
+                               else
+                                       styler.ColourTo(i, SCE_H_TAGUNKNOWN);
+                       }
+
+                       ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+                       continue;
+               }
+
                // handle the start of ASP pre-processor = Non-HTML
-               else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
+               else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
                        styler.ColourTo(i - 1, StateToPrint);
                        beforePreProc = state;
                        if (inScriptType == eNonHtmlScript)
@@ -807,17 +992,48 @@ 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)
-                       if (foldHTMLPreprocessor)
+                       if (foldHTMLPreprocessor || (state == SCE_H_COMMENT))
                                levelCurrent++;
                        continue;
                }
 
+               // handle the end of Mako Python code
+               else if (isMako && 
+                            ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && 
+                                (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
+                                isMakoBlockEnd(ch, chNext, makoBlockType)) {
+                       if (state == SCE_H_ASPAT) {
+                               aspScript = segIsScriptingIndicator(styler,
+                                                                   styler.GetStartSegment(), i - 1, aspScript);
+                       }
+                       if (state == SCE_HP_WORD) {
+                               classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
+                       } else {
+                               styler.ColourTo(i - 1, StateToPrint);
+                       }
+                       if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') {
+                               i++;
+                               visibleChars++;
+                   }
+                       if (0 != strcmp(makoBlockType, "%")) {
+                               styler.ColourTo(i, SCE_H_ASP);
+                       }
+                       state = beforePreProc;
+                       if (inScriptType == eNonHtmlScriptPreProc)
+                               inScriptType = eNonHtmlScript;
+                       else
+                               inScriptType = eHtml;
+                       if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
+                               levelCurrent--;
+                       }
+                       scriptLanguage = eScriptNone;
+                       continue;
+               }
+
                // handle the end of a pre-processor = Non-HTML
-               else if ((
-                            ((inScriptType == eNonHtmlPreProc)
-                             || (inScriptType == eNonHtmlScriptPreProc)) && (
-                                ((scriptLanguage != eScriptNone) && stateAllowsTermination(state) && ((ch == '%') || (ch == '?')))
-                            ) && (chNext == '>')) ||
+               else if ((!isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+                                 (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
+                                 (((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
                         ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
                        if (state == SCE_H_ASPAT) {
                                aspScript = segIsScriptingIndicator(styler,
@@ -1005,7 +1221,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        break;
                case SCE_H_COMMENT:
-                       if ((chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
+                       if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
                                styler.ColourTo(i, StateToPrint);
                                state = SCE_H_DEFAULT;
                                levelCurrent--;
@@ -1043,23 +1259,25 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        if (ch != '#' && !(isascii(ch) && isalnum(ch))  // Should check that '#' follows '&', but it is unlikely anyway...
                                && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML
-                               styler.ColourTo(i, SCE_H_TAGUNKNOWN);
+                               if (!isascii(ch))       // Possibly start of a multibyte character so don't allow this byte to be in entity style
+                                       styler.ColourTo(i-1, SCE_H_TAGUNKNOWN);
+                               else
+                                       styler.ColourTo(i, SCE_H_TAGUNKNOWN);
                                state = SCE_H_DEFAULT;
                        }
                        break;
                case SCE_H_TAGUNKNOWN:
                        if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) {
                                int eClass = classifyTagHTML(styler.GetStartSegment(),
-                                       i - 1, keywords, styler, tagDontFold, caseSensitive, isXml);
-                               if (eClass == SCE_H_SCRIPT) {
+                                       i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts);
+                               if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) {
                                        if (!tagClosing) {
                                                inScriptType = eNonHtmlScript;
-                                               scriptLanguage = clientScript;
-                                               eClass = SCE_H_TAG;
+                                               scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment;
                                        } else {
                                                scriptLanguage = eScriptNone;
-                                               eClass = SCE_H_TAG;
                                        }
+                                       eClass = SCE_H_TAG;
                                }
                                if (ch == '>') {
                                        styler.ColourTo(i, eClass);
@@ -1069,7 +1287,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                state = SCE_H_DEFAULT;
                                        }
                                        tagOpened = false;
-                                       if (!tagDontFold){
+                                       if (!tagDontFold) {
                                                if (tagClosing) {
                                                        levelCurrent--;
                                                } else {
@@ -1117,8 +1335,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                state = SCE_H_DEFAULT;
                                        }
                                        tagOpened = false;
-                                       if (!tagDontFold){
-                                               if (tagClosing){
+                                       if (!tagDontFold) {
+                                               if (tagClosing) {
                                                        levelCurrent--;
                                                } else {
                                                        levelCurrent++;
@@ -1143,8 +1361,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                        state = SCE_H_DEFAULT;
                                }
                                tagOpened = false;
-                               if (!tagDontFold){
-                                       if (tagClosing){
+                               if (!tagDontFold) {
+                                       if (tagClosing) {
                                                levelCurrent--;
                                        } else {
                                                levelCurrent++;
@@ -1217,8 +1435,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                                        state = SCE_H_DEFAULT;
                                                }
                                                tagOpened = false;
-                                               if (!tagDontFold){
-                                                       if (tagClosing){
+                                               if (!tagDontFold) {
+                                                       if (tagClosing) {
                                                                levelCurrent--;
                                                        } else {
                                                                levelCurrent++;
@@ -1577,10 +1795,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                        state = SCE_HPHP_HSTRING;
                                        strcpy(phpStringDelimiter, "\"");
                                } else if (styler.Match(i, "<<<")) {
-                                       state = SCE_HPHP_HSTRING;
-                                       i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
+                                       bool isSimpleString = false;
+                                       i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
+                                       if (strlen(phpStringDelimiter)) {
+                                               state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
+                                               if (foldHeredoc) levelCurrent++;
+                                       }
                                } else if (ch == '\'') {
                                        state = SCE_HPHP_SIMPLESTRING;
+                                       strcpy(phpStringDelimiter, "\'");
                                } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                        state = SCE_HPHP_VARIABLE;
                                } else if (IsOperator(ch)) {
@@ -1603,12 +1826,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                        }
                        break;
                case SCE_HPHP_VARIABLE:
-                       if (!IsPhpWordChar(ch)) {
-                               styler.ColourTo(i - 1, SCE_HPHP_VARIABLE);
-                               if (IsOperator(ch))
-                                       state = SCE_HPHP_OPERATOR;
-                               else
-                                       state = SCE_HPHP_DEFAULT;
+                       if (!IsPhpWordChar(chNext)) {
+                               styler.ColourTo(i, SCE_HPHP_VARIABLE);
+                               state = SCE_HPHP_DEFAULT;
                        }
                        break;
                case SCE_HPHP_COMMENT:
@@ -1635,26 +1855,48 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                styler.ColourTo(i - 1, StateToPrint);
                                state = SCE_HPHP_HSTRING_VARIABLE;
                        } else if (styler.Match(i, phpStringDelimiter)) {
+                               if (phpStringDelimiter[0] == '\"') {
+                                       styler.ColourTo(i, StateToPrint);
+                                       state = SCE_HPHP_DEFAULT;
+                               } else if (isLineEnd(chPrev)) {
                                const int psdLength = strlen(phpStringDelimiter);
-                               if ((psdLength > 1) && ((i + psdLength) < lengthDoc))
-                                       i += psdLength - 1;
-                               styler.ColourTo(i, StateToPrint);
-                               state = SCE_HPHP_DEFAULT;
+                                       const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
+                                       const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
+                                       if (isLineEnd(chAfterPsd) ||
+                                               (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
+                                                       i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
+                                               styler.ColourTo(i, StateToPrint);
+                                               state = SCE_HPHP_DEFAULT;
+                                               if (foldHeredoc) levelCurrent--;
+                                       }
+                               }
                        }
                        break;
                case SCE_HPHP_SIMPLESTRING:
-                       if (ch == '\\') {
-                               // skip the next char
-                               i++;
-                       } else if (ch == '\'') {
-                               styler.ColourTo(i, StateToPrint);
-                               state = SCE_HPHP_DEFAULT;
+                       if (phpStringDelimiter[0] == '\'') {
+                               if (ch == '\\') {
+                                       // skip the next char
+                                       i++;
+                               } else if (ch == '\'') {
+                                       styler.ColourTo(i, StateToPrint);
+                                       state = SCE_HPHP_DEFAULT;
+                               }
+                       } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
+                               const int psdLength = strlen(phpStringDelimiter);
+                               const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
+                               const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
+                               if (isLineEnd(chAfterPsd) ||
+                               (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
+                                       i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
+                                       styler.ColourTo(i, StateToPrint);
+                                       state = SCE_HPHP_DEFAULT;
+                                       if (foldHeredoc) levelCurrent--;
+                               }
                        }
                        break;
                case SCE_HPHP_HSTRING_VARIABLE:
-                       if (!IsPhpWordChar(ch)) {
-                               styler.ColourTo(i - 1, StateToPrint);
-                               i--; // strange but it works
+                       if (!IsPhpWordChar(chNext)) {
+                               styler.ColourTo(i, StateToPrint);
                                state = SCE_HPHP_HSTRING;
                        }
                        break;
@@ -1683,10 +1925,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                                state = SCE_HPHP_HSTRING;
                                strcpy(phpStringDelimiter, "\"");
                        } else if (styler.Match(i, "<<<")) {
-                               state = SCE_HPHP_HSTRING;
-                               i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
+                               bool isSimpleString = false;
+                               i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
+                               if (strlen(phpStringDelimiter)) {
+                                       state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
+                                       if (foldHeredoc) levelCurrent++;
+                               }
                        } else if (ch == '\'') {
                                state = SCE_HPHP_SIMPLESTRING;
+                               strcpy(phpStringDelimiter, "\'");
                        } else if (ch == '$' && IsPhpWordStart(chNext)) {
                                state = SCE_HPHP_VARIABLE;
                        } else if (IsOperator(ch)) {
@@ -1742,8 +1989,24 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
                }
        }
 
-       StateToPrint = statePrintForState(state, inScriptType);
+       switch (state) {
+       case SCE_HJ_WORD:
+               classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType);
+               break;
+       case SCE_HB_WORD:
+               classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
+               break;
+       case SCE_HP_WORD:
+               classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
+               break;
+       case SCE_HPHP_WORD:
+               classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);
+               break;
+       default:
+               StateToPrint = statePrintForState(state, inScriptType);
                styler.ColourTo(lengthDoc - 1, StateToPrint);
+               break;
+       }
 
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
        if (fold) {
@@ -1755,312 +2018,20 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 static void ColouriseXMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                                   Accessor &styler) {
        // Passing in true because we're lexing XML
-       ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists,styler, true);
+       ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true);
 }
 
 static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                                   Accessor &styler) {
        // Passing in false because we're notlexing XML
-       ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists,styler, false);
-}
-
-static bool isASPScript(int state) {
-       return
-               (state >= SCE_HJA_START && state <= SCE_HJA_REGEX) ||
-               (state >= SCE_HBA_START && state <= SCE_HBA_STRINGEOL) ||
-               (state >= SCE_HPA_DEFAULT && state <= SCE_HPA_IDENTIFIER);
-}
-
-static void ColouriseHBAPiece(StyleContext &sc, WordList *keywordlists[]) {
-       WordList &keywordsVBS = *keywordlists[2];
-       if (sc.state == SCE_HBA_WORD) {
-               if (!IsAWordChar(sc.ch)) {
-                       char s[100];
-                       sc.GetCurrentLowered(s, sizeof(s));
-                       if (keywordsVBS.InList(s)) {
-                               if (strcmp(s, "rem") == 0) {
-                                       sc.ChangeState(SCE_HBA_COMMENTLINE);
-                                       if (sc.atLineEnd) {
-                                               sc.SetState(SCE_HBA_DEFAULT);
-                                       }
-                               } else {
-                                       sc.SetState(SCE_HBA_DEFAULT);
-                               }
-                       } else {
-                               sc.ChangeState(SCE_HBA_IDENTIFIER);
-                               sc.SetState(SCE_HBA_DEFAULT);
-                       }
-               }
-       } else if (sc.state == SCE_HBA_NUMBER) {
-               if (!IsAWordChar(sc.ch)) {
-                       sc.SetState(SCE_HBA_DEFAULT);
-               }
-       } else if (sc.state == SCE_HBA_STRING) {
-               if (sc.ch == '\"') {
-                       sc.ForwardSetState(SCE_HBA_DEFAULT);
-               } else if (sc.ch == '\r' || sc.ch == '\n') {
-                       sc.ChangeState(SCE_HBA_STRINGEOL);
-                       sc.ForwardSetState(SCE_HBA_DEFAULT);
-               }
-       } else if (sc.state == SCE_HBA_COMMENTLINE) {
-               if (sc.ch == '\r' || sc.ch == '\n') {
-                       sc.SetState(SCE_HBA_DEFAULT);
-               }
-       }
-
-       if (sc.state == SCE_HBA_DEFAULT) {
-               if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-                       sc.SetState(SCE_HBA_NUMBER);
-               } else if (IsAWordStart(sc.ch)) {
-                       sc.SetState(SCE_HBA_WORD);
-               } else if (sc.ch == '\'') {
-                       sc.SetState(SCE_HBA_COMMENTLINE);
-               } else if (sc.ch == '\"') {
-                       sc.SetState(SCE_HBA_STRING);
-               }
-       }
-}
-
-static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) {
-       WordList &keywordsTags = *keywordlists[0];
-       if (sc.state == SCE_H_COMMENT) {
-               if (sc.Match("-->")) {
-                       sc.Forward();
-                       sc.Forward();
-                       sc.ForwardSetState(SCE_H_DEFAULT);
-               }
-       } else if (sc.state == SCE_H_ENTITY) {
-               if (sc.ch == ';') {
-                       sc.ForwardSetState(SCE_H_DEFAULT);
-               } else if (sc.ch != '#' && (sc.ch < 0x80) && !isalnum(sc.ch)    // Should check that '#' follows '&', but it is unlikely anyway...
-                       && sc.ch != '.' && sc.ch != '-' && sc.ch != '_' && sc.ch != ':') { // valid in XML
-                       sc.ChangeState(SCE_H_TAGUNKNOWN);
-                       sc.SetState(SCE_H_DEFAULT);
-               }
-       } else if (sc.state == SCE_H_TAGUNKNOWN) {
-               if (!ishtmlwordchar(sc.ch) && !((sc.ch == '/') && (sc.chPrev == '<')) && sc.ch != '[') {
-                       char s[100];
-                       sc.GetCurrentLowered(s, sizeof(s));
-                       if (s[1] == '/') {
-                               if (keywordsTags.InList(s + 2)) {
-                                       sc.ChangeState(SCE_H_TAG);
-                               }
-                       } else {
-                               if (keywordsTags.InList(s + 1)) {
-                                       sc.ChangeState(SCE_H_TAG);
-                               }
-                       }
-                       if (sc.ch == '>') {
-                               sc.ForwardSetState(SCE_H_DEFAULT);
-                       } else if (sc.Match('/', '>')) {
-                               sc.SetState(SCE_H_TAGEND);
-                               sc.Forward();
-                               sc.ForwardSetState(SCE_H_DEFAULT);
-                       } else {
-                               sc.SetState(SCE_H_OTHER);
-                       }
-               }
-       } else if (sc.state == SCE_H_ATTRIBUTE) {
-               if (!ishtmlwordchar(sc.ch)) {
-                       char s[100];
-                       sc.GetCurrentLowered(s, sizeof(s));
-                       if (!keywordsTags.InList(s)) {
-                               sc.ChangeState(SCE_H_ATTRIBUTEUNKNOWN);
-                       }
-                       sc.SetState(SCE_H_OTHER);
-               }
-       } else if (sc.state == SCE_H_OTHER) {
-               if (sc.ch == '>') {
-                       sc.SetState(SCE_H_TAG);
-                       sc.ForwardSetState(SCE_H_DEFAULT);
-               } else if (sc.Match('/', '>')) {
-                       sc.SetState(SCE_H_TAG);
-                       sc.Forward();
-                       sc.ForwardSetState(SCE_H_DEFAULT);
-               } else if (sc.chPrev == '=') {
-                       sc.SetState(SCE_H_VALUE);
-               }
-       } else if (sc.state == SCE_H_DOUBLESTRING) {
-               if (sc.ch == '\"') {
-                       sc.ForwardSetState(SCE_H_OTHER);
-               }
-       } else if (sc.state == SCE_H_SINGLESTRING) {
-               if (sc.ch == '\'') {
-                       sc.ForwardSetState(SCE_H_OTHER);
-               }
-       } else if (sc.state == SCE_H_NUMBER) {
-               if (!IsADigit(sc.ch)) {
-                       sc.SetState(SCE_H_OTHER);
-               }
-       }
-
-       if (sc.state == SCE_H_DEFAULT) {
-               if (sc.ch == '<') {
-                       if (sc.Match("<!--"))
-                               sc.SetState(SCE_H_COMMENT);
-                       else
-                               sc.SetState(SCE_H_TAGUNKNOWN);
-               } else if (sc.ch == '&') {
-                       sc.SetState(SCE_H_ENTITY);
-               }
-       } else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) {
-               if (sc.ch == '\"' && sc.chPrev == '=') {
-                       sc.SetState(SCE_H_DOUBLESTRING);
-               } else if (sc.ch == '\'' && sc.chPrev == '=') {
-                       sc.SetState(SCE_H_SINGLESTRING);
-               } else if (IsADigit(sc.ch)) {
-                       sc.SetState(SCE_H_NUMBER);
-               } else if (sc.ch == '>') {
-                       sc.SetState(SCE_H_TAG);
-                       sc.ForwardSetState(SCE_H_DEFAULT);
-               } else if (ishtmlwordchar(sc.ch)) {
-                       sc.SetState(SCE_H_ATTRIBUTE);
-               }
-       }
-}
-
-static void ColouriseASPPiece(StyleContext &sc, WordList *keywordlists[]) {
-       // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
-       if ((sc.state == SCE_H_ASPAT || isASPScript(sc.state)) && sc.Match('%', '>')) {
-               sc.SetState(SCE_H_ASP);
-               sc.Forward();
-               sc.ForwardSetState(SCE_H_DEFAULT);
-       }
-
-       // Handle some ASP script
-       if (sc.state >= SCE_HBA_START && sc.state <= SCE_HBA_STRINGEOL) {
-               ColouriseHBAPiece(sc, keywordlists);
-       } else if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
-               ColouriseHTMLPiece(sc, keywordlists);
-       }
-
-       // Enter new sc.state
-       if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
-               if (sc.Match('<', '%')) {
-                       if (sc.state == SCE_H_TAGUNKNOWN)
-                               sc.ChangeState(SCE_H_ASP);
-                       else
-                               sc.SetState(SCE_H_ASP);
-                       sc.Forward();
-                       sc.Forward();
-                       if (sc.ch == '@') {
-                               sc.ForwardSetState(SCE_H_ASPAT);
-                       } else {
-                               if (sc.ch == '=') {
-                                       sc.Forward();
-                               }
-                               sc.SetState(SCE_HBA_DEFAULT);
-                       }
-               }
-       }
-}
-
-static void ColouriseASPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                  Accessor &styler) {
-       // Lexer for HTML requires more lexical states (8 bits worth) than most lexers
-       StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(STYLE_MAX));
-       for (; sc.More(); sc.Forward()) {
-               ColouriseASPPiece(sc, keywordlists);
-       }
-       sc.Complete();
-}
-
-static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
-       // Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
-       if (sc.state >= SCE_HPHP_DEFAULT && sc.state <= SCE_HPHP_OPERATOR) {
-               if (!isPHPStringState(sc.state) &&
-                       (sc.state != SCE_HPHP_COMMENT) &&
-                       (sc.Match('?', '>'))) {
-                       sc.SetState(SCE_H_QUESTION);
-                       sc.Forward();
-                       sc.ForwardSetState(SCE_H_DEFAULT);
-               }
-       }
-
-       if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
-               ColouriseHTMLPiece(sc, keywordlists);
-       }
-
-       // Handle some PHP script
-       if (sc.state == SCE_HPHP_WORD) {
-               if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
-                       sc.SetState(SCE_HPHP_DEFAULT);
-               }
-       } else if (sc.state == SCE_HPHP_COMMENTLINE) {
-               if (sc.ch == '\r' || sc.ch == '\n') {
-                       sc.SetState(SCE_HPHP_DEFAULT);
-               }
-       } else if (sc.state == SCE_HPHP_COMMENT) {
-               if (sc.Match('*', '/')) {
-                       sc.Forward();
-                       sc.Forward();
-                       sc.SetState(SCE_HPHP_DEFAULT);
-               }
-       } else if (sc.state == SCE_HPHP_HSTRING) {
-               if (sc.ch == '\"') {
-                       sc.ForwardSetState(SCE_HPHP_DEFAULT);
-               }
-       } else if (sc.state == SCE_HPHP_SIMPLESTRING) {
-               if (sc.ch == '\'') {
-                       sc.ForwardSetState(SCE_HPHP_DEFAULT);
-               }
-       } else if (sc.state == SCE_HPHP_VARIABLE) {
-               if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
-                       sc.SetState(SCE_HPHP_DEFAULT);
-               }
-       } else if (sc.state == SCE_HPHP_OPERATOR) {
-               sc.SetState(SCE_HPHP_DEFAULT);
-       }
-
-       // Enter new sc.state
-       if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
-               if (sc.Match("<?php")) {
-                       sc.SetState(SCE_H_QUESTION);
-                       sc.Forward();
-                       sc.Forward();
-                       sc.Forward();
-                       sc.Forward();
-                       sc.Forward();
-                       sc.SetState(SCE_HPHP_DEFAULT);
-               }
-       }
-       if (sc.state == SCE_HPHP_DEFAULT) {
-               if (IsPhpWordStart(static_cast<char>(sc.ch))) {
-                       sc.SetState(SCE_HPHP_WORD);
-               } else if (sc.ch == '#') {
-                       sc.SetState(SCE_HPHP_COMMENTLINE);
-               } else if (sc.Match("<!--")) {
-                       sc.SetState(SCE_HPHP_COMMENTLINE);
-               } else if (sc.Match('/', '/')) {
-                       sc.SetState(SCE_HPHP_COMMENTLINE);
-               } else if (sc.Match('/', '*')) {
-                       sc.SetState(SCE_HPHP_COMMENT);
-               } else if (sc.ch == '\"') {
-                       sc.SetState(SCE_HPHP_HSTRING);
-               } else if (sc.ch == '\'') {
-                       sc.SetState(SCE_HPHP_SIMPLESTRING);
-               } 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);
-               }
-       }
-}
-
-static void ColourisePHPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                  Accessor &styler) {
-       // Lexer for HTML requires more lexical states (8 bits worth) than most lexers
-       StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(STYLE_MAX));
-       for (; sc.More(); sc.Forward()) {
-               ColourisePHPPiece(sc, keywordlists);
-       }
-       sc.Complete();
+       ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false);
 }
 
 static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                               Accessor &styler) {
-       if(startPos == 0) initStyle = SCE_HPHP_DEFAULT;
-               ColouriseHTMLDoc(startPos,length,initStyle,keywordlists,styler);
+        Accessor &styler) {
+       if (startPos == 0)
+               initStyle = SCE_HPHP_DEFAULT;
+       ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler);
 }
 
 static const char * const htmlWordListDesc[] = {
@@ -2085,7 +2056,4 @@ static const char * const phpscriptWordListDesc[] = {
 
 LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, 8);
 LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, 8);
-// SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
-LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 8);
-LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 8);
 LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 8);
index 095675ee5b9c605e07c6d534622d57a4b895e064..b528f3f0e3d2da50090fb3db1992e1e08956d805 100644 (file)
@@ -25,6 +25,7 @@
 #include "Platform.h"
 
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 #include "KeyWords.h"
@@ -179,6 +180,9 @@ static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
          // Digit
          if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
             sc.SetState(SCE_HA_NUMBER);
+            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too
+               sc.Forward(1);
+            }
          }
          // Comment line
          else if (sc.Match("--")) {
@@ -222,7 +226,7 @@ static const char* LexerName = "haskell";
 void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
                         char *words[], WindowID window, char *props)
 {
-   PropSet ps;
+   PropSetSimple ps;
    ps.SetMultiple(props);
    WindowAccessor wa(window, ps);
 
index 53817509676730e2696d16b06668481b7eafd853..6d1102c65480e3da3e9fd19e250a08a299f5129f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "StyleContext.h"
@@ -33,6 +34,8 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
        char *buffer = new char[length];
        int bufferCount = 0;
        bool isBOL, isEOL, isWS, isBOLWS = 0;
+       bool isCode = false;
+       bool isCStyleComment = false;
 
        WordList &sectionKeywords = *keywordLists[0];
        WordList &standardKeywords = *keywordLists[1];
@@ -63,7 +66,7 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 
                switch(state) {
                        case SCE_INNO_DEFAULT:
-                               if (ch == ';' && isBOLWS) {
+                               if (!isCode && ch == ';' && isBOLWS) {
                                        // Start of a comment
                                        state = SCE_INNO_COMMENT;
                                } else if (ch == '[' && isBOLWS) {
@@ -73,13 +76,17 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
                                } else if (ch == '#' && isBOLWS) {
                                        // Start of a preprocessor directive
                                        state = SCE_INNO_PREPROC;
-                               } else if (ch == '{' && chNext == '#') {
-                                       // Start of a preprocessor inline directive
-                                       state = SCE_INNO_PREPROC_INLINE;
-                               } else if ((ch == '{' && (chNext == ' ' || chNext == '\t'))
-                                          || (ch == '(' && chNext == '*')) {
+                               } else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
+                                       // Start of an inline expansion
+                                       state = SCE_INNO_INLINE_EXPANSION;
+                               } else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
                                        // Start of a Pascal comment
                                        state = SCE_INNO_COMMENT_PASCAL;
+                                       isCStyleComment = false;
+                               } else if (isCode && ch == '/' && chNext == '/') {
+                                       // Apparently, C-style comments are legal, too
+                                       state = SCE_INNO_COMMENT_PASCAL;
+                                       isCStyleComment = true;
                                } else if (ch == '"') {
                                        // Start of a double-quote string
                                        state = SCE_INNO_STRING_DOUBLE;
@@ -112,13 +119,13 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
                                        buffer[bufferCount] = '\0';
 
                                        // Check if the buffer contains a keyword
-                                       if (standardKeywords.InList(buffer)) {
+                                       if (!isCode && standardKeywords.InList(buffer)) {
                                                styler.ColourTo(i-1,SCE_INNO_KEYWORD);
-                                       } else if (parameterKeywords.InList(buffer)) {
+                                       } else if (!isCode && parameterKeywords.InList(buffer)) {
                                                styler.ColourTo(i-1,SCE_INNO_PARAMETER);
-                                       } else if (pascalKeywords.InList(buffer)) {
+                                       } else if (isCode && pascalKeywords.InList(buffer)) {
                                                styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
-                                       } else if (userKeywords.InList(buffer)) {
+                                       } else if (!isCode && userKeywords.InList(buffer)) {
                                                styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
                                        } else {
                                                styler.ColourTo(i-1,SCE_INNO_DEFAULT);
@@ -138,6 +145,7 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
                                        // Check if the buffer contains a section name
                                        if (sectionKeywords.InList(buffer)) {
                                                styler.ColourTo(i,SCE_INNO_SECTION);
+                                               isCode = !CompareCaseInsensitive(buffer, "code");
                                        } else {
                                                styler.ColourTo(i,SCE_INNO_DEFAULT);
                                        }
@@ -187,10 +195,10 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
                                }
                                break;
 
-                       case SCE_INNO_PREPROC_INLINE:
+                       case SCE_INNO_INLINE_EXPANSION:
                                if (ch == '}') {
                                        state = SCE_INNO_DEFAULT;
-                                       styler.ColourTo(i,SCE_INNO_PREPROC_INLINE);
+                                       styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
                                } else if (isEOL) {
                                        state = SCE_INNO_DEFAULT;
                                        styler.ColourTo(i,SCE_INNO_DEFAULT);
@@ -198,12 +206,19 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
                                break;
 
                        case SCE_INNO_COMMENT_PASCAL:
-                               if (ch == '}' || (ch == ')' && chPrev == '*')) {
-                                       state = SCE_INNO_DEFAULT;
-                                       styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
-                               } else if (isEOL) {
-                                       state = SCE_INNO_DEFAULT;
-                                       styler.ColourTo(i,SCE_INNO_DEFAULT);
+                               if (isCStyleComment) {
+                                       if (isEOL) {
+                                               state = SCE_INNO_DEFAULT;
+                                               styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
+                                       }
+                               } else {
+                                       if (ch == '}' || (ch == ')' && chPrev == '*')) {
+                                               state = SCE_INNO_DEFAULT;
+                                               styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
+                                       } else if (isEOL) {
+                                               state = SCE_INNO_DEFAULT;
+                                               styler.ColourTo(i,SCE_INNO_DEFAULT);
+                                       }
                                }
                                break;
 
@@ -223,72 +238,42 @@ static const char * const innoWordListDesc[] = {
 };
 
 static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
-       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
        unsigned int endPos = startPos + length;
-       int visibleChars = 0;
+       char chNext = styler[startPos];
+
        int lineCurrent = styler.GetLine(startPos);
 
-       char chNext = styler[startPos];
-       int styleNext = styler.StyleAt(startPos);
-       bool headerPoint = false;
-       int lev;
+       bool sectionFlag = false;
+       int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
+       int level;
 
        for (unsigned int i = startPos; i < endPos; i++) {
                char ch = chNext;
                chNext = styler[i+1];
-
-               int style = styleNext;
-               styleNext = styler.StyleAt(i + 1);
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               int style = styler.StyleAt(i);
 
                if (style == SCE_INNO_SECTION)
-                       headerPoint = true;
-
-               if (atEOL) {
-                       lev = SC_FOLDLEVELBASE;
-
-                       if (lineCurrent > 0) {
-                               int levelPrevious = styler.LevelAt(lineCurrent - 1);
-
-                               if (levelPrevious & SC_FOLDLEVELHEADERFLAG)
-                                       lev = SC_FOLDLEVELBASE + 1;
-                               else
-                                       lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
+                       sectionFlag = true;
+
+               if (atEOL || i == endPos - 1) {
+                       if (sectionFlag) {
+                               level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+                               if (level == levelPrev)
+                                       styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
+                       } else {
+                               level = levelPrev & SC_FOLDLEVELNUMBERMASK;
+                               if (levelPrev & SC_FOLDLEVELHEADERFLAG)
+                                       level++;
                        }
 
-                       if (headerPoint)
-                               lev = SC_FOLDLEVELBASE;
-
-                       if (visibleChars == 0 && foldCompact)
-                               lev |= SC_FOLDLEVELWHITEFLAG;
-
-                       if (headerPoint)
-                               lev |= SC_FOLDLEVELHEADERFLAG;
-
-                       if (lev != styler.LevelAt(lineCurrent))
-                               styler.SetLevel(lineCurrent, lev);
+                       styler.SetLevel(lineCurrent, level);
 
+                       levelPrev = level;
                        lineCurrent++;
-                       visibleChars = 0;
-                       headerPoint = false;
+                       sectionFlag = false;
                }
-               if (!isspacechar(ch))
-                       visibleChars++;
-       }
-
-       if (lineCurrent > 0) {
-               int levelPrevious = styler.LevelAt(lineCurrent - 1);
-
-               if (levelPrevious & SC_FOLDLEVELHEADERFLAG)
-                       lev = SC_FOLDLEVELBASE + 1;
-               else
-                       lev = levelPrevious & SC_FOLDLEVELNUMBERMASK;
-       } else {
-               lev = SC_FOLDLEVELBASE;
        }
-       int flagsNext = styler.LevelAt(lineCurrent);
-       styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
 }
 
 LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);
index 1072e13a3af2fdd62274b7dc4a450df660128e4b..e1d06cbac445c2483da5a075aee66f3539105d7c 100644 (file)
@@ -32,7 +32,7 @@ using namespace Scintilla;
 static inline bool isLispoperator(char ch) {
        if (isascii(ch) && isalnum(ch))
                return false;
-       if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' )
+       if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
                return true;
        return false;
 }
@@ -100,6 +100,9 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
                                styler.ColourTo(i - 1, state);
                                radix = -1;
                                state = SCE_LISP_MACRO_DISPATCH;
+                       } else if (ch == ':' && isLispwordstart(chNext)) {
+                               styler.ColourTo(i - 1, state);
+                               state = SCE_LISP_SYMBOL;
                        } else if (isLispwordstart(ch)) {
                                styler.ColourTo(i - 1, state);
                                state = SCE_LISP_IDENTIFIER;
@@ -243,9 +246,9 @@ static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */,
                styleNext = styler.StyleAt(i + 1);
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
                if (style == SCE_LISP_OPERATOR) {
-                       if (ch == '(') {
+                       if (ch == '(' || ch == '[' || ch == '{') {
                                levelCurrent++;
-                       } else if (ch == ')') {
+                       } else if (ch == ')' || ch == ']' || ch == '}') {
                                levelCurrent--;
                        }
                }
index 63114a976dfaeb63a060b3b46579920e87e8d0ec..a1e579f269281546bbdf540a3756e444e987a463 100644 (file)
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+#include "CharacterSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
-       return ch >= 0x80 ||
-              (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
-       return ch >= 0x80 ||
-              (isalpha(ch) || ch == '_');
-}
-
-static inline bool IsANumberChar(int ch) {
-       // Not exactly following number definition (several dots are seen as OK, etc.)
-       // but probably enough in most cases.
-       return (ch < 0x80) &&
-               (isdigit(ch) || toupper(ch) == 'E' ||
-               ch == '.' || ch == '-' || ch == '+' ||
-               (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'));
-}
-
-static inline bool IsLuaOperator(int ch) {
-       if (ch >= 0x80 || isalnum(ch)) {
-               return false;
-       }
-       // '.' left out as it is used to make up numbers
-       if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
-               ch == '(' || ch == ')' || ch == '=' ||
-               ch == '{' || ch == '}' || ch == '~' ||
-               ch == '[' || ch == ']' || ch == ';' ||
-               ch == '<' || ch == '>' || ch == ',' ||
-               ch == '.' || ch == '^' || ch == '%' || ch == ':' ||
-               ch == '#') {
-               return true;
-       }
-       return false;
-}
-
 // Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ],
 // return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on.
 // The maximum number of '=' characters allowed is 254.
@@ -91,6 +55,15 @@ static void ColouriseLuaDoc(
        WordList &keywords7 = *keywordlists[6];
        WordList &keywords8 = *keywordlists[7];
 
+       // Accepts accented characters
+       CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+       CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+       // Not exactly following number definition (several dots are seen as OK, etc.)
+       // but probably enough in most cases.
+       CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
+       CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
+       CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
+
        int currentLine = styler.GetLine(startPos);
        // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
        // if we are inside such a string. Block comment was introduced in Lua 5.0,
@@ -136,7 +109,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') {
@@ -151,14 +124,14 @@ static void ColouriseLuaDoc(
                        sc.SetState(SCE_LUA_DEFAULT);
                } else if (sc.state == SCE_LUA_NUMBER) {
                        // We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
-                       if (!IsANumberChar(sc.ch)) {
+                       if (!setNumber.Contains(sc.ch)) {
                                sc.SetState(SCE_LUA_DEFAULT);
                        } else if (sc.ch == '-' || sc.ch == '+') {
-                                if (sc.chPrev != 'E' && sc.chPrev != 'e')
-                                        sc.SetState(SCE_LUA_DEFAULT);
-                        }
+                               if (sc.chPrev != 'E' && sc.chPrev != 'e')
+                                       sc.SetState(SCE_LUA_DEFAULT);
+                       }
                } else if (sc.state == SCE_LUA_IDENTIFIER) {
-                       if (!IsAWordChar(sc.ch) || sc.Match('.', '.')) {
+                       if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
                                char s[100];
                                sc.GetCurrent(s, sizeof(s));
                                if (keywords.InList(s)) {
@@ -186,7 +159,7 @@ static void ColouriseLuaDoc(
                        }
                } else if (sc.state == SCE_LUA_STRING) {
                        if (sc.ch == '\\') {
-                               if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+                               if (setEscapeSkip.Contains(sc.chNext)) {
                                        sc.Forward();
                                }
                        } else if (sc.ch == '\"') {
@@ -197,7 +170,7 @@ static void ColouriseLuaDoc(
                        }
                } else if (sc.state == SCE_LUA_CHARACTER) {
                        if (sc.ch == '\\') {
-                               if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+                               if (setEscapeSkip.Contains(sc.chNext)) {
                                        sc.Forward();
                                }
                        } else if (sc.ch == '\'') {
@@ -233,9 +206,9 @@ static void ColouriseLuaDoc(
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
                                sc.SetState(SCE_LUA_NUMBER);
                                if (sc.ch == '0' && toupper(sc.chNext) == 'X') {
-                                       sc.Forward(1);
+                                       sc.Forward();
                                }
-                       } else if (IsAWordStart(sc.ch)) {
+                       } else if (setWordStart.Contains(sc.ch)) {
                                sc.SetState(SCE_LUA_IDENTIFIER);
                        } else if (sc.ch == '\"') {
                                sc.SetState(SCE_LUA_STRING);
@@ -265,11 +238,34 @@ static void ColouriseLuaDoc(
                                }
                        } 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 (setLuaOperator.Contains(sc.ch)) {
                                sc.SetState(SCE_LUA_OPERATOR);
                        }
                }
        }
+
+       if (setWord.Contains(sc.chPrev)) {
+               char s[100];
+               sc.GetCurrent(s, sizeof(s));
+               if (keywords.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD);
+               } else if (keywords2.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD2);
+               } else if (keywords3.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD3);
+               } else if (keywords4.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD4);
+               } else if (keywords5.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD5);
+               } else if (keywords6.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD6);
+               } else if (keywords7.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD7);
+               } else if (keywords8.InList(s)) {
+                       sc.ChangeState(SCE_LUA_WORD8);
+               }
+       }
+
        sc.Complete();
 }
 
index 93b8caba7c3c560d4ead05375a294e1cb57d1d50..b0099ff862f55d9a49ce3228f14efce5dd83a8a5 100644 (file)
@@ -11,6 +11,9 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
+
+#include <string>
+
 #include "Platform.h"
 
 #include "PropSet.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
-#include "SString.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static int GetLotLineState(SString &line) {
+static int GetLotLineState(std::string &line) {
        if (line.length()) {
                // Most of the time the first non-blank character in line determines that line's type
                // Now finds the first non-blank character
@@ -54,13 +56,13 @@ static int GetLotLineState(SString &line) {
 
                default:  // Any other line
                        // Checks for message at the end of lot file
-                       if (line.contains("PASSED")) {
+                       if (line.find("PASSED") != std::string::npos) {
                                return SCE_LOT_PASS;
                        }
-                       else if (line.contains("FAILED")) {
+                       else if (line.find("FAILED") != std::string::npos) {
                                return SCE_LOT_FAIL;
                        }
-                       else if (line.contains("ABORTED")) {
+                       else if (line.find("ABORTED") != std::string::npos) {
                                return SCE_LOT_ABORT;
                        }
                        else {
@@ -78,8 +80,8 @@ static void ColourizeLotDoc(unsigned int startPos, int length, int, WordList *[]
        styler.StartSegment(startPos);
        bool atLineStart = true;// Arms the 'at line start' flag
        char chNext = styler.SafeGetCharAt(startPos);
-       SString line("");
-       line.setsizegrowth(256);        // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
+       std::string line("");
+       line.reserve(256);      // Lot lines are less than 256 chars long most of the time. This should avoid reallocations
 
        // Styles LOT document
        unsigned int i;                 // Declared here because it's used after the for loop
diff --git a/src/stc/scintilla/src/LexMagik.cxx b/src/stc/scintilla/src/LexMagik.cxx
new file mode 100644 (file)
index 0000000..c6f6585
--- /dev/null
@@ -0,0 +1,445 @@
+// Scintilla source code edit control
+/**
+ * @file LexMagik.cxx
+ * Lexer for GE(r) Smallworld(tm) MagikSF
+ */
+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/**
+ * Is it a core character (C isalpha(), exclamation and question mark)
+ *
+ * \param  ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlphaCore(int ch) {
+    return (isalpha(ch) || ch == '!' || ch == '?');
+}
+
+/**
+ * Is it a character (IsAlphaCore() and underscore)
+ *
+ * \param  ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlpha(int ch) {
+    return (IsAlphaCore(ch) || ch == '_');
+}
+
+/**
+ * Is it a symbolic character (IsAlpha() and colon)
+ *
+ * \param  ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlphaSym(int ch) {
+    return (IsAlpha(ch) || ch == ':');
+}
+
+/**
+ * Is it a numerical character (IsAlpha() and 0 - 9)
+ *
+ * \param  ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlNum(int ch) {
+    return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
+}
+
+/**
+ * Is it a symbolic numerical character (IsAlNum() and colon)
+ *
+ * \param  ch The character
+ * \return True if ch is a character, False otherwise
+ */
+static inline bool IsAlNumSym(int ch) {
+    return (IsAlNum(ch) || ch == ':');
+}
+
+/**
+ * The lexer function
+ *
+ * \param  startPos Where to start scanning
+ * \param  length Where to scan to
+ * \param  initStyle The style at the initial point, not used in this folder
+ * \param  keywordslists The keywordslists, currently, number 5 is used
+ * \param  styler The styler
+ */
+static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
+                           WordList *keywordlists[], Accessor &styler) {
+    styler.StartAt(startPos);
+
+    WordList &keywords = *keywordlists[0];
+    WordList &pragmatics = *keywordlists[1];
+    WordList &containers = *keywordlists[2];
+    WordList &flow = *keywordlists[3];
+    WordList &characters = *keywordlists[4];
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+
+       for (; sc.More(); sc.Forward()) {
+
+    repeat:
+
+        if(sc.ch == '#') {
+            if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
+            else sc.SetState(SCE_MAGIK_COMMENT);
+            for(; sc.More() && !(sc.atLineEnd); sc.Forward());
+            sc.SetState(SCE_MAGIK_DEFAULT);
+            goto repeat;
+        }
+
+        if(sc.ch == '"') {
+            sc.SetState(SCE_MAGIK_STRING);
+
+            if(sc.More())
+            {
+                sc.Forward();
+                for(; sc.More() && sc.ch != '"'; sc.Forward());
+            }
+
+            sc.ForwardSetState(SCE_MAGIK_DEFAULT);
+            goto repeat;
+        }
+
+           // The default state
+           if(sc.state == SCE_MAGIK_DEFAULT) {
+
+               // A certain keyword has been detected
+               if (sc.ch == '_' && (
+                    sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
+                   char keyword[50];
+                   memset(keyword, '\0', 50);
+
+                   for(
+                    int scanPosition = 0;
+                    scanPosition < 50;
+                    scanPosition++) {
+                       char keywordChar = static_cast<char>(
+                        tolower(styler.SafeGetCharAt(
+                            scanPosition +
+                                static_cast<int>(sc.currentPos+1), ' ')));
+                    if(IsAlpha(keywordChar)) {
+                        keyword[scanPosition] = keywordChar;
+                    } else {
+                        break;
+                    }
+                   }
+
+                // It is a pragma
+                   if(pragmatics.InList(keyword)) {
+                       sc.SetState(SCE_MAGIK_PRAGMA);
+                   }
+
+                   // it is a normal keyword like _local, _self, etc.
+                   else if(keywords.InList(keyword)) {
+                       sc.SetState(SCE_MAGIK_KEYWORD);
+                   }
+
+                // It is a container keyword, such as _method, _proc, etc.
+                   else if(containers.InList(keyword)) {
+                       sc.SetState(SCE_MAGIK_CONTAINER);
+                   }
+
+                   // It is a flow keyword, such as _for, _if, _try, etc.
+                   else if(flow.InList(keyword)) {
+                       sc.SetState(SCE_MAGIK_FLOW);
+                   }
+
+                   // Interpret as unknown keyword
+                   else {
+                       sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
+                   }
+               }
+
+            // Symbolic expression
+               else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
+                   sc.SetState(SCE_MAGIK_SYMBOL);
+                   bool firstTrip = true;
+                   for(sc.Forward(); sc.More(); sc.Forward()) {
+                       if(firstTrip && IsAlphaSym(sc.ch));
+                       else if(!firstTrip && IsAlNumSym(sc.ch));
+                       else if(sc.ch == '|') {
+                           for(sc.Forward();
+                            sc.More() && sc.ch != '|';
+                            sc.Forward());
+                       }
+                       else break;
+
+                       firstTrip = false;
+                   }
+                   sc.SetState(SCE_MAGIK_DEFAULT);
+                   goto repeat;
+               }
+
+            // Identifier (label) expression
+               else if(sc.ch == '@') {
+                   sc.SetState(SCE_MAGIK_IDENTIFIER);
+                   bool firstTrip = true;
+                   for(sc.Forward(); sc.More(); sc.Forward()) {
+                       if(firstTrip && IsAlphaCore(sc.ch)) {
+                           firstTrip = false;
+                       }
+                       else if(!firstTrip && IsAlpha(sc.ch));
+                       else break;
+                   }
+                   sc.SetState(SCE_MAGIK_DEFAULT);
+                   goto repeat;
+               }
+
+               // Start of a character
+            else if(sc.ch == '%') {
+                sc.SetState(SCE_MAGIK_CHARACTER);
+                sc.Forward();
+                char keyword[50];
+                   memset(keyword, '\0', 50);
+
+                   for(
+                    int scanPosition = 0;
+                    scanPosition < 50;
+                    scanPosition++) {
+                       char keywordChar = static_cast<char>(
+                        tolower(styler.SafeGetCharAt(
+                            scanPosition +
+                                static_cast<int>(sc.currentPos), ' ')));
+                    if(IsAlpha(keywordChar)) {
+                        keyword[scanPosition] = keywordChar;
+                    } else {
+                        break;
+                    }
+                   }
+
+                   if(characters.InList(keyword)) {
+                       sc.Forward(strlen(keyword));
+                   } else {
+                       sc.Forward();
+                   }
+
+                sc.SetState(SCE_MAGIK_DEFAULT);
+                goto repeat;
+            }
+
+            // Operators
+               else if(
+                sc.ch == '>' ||
+                sc.ch == '<' ||
+                sc.ch == '.' ||
+                sc.ch == ',' ||
+                sc.ch == '+' ||
+                sc.ch == '-' ||
+                sc.ch == '/' ||
+                sc.ch == '*' ||
+                sc.ch == '~' ||
+                sc.ch == '$' ||
+                sc.ch == '=') {
+                sc.SetState(SCE_MAGIK_OPERATOR);
+            }
+
+            // Braces
+            else if(sc.ch == '(' || sc.ch == ')') {
+                sc.SetState(SCE_MAGIK_BRACE_BLOCK);
+            }
+
+            // Brackets
+            else if(sc.ch == '{' || sc.ch == '}') {
+                sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
+            }
+
+            // Square Brackets
+            else if(sc.ch == '[' || sc.ch == ']') {
+                sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
+            }
+
+
+           }
+
+           // It is an operator
+           else if(
+            sc.state == SCE_MAGIK_OPERATOR ||
+            sc.state == SCE_MAGIK_BRACE_BLOCK ||
+            sc.state == SCE_MAGIK_BRACKET_BLOCK ||
+            sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
+               sc.SetState(SCE_MAGIK_DEFAULT);
+               goto repeat;
+           }
+
+           // It is the pragma state
+           else if(sc.state == SCE_MAGIK_PRAGMA) {
+               if(!IsAlpha(sc.ch)) {
+                   sc.SetState(SCE_MAGIK_DEFAULT);
+                goto repeat;
+               }
+           }
+
+           // It is the keyword state
+           else if(
+            sc.state == SCE_MAGIK_KEYWORD ||
+            sc.state == SCE_MAGIK_CONTAINER ||
+            sc.state == SCE_MAGIK_FLOW ||
+            sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
+               if(!IsAlpha(sc.ch)) {
+                   sc.SetState(SCE_MAGIK_DEFAULT);
+                   goto repeat;
+               }
+           }
+       }
+
+       sc.Complete();
+}
+
+/**
+ * The word list description
+ */
+static const char * const magikWordListDesc[] = {
+    "Accessors (local, global, self, super, thisthread)",
+    "Pragmatic (pragma, private)",
+    "Containers (method, block, proc)",
+    "Flow (if, then, elif, else)",
+    "Characters (space, tab, newline, return)",
+    "Fold Containers (method, proc, block, if, loop)",
+    0};
+
+/**
+ * This function detects keywords which are able to have a body. Note that it
+ * uses the Fold Containers word description, not the containers description. It
+ * only works when the style at that particular position is set on Containers
+ * or Flow (number 3 or 4).
+ *
+ * \param  keywordslist The list of keywords that are scanned, they should only
+ *         contain the start keywords, not the end keywords
+ * \param  The actual keyword
+ * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
+ *         0 otherwise
+ */
+static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
+    if(
+        strlen(keyword) > 3 &&
+        keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
+        if (keywordslist.InList(keyword + 3)) {
+            return -1;
+        }
+
+    } else {
+        if(keywordslist.InList(keyword)) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * The folding function
+ *
+ * \param  startPos Where to start scanning
+ * \param  length Where to scan to
+ * \param  keywordslists The keywordslists, currently, number 5 is used
+ * \param  styler The styler
+ */
+static void FoldMagikDoc(unsigned int startPos, int length, int,
+    WordList *keywordslists[], Accessor &styler) {
+
+    bool compact = styler.GetPropertyInt("fold.compact") != 0;
+
+    WordList &foldingElements = *keywordslists[5];
+    int endPos = startPos + length;
+    int line = styler.GetLine(startPos);
+    int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
+    int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
+
+    for(
+        int currentPos = startPos;
+        currentPos < endPos;
+        currentPos++) {
+            char currentState = styler.StyleAt(currentPos);
+            char c = styler.SafeGetCharAt(currentPos, ' ');
+            int prevLine = styler.GetLine(currentPos - 1);
+            line = styler.GetLine(currentPos);
+
+            // Default situation
+            if(prevLine < line) {
+                styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
+                flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
+            }
+
+            if(
+                (
+                    currentState == SCE_MAGIK_CONTAINER ||
+                    currentState == SCE_MAGIK_FLOW
+                ) &&
+                c == '_') {
+
+                char keyword[50];
+                memset(keyword, '\0', 50);
+
+                for(
+                    int scanPosition = 0;
+                    scanPosition < 50;
+                    scanPosition++) {
+                    char keywordChar = static_cast<char>(
+                        tolower(styler.SafeGetCharAt(
+                            scanPosition +
+                                currentPos + 1, ' ')));
+                    if(IsAlpha(keywordChar)) {
+                        keyword[scanPosition] = keywordChar;
+                    } else {
+                        break;
+                    }
+                }
+
+                if(IsFoldingContainer(foldingElements, keyword) > 0) {
+                    styler.SetLevel(
+                        line,
+                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
+                    level++;
+                } else if(IsFoldingContainer(foldingElements, keyword) < 0) {
+                    styler.SetLevel(line, styler.LevelAt(line));
+                    level--;
+                }
+            }
+
+            if(
+                compact && (
+                    currentState == SCE_MAGIK_BRACE_BLOCK ||
+                    currentState == SCE_MAGIK_BRACKET_BLOCK ||
+                    currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
+                if(c == '{' || c == '[' || c == '(') {
+                    styler.SetLevel(
+                        line,
+                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
+                    level++;
+                } else if(c == '}' || c == ']' || c == ')') {
+                    styler.SetLevel(line, styler.LevelAt(line));
+                    level--;
+                }
+            }
+        }
+
+}
+
+/**
+ * Injecting the module
+ */
+LexerModule lmMagikSF(
+    SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);
+
diff --git a/src/stc/scintilla/src/LexMarkdown.cxx b/src/stc/scintilla/src/LexMarkdown.cxx
new file mode 100644 (file)
index 0000000..f7fc48f
--- /dev/null
@@ -0,0 +1,412 @@
+/******************************************************************
+ *  LexMarkdown.cxx
+ *
+ *  A simple Markdown lexer for scintilla.
+ *   
+ *  Includes highlighting for some extra features from the
+ *  Pandoc implementation; strikeout, using '#.' as a default 
+ *  ordered list item marker, and delimited code blocks.
+ * 
+ *  Limitations:
+ * 
+ *  Standard indented code blocks are not highlighted at all,
+ *  as it would conflict with other indentation schemes. Use 
+ *  delimited code blocks for blanket highlighting of an
+ *  entire code block.  Embedded HTML is not highlighted either.
+ *  Blanket HTML highlighting has issues, because some Markdown
+ *  implementations allow Markdown markup inside of the HTML. Also,
+ *  there is a following blank line issue that can't be ignored, 
+ *  explained in the next paragraph. Embedded HTML and code 
+ *  blocks would be better supported with language specific 
+ *  highlighting.
+ * 
+ *  The highlighting aims to accurately reflect correct syntax,
+ *  but a few restrictions are relaxed. Delimited code blocks are
+ *  highlighted, even if the line following the code block is not blank.  
+ *  Requiring a blank line after a block, breaks the highlighting
+ *  in certain cases, because of the way Scintilla ends up calling
+ *  the lexer.
+ * 
+ *  Written by Jon Strait - jstrait@moonloop.net
+ *
+ *  The License.txt file describes the conditions under which this
+ *  software may be distributed.
+ *
+ *****************************************************************/
+
+#include <stdlib.h>         
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsNewline(const int ch) {
+    return (ch == '\n' || ch == '\r');
+}
+
+// True if can follow ch down to the end with possibly trailing whitespace
+static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
+    unsigned int i = 0;
+    while (sc.GetRelative(++i) == ch)
+        ;
+    // Skip over whitespace
+    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+        ++i;
+    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
+        sc.Forward(i);
+        sc.ChangeState(state);
+        sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+        return true;
+    }
+    else return false;
+}
+
+// Set the state on text section from current to length characters, 
+// then set the rest until the newline to default, except for any characters matching token
+static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
+    sc.SetState(state);
+    sc.Forward(length);
+    sc.SetState(SCE_MARKDOWN_DEFAULT);
+    sc.Forward();
+    bool started = false;
+    while (sc.More() && !IsNewline(sc.ch)) {
+        if (sc.ch == token && !started) {
+            sc.SetState(state);
+            started = true;
+        }
+        else if (sc.ch != token) {
+            sc.SetState(SCE_MARKDOWN_DEFAULT);
+            started = false;
+        }
+        sc.Forward();
+    }
+    sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+}
+
+// Does the previous line have more than spaces and tabs?
+static bool HasPrevLineContent(StyleContext &sc) {
+    int i = 0;
+    // Go back to the previous newline
+    while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) 
+        ;
+    while (--i + sc.currentPos) {
+        if (IsNewline(sc.GetRelative(i)))
+            break;
+        if (!IsASpaceOrTab(sc.GetRelative(i)))
+            return true;
+    }
+    return false;
+}
+
+static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
+    int c, count = 1;
+    unsigned int i = 0;
+    while (++i) {
+        c = sc.GetRelative(i);
+        if (c == sc.ch) 
+            ++count;
+        // hit a terminating character
+        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
+            // Are we a valid HRULE
+            if ((IsNewline(c) || sc.currentPos + i == endPos) && 
+                    count >= 3 && !HasPrevLineContent(sc)) {
+                sc.SetState(SCE_MARKDOWN_HRULE);
+                sc.Forward(i);
+                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+                return true;
+            }
+            else {
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+               return false;
+            }
+        }
+    }
+    return false;
+}
+
+static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle,
+                               WordList **, Accessor &styler) {
+    unsigned int endPos = startPos + length;
+    int precharCount = 0;
+    // Don't advance on a new loop iteration and retry at the same position.
+    // Useful in the corner case of having to start at the beginning file position
+    // in the default state.
+    bool freezeCursor = false;
+    
+    StyleContext sc(startPos, length, initStyle, styler);
+
+    while (sc.More()) {
+        // Skip past escaped characters
+        if (sc.ch == '\\') {
+            sc.Forward();
+            continue;
+        }
+        
+        // A blockquotes resets the line semantics
+        if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
+            sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+        
+        // Conditional state-based actions
+        if (sc.state == SCE_MARKDOWN_CODE2) {
+            if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
+                sc.Forward(2);
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+        }    
+        else if (sc.state == SCE_MARKDOWN_CODE) {
+            if (sc.ch == '`' && sc.chPrev != ' ')
+                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+        }
+        /* De-activated because it gets in the way of other valid indentation
+         * schemes, for example multiple paragraphs inside a list item.
+        // Code block
+        else if (sc.state == SCE_MARKDOWN_CODEBK) {
+            bool d = true;
+            if (IsNewline(sc.ch)) {
+                if (sc.chNext != '\t') {
+                    for (int c = 1; c < 5; ++c) {
+                        if (sc.GetRelative(c) != ' ')
+                            d = false;
+                    }
+                }
+            }
+            else if (sc.atLineStart) {
+                if (sc.ch != '\t' ) {
+                    for (int i = 0; i < 4; ++i) {
+                        if (sc.GetRelative(i) != ' ')
+                            d = false;
+                    }
+                }
+            }
+            if (!d)
+                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+        }
+        */
+        // Strong
+        else if (sc.state == SCE_MARKDOWN_STRONG1) {
+            if (sc.Match("**") && sc.chPrev != ' ') {
+                sc.Forward(2);
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+        } 
+        else if (sc.state == SCE_MARKDOWN_STRONG2) {  
+            if (sc.Match("__") && sc.chPrev != ' ') {  
+                sc.Forward(2);
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+        }
+        // Emphasis    
+        else if (sc.state == SCE_MARKDOWN_EM1) {
+            if (sc.ch == '*' && sc.chPrev != ' ')
+                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+        }
+        else if (sc.state == SCE_MARKDOWN_EM2) {
+            if (sc.ch == '_' && sc.chPrev != ' ')
+                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+        }
+        else if (sc.state == SCE_MARKDOWN_CODEBK) {
+            if (sc.atLineStart && sc.Match("~~~")) {
+                int i = 1;
+                while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+                    i++;
+                sc.Forward(i);
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+        }
+        else if (sc.state == SCE_MARKDOWN_STRIKEOUT) {
+            if (sc.Match("~~") && sc.chPrev != ' ') {
+                sc.Forward(2);
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+        }
+        else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) {
+            // Header
+            if (sc.Match("######"))
+                SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc);
+            else if (sc.Match("#####"))
+                SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc);
+            else if (sc.Match("####"))
+                SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc);
+            else if (sc.Match("###"))
+                SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc);
+            else if (sc.Match("##"))
+                SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc);
+            else if (sc.Match("#")) {
+                // Catch the special case of an unordered list
+                if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+                    precharCount = 0;
+                    sc.SetState(SCE_MARKDOWN_PRECHAR);
+                }
+                else
+                    SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc);
+            }
+            // Code block
+            else if (sc.Match("~~~")) {
+                if (!HasPrevLineContent(sc))
+                    sc.SetState(SCE_MARKDOWN_CODEBK);
+                else
+                    sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+            else if (sc.ch == '=') {
+                if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc))
+                    ;
+                else
+                    sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+            else if (sc.ch == '-') {
+                if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc))
+                    ;
+                else {
+                    precharCount = 0;
+                    sc.SetState(SCE_MARKDOWN_PRECHAR);
+                }
+            }
+            else if (IsNewline(sc.ch))
+                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+            else {
+                precharCount = 0;
+                sc.SetState(SCE_MARKDOWN_PRECHAR);
+            }
+        }
+                
+        // The header lasts until the newline
+        else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
+                sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
+                sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) {
+            if (IsNewline(sc.ch))
+                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+        }
+        
+        // New state only within the initial whitespace
+        if (sc.state == SCE_MARKDOWN_PRECHAR) {
+            // Blockquote
+            if (sc.ch == '>' && precharCount < 5)
+                sc.SetState(SCE_MARKDOWN_BLOCKQUOTE);
+            /*
+            // Begin of code block
+            else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
+                sc.SetState(SCE_MARKDOWN_CODEBK);
+            */
+            // HRule - Total of three or more hyphens, asterisks, or underscores 
+            // on a line by themselves    
+            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
+                ;
+            // Unordered list
+            else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) {
+                sc.SetState(SCE_MARKDOWN_ULIST_ITEM);
+                sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+            }
+            // Ordered list
+            else if (IsADigit(sc.ch)) {
+                int digitCount = 0;
+                while (IsADigit(sc.GetRelative(++digitCount)))
+                    ;
+                if (sc.GetRelative(digitCount) == '.' && 
+                        IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
+                    sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
+                    sc.Forward(digitCount + 1);
+                    sc.SetState(SCE_MARKDOWN_DEFAULT);
+                }
+            }
+            // Alternate Ordered list
+            else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+                sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
+                sc.Forward(2);
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            }
+            else if (sc.ch != ' ' || precharCount > 2)
+                sc.SetState(SCE_MARKDOWN_DEFAULT);
+            else
+                ++precharCount;
+        }
+        
+        // New state anywhere in doc
+        if (sc.state == SCE_MARKDOWN_DEFAULT) {
+            if (sc.atLineStart && sc.ch == '#') {
+                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+                freezeCursor = true;
+            }
+            // Links and Images
+            if (sc.Match("![") || sc.ch == '[') {
+                int i = 0, j = 0, k = 0;
+                int len = endPos - sc.currentPos;
+                while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+                    ;
+                if (sc.GetRelative(i) == ']') {
+                    j = i;
+                    if (sc.GetRelative(++i) == '(') {
+                        while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\'))
+                            ;
+                        if (sc.GetRelative(i) == ')')
+                            k = i;
+                    }
+                    else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
+                        while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+                            ;
+                        if (sc.GetRelative(i) == ']')
+                            k = i;
+                    }
+                }
+                // At least a link text
+                if (j) {
+                    sc.SetState(SCE_MARKDOWN_LINK);
+                    sc.Forward(j);
+                    // Also has a URL or reference portion
+                    if (k)
+                        sc.Forward(k - j);
+                    sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
+                }
+            }
+            // Code - also a special case for alternate inside spacing
+            if (sc.Match("``") && sc.GetRelative(3) != ' ') {
+                sc.SetState(SCE_MARKDOWN_CODE2);
+                sc.Forward();
+            }
+            else if (sc.ch == '`' && sc.chNext != ' ') {
+                sc.SetState(SCE_MARKDOWN_CODE);
+            }
+            // Strong
+            else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_MARKDOWN_STRONG1);
+                sc.Forward();
+           }
+            else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_MARKDOWN_STRONG2);
+                sc.Forward();
+            }
+            // Emphasis
+            else if (sc.ch == '*' && sc.chNext != ' ')
+                sc.SetState(SCE_MARKDOWN_EM1);
+            else if (sc.ch == '_' && sc.chNext != ' ')
+                sc.SetState(SCE_MARKDOWN_EM2);
+            // Strikeout
+            else if (sc.Match("~~") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_MARKDOWN_STRIKEOUT);
+                sc.Forward();
+            }
+            // Beginning of line
+            else if (IsNewline(sc.ch))
+                sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
+        }
+        // Advance if not holding back the cursor for this iteration.
+        if (!freezeCursor)
+            sc.Forward();
+        freezeCursor = false;
+    }
+    sc.Complete();
+}
+
+LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown");
index af5f59aea5dff63524bbb22fcdbf1323ff838983..4e467bd2ff1fc0f9c7d23823328922cf293fb0a9 100644 (file)
@@ -1,7 +1,7 @@
 // Scintilla source code edit control
 /** @file LexMatlab.cxx
  ** Lexer for Matlab.
- ** Written by Jose' Fonseca
+ ** Written by José Fonseca
  **
  ** Changes by Christoph Dalitz 2003/12/04:
  **   - added support for Octave
@@ -128,7 +128,7 @@ static void ColouriseMatlabOctaveDoc(
                if (sc.state == SCE_MATLAB_DEFAULT) {
                        if (IsCommentChar(sc.ch)) {
                                sc.SetState(SCE_MATLAB_COMMENT);
-                       } else if (sc.ch == '!') {
+                       } else if (sc.ch == '!' && sc.chNext != '=' ) {
                                sc.SetState(SCE_MATLAB_COMMAND);
                        } else if (sc.ch == '\'') {
                                if (transpose) {
diff --git a/src/stc/scintilla/src/LexMySQL.cxx b/src/stc/scintilla/src/LexMySQL.cxx
new file mode 100644 (file)
index 0000000..e8496ce
--- /dev/null
@@ -0,0 +1,518 @@
+/**
+ * Scintilla source code edit control
+ * @file LexMySQL.cxx
+ * Lexer for MySQL
+ *
+ * Improved by Mike Lischke <mike.lischke@sun.com>
+ * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com>
+ * Original work by Neil Hodgson <neilh@scintilla.org>
+ * Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
+ * The License.txt file describes the conditions under which this software may be distributed.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsAWordChar(int ch) {
+       return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordStart(int ch) {
+       return (ch < 0x80) && (isalpha(ch) || ch == '_');
+}
+
+static inline bool IsADoxygenChar(int ch) {
+       return (islower(ch) || ch == '$' || ch == '@' ||
+               ch == '\\' || ch == '&' || ch == '<' ||
+               ch == '>' || ch == '#' || ch == '{' ||
+               ch == '}' || ch == '[' || ch == ']');
+}
+
+static inline bool IsANumberChar(int ch) {
+       // Not exactly following number definition (several dots are seen as OK, etc.)
+       // but probably enough in most cases.
+       return (ch < 0x80) &&
+               (isdigit(ch) || toupper(ch) == 'E' ||
+             ch == '.' || ch == '-' || ch == '+');
+}
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Check if the current content context represent a keyword and set the context state if so.
+ */
+static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[])
+{
+  int length = sc.LengthCurrent() + 1; // +1 for the next char
+  char* s = new char[length];
+  sc.GetCurrentLowered(s, length);
+  if (keywordlists[0]->InList(s))
+    sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
+  else
+    if (keywordlists[1]->InList(s))
+      sc.ChangeState(SCE_MYSQL_KEYWORD);
+    else
+      if (keywordlists[2]->InList(s))
+        sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
+      else
+        if (keywordlists[3]->InList(s))
+          sc.ChangeState(SCE_MYSQL_FUNCTION);
+        else
+          if (keywordlists[5]->InList(s))
+            sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
+          else
+            if (keywordlists[6]->InList(s))
+              sc.ChangeState(SCE_MYSQL_USER1);
+            else
+              if (keywordlists[7]->InList(s))
+                sc.ChangeState(SCE_MYSQL_USER2);
+              else
+                if (keywordlists[8]->InList(s))
+                  sc.ChangeState(SCE_MYSQL_USER3);
+  delete [] s;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler)
+{
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       for (; sc.More(); sc.Forward())
+  {
+               // Determine if the current state should terminate.
+               switch (sc.state)
+    {
+      case SCE_MYSQL_OPERATOR:
+        sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_NUMBER:
+        // We stop the number definition on non-numerical non-dot non-eE non-sign char.
+        if (!IsANumberChar(sc.ch))
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_IDENTIFIER:
+        // Switch from identifier to keyword state and open a new state for the new char.
+        if (!IsAWordChar(sc.ch))
+        {
+          CheckForKeyword(sc, keywordlists);
+          
+          // Additional check for function keywords needed.
+          // A function name must be followed by an opening parenthesis.
+          if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
+            sc.ChangeState(SCE_MYSQL_DEFAULT);
+            
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        }
+        break;
+      case SCE_MYSQL_VARIABLE:
+        if (!IsAWordChar(sc.ch))
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_SYSTEMVARIABLE:
+        if (!IsAWordChar(sc.ch))
+        {
+          int length = sc.LengthCurrent() + 1;
+          char* s = new char[length];
+          sc.GetCurrentLowered(s, length);
+
+          // Check for known system variables here.
+          if (keywordlists[4]->InList(&s[2]))
+            sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
+          delete [] s;
+          
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        }
+        break;
+      case SCE_MYSQL_QUOTEDIDENTIFIER:
+        if (sc.ch == '`')
+        {
+          if (sc.chNext == '`')
+            sc.Forward();      // Ignore it
+          else
+            sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+                               }
+                       break;
+      case SCE_MYSQL_COMMENT:
+      case SCE_MYSQL_HIDDENCOMMAND:
+        if (sc.Match('*', '/'))
+        {
+          sc.Forward();
+          sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+        }
+        break;
+      case SCE_MYSQL_COMMENTLINE:
+        if (sc.atLineStart)
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_SQSTRING:
+        if (sc.ch == '\\')
+          sc.Forward(); // Escape sequence
+        else
+          if (sc.ch == '\'')
+          {
+            // End of single quoted string reached?
+            if (sc.chNext == '\'')
+              sc.Forward();
+            else
+              sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+          }
+        break;
+      case SCE_MYSQL_DQSTRING:
+        if (sc.ch == '\\')
+          sc.Forward(); // Escape sequence
+        else
+          if (sc.ch == '\"')
+          {
+            // End of single quoted string reached?
+            if (sc.chNext == '\"')
+              sc.Forward();
+            else
+              sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+          }
+        break;
+    }
+
+    // Determine if a new state should be entered.
+    if (sc.state == SCE_MYSQL_DEFAULT)
+    {
+      switch (sc.ch)
+      {
+        case '@':
+          if (sc.chNext == '@')
+          {
+            sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
+            sc.Forward(2); // Skip past @@.
+          }
+          else
+            if (IsAWordStart(sc.ch))
+            {
+              sc.SetState(SCE_MYSQL_VARIABLE);
+              sc.Forward(); // Skip past @.
+            }
+            else
+              sc.SetState(SCE_MYSQL_OPERATOR);
+          break;
+        case '`':
+          sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
+          break;
+        case '#':
+          sc.SetState(SCE_MYSQL_COMMENTLINE);
+          break;
+        case '\'':
+          sc.SetState(SCE_MYSQL_SQSTRING);
+          break;
+        case '\"':
+          sc.SetState(SCE_MYSQL_DQSTRING);
+          break;
+        default:
+          if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+            sc.SetState(SCE_MYSQL_NUMBER);
+          else
+            if (IsAWordStart(sc.ch))
+              sc.SetState(SCE_MYSQL_IDENTIFIER);
+            else
+              if (sc.Match('/', '*'))
+              {
+                sc.SetState(SCE_MYSQL_COMMENT);
+                
+                // Skip comment introducer and check for hidden command.
+                sc.Forward(2);
+                if (sc.ch == '!')
+                {
+                  sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
+                  sc.Forward();
+                }
+              }
+              else
+                if (sc.Match("--"))
+                {
+                  // Special MySQL single line comment.
+                  sc.SetState(SCE_MYSQL_COMMENTLINE);
+                  sc.Forward(2);
+                  
+                  // Check the third character too. It must be a space or EOL.
+                  if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
+                    sc.ChangeState(SCE_MYSQL_OPERATOR);
+                }
+                else
+                  if (isoperator(static_cast<char>(sc.ch)))
+                    sc.SetState(SCE_MYSQL_OPERATOR);
+      }
+    }
+  }
+  
+  // Do a final check for keywords if we currently have an identifier, to highlight them
+  // also at the end of a line.
+  if (sc.state == SCE_MYSQL_IDENTIFIER)
+  {
+    CheckForKeyword(sc, keywordlists);
+
+    // Additional check for function keywords needed.
+    // A function name must be followed by an opening parenthesis.
+    if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
+      sc.ChangeState(SCE_MYSQL_DEFAULT);
+  }
+       
+  sc.Complete();
+}
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Helper function to determine if we have a foldable comment currently.
+ */
+static bool IsStreamCommentStyle(int style)
+{
+       return style == SCE_MYSQL_COMMENT;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Code copied from StyleContext and modified to work here. Should go into Accessor as a
+ * companion to Match()...
+ */
+bool MatchIgnoreCase(Accessor &styler, int currentPos, const char *s)
+{
+  for (int n = 0; *s; n++)
+  {
+    if (*s != tolower(styler.SafeGetCharAt(currentPos + n)))
+      return false;
+    s++;
+  }
+  return true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment.
+static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)
+{
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
+
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelCurrent = SC_FOLDLEVELBASE;
+       if (lineCurrent > 0)
+               levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
+       int levelNext = levelCurrent;
+
+       int styleNext = styler.StyleAt(startPos);
+       int style = initStyle;
+       
+  bool endFound = false;
+       bool whenFound = false;
+       bool elseFound = false;
+
+  char nextChar = styler.SafeGetCharAt(startPos);
+  for (unsigned int i = startPos; length > 0; i++, length--)
+  {
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+    
+    char currentChar = nextChar;
+    nextChar = styler.SafeGetCharAt(i + 1);
+               bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
+       
+    switch (style)
+    {
+      case SCE_MYSQL_COMMENT:
+        if (foldComment)
+        {
+          // Multiline comment style /* .. */.
+          if (IsStreamCommentStyle(style))
+          {
+            // Increase level if we just start a foldable comment.
+            if (!IsStreamCommentStyle(stylePrev))
+              levelNext++;
+            else
+              // If we are in the middle of a foldable comment check if it ends now.
+              // Don't end at the line end, though.
+              if (!IsStreamCommentStyle(styleNext) && !atEOL)
+                levelNext--;
+          }
+        }
+        break;
+      case SCE_MYSQL_COMMENTLINE:
+        if (foldComment)
+        { 
+          // Not really a standard, but we add support for single line comments
+          // with special curly braces syntax as foldable comments too.
+          // MySQL needs -- comments to be followed by space or control char
+          if (styler.Match(i, "--"))
+          {
+            char chNext2 = styler.SafeGetCharAt(i + 2);
+            char chNext3 = styler.SafeGetCharAt(i + 3);
+            if (chNext2 == '{' || chNext3 == '{')
+              levelNext++;
+            else
+              if (chNext2 == '}' || chNext3 == '}')
+                levelNext--;
+          }
+        }
+        break;
+      case SCE_MYSQL_HIDDENCOMMAND:
+        if (style != stylePrev)
+          levelNext++;
+        else
+          if (style != styleNext)
+            levelNext--;
+        break;
+      case SCE_MYSQL_OPERATOR:
+        if (currentChar == '(')
+          levelNext++;
+        else
+          if (currentChar == ')')
+            levelNext--;
+        break;
+      case SCE_MYSQL_MAJORKEYWORD:
+      case SCE_MYSQL_KEYWORD:
+      case SCE_MYSQL_FUNCTION:
+      case SCE_MYSQL_PROCEDUREKEYWORD:
+        // Reserved and other keywords.
+        if (style != stylePrev)
+        {
+          bool beginFound = MatchIgnoreCase(styler, i, "begin");
+          bool ifFound = MatchIgnoreCase(styler, i, "if");
+          bool thenFound = MatchIgnoreCase(styler, i, "then");
+          bool whileFound = MatchIgnoreCase(styler, i, "while");
+          bool loopFound = MatchIgnoreCase(styler, i, "loop");
+          bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
+          
+          if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
+          {
+            endFound = false;
+            levelNext--;
+            if (levelNext < SC_FOLDLEVELBASE)
+              levelNext = SC_FOLDLEVELBASE;
+            
+            // Note that "else" is special here. It may or may not be followed by an "if .. then",
+            // but in any case the level stays the same. When followed by an "if .. then" the level
+            // will be increased later, if not, then at eol.
+          }
+          else
+            if (!foldOnlyBegin && MatchIgnoreCase(styler, i, "else"))
+            {
+              levelNext--;
+              elseFound = true;
+            }
+            else
+              if (!foldOnlyBegin && thenFound)
+              {
+                if (whenFound)
+                  whenFound = false;
+                else
+                  levelNext++;
+              }
+              else
+                if (ifFound)
+                  elseFound = false;
+                else
+                  if (MatchIgnoreCase(styler, i, "when"))
+                    whenFound = true;
+                  else
+                  {
+                    if (beginFound)
+                      levelNext++;
+                    else
+                      if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
+                      {
+                        if (endFound)
+                          endFound = false;
+                        else
+                          levelNext++;
+                      }
+                      else
+                        if (MatchIgnoreCase(styler, i, "end"))
+                        {
+                          // Multiple "end" in a row are counted multiple times!
+                          if (endFound)
+                          {
+                            levelNext--;
+                            if (levelNext < SC_FOLDLEVELBASE)
+                              levelNext = SC_FOLDLEVELBASE;
+                          }
+                          endFound = true;
+                          whenFound = false;
+                        }
+                  }
+        }
+        break;
+    }
+    
+    // Handle the case of a trailing end without an if / while etc, as in the case of a begin.
+               if (endFound)
+    {
+                       endFound = false;
+                       levelNext--;
+                       if (levelNext < SC_FOLDLEVELBASE)
+        levelNext = SC_FOLDLEVELBASE;
+               }
+    
+               if (atEOL)
+    {
+                       if (elseFound)
+      {
+                               levelNext++;
+        elseFound = false;
+      }
+
+                       int levelUse = levelCurrent;
+                       int lev = levelUse | levelNext << 16;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if (levelUse < levelNext)
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent))
+                               styler.SetLevel(lineCurrent, lev);
+      
+                       lineCurrent++;
+                       levelCurrent = levelNext;
+                       visibleChars = 0;
+                       endFound = false;
+                       whenFound = false;
+               }
+    
+               if (!isspacechar(currentChar))
+                       visibleChars++;
+       }
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static const char * const mysqlWordListDesc[] = {
+       "Major Keywords",
+       "Keywords",
+       "Database Objects",
+       "Functions",
+       "System Variables",
+       "Procedure keywords",
+       "User Keywords 1",
+       "User Keywords 2",
+       "User Keywords 3",
+       0
+};
+
+LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc);
diff --git a/src/stc/scintilla/src/LexNimrod.cxx b/src/stc/scintilla/src/LexNimrod.cxx
new file mode 100644 (file)
index 0000000..8c4d043
--- /dev/null
@@ -0,0 +1,430 @@
+// Scintilla source code edit control
+// Nimrod lexer
+// (c) 2009 Andreas Rumpf
+/** @file LexNimrod.cxx
+ ** Lexer for Nimrod.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsAWordChar(int ch) {
+       return (ch >= 0x80) || isalnum(ch) || ch == '_';
+}
+
+static int tillEndOfTripleQuote(Accessor &styler, int pos, int max) {
+  /* search for """ */
+  for (;;) {
+    if (styler.SafeGetCharAt(pos, '\0') == '\0') return pos;
+    if (pos >= max) return pos;
+    if (styler.Match(pos, "\"\"\"")) {
+      return pos + 2;
+    }
+    pos++;
+  }
+}
+
+#define CR 13 /* use both because Scite allows changing the line ending */
+#define LF 10
+
+static bool inline isNewLine(int ch) {
+  return ch == CR || ch == LF;
+}
+
+static int scanString(Accessor &styler, int pos, int max, bool rawMode) {
+  for (;;) {
+    if (pos >= max) return pos;
+    char ch = styler.SafeGetCharAt(pos, '\0');
+    if (ch == CR || ch == LF || ch == '\0') return pos;
+    if (ch == '"') return pos;
+    if (ch == '\\' && !rawMode) {
+      pos += 2;
+    } else {
+      pos++;
+    }
+  }
+}
+
+static int scanChar(Accessor &styler, int pos, int max) {
+  for (;;) {
+    if (pos >= max) return pos;
+    char ch = styler.SafeGetCharAt(pos, '\0');
+    if (ch == CR || ch == LF || ch == '\0') return pos;
+    if (ch == '\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\0')) )
+      return pos;
+    if (ch == '\\') {
+      pos += 2;
+    } else {
+      pos++;
+    }
+  }
+}
+
+static int scanIdent(Accessor &styler, int pos, WordList &keywords) {
+  char buf[100]; /* copy to lowercase and ignore underscores */
+  int i = 0;
+
+  for (;;) {
+    char ch = styler.SafeGetCharAt(pos, '\0');
+    if (!IsAWordChar(ch)) break;
+    if (ch != '_' && i < ((int)sizeof(buf))-1) {
+      buf[i] = static_cast<char>(tolower(ch));
+      i++;
+    }
+    pos++;
+  }
+  buf[i] = '\0';
+  /* look for keyword */
+  if (keywords.InList(buf)) {
+    styler.ColourTo(pos-1, SCE_P_WORD);
+  } else {
+    styler.ColourTo(pos-1, SCE_P_IDENTIFIER);
+  }
+  return pos;
+}
+
+static int scanNumber(Accessor &styler, int pos) {
+  char ch, ch2;
+  ch = styler.SafeGetCharAt(pos, '\0');
+  ch2 = styler.SafeGetCharAt(pos+1, '\0');
+  if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) {
+    /* binary number: */
+    pos += 2;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
+      else break;
+    }
+  } else if (ch == '0' && 
+            (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
+    /* octal number: */
+    pos += 2;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos;
+      else break;
+    }
+  } else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) {
+    /* hexadecimal number: */
+    pos += 2;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '9')
+          || (ch >= 'a' && ch <= 'f')
+          || (ch >= 'A' && ch <= 'F')) ++pos;
+      else break;
+    }
+  } else {
+    // skip decimal part:
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+      else break;
+    }
+    ch2 = styler.SafeGetCharAt(pos+1, '\0');
+    if (ch == '.' && ch2 >= '0' && ch2 <= '9') {
+      ++pos; // skip '.'
+      for (;;) {
+        ch = styler.SafeGetCharAt(pos, '\0');
+        if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+        else break;
+      }
+    }
+    if (ch == 'e' || ch == 'E') {
+      ++pos;
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '-' || ch == '+') ++pos;
+      for (;;) {
+        ch = styler.SafeGetCharAt(pos, '\0');
+        if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+        else break;
+      }
+    }
+  }
+  if (ch == '\'') {
+    /* a type suffix: */
+    pos++;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos);
+      if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')
+         || (ch >= 'a' && ch <= 'z') || ch == '_') ++pos;
+      else break;
+    }
+  }
+  styler.ColourTo(pos-1, SCE_P_NUMBER);
+  return pos;
+}
+
+/* rewritten from scratch, because I couldn't get rid of the bugs...
+   (A character based approach sucks!)
+*/
+static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
+                                WordList *keywordlists[], Accessor &styler) {
+  int pos = startPos;
+  int max = startPos + length;
+  char ch;
+  WordList &keywords = *keywordlists[0];
+
+  styler.StartAt(startPos);
+  styler.StartSegment(startPos);
+
+  switch (initStyle) {
+    /* check where we are: */
+    case SCE_P_TRIPLEDOUBLE:
+      pos = tillEndOfTripleQuote(styler, pos, max);
+      styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
+      pos++;
+    break;
+    default: /* nothing to do: */
+    break;
+  }
+  while (pos < max) {
+    ch = styler.SafeGetCharAt(pos, '\0');
+    switch (ch) {
+      case '\0': return;
+      case '#': {
+        bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
+        while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
+        if (doccomment) 
+          styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
+        else
+          styler.ColourTo(pos, SCE_P_COMMENTLINE);
+      } break;
+      case 'r': case 'R': {
+        if (styler.SafeGetCharAt(pos+1) == '"') {
+          pos = scanString(styler, pos+2, max, true);
+          styler.ColourTo(pos, SCE_P_STRING);
+          pos++;
+        } else {
+          pos = scanIdent(styler, pos, keywords);
+        }
+      } break;
+      case '"':
+        if (styler.Match(pos+1, "\"\"")) {
+          pos = tillEndOfTripleQuote(styler, pos+3, max);
+          styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
+        } else {
+          pos = scanString(styler, pos+1, max, false);
+          styler.ColourTo(pos, SCE_P_STRING);
+        }
+        pos++;
+      break;
+      case '\'':
+        pos = scanChar(styler, pos+1, max);
+        styler.ColourTo(pos, SCE_P_CHARACTER);
+        pos++;
+      break;
+      default: // identifers, numbers, operators, whitespace
+        if (ch >= '0' && ch <= '9') {
+          pos = scanNumber(styler, pos);
+        } else if (IsAWordChar(ch)) {
+          pos = scanIdent(styler, pos, keywords);
+        } else if (ch == '`') {
+          pos++;
+          while (pos < max) {
+            ch = styler.SafeGetCharAt(pos, LF);
+            if (ch == '`') {
+              ++pos;
+              break;
+            }
+            if (ch == CR || ch == LF) break;
+            ++pos;
+          }
+          styler.ColourTo(pos, SCE_P_IDENTIFIER);
+        } else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", ch)) {
+          styler.ColourTo(pos, SCE_P_OPERATOR);
+          pos++;
+        } else {
+          styler.ColourTo(pos, SCE_P_DEFAULT);
+          pos++;
+        }
+      break;
+    }
+  }
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+       int pos = styler.LineStart(line);
+       int eol_pos = styler.LineStart(line + 1) - 1;
+       for (int i = pos; i < eol_pos; i++) {
+               char ch = styler[i];
+               if (ch == '#')
+                       return true;
+               else if (ch != ' ' && ch != '\t')
+                       return false;
+       }
+       return false;
+}
+
+static bool IsQuoteLine(int line, Accessor &styler) {
+       int style = styler.StyleAt(styler.LineStart(line)) & 31;
+       return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+}
+
+
+static void FoldNimrodDoc(unsigned int startPos, int length, 
+                          int /*initStyle - unused*/,
+                          WordList *[], Accessor &styler) {
+       const int maxPos = startPos + length;
+       const int maxLines = styler.GetLine(maxPos - 1); // Requested last line
+       const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
+       const bool foldComment = styler.GetPropertyInt("fold.comment.nimrod") != 0;
+       const bool foldQuotes = styler.GetPropertyInt("fold.quotes.nimrod") != 0;
+
+       // Backtrack to previous non-blank line so we can determine indent level
+       // for any white space lines (needed esp. within triple quoted strings)
+       // and so we can fix any preceding fold level (which is why we go back
+       // at least one line in all cases)
+       int spaceFlags = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+       while (lineCurrent > 0) {
+               lineCurrent--;
+               indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+               if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
+                       (!IsCommentLine(lineCurrent, styler)) &&
+                       (!IsQuoteLine(lineCurrent, styler)))
+                       break;
+       }
+       int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+
+       // Set up initial loop state
+       startPos = styler.LineStart(lineCurrent);
+       int prev_state = SCE_P_DEFAULT & 31;
+       if (lineCurrent >= 1)
+               prev_state = styler.StyleAt(startPos - 1) & 31;
+       int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || 
+                                      (prev_state == SCE_P_TRIPLEDOUBLE));
+       int prevComment = 0;
+       if (lineCurrent >= 1)
+               prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
+
+       // Process all characters to end of requested range or end of any triple quote
+       // or comment that hangs over the end of the range.  Cap processing in all cases
+       // to end of document (in case of unclosed quote or comment at end).
+       while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || 
+                                             prevQuote || prevComment)) {
+
+               // Gather info
+               int lev = indentCurrent;
+               int lineNext = lineCurrent + 1;
+               int indentNext = indentCurrent;
+               int quote = false;
+               if (lineNext <= docLines) {
+                       // Information about next line is only available if not at end of document
+                       indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+                       int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
+                       quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+               }
+               const int quote_start = (quote && !prevQuote);
+               const int quote_continue = (quote && prevQuote);
+               const int comment = foldComment && IsCommentLine(lineCurrent, styler);
+               const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
+                                          IsCommentLine(lineNext, styler) && 
+                                          (lev > SC_FOLDLEVELBASE));
+               const int comment_continue = (comment && prevComment);
+               if ((!quote || !prevQuote) && !comment)
+                       indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+               if (quote)
+                       indentNext = indentCurrentLevel;
+               if (indentNext & SC_FOLDLEVELWHITEFLAG)
+                       indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+               if (quote_start) {
+                       // Place fold point at start of triple quoted string
+                       lev |= SC_FOLDLEVELHEADERFLAG;
+               } else if (quote_continue || prevQuote) {
+                       // Add level to rest of lines in the string
+                       lev = lev + 1;
+               } else if (comment_start) {
+                       // Place fold point at start of a block of comments
+                       lev |= SC_FOLDLEVELHEADERFLAG;
+               } else if (comment_continue) {
+                       // Add level to rest of lines in the block
+                       lev = lev + 1;
+               }
+
+               // Skip past any blank lines for next indent level info; we skip also
+               // comments (all comments, not just those starting in column 0)
+               // which effectively folds them into surrounding code rather
+               // than screwing up folding.
+
+               while (!quote &&
+                       (lineNext < docLines) &&
+                       ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
+                        (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
+
+                       lineNext++;
+                       indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+               }
+
+               const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+               const int levelBeforeComments = 
+                   Platform::Maximum(indentCurrentLevel,levelAfterComments);
+
+               // Now set all the indent levels on the lines we skipped
+               // Do this from end to start.  Once we encounter one line
+               // which is indented more than the line after the end of
+               // the comment-block, use the level of the block before
+
+               int skipLine = lineNext;
+               int skipLevel = levelAfterComments;
+
+               while (--skipLine > lineCurrent) {
+                       int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+                       if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+                               skipLevel = levelBeforeComments;
+
+                       int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+                       styler.SetLevel(skipLine, skipLevel | whiteFlag);
+               }
+
+               // Set fold header on non-quote/non-comment line
+               if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
+                       if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < 
+                            (indentNext & SC_FOLDLEVELNUMBERMASK))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+               }
+
+               // Keep track of triple quote and block comment state of previous line
+               prevQuote = quote;
+               prevComment = comment_start || comment_continue;
+
+               // Set fold level for this line and move to next line
+               styler.SetLevel(lineCurrent, lev);
+               indentCurrent = indentNext;
+               lineCurrent = lineNext;
+       }
+
+       // NOTE: Cannot set level of last line here because indentCurrent doesn't have
+       // header flag set; the loop above is crafted to take care of this case!
+       //styler.SetLevel(lineCurrent, indentCurrent);
+}
+
+static const char * const nimrodWordListDesc[] = {
+       "Keywords",
+       0
+};
+
+LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, "nimrod", FoldNimrodDoc,
+                                    nimrodWordListDesc);
index ab6304c42e825bca4ee38066679d0a72319034a4..43ddc470619442819c0727b95f18a5c353c5009c 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "KeyWords.h"
@@ -77,7 +78,7 @@ static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &
     }
   }
 
-  if( nNextLine == -1 ) // We never foudn the next line...
+  if( nNextLine == -1 ) // We never found the next line...
     return false;
 
   for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
@@ -145,7 +146,7 @@ static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel
 
   if( s[0] == '!' )
   {
-    if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
+    if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
       newFoldlevel++;
     else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
       newFoldlevel--;
@@ -190,16 +191,16 @@ static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keyw
        }
 
        // Check for special words...
-       if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !micro and !microend
+       if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
                return SCE_NSIS_MACRODEF;
 
-       if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 )
+       if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
                return SCE_NSIS_IFDEFINEDEF;
 
-  if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 )
+       if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase )  == 0 ) // Covers !if and else
                return SCE_NSIS_IFDEFINEDEF;
 
-  if( NsisCmp(s, "!if", bIgnoreCase ) == 0 )
+       if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase )  == 0 ) // Covers !ifmacrodef and !ifnmacrodef
                return SCE_NSIS_IFDEFINEDEF;
 
   if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
index fbc3b28911aeac7613b48732cdad12c2a0b15712..75458f6d59ec3a7f1105bec9c5b3afd60a1c212c 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "KeyWords.h"
 using namespace Scintilla;
 #endif
 
+static bool strstart(const char *haystack, const char *needle) {
+       return strncmp(haystack, needle, strlen(needle)) == 0;
+}
+
 static bool Is0To9(char ch) {
        return (ch >= '0') && (ch <= '9');
 }
@@ -58,7 +63,6 @@ static void ColouriseBatchLine(
     Accessor &styler) {
 
        unsigned int offset = 0;        // Line Buffer Offset
-       unsigned int enVarEnd;          // Environment Variable End point
        unsigned int cmdLoc;            // External Command / Program Location
        char wordBuffer[81];            // Word Buffer - large to catch long paths
        unsigned int wbl;               // Word Buffer Length
@@ -111,39 +115,6 @@ static void ColouriseBatchLine(
        if (lineBuffer[offset] == '@') {
                styler.ColourTo(startLine + offset, SCE_BAT_HIDE);
                offset++;
-       // Check for Argument (%n) or Environment Variable (%x...%)
-       } else if (lineBuffer[offset] == '%') {
-               enVarEnd = offset + 1;
-               // Search end of word for second % (can be a long path)
-               while ((enVarEnd < lengthLine) &&
-                       (!isspacechar(lineBuffer[enVarEnd])) &&
-                       (lineBuffer[enVarEnd] != '%') &&
-                       (!IsBOperator(lineBuffer[enVarEnd])) &&
-                       (!IsBSeparator(lineBuffer[enVarEnd]))) {
-                       enVarEnd++;
-               }
-               // Check for Argument (%n)
-               if ((Is0To9(lineBuffer[offset + 1])) &&
-                       (lineBuffer[enVarEnd] != '%')) {
-                       // Colorize Argument
-                       styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
-                       offset += 2;
-                       // Check for External Command / Program
-                       if (offset < lengthLine && !isspacechar(lineBuffer[offset])) {
-                               cmdLoc = offset;
-                       }
-               // Check for Environment Variable (%x...%)
-               } else if ((lineBuffer[offset + 1] != '%') &&
-                       (lineBuffer[enVarEnd] == '%')) {
-                       offset = enVarEnd;
-                       // Colorize Environment Variable
-                       styler.ColourTo(startLine + offset, SCE_BAT_IDENTIFIER);
-                       offset++;
-                       // Check for External Command / Program
-                       if (offset < lengthLine && !isspacechar(lineBuffer[offset])) {
-                               cmdLoc = offset;
-                       }
-               }
        }
        // Skip next spaces
        while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
@@ -243,6 +214,7 @@ static void ColouriseBatchLine(
                        // No need to Reset Offset
                // Check for Special Keyword in list, External Command / Program, or Default Text
                } else if ((wordBuffer[0] != '%') &&
+                                  (wordBuffer[0] != '!') &&
                        (!IsBOperator(wordBuffer[0])) &&
                        (continueProcessing)) {
                        // Check for Special Keyword
@@ -279,6 +251,7 @@ static void ColouriseBatchLine(
                                        // Read up to %, Operator or Separator
                                        while ((wbo < wbl) &&
                                                (wordBuffer[wbo] != '%') &&
+                                               (wordBuffer[wbo] != '!') &&
                                                (!IsBOperator(wordBuffer[wbo])) &&
                                                (!IsBSeparator(wordBuffer[wbo]))) {
                                                wbo++;
@@ -328,6 +301,7 @@ static void ColouriseBatchLine(
                                        // Read up to %, Operator or Separator
                                        while ((wbo < wbl) &&
                                                (wordBuffer[wbo] != '%') &&
+                                               (wordBuffer[wbo] != '!') &&
                                                (!IsBOperator(wordBuffer[wbo])) &&
                                                (!IsBSeparator(wordBuffer[wbo]))) {
                                                wbo++;
@@ -350,8 +324,8 @@ static void ColouriseBatchLine(
                                (!IsBSeparator(wordBuffer[wbo]))) {
                                wbo++;
                        }
-                       // Check for Argument (%n)
-                       if ((Is0To9(wordBuffer[1])) &&
+                       // Check for Argument (%n) or (%*)
+                       if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) &&
                                (wordBuffer[wbo] != '%')) {
                                // Check for External Command / Program
                                if (cmdLoc == offset - wbl) {
@@ -361,6 +335,17 @@ static void ColouriseBatchLine(
                                styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
                                // Reset Offset to re-process remainder of word
                                offset -= (wbl - 2);
+                       // Check for Expanded Argument (%~...) / Variable (%%~...)
+                       } else if (((wbl > 1) && (wordBuffer[1] == '~')) ||
+                               ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) {
+                               // Check for External Command / Program
+                               if (cmdLoc == offset - wbl) {
+                                       cmdLoc = offset - (wbl - wbo);
+                               }
+                               // Colorize Expanded Argument / Variable
+                               styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
+                               // Reset Offset to re-process remainder of word
+                               offset -= (wbl - wbo);
                        // Check for Environment Variable (%x...%)
                        } else if ((wordBuffer[1] != '%') &&
                                (wordBuffer[wbo] == '%')) {
@@ -389,6 +374,29 @@ static void ColouriseBatchLine(
                                // Reset Offset to re-process remainder of word
                                offset -= (wbl - 3);
                        }
+               // Check for Environment Variable (!x...!)
+               } else if (wordBuffer[0] == '!') {
+                       // Colorize Default Text
+                       styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+                       wbo++;
+                       // Search to end of word for second ! (can be a long path)
+                       while ((wbo < wbl) &&
+                               (wordBuffer[wbo] != '!') &&
+                               (!IsBOperator(wordBuffer[wbo])) &&
+                               (!IsBSeparator(wordBuffer[wbo]))) {
+                               wbo++;
+                       }
+                       if (wordBuffer[wbo] == '!') {
+                               wbo++;
+                               // Check for External Command / Program
+                               if (cmdLoc == offset - wbl) {
+                                       cmdLoc = offset - (wbl - wbo);
+                               }
+                               // Colorize Environment Variable
+                               styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
+                               // Reset Offset to re-process remainder of word
+                               offset -= (wbl - wbo);
+                       }
                // Check for Operator
                } else if (IsBOperator(wordBuffer[0])) {
                        // Colorize Default Text
@@ -436,6 +444,7 @@ static void ColouriseBatchLine(
                        // Read up to %, Operator or Separator
                        while ((wbo < wbl) &&
                                (wordBuffer[wbo] != '%') &&
+                               (wordBuffer[wbo] != '!') &&
                                (!IsBOperator(wordBuffer[wbo])) &&
                                (!IsBSeparator(wordBuffer[wbo]))) {
                                wbo++;
@@ -491,9 +500,13 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
        // otherwise it is considered a comment (Only in..., Binary file...)
        if (0 == strncmp(lineBuffer, "diff ", 5)) {
                styler.ColourTo(endLine, SCE_DIFF_COMMAND);
-       } else if (0 == strncmp(lineBuffer, "--- ", 4)) {
+       } else if (0 == strncmp(lineBuffer, "Index: ", 7)) {  // For subversion's diff
+               styler.ColourTo(endLine, SCE_DIFF_COMMAND);
+       } else if (0 == strncmp(lineBuffer, "---", 3)) {
                // In a context diff, --- appears in both the header and the position markers
-               if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/'))
+               if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
+                       styler.ColourTo(endLine, SCE_DIFF_POSITION);
+               else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
                        styler.ColourTo(endLine, SCE_DIFF_POSITION);
                else
                        styler.ColourTo(endLine, SCE_DIFF_HEADER);
@@ -526,6 +539,8 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
                styler.ColourTo(endLine, SCE_DIFF_DELETED);
        } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') {
                styler.ColourTo(endLine, SCE_DIFF_ADDED);
+       } else if (lineBuffer[0] == '!') {
+               styler.ColourTo(endLine, SCE_DIFF_CHANGED);
        } else if (lineBuffer[0] != ' ') {
                styler.ColourTo(endLine, SCE_DIFF_COMMENT);
        } else {
@@ -552,25 +567,24 @@ static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[
        }
 }
 
-static void FoldDiffDoc(unsigned int startPos, int length, int, WordList*[], Accessor &styler) {
+static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
        int curLine = styler.GetLine(startPos);
-       int prevLevel = SC_FOLDLEVELBASE;
-       if (curLine > 0)
-               prevLevel = styler.LevelAt(curLine-1);
-
        int curLineStart = styler.LineStart(curLine);
-       do {
-               int nextLevel = prevLevel;
-               if (prevLevel & SC_FOLDLEVELHEADERFLAG)
-                       nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
+       int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE;
+       int nextLevel;
 
+       do {
                int lineType = styler.StyleAt(curLineStart);
                if (lineType == SCE_DIFF_COMMAND)
+                       nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+               else if (lineType == SCE_DIFF_HEADER)
                        nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
-               else if (lineType == SCE_DIFF_HEADER) {
+               else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-')
                        nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
-               } else if (lineType == SCE_DIFF_POSITION)
-                       nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG;
+               else if (prevLevel & SC_FOLDLEVELHEADERFLAG)
+                       nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
+               else
+                       nextLevel = prevLevel;
 
                if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
                        styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
@@ -582,8 +596,7 @@ static void FoldDiffDoc(unsigned int startPos, int length, int, WordList*[], Acc
        } while (static_cast<int>(startPos) + length > curLineStart);
 }
 
-
-static void ColourisePropsLine(
+static void ColourisePoLine(
     char *lineBuffer,
     unsigned int lengthLine,
     unsigned int startLine,
@@ -591,8 +604,91 @@ static void ColourisePropsLine(
     Accessor &styler) {
 
        unsigned int i = 0;
+       static unsigned int state = SCE_PO_DEFAULT;
+       unsigned int state_start = SCE_PO_DEFAULT;
+
        while ((i < lengthLine) && isspacechar(lineBuffer[i]))  // Skip initial spaces
                i++;
+       if (i < lengthLine) {
+               if (lineBuffer[i] == '#') {
+                       // check if the comment contains any flags ("#, ") and
+                       // then whether the flags contain "fuzzy"
+                       if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
+                               styler.ColourTo(endPos, SCE_PO_FUZZY);
+                       else
+                               styler.ColourTo(endPos, SCE_PO_COMMENT);
+               } else {
+                       if (lineBuffer[0] == '"') {
+                               // line continuation, use previous style
+                               styler.ColourTo(endPos, state);
+                               return;
+                       // this implicitly also matches "msgid_plural"
+                       } else if (strstart(lineBuffer, "msgid")) {
+                               state_start = SCE_PO_MSGID;
+                               state = SCE_PO_MSGID_TEXT;
+                       } else if (strstart(lineBuffer, "msgstr")) {
+                               state_start = SCE_PO_MSGSTR;
+                               state = SCE_PO_MSGSTR_TEXT;
+                       } else if (strstart(lineBuffer, "msgctxt")) {
+                               state_start = SCE_PO_MSGCTXT;
+                               state = SCE_PO_MSGCTXT_TEXT;
+                       }
+                       if (state_start != SCE_PO_DEFAULT) {
+                               // find the next space
+                               while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
+                                       i++;
+                               styler.ColourTo(startLine + i - 1, state_start);
+                               styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
+                               styler.ColourTo(endPos, state);
+                       }
+               }
+       } else {
+               styler.ColourTo(endPos, SCE_PO_DEFAULT);
+       }
+}
+
+static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+       char lineBuffer[1024];
+       styler.StartAt(startPos);
+       styler.StartSegment(startPos);
+       unsigned int linePos = 0;
+       unsigned int startLine = startPos;
+       for (unsigned int i = startPos; i < startPos + length; i++) {
+               lineBuffer[linePos++] = styler[i];
+               if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
+                       // End of line (or of line buffer) met, colourise it
+                       lineBuffer[linePos] = '\0';
+                       ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
+                       linePos = 0;
+                       startLine = i + 1;
+               }
+       }
+       if (linePos > 0) {      // Last line does not have ending characters
+               ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
+       }
+}
+
+static inline bool isassignchar(unsigned char ch) {
+       return (ch == '=') || (ch == ':');
+}
+
+static void ColourisePropsLine(
+    char *lineBuffer,
+    unsigned int lengthLine,
+    unsigned int startLine,
+    unsigned int endPos,
+    Accessor &styler,
+    bool allowInitialSpaces) {
+
+       unsigned int i = 0;
+       if (allowInitialSpaces) {
+               while ((i < lengthLine) && isspacechar(lineBuffer[i]))  // Skip initial spaces
+                       i++;
+       } else {
+               if (isspacechar(lineBuffer[i])) // don't allow initial spaces
+                       i = lengthLine;
+       }
+
        if (i < lengthLine) {
                if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
                        styler.ColourTo(endPos, SCE_PROPS_COMMENT);
@@ -600,14 +696,14 @@ static void ColourisePropsLine(
                        styler.ColourTo(endPos, SCE_PROPS_SECTION);
                } else if (lineBuffer[i] == '@') {
                        styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);
-                       if (lineBuffer[++i] == '=')
+                       if (isassignchar(lineBuffer[i++]))
                                styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
                        styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
                } else {
                        // Search for the '=' character
-                       while ((i < lengthLine) && (lineBuffer[i] != '='))
+                       while ((i < lengthLine) && !isassignchar(lineBuffer[i]))
                                i++;
-                       if ((i < lengthLine) && (lineBuffer[i] == '=')) {
+                       if ((i < lengthLine) && isassignchar(lineBuffer[i])) {
                                styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
                                styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
                                styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
@@ -626,18 +722,25 @@ static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *
        styler.StartSegment(startPos);
        unsigned int linePos = 0;
        unsigned int startLine = startPos;
+
+       // property lexer.props.allow.initial.spaces 
+       //      For properties files, set to 0 to style all lines that start with whitespace in the default style. 
+       //      This is not suitable for SciTE .properties files which use indentation for flow control but 
+       //      can be used for RFC2822 text where indentation is used for continuation lines. 
+       bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
+
        for (unsigned int i = startPos; i < startPos + length; i++) {
                lineBuffer[linePos++] = styler[i];
                if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
                        // End of line (or of line buffer) met, colourise it
                        lineBuffer[linePos] = '\0';
-                       ColourisePropsLine(lineBuffer, linePos, startLine, i, styler);
+                       ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces);
                        linePos = 0;
                        startLine = i + 1;
                }
        }
        if (linePos > 0) {      // Last line does not have ending characters
-               ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
+               ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces);
        }
 }
 
@@ -712,7 +815,7 @@ static void FoldPropsDoc(unsigned int startPos, int length, int, WordList *[], A
                lev = SC_FOLDLEVELBASE;
        }
        int flagsNext = styler.LevelAt(lineCurrent);
-       styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
+       styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK));
 }
 
 static void ColouriseMakeLine(
@@ -814,10 +917,6 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[
        }
 }
 
-static bool strstart(const char *haystack, const char *needle) {
-       return strncmp(haystack, needle, strlen(needle)) == 0;
-}
-
 static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) {
        if (lineBuffer[0] == '>') {
                // Command or return status
@@ -921,7 +1020,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
                                        if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) {
                                                // This check is not completely accurate as may be on
                                                // GTK+ with a file name that includes ':'.
-                                               state = stGccStart;                                             
+                                               state = stGccStart;
                                        } else if (chNext == ' ') { // indicates a Lua 5.1 error message
                                                initialColonPart = true;
                                        }
@@ -1031,6 +1130,12 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
        styler.StartAt(startPos);
        styler.StartSegment(startPos);
        unsigned int linePos = 0;
+
+       // property lexer.errorlist.value.separate 
+       //      For lines in the output pane that are matches from Find in Files or GCC-style 
+       //      diagnostics, style the path and line number separately from the rest of the 
+       //      line with style 21 used for the rest of the line. 
+       //      This allows matched text to be more easily distinguished from its location. 
        bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
        for (unsigned int i = startPos; i < startPos + length; i++) {
                lineBuffer[linePos++] = styler[i];
@@ -1169,6 +1274,7 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[
 
 LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
 LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
+LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
 LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
 LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
 LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
index 0e4576064e9eedac13e7cced2b2b929f11553d19..3dcf35ad531eaaa9d946adf011602ff4c5cef322 100644 (file)
@@ -4,8 +4,109 @@
  ** Written by Laurent le Tynevez
  ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
  ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Completely rewritten by Marko Njezic <sf@maxempire.com> October 2008
  **/
 
+/*
+
+A few words about features of the new completely rewritten LexPascal...
+
+Generally speaking LexPascal tries to support all available Delphi features (up 
+to Delphi 2009 at this time), including .NET specific features.
+
+~ HIGHLIGHTING:
+
+If you enable "lexer.pascal.smart.highlighting" property, some keywords will 
+only be highlighted in appropriate context. As implemented those are keywords 
+related to property and DLL exports declarations (similar to how Delphi IDE 
+works). 
+
+For example, keywords "read" and "write" will only be highlighted if they are in 
+property declaration:
+
+property MyProperty: boolean read FMyProperty write FMyProperty; 
+
+~ FOLDING:
+
+Folding is supported in the following cases:
+
+- Folding of stream-like comments
+- Folding of groups of consecutive line comments
+- Folding of preprocessor blocks (the following preprocessor blocks are 
+supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION 
+blocks), including nesting of preprocessor blocks up to 255 levels
+- Folding of code blocks on appropriate keywords (the following code blocks are 
+supported: "begin, asm, record, try, case / end" blocks, class & object 
+declarations and interface declarations)
+
+Remarks:
+
+- Folding of code blocks tries to handle all special cases in which folding 
+should not occur. As implemented those are:
+
+1. Structure "record case / end" (there's only one "end" statement and "case" is 
+ignored as fold point)
+2. Forward class declarations ("type TMyClass = class;") and object method 
+declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are 
+ignored as fold points
+3. Simplified complete class declarations ("type TMyClass = class(TObject);") 
+are ignored as fold points
+4. Every other situation when class keyword doesn't actually start class 
+declaration ("class procedure", "class function", "class of", "class var", 
+"class property" and "class operator")
+
+- Folding of code blocks inside preprocessor blocks is disabled (any comments 
+inside them will be folded fine) because there is no guarantee that complete 
+code block will be contained inside folded preprocessor block in which case 
+folded code block could end prematurely at the end of preprocessor block if 
+there is no closing statement inside. This was done in order to properly process 
+document that may contain something like this:
+
+type
+{$IFDEF UNICODE}
+  TMyClass = class(UnicodeAncestor)
+{$ELSE}
+  TMyClass = class(AnsiAncestor)
+{$ENDIF}
+  private
+  ...
+  public
+  ...
+  published
+  ...
+end;
+
+If class declarations were folded, then the second class declaration would end 
+at "$ENDIF" statement, first class statement would end at "end;" statement and 
+preprocessor "$IFDEF" block would go all the way to the end of document. 
+However, having in mind all this, if you want to enable folding of code blocks 
+inside preprocessor blocks, you can disable folding of preprocessor blocks by 
+changing "fold.preprocessor" property, in which case everything inside them 
+would be folded.
+
+~ KEYWORDS:
+
+The list of keywords that can be used in pascal.properties file (up to Delphi 
+2009):
+
+- Keywords: absolute abstract and array as asm assembler automated begin case 
+cdecl class const constructor deprecated destructor dispid dispinterface div do 
+downto dynamic else end except export exports external far file final 
+finalization finally for forward function goto if implementation in inherited 
+initialization inline interface is label library message mod near nil not object 
+of on or out overload override packed pascal platform private procedure program 
+property protected public published raise record register reintroduce repeat 
+resourcestring safecall sealed set shl shr static stdcall strict string then 
+threadvar to try type unit unsafe until uses var varargs virtual while with xor
+
+- Keywords related to the "smart highlithing" feature: add default implements 
+index name nodefault read readonly remove stored write writeonly
+
+- Keywords related to Delphi packages (in addition to all above): package 
+contains requires
+
+*/
+
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include "Scintilla.h"
 #include "SciLexer.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static void getRange(unsigned int start,
+static void GetRangeLowered(unsigned int start,
                unsigned int end,
                Accessor &styler,
                char *s,
@@ -38,239 +140,361 @@ static void getRange(unsigned int start,
        s[i] = '\0';
 }
 
-static bool IsStreamCommentStyle(int style) {
-       return style == SCE_C_COMMENT ||
-               style == SCE_C_COMMENTDOC ||
-               style == SCE_C_COMMENTDOCKEYWORD ||
-               style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
+static void GetForwardRangeLowered(unsigned int start,
+               CharacterSet &charSet,
+               Accessor &styler,
+               char *s,
+               unsigned int len) {
+       unsigned int i = 0;
+       while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
+               s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
+               i++;
+       }
+       s[i] = '\0';
 
-static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
-       if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
-               styler.ColourTo(end, SCE_C_REGEX);
-       } else
-               styler.ColourTo(end, attr);
 }
 
-// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
-static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInClass, bool bInAsm) {
-       int ret = 0;
+enum {
+       stateInAsm = 0x1000, 
+       stateInProperty = 0x2000, 
+       stateInExport = 0x4000, 
+       stateFoldInPreprocessor = 0x0100, 
+       stateFoldInRecord = 0x0200, 
+       stateFoldInPreprocessorLevelMask = 0x00FF, 
+       stateFoldMaskAll = 0x0FFF
+};
 
+static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) {
        WordList& keywords = *keywordlists[0];
-       WordList& classwords = *keywordlists[1];
 
        char s[100];
-       getRange(start, end, styler, s, sizeof(s));
-
-       char chAttr = SCE_C_IDENTIFIER;
-       if (isdigit(s[0]) || (s[0] == '.') ||(s[0] == '$')) {
-               chAttr = SCE_C_NUMBER;
+       sc.GetCurrentLowered(s, sizeof(s));
+       if (keywords.InList(s)) {
+               if (curLineState & stateInAsm) {
+                       if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') {
+                               curLineState &= ~stateInAsm;
+                               sc.ChangeState(SCE_PAS_WORD);
+                       } else {
+                               sc.ChangeState(SCE_PAS_ASM);
+                       }
+               } else {
+                       bool ignoreKeyword = false;
+                       if (strcmp(s, "asm") == 0) {
+                               curLineState |= stateInAsm;
+                       } else if (bSmartHighlighting) {
+                               if (strcmp(s, "property") == 0) {
+                                       curLineState |= stateInProperty;
+                               } else if (strcmp(s, "exports") == 0) {
+                                       curLineState |= stateInExport;
+                               } else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) {
+                                       ignoreKeyword = true;
+                               } else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) {
+                                       ignoreKeyword = true;
+                               } else if (!(curLineState & stateInProperty) && 
+                                       (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 || 
+                                        strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 || 
+                                        strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 || 
+                                        strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 || 
+                                        strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) {
+                                       ignoreKeyword = true;
+                               }
+                       }
+                       if (!ignoreKeyword) {
+                               sc.ChangeState(SCE_PAS_WORD);
+                       }
+               }
+       } else if (curLineState & stateInAsm) {
+               sc.ChangeState(SCE_PAS_ASM);
        }
-       else {
-               if (s[0] == '#') {
-                       chAttr = SCE_C_CHARACTER;
+       sc.SetState(SCE_PAS_DEFAULT);
+}
+
+static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+               Accessor &styler) {
+       bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0;
+
+       CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+       CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+       CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
+       CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
+       CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}");
+
+       int curLine = styler.GetLine(startPos);
+       int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       for (; sc.More(); sc.Forward()) {
+               if (sc.atLineEnd) {
+                       // Update the line state, so it can be seen by next line
+                       curLine = styler.GetLine(sc.currentPos);
+                       styler.SetLineState(curLine, curLineState);
                }
-               else {
-                       if (keywords.InList(s)) {
-                               chAttr = SCE_C_WORD;
 
-                               if(strcmp(s, "class") == 0) {
-                                       ret = 1;
+               // Determine if the current state should terminate.
+               switch (sc.state) {
+                       case SCE_PAS_NUMBER:
+                               if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
+                                       sc.SetState(SCE_PAS_DEFAULT);
+                               } else if (sc.ch == '-' || sc.ch == '+') {
+                                       if (sc.chPrev != 'E' && sc.chPrev != 'e') {
+                                               sc.SetState(SCE_PAS_DEFAULT);
+                                       }
                                }
-                               else if (strcmp(s, "asm") == 0) {
-                                       ret = 2;
+                               break;
+                       case SCE_PAS_IDENTIFIER:
+                               if (!setWord.Contains(sc.ch)) {
+                                       ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
                                }
-                               else if (strcmp(s, "end") == 0) {
-                                       ret = -1;
+                               break;
+                       case SCE_PAS_HEXNUMBER:
+                               if (!setHexNumber.Contains(sc.ch)) {
+                                       sc.SetState(SCE_PAS_DEFAULT);
                                }
-                       } else if (bInClass) {
-                               if (classwords.InList(s)) {
-                                       chAttr = SCE_C_WORD;
+                               break;
+                       case SCE_PAS_COMMENT:
+                       case SCE_PAS_PREPROCESSOR:
+                               if (sc.ch == '}') {
+                                       sc.ForwardSetState(SCE_PAS_DEFAULT);
                                }
-                       }
+                               break;
+                       case SCE_PAS_COMMENT2:
+                       case SCE_PAS_PREPROCESSOR2:
+                               if (sc.Match('*', ')')) {
+                                       sc.Forward();
+                                       sc.ForwardSetState(SCE_PAS_DEFAULT);
+                               }
+                               break;
+                       case SCE_PAS_COMMENTLINE:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_PAS_DEFAULT);
+                               }
+                               break;
+                       case SCE_PAS_STRING:
+                               if (sc.atLineEnd) {
+                                       sc.ChangeState(SCE_PAS_STRINGEOL);
+                               } else if (sc.ch == '\'' && sc.chNext == '\'') {
+                                       sc.Forward();
+                               } else if (sc.ch == '\'') {
+                                       sc.ForwardSetState(SCE_PAS_DEFAULT);
+                               }
+                               break;
+                       case SCE_PAS_STRINGEOL:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_PAS_DEFAULT);
+                               }
+                               break;
+                       case SCE_PAS_CHARACTER:
+                               if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
+                                       sc.SetState(SCE_PAS_DEFAULT);
+                               }
+                               break;
+                       case SCE_PAS_OPERATOR:
+                               if (bSmartHighlighting && sc.chPrev == ';') {
+                                       curLineState &= ~(stateInProperty | stateInExport);
+                               }
+                               sc.SetState(SCE_PAS_DEFAULT);
+                               break;
+                       case SCE_PAS_ASM:
+                               sc.SetState(SCE_PAS_DEFAULT);
+                               break;
                }
-       }
-       ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
-       return ret;
-}
 
-static int classifyFoldPointPascal(const char* s) {
-       int lev = 0;
-       if (!(isdigit(s[0]) || (s[0] == '.'))) {
-               if (strcmp(s, "begin") == 0 ||
-                       strcmp(s, "object") == 0 ||
-                       strcmp(s, "case") == 0 ||
-                       strcmp(s, "class") == 0 ||
-                       strcmp(s, "record") == 0 ||
-                       strcmp(s, "try") == 0) {
-                       lev=1;
-               } else if (strcmp(s, "end") == 0) {
-                       lev=-1;
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_PAS_DEFAULT) {
+                       if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) {
+                               sc.SetState(SCE_PAS_NUMBER);
+                       } else if (setWordStart.Contains(sc.ch)) {
+                               sc.SetState(SCE_PAS_IDENTIFIER);
+                       } else if (sc.ch == '$' && !(curLineState & stateInAsm)) {
+                               sc.SetState(SCE_PAS_HEXNUMBER);
+                       } else if (sc.Match('{', '$')) {
+                               sc.SetState(SCE_PAS_PREPROCESSOR);
+                       } else if (sc.ch == '{') {
+                               sc.SetState(SCE_PAS_COMMENT);
+                       } else if (sc.Match("(*$")) {
+                               sc.SetState(SCE_PAS_PREPROCESSOR2);
+                       } else if (sc.Match('(', '*')) {
+                               sc.SetState(SCE_PAS_COMMENT2);
+                               sc.Forward();   // Eat the * so it isn't used for the end of the comment
+                       } else if (sc.Match('/', '/')) {
+                               sc.SetState(SCE_PAS_COMMENTLINE);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_PAS_STRING);
+                       } else if (sc.ch == '#') {
+                               sc.SetState(SCE_PAS_CHARACTER);
+                       } else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) {
+                               sc.SetState(SCE_PAS_OPERATOR);
+                       } else if (curLineState & stateInAsm) {
+                               sc.SetState(SCE_PAS_ASM);
+                       }
                }
        }
-       return lev;
-}
 
-static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-       Accessor &styler) {
-
-       styler.StartAt(startPos);
+       if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) {
+               ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
+       }
 
-       int state = initStyle;
-       if (state == SCE_C_CHARACTER)   // Does not leak onto next line
-               state = SCE_C_DEFAULT;
-       char chPrev = ' ';
-       char chNext = styler[startPos];
-       unsigned int lengthDoc = startPos + length;
+       sc.Complete();
+}
 
-       bool bInClassDefinition;
+static bool IsStreamCommentStyle(int style) {
+       return style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2;
+}
 
-       int currentLine = styler.GetLine(startPos);
-       if (currentLine > 0) {
-               styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
-               bInClassDefinition = (styler.GetLineState(currentLine) == 1);
-       } else {
-               styler.SetLineState(currentLine, 0);
-               bInClassDefinition = false;
+static bool IsCommentLine(int line, Accessor &styler) {
+       int pos = styler.LineStart(line);
+       int eolPos = styler.LineStart(line + 1) - 1;
+       for (int i = pos; i < eolPos; i++) {
+               char ch = styler[i];
+               char chNext = styler.SafeGetCharAt(i + 1);
+               int style = styler.StyleAt(i);
+               if (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) {
+                       return true;
+               } else if (!IsASpaceOrTab(ch)) {
+                       return false;
+               }
        }
+       return false;
+}
 
-       bool bInAsm = (state == SCE_C_REGEX);
-       if (bInAsm)
-               state = SCE_C_DEFAULT;
-
-       styler.StartSegment(startPos);
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
+static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
+       return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
+}
 
-               chNext = styler.SafeGetCharAt(i + 1);
+static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
+       lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
+       lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
+}
 
-               if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-                       // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-                       // Avoid triggering two times on Dos/Win
-                       // End of line
-                       if (state == SCE_C_CHARACTER) {
-                               ColourTo(styler, i, state, bInAsm);
-                               state = SCE_C_DEFAULT;
-                       }
-                       currentLine++;
-                       styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+               unsigned int startPos, Accessor &styler) {
+       CharacterSet setWord(CharacterSet::setAlpha);
+
+       char s[11];     // Size of the longest possible keyword + one additional character + null
+       GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
+
+       unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
+
+       if (strcmp(s, "if") == 0 || 
+               strcmp(s, "ifdef") == 0 || 
+               strcmp(s, "ifndef") == 0 || 
+               strcmp(s, "ifopt") == 0 || 
+               strcmp(s, "region") == 0) {
+               nestLevel++;
+               SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+               lineFoldStateCurrent |= stateFoldInPreprocessor;
+               levelCurrent++;
+       } else if (strcmp(s, "endif") == 0 || 
+               strcmp(s, "ifend") == 0 || 
+               strcmp(s, "endregion") == 0) {
+               nestLevel--;
+               SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+               if (nestLevel == 0) {
+                       lineFoldStateCurrent &= ~stateFoldInPreprocessor;
                }
-
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       chPrev = ' ';
-                       i += 1;
-                       continue;
+               levelCurrent--;
+               if (levelCurrent < SC_FOLDLEVELBASE) {
+                       levelCurrent = SC_FOLDLEVELBASE;
                }
+       }
+}
 
-               if (state == SCE_C_DEFAULT) {
-                       if (iswordstart(ch) || ch == '#' || ch == '$' || (ch == '@' && bInAsm)) {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               state = SCE_C_IDENTIFIER;
-                       } else if (ch == '{' && chNext != '$' && chNext != '&') {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               state = SCE_C_COMMENT;
-                       } else if (ch == '(' && chNext == '*'
-                                               && styler.SafeGetCharAt(i + 2) != '$'
-                                               && styler.SafeGetCharAt(i + 2) != '&') {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               state = SCE_C_COMMENTDOC;
-                       } else if (ch == '/' && chNext == '/') {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               state = SCE_C_COMMENTLINE;
-                       } else if (ch == '\'') {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               state = SCE_C_CHARACTER;
-                       } else if (ch == '{' && (chNext == '$' || chNext=='&')) {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               state = SCE_C_PREPROCESSOR;
-                       } else if (isoperator(ch)) {
-                               ColourTo(styler, i-1, state, bInAsm);
-                               ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
-
-                       }
-               } else if (state == SCE_C_IDENTIFIER) {
-                       bool bDoublePoint = ((ch == '.') && (chPrev == '.'));
-                       if ((!iswordchar(ch) && ch != '$' && ch != '#' && (ch != '@' || !bInAsm)) || bDoublePoint) {
-                               if (bDoublePoint) i--;
-                               int lStateChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywordlists, styler, bInClassDefinition, bInAsm);
-
-                               if(lStateChange == 1) {
-                                       styler.SetLineState(currentLine, 1);
-                                       bInClassDefinition = true;
-                               } else if(lStateChange == 2) {
-                                       bInAsm = true;
-                               } else if(lStateChange == -1) {
-                                       styler.SetLineState(currentLine, 0);
-                                       bInClassDefinition = false;
-                                       bInAsm = false;
-                               }
-                               if (bDoublePoint) {
-                                       i++;
-                                       ColourTo(styler, i-1, SCE_C_DEFAULT, bInAsm);
-                               }
+static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos, 
+               Accessor &styler, bool includeChars = false) {
+       CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+       unsigned int j = currentPos + 1;
+       char ch = styler.SafeGetCharAt(j);
+       while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+               IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
+               j++;
+               ch = styler.SafeGetCharAt(j);
+       }
+       return j;
+}
 
-                               state = SCE_C_DEFAULT;
-                               chNext = styler.SafeGetCharAt(i + 1);
-                               if (ch == '{' && chNext != '$' && chNext != '&') {
-                                       state = SCE_C_COMMENT;
-                               } else if (ch == '(' && chNext == '*'
-                                               && styler.SafeGetCharAt(i + 2) != '$'
-                                               && styler.SafeGetCharAt(i + 2) != '&') {
-                                       ColourTo(styler, i-1, state, bInAsm);
-                                       state = SCE_C_COMMENTDOC;
-                               } else if (ch == '/' && chNext == '/') {
-                                       state = SCE_C_COMMENTLINE;
-                               } else if (ch == '\'') {
-                                       state = SCE_C_CHARACTER;
-                               } else if (isoperator(ch)) {
-                                       ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
-                               }
-                       }
-               } else {
-                       if (state == SCE_C_PREPROCESSOR) {
-                               if (ch=='}'){
-                                       ColourTo(styler, i, state, bInAsm);
-                                       state = SCE_C_DEFAULT;
-                               } else {
-                                       if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
-                                               ColourTo(styler, i-1, state, bInAsm);
-                                               state = SCE_C_DEFAULT;
+static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+               int startPos, unsigned int endPos, 
+               unsigned int lastStart, unsigned int currentPos, Accessor &styler) {
+       char s[100];
+       GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
+
+       if (strcmp(s, "record") == 0) {
+               lineFoldStateCurrent |= stateFoldInRecord;
+               levelCurrent++;
+       } else if (strcmp(s, "begin") == 0 || 
+               strcmp(s, "asm") == 0 || 
+               strcmp(s, "try") == 0 || 
+               (strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {
+               levelCurrent++;
+       } else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) {
+               // "class" & "object" keywords require special handling...
+               bool ignoreKeyword = false;
+               unsigned int j = SkipWhiteSpace(currentPos, endPos, styler);
+               if (j < endPos) {
+                       CharacterSet setWordStart(CharacterSet::setAlpha, "_");
+                       CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+
+                       if (styler.SafeGetCharAt(j) == ';') {
+                               // Handle forward class declarations ("type TMyClass = class;") 
+                               // and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;")
+                               ignoreKeyword = true;
+                       } else if (strcmp(s, "class") == 0) {
+                               // "class" keyword has a few more special cases...
+                               if (styler.SafeGetCharAt(j) == '(') {
+                                       // Handle simplified complete class declarations ("type TMyClass = class(TObject);") 
+                                       j = SkipWhiteSpace(j, endPos, styler, true);
+                                       if (j < endPos && styler.SafeGetCharAt(j) == ')') {
+                                               j = SkipWhiteSpace(j, endPos, styler);
+                                               if (j < endPos && styler.SafeGetCharAt(j) == ';') {
+                                                       ignoreKeyword = true;
+                                               }
                                        }
-                               }
-                       } else if (state == SCE_C_COMMENT) {
-                               if (ch == '}' ) {
-                                       ColourTo(styler, i, state, bInAsm);
-                                       state = SCE_C_DEFAULT;
-                               }
-                       } else if (state == SCE_C_COMMENTDOC) {
-                               if (ch == ')' && chPrev == '*') {
-                                       if (((i > styler.GetStartSegment() + 2) || (
-                                               (initStyle == SCE_C_COMMENTDOC) &&
-                                               (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
-                                                       ColourTo(styler, i, state, bInAsm);
-                                                       state = SCE_C_DEFAULT;
+                               } else if (setWordStart.Contains(styler.SafeGetCharAt(j))) {
+                                       char s2[11];    // Size of the longest possible keyword + one additional character + null
+                                       GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));
+
+                                       if (strcmp(s2, "procedure") == 0 || 
+                                               strcmp(s2, "function") == 0 || 
+                                               strcmp(s2, "of") == 0 || 
+                                               strcmp(s2, "var") == 0 || 
+                                               strcmp(s2, "property") == 0 || 
+                                               strcmp(s2, "operator") == 0) {
+                                               ignoreKeyword = true;
                                        }
                                }
-                       } else if (state == SCE_C_COMMENTLINE) {
-                               if (ch == '\r' || ch == '\n') {
-                                       ColourTo(styler, i-1, state, bInAsm);
-                                       state = SCE_C_DEFAULT;
-                               }
-                       } else if (state == SCE_C_CHARACTER) {
-                               if (ch == '\'') {
-                                       ColourTo(styler, i, state, bInAsm);
-                                       state = SCE_C_DEFAULT;
-                               }
                        }
                }
-               chPrev = ch;
+               if (!ignoreKeyword) {
+                       levelCurrent++;
+               }
+       } else if (strcmp(s, "interface") == 0) {
+               // "interface" keyword requires special handling...
+               bool ignoreKeyword = true;
+               int j = lastStart - 1;
+               char ch = styler.SafeGetCharAt(j);
+               while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+                       IsStreamCommentStyle(styler.StyleAt(j)))) {
+                       j--;
+                       ch = styler.SafeGetCharAt(j);
+               }
+               if (j >= startPos && styler.SafeGetCharAt(j) == '=') {
+                       ignoreKeyword = false;
+               }
+               if (!ignoreKeyword) {
+                       levelCurrent++;
+               }
+       } else if (strcmp(s, "end") == 0) {
+               lineFoldStateCurrent &= ~stateFoldInRecord;
+               levelCurrent--;
+               if (levelCurrent < SC_FOLDLEVELBASE) {
+                       levelCurrent = SC_FOLDLEVELBASE;
+               }
        }
-       ColourTo(styler, lengthDoc - 1, state, bInAsm);
 }
 
 static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[],
-                            Accessor &styler) {
+               Accessor &styler) {
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
        bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@@ -279,11 +503,13 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
        int lineCurrent = styler.GetLine(startPos);
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
        int levelCurrent = levelPrev;
+       int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
        char chNext = styler[startPos];
        int styleNext = styler.StyleAt(startPos);
        int style = initStyle;
 
        int lastStart = 0;
+       CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
 
        for (unsigned int i = startPos; i < endPos; i++) {
                char ch = chNext;
@@ -293,53 +519,45 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
                styleNext = styler.StyleAt(i + 1);
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
-               if (stylePrev != SCE_C_WORD && style == SCE_C_WORD)
+               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 && atEOL && IsCommentLine(lineCurrent, styler))
                {
-                       // Store last word start point.
-                       lastStart = i;
+                       if (!IsCommentLine(lineCurrent - 1, styler)
+                           && IsCommentLine(lineCurrent + 1, styler))
+                               levelCurrent++;
+                       else if (IsCommentLine(lineCurrent - 1, styler)
+                                && !IsCommentLine(lineCurrent+1, styler))
+                               levelCurrent--;
                }
-
-               if (stylePrev == SCE_C_WORD) {
-                       if(iswordchar(ch) && !iswordchar(chNext)) {
-                               char s[100];
-                               getRange(lastStart, i, styler, s, sizeof(s));
-                               levelCurrent += classifyFoldPointPascal(s);
+               if (foldPreprocessor) {
+                       if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
+                               ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
+                       } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' 
+                                  && styler.SafeGetCharAt(i + 2) == '$') {
+                               ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
                        }
                }
 
-               if (foldComment && (style == SCE_C_COMMENTLINE)) {
-                       if ((ch == '/') && (chNext == '/')) {
-                               char chNext2 = styler.SafeGetCharAt(i + 2);
-                               if (chNext2 == '{') {
-                                       levelCurrent++;
-                               } else if (chNext2 == '}') {
-                                       levelCurrent--;
-                               }
-                       }
+               if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD)
+               {
+                       // Store last word start point.
+                       lastStart = i;
                }
-
-               if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
-                       if (ch == '{' && chNext == '$') {
-                               unsigned int j=i+2; // skip {$
-                               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 (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) {
+                       if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
+                               ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler);
                        }
                }
 
-               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 (!IsASpace(ch))
+                       visibleChars++;
 
                if (atEOL) {
                        int lev = levelPrev;
@@ -350,23 +568,24 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
                        if (lev != styler.LevelAt(lineCurrent)) {
                                styler.SetLevel(lineCurrent, lev);
                        }
+                       int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
+                       styler.SetLineState(lineCurrent, newLineState);
                        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);
+       // If we didn't reach the EOL in previous loop, store line level and whitespace information.
+       // The rest will be filled in later...
+       int lev = levelPrev;
+       if (visibleChars == 0 && foldCompact)
+               lev |= SC_FOLDLEVELWHITEFLAG;
+       styler.SetLevel(lineCurrent, lev);
 }
 
 static const char * const pascalWordListDesc[] = {
        "Keywords",
-       "Classwords",
        0
 };
 
index d7e817049645c28106a0c8fe856b5e4e045462c3..0c66036200f5f079b14897424bab554f30437171 100644 (file)
@@ -1,8 +1,8 @@
 // Scintilla source code edit control
 /** @file LexPerl.cxx
- ** Lexer for subset of Perl.
+ ** Lexer for Perl.
  **/
-// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2008 by Neil Hodgson <neilh@scintilla.org>
 // Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 
 #include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+#include "CharacterSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-#define PERLNUM_BINARY 1    // order is significant: 1-4 cannot have a dot
-#define PERLNUM_HEX 2
-#define PERLNUM_OCTAL 3
-#define PERLNUM_FLOAT 4     // actually exponent part
-#define PERLNUM_DECIMAL 5   // 1-5 are numbers; 6-7 are strings
-#define PERLNUM_VECTOR 6
-#define PERLNUM_V_VECTOR 7
-#define PERLNUM_BAD 8
+// Info for HERE document handling from perldata.pod (reformatted):
+// ----------------------------------------------------------------
+// A line-oriented form of quoting is based on the shell ``here-doc'' syntax.
+// Following a << you specify a string to terminate the quoted material, and
+// all lines following the current line down to the terminating string are
+// the value of the item.
+// * The terminating string may be either an identifier (a word), or some
+//   quoted text.
+// * If quoted, the type of quotes you use determines the treatment of the
+//   text, just as in regular quoting.
+// * An unquoted identifier works like double quotes.
+// * There must be no space between the << and the identifier.
+//   (If you put a space it will be treated as a null identifier,
+//    which is valid, and matches the first empty line.)
+//   (This is deprecated, -w warns of this syntax)
+// * The terminating string must appear by itself (unquoted and
+//   with no surrounding whitespace) on the terminating line.
 
-#define BACK_NONE 0         // lookback state for bareword disambiguation:
-#define BACK_OPERATOR 1     // whitespace/comments are insignificant
-#define BACK_KEYWORD 2      // operators/keywords are needed for disambiguation
+#define HERE_DELIM_MAX 256             // maximum length of HERE doc delimiter
 
-#define HERE_DELIM_MAX 256
+#define PERLNUM_BINARY         1       // order is significant: 1-4 cannot have a dot
+#define PERLNUM_HEX                    2
+#define PERLNUM_OCTAL          3
+#define PERLNUM_FLOAT_EXP      4       // exponent part only
+#define PERLNUM_DECIMAL                5       // 1-5 are numbers; 6-7 are strings
+#define PERLNUM_VECTOR         6
+#define PERLNUM_V_VECTOR       7
+#define PERLNUM_BAD                    8
 
-static inline bool isEOLChar(char ch) {
-       return (ch == '\r') || (ch == '\n');
-}
-
-static bool isSingleCharOp(char ch) {
-       char strCharSet[2];
-       strCharSet[0] = ch;
-       strCharSet[1] = '\0';
-       return (NULL != strstr("rwxoRWXOezsfdlpSbctugkTBMAC", strCharSet));
-}
-
-static inline bool isPerlOperator(char ch) {
-       if (ch == '^' || ch == '&' || ch == '\\' ||
-               ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
-               ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
-               ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
-               ch == '>' || ch == ',' ||
-               ch == '?' || ch == '!' || ch == '.' || ch == '~')
-               return true;
-       // these chars are already tested before this call
-       // ch == '%' || ch == '*' || ch == '<' || ch == '/' ||
-       return false;
-}
+#define BACK_NONE              0       // lookback state for bareword disambiguation:
+#define BACK_OPERATOR  1       // whitespace/comments are insignificant
+#define BACK_KEYWORD   2       // operators/keywords are needed for disambiguation
 
-static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler)
+{
+       // old-style keyword matcher; needed because GetCurrent() needs
+       // current segment to be committed, but we may abandon early...
        char s[100];
-    unsigned int i, len = end - start;
-    if (len > 30) { len = 30; }
+       unsigned int i, len = end - start;
+       if (len > 30) { len = 30; }
        for (i = 0; i < len; i++, start++) s[i] = styler[start];
-    s[i] = '\0';
+       s[i] = '\0';
        return keywords.InList(s);
 }
 
-// Note: as lexer uses chars, UTF-8 bytes are considered as <0 values
-// Note: iswordchar() was used in only one place in LexPerl, it is
-// unnecessary as '.' is processed as the concatenation operator, so
-// only isWordStart() is used in LexPerl
-
-static inline bool isWordStart(char ch) {
-       return !isascii(ch) || isalnum(ch) || ch == '_';
+static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int fw,
+                                int backFlag, unsigned int backPos, unsigned int endPos)
+{
+       // identifiers are recognized by Perl as barewords under some
+       // conditions, the following attempts to do the disambiguation
+       // by looking backward and forward; result in 2 LSB
+       int result = 0;
+       bool moreback = false;          // true if passed newline/comments
+       bool brace = false;                     // true if opening brace found
+       // if BACK_NONE, neither operator nor keyword, so skip test
+       if (backFlag == BACK_NONE)
+               return result;
+       // first look backwards past whitespace/comments to set EOL flag
+       // (some disambiguation patterns must be on a single line)
+       if (backPos <= static_cast<unsigned int>(styler.LineStart(styler.GetLine(bk))))
+               moreback = true;
+       // look backwards at last significant lexed item for disambiguation
+       bk = backPos - 1;
+       int ch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
+       if (ch == '{' && !moreback) {
+               // {bareword: possible variable spec
+               brace = true;
+       } else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&')
+                       // &bareword: subroutine call
+                          || styler.Match(bk - 1, "->")
+                       // ->bareword: part of variable spec
+                          || styler.Match(bk - 2, "sub")) {
+                       // sub bareword: subroutine declaration
+                       // (implied BACK_KEYWORD, no keywords end in 'sub'!)
+               result |= 1;
+       }
+       // next, scan forward after word past tab/spaces only;
+       // if ch isn't one of '[{(,' we can skip the test
+       if ((ch == '{' || ch == '(' || ch == '['|| ch == ',')
+               && fw < endPos) {
+               while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)),
+                          IsASpaceOrTab(ch) && fw < endPos) {
+                       fw++;
+               }
+               if ((ch == '}' && brace)
+                       // {bareword}: variable spec
+                       || styler.Match(fw, "=>")) {
+                       // [{(, bareword=>: hash literal
+                       result |= 2;
+               }
+       }
+       return result;
 }
 
-static inline bool isEndVar(char ch) {
-       return isascii(ch) && !isalnum(ch) && ch != '#' && ch != '$' &&
-              ch != '_' && ch != '\'';
+static void skipWhitespaceComment(Accessor &styler, unsigned int &p)
+{
+       // when backtracking, we need to skip whitespace and comments
+       int style;
+       while ((p > 0) && (style = styler.StyleAt(p),
+                  style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
+               p--;
 }
 
-static inline bool isNonQuote(char ch) {
-       return !isascii(ch) || isalnum(ch) || ch == '_';
+static int styleBeforeBracePair(Accessor &styler, unsigned int bk)
+{
+       // backtrack to find open '{' corresponding to a '}', balanced
+       // return significant style to be tested for '/' disambiguation
+       int braceCount = 1;
+       if (bk == 0)
+               return SCE_PL_DEFAULT;
+       while (--bk > 0) {
+               if (styler.StyleAt(bk) == SCE_PL_OPERATOR) {
+                       int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
+                       if (bkch == ';') {      // early out
+                               break;
+                       } else if (bkch == '}') {
+                               braceCount++;
+                       } else if (bkch == '{') {
+                               if (--braceCount == 0) break;
+                       }
+               }
+       }
+       if (bk > 0 && braceCount == 0) {
+               // balanced { found, bk > 0, skip more whitespace/comments
+               bk--;
+               skipWhitespaceComment(styler, bk);
+               return styler.StyleAt(bk);
+       }
+       return SCE_PL_DEFAULT;
 }
 
-static inline char actualNumStyle(int numberStyle) {
-    if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) {
-        return SCE_PL_STRING;
-    } else if (numberStyle == PERLNUM_BAD) {
-        return SCE_PL_ERROR;
-    }
-    return SCE_PL_NUMBER;
+static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
+{
+       // backtrack to classify sub-styles of identifier under test
+       // return sub-style to be tested for '/' disambiguation
+       if (styler.SafeGetCharAt(bk) == '>')    // inputsymbol, like <foo>
+               return 1;
+       // backtrack to check for possible "->" or "::" before identifier
+       while (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) {
+               bk--;
+       }
+       while (bk > 0) {
+               int bkstyle = styler.StyleAt(bk);
+               if (bkstyle == SCE_PL_DEFAULT
+                       || bkstyle == SCE_PL_COMMENTLINE) {
+                       // skip whitespace, comments
+               } else if (bkstyle == SCE_PL_OPERATOR) {
+                       // test for "->" and "::"
+                       if (styler.Match(bk - 1, "->") || styler.Match(bk - 1, "::"))
+                               return 2;
+               } else
+                       return 3;       // bare identifier
+               bk--;
+       }
+       return 0;
 }
 
-static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
-       if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) {
-               return false;
+static int inputsymbolScan(Accessor &styler, unsigned int pos, unsigned int endPos)
+{
+       // looks forward for matching > on same line; a bit ugly
+       unsigned int fw = pos;
+       while (++fw < endPos) {
+               int fwch = static_cast<unsigned char>(styler.SafeGetCharAt(fw));
+               if (fwch == '\r' || fwch == '\n') {
+                       return 0;
+               } else if (fwch == '>') {
+                       if (styler.Match(fw - 2, "<=>"))        // '<=>' case
+                               return 0;
+                       return fw - pos;
+               }
        }
-       while (*val) {
-               if (*val != styler[pos++]) {
-                       return false;
+       return 0;
+}
+
+static int podLineScan(Accessor &styler, unsigned int &pos, unsigned int endPos)
+{
+       // forward scan the current line to classify line for POD style
+       int state = -1;
+       while (pos <= endPos) {
+               int ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+               if (ch == '\n' || ch == '\r' || pos >= endPos) {
+                       if (ch == '\r' && styler.SafeGetCharAt(pos + 1) == '\n') pos++;
+                       break;
                }
-               val++;
+               if (IsASpaceOrTab(ch)) {        // whitespace, take note
+                       if (state == -1)
+                               state = SCE_PL_DEFAULT;
+               } else if (state == SCE_PL_DEFAULT) {   // verbatim POD line
+                       state = SCE_PL_POD_VERB;
+               } else if (state != SCE_PL_POD_VERB) {  // regular POD line
+                       state = SCE_PL_POD;
+               }
+               pos++;
+       }
+       if (state == -1)
+               state = SCE_PL_DEFAULT;
+       return state;
+}
+
+static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
+{
+       // backtrack to identify if we're starting a subroutine prototype
+       // we also need to ignore whitespace/comments:
+       // 'sub' [whitespace|comment] <identifier> [whitespace|comment]
+       styler.Flush();
+       skipWhitespaceComment(styler, bk);
+       if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier
+               return false;
+       while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) {
+               bk--;
        }
+       skipWhitespaceComment(styler, bk);
+       if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword
+               || !styler.Match(bk - 2, "sub"))        // assume suffix is unique!
+               return false;
        return true;
 }
 
-static char opposite(char ch) {
-       if (ch == '(')
-               return ')';
-       if (ch == '[')
-               return ']';
-       if (ch == '{')
-               return '}';
-       if (ch == '<')
-               return '>';
+static bool isMatch(const char *sref, char *s)
+{
+       // match per-line delimiter - must kill trailing CR if CRLF
+       int i = strlen(s);
+       if (i != 0 && s[i - 1] == '\r')
+               s[i - 1] = '\0';
+       return (strcmp(sref, s) == 0);
+}
+
+static int actualNumStyle(int numberStyle) {
+       if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) {
+               return SCE_PL_STRING;
+       } else if (numberStyle == PERLNUM_BAD) {
+               return SCE_PL_ERROR;
+       }
+       return SCE_PL_NUMBER;
+}
+
+static int opposite(int ch) {
+       if (ch == '(') return ')';
+       if (ch == '[') return ']';
+       if (ch == '{') return '}';
+       if (ch == '<') return '>';
        return ch;
 }
 
 static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
                              WordList *keywordlists[], Accessor &styler) {
 
-       // Lexer for perl often has to backtrack to start of current style to determine
-       // which characters are being used as quotes, how deeply nested is the
-       // start position and what the termination string is for here documents
-
        WordList &keywords = *keywordlists[0];
 
-    // keywords that forces /PATTERN/ at all times
-    WordList reWords;
-    reWords.Set("elsif if split while");
+       // keywords that forces /PATTERN/ at all times; should track vim's behaviour
+       WordList reWords;
+       reWords.Set("elsif if split while");
+
+       // charset classes
+       CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+       CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+       CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMAC");
+       // lexing of "%*</" operators is non-trivial; these are missing in the set below
+       CharacterSet setPerlOperator(CharacterSet::setNone, "^&\\()-+=|{}[]:;>,?!.~");
+       CharacterSet setQDelim(CharacterSet::setNone, "qrwx");
+       CharacterSet setModifiers(CharacterSet::setAlpha);
+       CharacterSet setPreferRE(CharacterSet::setNone, "*/<%");
+       // setArray and setHash also accepts chars for special vars like $_,
+       // which are then truncated when the next char does not match setVar
+       CharacterSet setVar(CharacterSet::setAlphaNum, "#$_'", 0x80, true);
+       CharacterSet setArray(CharacterSet::setAlpha, "#$_+-", 0x80, true);
+       CharacterSet setHash(CharacterSet::setAlpha, "#$_!^+-", 0x80, true);
+       CharacterSet &setPOD = setModifiers;
+       CharacterSet setNonHereDoc(CharacterSet::setDigits, "=$@");
+       CharacterSet setHereDocDelim(CharacterSet::setAlphaNum, "_");
+       CharacterSet setSubPrototype(CharacterSet::setNone, "\\[$@%&*];");
+       // for format identifiers
+       CharacterSet setFormatStart(CharacterSet::setAlpha, "_=");
+       CharacterSet &setFormat = setHereDocDelim;
 
-       class HereDocCls {
+       // Lexer for perl often has to backtrack to start of current style to determine
+       // which characters are being used as quotes, how deeply nested is the
+       // start position and what the termination string is for HERE documents.
+
+       class HereDocCls {      // Class to manage HERE doc sequence
        public:
                int State;              // 0: '<<' encountered
-               // 1: collect the delimiter
-               // 2: here doc text (lines after the delimiter)
-               char Quote;             // the char after '<<'
+                                               // 1: collect the delimiter
+                                               // 2: here doc text (lines after the delimiter)
+               int Quote;              // the char after '<<'
                bool Quoted;            // true if Quote in ('\'','"','`')
                int DelimiterLength;    // strlen(Delimiter)
                char *Delimiter;        // the Delimiter, 256: sizeof PL_tokenbuf
                HereDocCls() {
                        State = 0;
-            Quote = 0;
-            Quoted = false;
+                       Quote = 0;
+                       Quoted = false;
                        DelimiterLength = 0;
                        Delimiter = new char[HERE_DELIM_MAX];
                        Delimiter[0] = '\0';
                }
+               void Append(int ch) {
+                       Delimiter[DelimiterLength++] = static_cast<char>(ch);
+                       Delimiter[DelimiterLength] = '\0';
+               }
                ~HereDocCls() {
                        delete []Delimiter;
                }
        };
-       HereDocCls HereDoc;     // TODO: FIFO for stacked here-docs
+       HereDocCls HereDoc;             // TODO: FIFO for stacked here-docs
 
-       class QuoteCls {
+       class QuoteCls {        // Class to manage quote pairs
                public:
-               int  Rep;
-               int  Count;
-               char Up;
-               char Down;
+               int Rep;
+               int Count;
+               int Up, Down;
                QuoteCls() {
                        this->New(1);
                }
-               void New(int r) {
+               void New(int r = 1) {
                        Rep   = r;
                        Count = 0;
                        Up    = '\0';
                        Down  = '\0';
                }
-               void Open(char u) {
+               void Open(int u) {
                        Count++;
                        Up    = u;
                        Down  = opposite(Up);
@@ -183,523 +354,701 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
        };
        QuoteCls Quote;
 
-       int state = initStyle;
-       char numState = PERLNUM_DECIMAL;
+       // additional state for number lexing
+       int numState = PERLNUM_DECIMAL;
        int dotCount = 0;
-       unsigned int lengthDoc = startPos + length;
-       //int sookedpos = 0; // these have no apparent use, see POD state
-       //char sooked[100];
-       //sooked[sookedpos] = '\0';
 
-       styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
-       // If in a long distance lexical state, seek to the beginning to find quote characters
-       // Perl strings can be multi-line with embedded newlines, so backtrack.
-       // Perl numbers have additional state during lexing, so backtrack too.
-       if (state == SCE_PL_HERE_Q || state == SCE_PL_HERE_QQ || state == SCE_PL_HERE_QX) {
-               while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_PL_HERE_DELIM)) {
+       unsigned int endPos = startPos + length;
+
+       // Backtrack to beginning of style if required...
+       // If in a long distance lexical state, backtrack to find quote characters.
+       // Includes strings (may be multi-line), numbers (additional state), format
+       // bodies, as well as POD sections.
+       if (initStyle == SCE_PL_HERE_Q
+               || initStyle == SCE_PL_HERE_QQ
+               || initStyle == SCE_PL_HERE_QX
+               || initStyle == SCE_PL_FORMAT
+       ) {
+               int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;
+               while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {
                        startPos--;
                }
                startPos = styler.LineStart(styler.GetLine(startPos));
-               state = styler.StyleAt(startPos - 1);
+               initStyle = styler.StyleAt(startPos - 1);
        }
-    // Backtrack for format body.
-       if (state == SCE_PL_FORMAT) {
-               while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_PL_FORMAT_IDENT)) {
+       if (initStyle == SCE_PL_STRING_Q
+               || initStyle == SCE_PL_STRING_QQ
+               || initStyle == SCE_PL_STRING_QX
+               || initStyle == SCE_PL_STRING_QR
+               || initStyle == SCE_PL_STRING_QW
+               || initStyle == SCE_PL_REGEX
+               || initStyle == SCE_PL_REGSUBST
+               || initStyle == SCE_PL_STRING
+               || initStyle == SCE_PL_BACKTICKS
+               || initStyle == SCE_PL_CHARACTER
+               || initStyle == SCE_PL_NUMBER
+               || initStyle == SCE_PL_IDENTIFIER
+               || initStyle == SCE_PL_ERROR
+               || initStyle == SCE_PL_SUB_PROTOTYPE
+       ) {
+               while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
                        startPos--;
                }
-               startPos = styler.LineStart(styler.GetLine(startPos));
-               state = styler.StyleAt(startPos - 1);
-       }
-       if ( state == SCE_PL_STRING_Q
-       || state == SCE_PL_STRING_QQ
-       || state == SCE_PL_STRING_QX
-       || state == SCE_PL_STRING_QR
-       || state == SCE_PL_STRING_QW
-       || state == SCE_PL_REGEX
-       || state == SCE_PL_REGSUBST
-       || state == SCE_PL_STRING
-       || state == SCE_PL_BACKTICKS
-       || state == SCE_PL_CHARACTER
-       || state == SCE_PL_NUMBER
-       || state == SCE_PL_IDENTIFIER
-    || state == SCE_PL_ERROR
-    || state == SCE_PL_SUB_PROTOTYPE
+               initStyle = SCE_PL_DEFAULT;
+       } else if (initStyle == SCE_PL_POD
+                          || initStyle == SCE_PL_POD_VERB
        ) {
-               while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) {
-                       startPos--;
+               // POD backtracking finds preceeding blank lines and goes back past them
+               int ln = styler.GetLine(startPos);
+               if (ln > 0) {
+                       initStyle = styler.StyleAt(styler.LineStart(--ln));
+                       if (initStyle == SCE_PL_POD || initStyle == SCE_PL_POD_VERB) {
+                               while (ln > 0 && styler.GetLineState(ln) == SCE_PL_DEFAULT)
+                                       ln--;
+                       }
+                       startPos = styler.LineStart(++ln);
+                       initStyle = styler.StyleAt(startPos - 1);
+               } else {
+                       startPos = 0;
+                       initStyle = SCE_PL_DEFAULT;
                }
-               state = SCE_PL_DEFAULT;
        }
 
-    // lookback at start of lexing to set proper state for backflag
-    // after this, they are updated when elements are lexed
-    int backflag = BACK_NONE;
-    unsigned int backPos = startPos;
-    if (backPos > 0) {
-        backPos--;
-        int sty = SCE_PL_DEFAULT;
-        while ((backPos > 0) && (sty = styler.StyleAt(backPos),
-               sty == SCE_PL_DEFAULT || sty == SCE_PL_COMMENTLINE))
-            backPos--;
-        if (sty == SCE_PL_OPERATOR)
-            backflag = BACK_OPERATOR;
-        else if (sty == SCE_PL_WORD)
-            backflag = BACK_KEYWORD;
-    }
+       // backFlag, backPos are additional state to aid identifier corner cases.
+       // Look backwards past whitespace and comments in order to detect either
+       // operator or keyword. Later updated as we go along.
+       int backFlag = BACK_NONE;
+       unsigned int backPos = startPos;
+       if (backPos > 0) {
+               backPos--;
+               skipWhitespaceComment(styler, backPos);
+               if (styler.StyleAt(backPos) == SCE_PL_OPERATOR)
+                       backFlag = BACK_OPERATOR;
+               else if (styler.StyleAt(backPos) == SCE_PL_WORD)
+                       backFlag = BACK_KEYWORD;
+               backPos++;
+       }
 
-       styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
-       char chPrev = styler.SafeGetCharAt(startPos - 1);
-       if (startPos == 0)
-               chPrev = '\n';
-       char chNext = styler[startPos];
-       styler.StartSegment(startPos);
+       StyleContext sc(startPos, endPos - startPos, initStyle, styler, static_cast<char>(STYLE_MAX));
 
-       for (unsigned int i = startPos; i < lengthDoc; i++) {
-               char ch = chNext;
-               // if the current character is not consumed due to the completion of an
-               // earlier style, lexing can be restarted via a simple goto
-       restartLexer:
-               chNext = styler.SafeGetCharAt(i + 1);
-               char chNext2 = styler.SafeGetCharAt(i + 2);
+       for (; sc.More(); sc.Forward()) {
 
-               if (styler.IsLeadByte(ch)) {
-                       chNext = styler.SafeGetCharAt(i + 2);
-                       chPrev = ' ';
-                       i += 1;
-                       continue;
+               // Determine if the current state should terminate.
+               switch (sc.state) {
+                       case SCE_PL_OPERATOR:
+                               sc.SetState(SCE_PL_DEFAULT);
+                               backFlag = BACK_OPERATOR;
+                               backPos = sc.currentPos;
+                               break;
+                       case SCE_PL_IDENTIFIER:         // identifier, bareword, inputsymbol
+                               if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
+                                       || sc.Match('.', '.')
+                                       || sc.chPrev == '>') {  // end of inputsymbol
+                                       sc.SetState(SCE_PL_DEFAULT);
+                               }
+                               break;
+                       case SCE_PL_WORD:               // keyword, plus special cases
+                               if (!setWord.Contains(sc.ch)) {
+                                       char s[100];
+                                       sc.GetCurrent(s, sizeof(s));
+                                       if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
+                                               sc.ChangeState(SCE_PL_DATASECTION);
+                                       } else {
+                                               if ((strcmp(s, "format") == 0)) {
+                                                       sc.SetState(SCE_PL_FORMAT_IDENT);
+                                                       HereDoc.State = 0;
+                                               } else {
+                                                       sc.SetState(SCE_PL_DEFAULT);
+                                               }
+                                               backFlag = BACK_KEYWORD;
+                                               backPos = sc.currentPos;
+                                       }
+                               }
+                               break;
+                       case SCE_PL_SCALAR:
+                       case SCE_PL_ARRAY:
+                       case SCE_PL_HASH:
+                       case SCE_PL_SYMBOLTABLE:
+                               if (sc.Match(':', ':')) {       // skip ::
+                                       sc.Forward();
+                               } else if (!setVar.Contains(sc.ch)) {
+                                       if (sc.LengthCurrent() == 1) {
+                                               // Special variable: $(, $_ etc.
+                                               sc.Forward();
+                                       }
+                                       sc.SetState(SCE_PL_DEFAULT);
+                               }
+                               break;
+                       case SCE_PL_NUMBER:
+                               // if no early break, number style is terminated at "(go through)"
+                               if (sc.ch == '.') {
+                                       if (sc.chNext == '.') {
+                                               // double dot is always an operator (go through)
+                                       } else if (numState <= PERLNUM_FLOAT_EXP) {
+                                               // non-decimal number or float exponent, consume next dot
+                                               sc.SetState(SCE_PL_OPERATOR);
+                                               break;
+                                       } else {        // decimal or vectors allows dots
+                                               dotCount++;
+                                               if (numState == PERLNUM_DECIMAL) {
+                                                       if (dotCount <= 1)      // number with one dot in it
+                                                               break;
+                                                       if (IsADigit(sc.chNext)) {      // really a vector
+                                                               numState = PERLNUM_VECTOR;
+                                                               break;
+                                                       }
+                                                       // number then dot (go through)
+                                               } else if (IsADigit(sc.chNext)) // vectors
+                                                       break;
+                                               // vector then dot (go through)
+                                       }
+                               } else if (sc.ch == '_') {
+                                       // permissive underscoring for number and vector literals
+                                       break;
+                               } else if (numState == PERLNUM_DECIMAL) {
+                                       if (sc.ch == 'E' || sc.ch == 'e') {     // exponent, sign
+                                               numState = PERLNUM_FLOAT_EXP;
+                                               if (sc.chNext == '+' || sc.chNext == '-') {
+                                                       sc.Forward();
+                                               }
+                                               break;
+                                       } else if (IsADigit(sc.ch))
+                                               break;
+                                       // number then word (go through)
+                               } else if (numState == PERLNUM_HEX) {
+                                       if (IsADigit(sc.ch, 16))
+                                               break;
+                               } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
+                                       if (IsADigit(sc.ch))    // vector
+                                               break;
+                                       if (setWord.Contains(sc.ch) && dotCount == 0) { // change to word
+                                               sc.ChangeState(SCE_PL_IDENTIFIER);
+                                               break;
+                                       }
+                                       // vector then word (go through)
+                               } else if (IsADigit(sc.ch)) {
+                                       if (numState == PERLNUM_FLOAT_EXP) {
+                                               break;
+                                       } else if (numState == PERLNUM_OCTAL) {
+                                               if (sc.ch <= '7') break;
+                                       } else if (numState == PERLNUM_BINARY) {
+                                               if (sc.ch <= '1') break;
+                                       }
+                                       // mark invalid octal, binary numbers (go through)
+                                       numState = PERLNUM_BAD;
+                                       break;
+                               }
+                               // complete current number or vector
+                               sc.ChangeState(actualNumStyle(numState));
+                               sc.SetState(SCE_PL_DEFAULT);
+                               break;
+                       case SCE_PL_COMMENTLINE:
+                               if (sc.atLineEnd) {
+                                       sc.SetState(SCE_PL_DEFAULT);
+                               }
+                               break;
+                       case SCE_PL_HERE_DELIM:
+                               if (HereDoc.State == 0) { // '<<' encountered
+                                       int delim_ch = sc.chNext;
+                                       int ws_skip = 0;
+                                       HereDoc.State = 1;      // pre-init HERE doc class
+                                       HereDoc.Quote = sc.chNext;
+                                       HereDoc.Quoted = false;
+                                       HereDoc.DelimiterLength = 0;
+                                       HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+                                       if (IsASpaceOrTab(delim_ch)) {
+                                               // skip whitespace; legal only for quoted delimiters
+                                               unsigned int i = sc.currentPos + 1;
+                                               while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
+                                                       i++;
+                                                       delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+                                               }
+                                               ws_skip = i - sc.currentPos - 1;
+                                       }
+                                       if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
+                                               // a quoted here-doc delimiter; skip any whitespace
+                                               sc.Forward(ws_skip + 1);
+                                               HereDoc.Quote = delim_ch;
+                                               HereDoc.Quoted = true;
+                                       } else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
+                                                          || ws_skip > 0) {
+                                               // left shift << or <<= operator cases
+                                               // restore position if operator
+                                               sc.ChangeState(SCE_PL_OPERATOR);
+                                               sc.ForwardSetState(SCE_PL_DEFAULT);
+                                               backFlag = BACK_OPERATOR;
+                                               backPos = sc.currentPos;
+                                               HereDoc.State = 0;
+                                       } else {
+                                               // specially handle initial '\' for identifier
+                                               if (ws_skip == 0 && HereDoc.Quote == '\\')
+                                                       sc.Forward();
+                                               // an unquoted here-doc delimiter, no special handling
+                                               // (cannot be prefixed by spaces/tabs), or
+                                               // symbols terminates; deprecated zero-length delimiter
+                                       }
+                               } else if (HereDoc.State == 1) { // collect the delimiter
+                                       backFlag = BACK_NONE;
+                                       if (HereDoc.Quoted) { // a quoted here-doc delimiter
+                                               if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
+                                                       sc.ForwardSetState(SCE_PL_DEFAULT);
+                                               } else if (!sc.atLineEnd) {
+                                                       if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
+                                                               sc.Forward();
+                                                       }
+                                                       if (sc.ch != '\r') {    // skip CR if CRLF
+                                                               HereDoc.Append(sc.ch);
+                                                       }
+                                               }
+                                       } else { // an unquoted here-doc delimiter
+                                               if (setHereDocDelim.Contains(sc.ch)) {
+                                                       HereDoc.Append(sc.ch);
+                                               } else {
+                                                       sc.SetState(SCE_PL_DEFAULT);
+                                               }
+                                       }
+                                       if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
+                                               sc.SetState(SCE_PL_ERROR);
+                                               HereDoc.State = 0;
+                                       }
+                               }
+                               break;
+                       case SCE_PL_HERE_Q:
+                       case SCE_PL_HERE_QQ:
+                       case SCE_PL_HERE_QX: {
+                               // also implies HereDoc.State == 2
+                               sc.Complete();
+                               while (!sc.atLineEnd)
+                                       sc.Forward();
+                               char s[HERE_DELIM_MAX];
+                               sc.GetCurrent(s, sizeof(s));
+                               if (isMatch(HereDoc.Delimiter, s)) {
+                                       sc.SetState(SCE_PL_DEFAULT);
+                                       backFlag = BACK_NONE;
+                                       HereDoc.State = 0;
+                               }
+                               } break;
+                       case SCE_PL_POD:
+                       case SCE_PL_POD_VERB: {
+                               unsigned int fw = sc.currentPos;
+                               int ln = styler.GetLine(fw);
+                               if (sc.atLineStart && sc.Match("=cut")) {       // end of POD
+                                       sc.SetState(SCE_PL_POD);
+                                       sc.Forward(4);
+                                       sc.SetState(SCE_PL_DEFAULT);
+                                       styler.SetLineState(ln, SCE_PL_POD);
+                                       break;
+                               }
+                               int pod = podLineScan(styler, fw, endPos);      // classify POD line
+                               styler.SetLineState(ln, pod);
+                               if (pod == SCE_PL_DEFAULT) {
+                                       if (sc.state == SCE_PL_POD_VERB) {
+                                               unsigned int fw2 = fw;
+                                               while (fw2 <= endPos && pod == SCE_PL_DEFAULT) {
+                                                       fw = fw2++;     // penultimate line (last blank line)
+                                                       pod = podLineScan(styler, fw2, endPos);
+                                                       styler.SetLineState(styler.GetLine(fw2), pod);
+                                               }
+                                               if (pod == SCE_PL_POD) {        // truncate verbatim POD early
+                                                       sc.SetState(SCE_PL_POD);
+                                               } else
+                                                       fw = fw2;
+                                       } else
+                                               pod = SCE_PL_POD;
+                               } else {
+                                       if (pod == SCE_PL_POD_VERB      // still part of current paragraph
+                                           && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
+                                               pod = SCE_PL_POD;
+                                               styler.SetLineState(ln, pod);
+                                       } else if (pod == SCE_PL_POD
+                                                          && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
+                                               pod = SCE_PL_POD_VERB;
+                                               styler.SetLineState(ln, pod);
+                                       }
+                                       sc.SetState(pod);
+                               }
+                               sc.Forward(fw - sc.currentPos); // commit style
+                               } break;
+                       case SCE_PL_REGEX:
+                       case SCE_PL_STRING_QR:
+                               if (Quote.Rep <= 0) {
+                                       if (!setModifiers.Contains(sc.ch))
+                                               sc.SetState(SCE_PL_DEFAULT);
+                               } else if (!Quote.Up && !IsASpace(sc.ch)) {
+                                       Quote.Open(sc.ch);
+                               } else if (sc.ch == '\\' && Quote.Up != '\\') {
+                                       sc.Forward();
+                               } else if (sc.ch == Quote.Down) {
+                                       Quote.Count--;
+                                       if (Quote.Count == 0)
+                                               Quote.Rep--;
+                               } else if (sc.ch == Quote.Up) {
+                                       Quote.Count++;
+                               }
+                               break;
+                       case SCE_PL_REGSUBST:
+                               if (Quote.Rep <= 0) {
+                                       if (!setModifiers.Contains(sc.ch))
+                                               sc.SetState(SCE_PL_DEFAULT);
+                               } else if (!Quote.Up && !IsASpace(sc.ch)) {
+                                       Quote.Open(sc.ch);
+                               } else if (sc.ch == '\\' && Quote.Up != '\\') {
+                                       sc.Forward();
+                               } else if (Quote.Count == 0 && Quote.Rep == 1) {
+                                       // We matched something like s(...) or tr{...}, Perl 5.10
+                                       // appears to allow almost any character for use as the
+                                       // next delimiters. Whitespace and comments are accepted in
+                                       // between, but we'll limit to whitespace here.
+                                       // For '#', if no whitespace in between, it's a delimiter.
+                                       if (IsASpace(sc.ch)) {
+                                               // Keep going
+                                       } else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) {
+                                               sc.SetState(SCE_PL_DEFAULT);
+                                       } else {
+                                               Quote.Open(sc.ch);
+                                       }
+                               } else if (sc.ch == Quote.Down) {
+                                       Quote.Count--;
+                                       if (Quote.Count == 0)
+                                               Quote.Rep--;
+                                       if (Quote.Up == Quote.Down)
+                                               Quote.Count++;
+                               } else if (sc.ch == Quote.Up) {
+                                       Quote.Count++;
+                               }
+                               break;
+                       case SCE_PL_STRING_Q:
+                       case SCE_PL_STRING_QQ:
+                       case SCE_PL_STRING_QX:
+                       case SCE_PL_STRING_QW:
+                       case SCE_PL_STRING:
+                       case SCE_PL_CHARACTER:
+                       case SCE_PL_BACKTICKS:
+                               if (!Quote.Down && !IsASpace(sc.ch)) {
+                                       Quote.Open(sc.ch);
+                               } else if (sc.ch == '\\' && Quote.Up != '\\') {
+                                       sc.Forward();
+                               } else if (sc.ch == Quote.Down) {
+                                       Quote.Count--;
+                                       if (Quote.Count == 0)
+                                               sc.ForwardSetState(SCE_PL_DEFAULT);
+                               } else if (sc.ch == Quote.Up) {
+                                       Quote.Count++;
+                               }
+                               break;
+                       case SCE_PL_SUB_PROTOTYPE: {
+                               int i = 0;
+                               // forward scan; must all be valid proto characters
+                               while (setSubPrototype.Contains(sc.GetRelative(i)))
+                                       i++;
+                               if (sc.GetRelative(i) == ')') { // valid sub prototype
+                                       sc.Forward(i);
+                                       sc.ForwardSetState(SCE_PL_DEFAULT);
+                               } else {
+                                       // abandon prototype, restart from '('
+                                       sc.ChangeState(SCE_PL_OPERATOR);
+                                       sc.SetState(SCE_PL_DEFAULT);
+                               }
+                               } break;
+                       case SCE_PL_FORMAT: {
+                               sc.Complete();
+                               while (!sc.atLineEnd)
+                                       sc.Forward();
+                               char s[10];
+                               sc.GetCurrent(s, sizeof(s));
+                               if (isMatch(".", s))
+                                       sc.SetState(SCE_PL_DEFAULT);
+                               } break;
+                       case SCE_PL_ERROR:
+                               break;
                }
-               if ((chPrev == '\r' && ch == '\n')) {   // skip on DOS/Windows
-                       styler.ColourTo(i, state);
-                       chPrev = ch;
-                       continue;
+               // Needed for specific continuation styles (one follows the other)
+               switch (sc.state) {
+                       // continued from SCE_PL_WORD
+                       case SCE_PL_FORMAT_IDENT:
+                               // occupies HereDoc state 3 to avoid clashing with HERE docs
+                               if (IsASpaceOrTab(sc.ch)) {             // skip whitespace
+                                       sc.ChangeState(SCE_PL_DEFAULT);
+                                       while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+                                               sc.Forward();
+                                       sc.SetState(SCE_PL_FORMAT_IDENT);
+                               }
+                               if (setFormatStart.Contains(sc.ch)) {   // identifier or '='
+                                       if (sc.ch != '=') {
+                                               do {
+                                                       sc.Forward();
+                                               } while (setFormat.Contains(sc.ch));
+                                       }
+                                       while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+                                               sc.Forward();
+                                       if (sc.ch == '=') {
+                                               sc.ForwardSetState(SCE_PL_DEFAULT);
+                                               HereDoc.State = 3;
+                                       } else {
+                                               // invalid indentifier; inexact fallback, but hey
+                                               sc.ChangeState(SCE_PL_IDENTIFIER);
+                                               sc.SetState(SCE_PL_DEFAULT);
+                                       }
+                               } else {
+                                       sc.ChangeState(SCE_PL_DEFAULT); // invalid indentifier
+                               }
+                               backFlag = BACK_NONE;
+                               break;
                }
 
-               if (HereDoc.State == 1 && isEOLChar(ch)) {
+               // Must check end of HereDoc states here before default state is handled
+               if (HereDoc.State == 1 && sc.atLineEnd) {
                        // Begin of here-doc (the line after the here-doc delimiter):
                        // Lexically, the here-doc starts from the next line after the >>, but the
                        // first line of here-doc seem to follow the style of the last EOL sequence
+                       int st_new = SCE_PL_HERE_QQ;
                        HereDoc.State = 2;
                        if (HereDoc.Quoted) {
-                               if (state == SCE_PL_HERE_DELIM) {
+                               if (sc.state == SCE_PL_HERE_DELIM) {
                                        // Missing quote at end of string! We are stricter than perl.
                                        // Colour here-doc anyway while marking this bit as an error.
-                                       state = SCE_PL_ERROR;
+                                       sc.ChangeState(SCE_PL_ERROR);
                                }
-                               styler.ColourTo(i - 1, state);
                                switch (HereDoc.Quote) {
-                               case '\'':
-                                       state = SCE_PL_HERE_Q ;
-                                       break;
-                               case '"':
-                                       state = SCE_PL_HERE_QQ;
-                                       break;
-                               case '`':
-                                       state = SCE_PL_HERE_QX;
-                                       break;
+                                       case '\'': st_new = SCE_PL_HERE_Q ; break;
+                                       case '"' : st_new = SCE_PL_HERE_QQ; break;
+                                       case '`' : st_new = SCE_PL_HERE_QX; break;
                                }
                        } else {
-                               styler.ColourTo(i - 1, state);
-                               switch (HereDoc.Quote) {
-                               case '\\':
-                                       state = SCE_PL_HERE_Q ;
-                                       break;
-                               default :
-                                       state = SCE_PL_HERE_QQ;
-                               }
+                               if (HereDoc.Quote == '\\')
+                                       st_new = SCE_PL_HERE_Q;
                        }
+                       sc.SetState(st_new);
+               }
+               if (HereDoc.State == 3 && sc.atLineEnd) {
+                       // Start of format body.
+                       HereDoc.State = 0;
+                       sc.SetState(SCE_PL_FORMAT);
                }
-        if (HereDoc.State == 4 && isEOLChar(ch)) {
-            // Start of format body.
-            HereDoc.State = 0;
-            styler.ColourTo(i - 1, state);
-            state = SCE_PL_FORMAT;
-        }
 
-               if (state == SCE_PL_DEFAULT) {
-                       if ((isascii(ch) && isdigit(ch)) || (isascii(chNext) && isdigit(chNext) &&
-                               (ch == '.' || ch == 'v'))) {
-                               state = SCE_PL_NUMBER;
-                backflag = BACK_NONE;
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_PL_DEFAULT) {
+                       if (IsADigit(sc.ch) ||
+                               (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
+                               sc.SetState(SCE_PL_NUMBER);
+                               backFlag = BACK_NONE;
                                numState = PERLNUM_DECIMAL;
                                dotCount = 0;
-                               if (ch == '0') {        // hex,bin,octal
-                                       if (chNext == 'x') {
+                               if (sc.ch == '0') {             // hex,bin,octal
+                                       if (sc.chNext == 'x') {
                                                numState = PERLNUM_HEX;
-                                       } else if (chNext == 'b') {
-                        numState = PERLNUM_BINARY;
-                    } else if (isascii(chNext) && isdigit(chNext)) {
-                        numState = PERLNUM_OCTAL;
-                    }
-                    if (numState != PERLNUM_DECIMAL) {
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
-                    }
-                               } else if (ch == 'v') { // vector
+                                       } else if (sc.chNext == 'b') {
+                                               numState = PERLNUM_BINARY;
+                                       } else if (IsADigit(sc.chNext)) {
+                                               numState = PERLNUM_OCTAL;
+                                       }
+                                       if (numState != PERLNUM_DECIMAL) {
+                                               sc.Forward();
+                                       }
+                               } else if (sc.ch == 'v') {              // vector
                                        numState = PERLNUM_V_VECTOR;
                                }
-                       } else if (isWordStart(ch)) {
-                // if immediately prefixed by '::', always a bareword
-                state = SCE_PL_WORD;
-                if (chPrev == ':' && styler.SafeGetCharAt(i - 2) == ':') {
-                    state = SCE_PL_IDENTIFIER;
-                }
-                unsigned int kw = i + 1;
-                // first check for possible quote-like delimiter
-                               if (ch == 's' && !isNonQuote(chNext)) {
-                                       state = SCE_PL_REGSUBST;
+                       } else if (setWord.Contains(sc.ch)) {
+                               // if immediately prefixed by '::', always a bareword
+                               sc.SetState(SCE_PL_WORD);
+                               if (sc.chPrev == ':' && sc.GetRelative(-2) == ':') {
+                                       sc.ChangeState(SCE_PL_IDENTIFIER);
+                               }
+                               unsigned int bk = sc.currentPos;
+                               unsigned int fw = sc.currentPos + 1;
+                               // first check for possible quote-like delimiter
+                               if (sc.ch == 's' && !setWord.Contains(sc.chNext)) {
+                                       sc.ChangeState(SCE_PL_REGSUBST);
                                        Quote.New(2);
-                               } else if (ch == 'm' && !isNonQuote(chNext)) {
-                                       state = SCE_PL_REGEX;
-                                       Quote.New(1);
-                               } else if (ch == 'q' && !isNonQuote(chNext)) {
-                                       state = SCE_PL_STRING_Q;
-                                       Quote.New(1);
-                               } else if (ch == 'y' && !isNonQuote(chNext)) {
-                                       state = SCE_PL_REGSUBST;
+                               } else if (sc.ch == 'm' && !setWord.Contains(sc.chNext)) {
+                                       sc.ChangeState(SCE_PL_REGEX);
+                                       Quote.New();
+                               } else if (sc.ch == 'q' && !setWord.Contains(sc.chNext)) {
+                                       sc.ChangeState(SCE_PL_STRING_Q);
+                                       Quote.New();
+                               } else if (sc.ch == 'y' && !setWord.Contains(sc.chNext)) {
+                                       sc.ChangeState(SCE_PL_REGSUBST);
                                        Quote.New(2);
-                               } else if (ch == 't' && chNext == 'r' && !isNonQuote(chNext2)) {
-                                       state = SCE_PL_REGSUBST;
+                               } else if (sc.Match('t', 'r') && !setWord.Contains(sc.GetRelative(2))) {
+                                       sc.ChangeState(SCE_PL_REGSUBST);
                                        Quote.New(2);
-                    kw++;
-                               } else if (ch == 'q' && (chNext == 'q' || chNext == 'r' || chNext == 'w' || chNext == 'x') && !isNonQuote(chNext2)) {
-                                       if      (chNext == 'q') state = SCE_PL_STRING_QQ;
-                                       else if (chNext == 'x') state = SCE_PL_STRING_QX;
-                                       else if (chNext == 'r') state = SCE_PL_STRING_QR;
-                                       else if (chNext == 'w') state = SCE_PL_STRING_QW;
-                                       Quote.New(1);
-                    kw++;
-                               } else if (ch == 'x' && (chNext == '=' ||       // repetition
-                           !isWordStart(chNext) ||
-                           (isdigit(chPrev) && isdigit(chNext)))) {
-                    state = SCE_PL_OPERATOR;
-                }
-                // if potentially a keyword, scan forward and grab word, then check
-                // if it's really one; if yes, disambiguation test is performed
-                // otherwise it is always a bareword and we skip a lot of scanning
-                // note: keywords assumed to be limited to [_a-zA-Z] only
-                if (state == SCE_PL_WORD) {
-                    while (isWordStart(styler.SafeGetCharAt(kw))) kw++;
-                    if (!isPerlKeyword(styler.GetStartSegment(), kw, keywords, styler)) {
-                        state = SCE_PL_IDENTIFIER;
-                    }
-                }
-                // if already SCE_PL_IDENTIFIER, then no ambiguity, skip this
-                // for quote-like delimiters/keywords, attempt to disambiguate
-                // to select for bareword, change state -> SCE_PL_IDENTIFIER
-                if (state != SCE_PL_IDENTIFIER && i > 0) {
-                    unsigned int j = i;
-                    bool moreback = false;      // true if passed newline/comments
-                    bool brace = false;         // true if opening brace found
-                    char ch2;
-                    // first look backwards past whitespace/comments for EOLs
-                    // if BACK_NONE, neither operator nor keyword, so skip test
-                    if (backflag != BACK_NONE) {
-                        while (--j > backPos) {
-                            if (isEOLChar(styler.SafeGetCharAt(j)))
-                                moreback = true;
-                        }
-                        ch2 = styler.SafeGetCharAt(j);
-                        if (ch2 == '{' && !moreback) {
-                            // {bareword: possible variable spec
-                            brace = true;
-                        } else if ((ch2 == '&' && styler.SafeGetCharAt(j - 1) != '&')
-                                // &bareword: subroutine call
-                                || (ch2 == '>' && styler.SafeGetCharAt(j - 1) == '-')
-                                // ->bareword: part of variable spec
-                                || (ch2 == 'b' && styler.Match(j - 2, "su"))) {
-                                // sub bareword: subroutine declaration
-                                // (implied BACK_KEYWORD, no keywords end in 'sub'!)
-                            state = SCE_PL_IDENTIFIER;
-                        }
-                        // if status still ambiguous, look forward after word past
-                        // tabs/spaces only; if ch2 isn't one of '[{(,' it can never
-                        // match anything, so skip the whole thing
-                        j = kw;
-                        if (state != SCE_PL_IDENTIFIER
-                            && (ch2 == '{' || ch2 == '(' || ch2 == '['|| ch2 == ',')
-                            && kw < lengthDoc) {
-                            while (ch2 = styler.SafeGetCharAt(j),
-                                   (ch2 == ' ' || ch2 == '\t') && j < lengthDoc) {
-                                j++;
-                            }
-                            if ((ch2 == '}' && brace)
-                             // {bareword}: variable spec
-                             || (ch2 == '=' && styler.SafeGetCharAt(j + 1) == '>')) {
-                             // [{(, bareword=>: hash literal
-                                state = SCE_PL_IDENTIFIER;
-                            }
-                        }
-                    }
-                }
-                backflag = BACK_NONE;
-                // an identifier or bareword
-                if (state == SCE_PL_IDENTIFIER) {
-                    if ((!isWordStart(chNext) && chNext != '\'')
-                        || (chNext == '.' && chNext2 == '.')) {
-                        // We need that if length of word == 1!
-                        // This test is copied from the SCE_PL_WORD handler.
-                        styler.ColourTo(i, SCE_PL_IDENTIFIER);
-                        state = SCE_PL_DEFAULT;
-                    }
-                // a keyword
-                } else if (state == SCE_PL_WORD) {
-                    i = kw - 1;
-                    if (ch == '_' && chNext == '_' &&
-                        (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")
-                      || isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__"))) {
-                        styler.ColourTo(i, SCE_PL_DATASECTION);
-                        state = SCE_PL_DATASECTION;
-                    } else {
-                        if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "format")) {
-                            state = SCE_PL_FORMAT_IDENT;
-                            HereDoc.State = 0;
-                        } else {
-                            state = SCE_PL_DEFAULT;
-                        }
-                        styler.ColourTo(i, SCE_PL_WORD);
-                        backflag = BACK_KEYWORD;
-                        backPos = i;
-                    }
-                    ch = styler.SafeGetCharAt(i);
-                    chNext = styler.SafeGetCharAt(i + 1);
-                // a repetition operator 'x'
-                } else if (state == SCE_PL_OPERATOR) {
-                    state = SCE_PL_DEFAULT;
-                    goto handleOperator;
-                // quote-like delimiter, skip one char if double-char delimiter
-                } else {
-                    i = kw - 1;
-                    chNext = styler.SafeGetCharAt(i + 1);
-                }
-                       } else if (ch == '#') {
-                               state = SCE_PL_COMMENTLINE;
-                       } else if (ch == '\"') {
-                               state = SCE_PL_STRING;
-                               Quote.New(1);
-                               Quote.Open(ch);
-                backflag = BACK_NONE;
-                       } else if (ch == '\'') {
-                               if (chPrev == '&') {
-                                       // Archaic call
-                                       styler.ColourTo(i, state);
-                               } else {
-                                       state = SCE_PL_CHARACTER;
-                                       Quote.New(1);
-                                       Quote.Open(ch);
+                                       sc.Forward();
+                                       fw++;
+                               } else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext)
+                                                  && !setWord.Contains(sc.GetRelative(2))) {
+                                       if      (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
+                                       else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);
+                                       else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);
+                                       else sc.ChangeState(SCE_PL_STRING_QW);  // sc.chNext == 'w'
+                                       Quote.New();
+                                       sc.Forward();
+                                       fw++;
+                               } else if (sc.ch == 'x' && (sc.chNext == '=' || // repetition
+                                                  !setWord.Contains(sc.chNext) ||
+                                                  (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
+                                       sc.ChangeState(SCE_PL_OPERATOR);
                                }
-                backflag = BACK_NONE;
-                       } else if (ch == '`') {
-                               state = SCE_PL_BACKTICKS;
-                               Quote.New(1);
-                               Quote.Open(ch);
-                backflag = BACK_NONE;
-                       } else if (ch == '$') {
-                               if ((chNext == '{') || isspacechar(chNext)) {
-                                       styler.ColourTo(i, SCE_PL_SCALAR);
-                               } else {
-                                       state = SCE_PL_SCALAR;
-                                       if ((chNext == '`' && chNext2 == '`')
-                     || (chNext == ':' && chNext2 == ':')) {
-                                               i += 2;
-                                               ch = styler.SafeGetCharAt(i);
-                                               chNext = styler.SafeGetCharAt(i + 1);
-                                       } else {
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
+                               // if potentially a keyword, scan forward and grab word, then check
+                               // if it's really one; if yes, disambiguation test is performed
+                               // otherwise it is always a bareword and we skip a lot of scanning
+                               if (sc.state == SCE_PL_WORD) {
+                                       while (setWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(fw))))
+                                               fw++;
+                                       if (!isPerlKeyword(styler.GetStartSegment(), fw, keywords, styler)) {
+                                               sc.ChangeState(SCE_PL_IDENTIFIER);
                                        }
                                }
-                backflag = BACK_NONE;
-                       } else if (ch == '@') {
-                               if (!isascii(chNext) || isalpha(chNext) || chNext == '#' || chNext == '$'
-                                       || chNext == '_' || chNext == '+' || chNext == '-') {
-                                       state = SCE_PL_ARRAY;
-                } else if (chNext == ':' && chNext2 == ':') {
-                    state = SCE_PL_ARRAY;
-                    i += 2;
-                    ch = styler.SafeGetCharAt(i);
-                    chNext = styler.SafeGetCharAt(i + 1);
-                               } else if (chNext != '{' && chNext != '[') {
-                                       styler.ColourTo(i, SCE_PL_ARRAY);
-                               } else {
-                                       styler.ColourTo(i, SCE_PL_ARRAY);
+                               // if already SCE_PL_IDENTIFIER, then no ambiguity, skip this
+                               // for quote-like delimiters/keywords, attempt to disambiguate
+                               // to select for bareword, change state -> SCE_PL_IDENTIFIER
+                               if (sc.state != SCE_PL_IDENTIFIER && bk > 0) {
+                                       if (disambiguateBareword(styler, bk, fw, backFlag, backPos, endPos))
+                                               sc.ChangeState(SCE_PL_IDENTIFIER);
                                }
-                backflag = BACK_NONE;
-                       } else if (ch == '%') {
-                backflag = BACK_NONE;
-                               if (!isascii(chNext) || isalpha(chNext) || chNext == '#' || chNext == '$'
-                    || chNext == '_' || chNext == '!' || chNext == '^') {
-                                       state = SCE_PL_HASH;
-                    i++;
-                    ch = chNext;
-                    chNext = chNext2;
-                } else if (chNext == ':' && chNext2 == ':') {
-                    state = SCE_PL_HASH;
-                    i += 2;
-                    ch = styler.SafeGetCharAt(i);
-                    chNext = styler.SafeGetCharAt(i + 1);
-                               } else if (chNext == '{') {
-                                       styler.ColourTo(i, SCE_PL_HASH);
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '#') {
+                               sc.SetState(SCE_PL_COMMENTLINE);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_PL_STRING);
+                               Quote.New();
+                               Quote.Open(sc.ch);
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '\'') {
+                               if (sc.chPrev == '&' && setWordStart.Contains(sc.chNext)) {
+                                       // Archaic call
+                                       sc.SetState(SCE_PL_IDENTIFIER);
                                } else {
-                    goto handleOperator;
+                                       sc.SetState(SCE_PL_CHARACTER);
+                                       Quote.New();
+                                       Quote.Open(sc.ch);
                                }
-                       } else if (ch == '*') {
-                backflag = BACK_NONE;
-                char strch[2];
-                strch[0] = chNext;
-                strch[1] = '\0';
-                if (chNext == ':' && chNext2 == ':') {
-                    state = SCE_PL_SYMBOLTABLE;
-                    i += 2;
-                    ch = styler.SafeGetCharAt(i);
-                    chNext = styler.SafeGetCharAt(i + 1);
-                               } else if (!isascii(chNext) || isalpha(chNext) || chNext == '_'
-                        || NULL != strstr("^/|,\\\";#%^:?<>)[]", strch)) {
-                                       state = SCE_PL_SYMBOLTABLE;
-                    i++;
-                    ch = chNext;
-                    chNext = chNext2;
-                               } else if (chNext == '{') {
-                                       styler.ColourTo(i, SCE_PL_SYMBOLTABLE);
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '`') {
+                               sc.SetState(SCE_PL_BACKTICKS);
+                               Quote.New();
+                               Quote.Open(sc.ch);
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '$') {
+                               sc.SetState(SCE_PL_SCALAR);
+                               if (sc.chNext == '{') {
+                                       sc.ForwardSetState(SCE_PL_OPERATOR);
+                               } else if (IsASpace(sc.chNext)) {
+                                       sc.ForwardSetState(SCE_PL_DEFAULT);
                                } else {
-                                       if (chNext == '*') {    // exponentiation
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
+                                       sc.Forward();
+                                       if (sc.Match('`', '`') || sc.Match(':', ':')) {
+                                               sc.Forward();
                                        }
-                    goto handleOperator;
                                }
-                       } else if (ch == '/' || (ch == '<' && chNext == '<')) {
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '@') {
+                               sc.SetState(SCE_PL_ARRAY);
+                               if (setArray.Contains(sc.chNext)) {
+                                       // no special treatment
+                               } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
+                                       sc.Forward(2);
+                               } else if (sc.chNext == '{' || sc.chNext == '[') {
+                                       sc.ForwardSetState(SCE_PL_OPERATOR);
+                               } else {
+                                       sc.ChangeState(SCE_PL_OPERATOR);
+                               }
+                               backFlag = BACK_NONE;
+                       } else if (setPreferRE.Contains(sc.ch)) {
                                // Explicit backward peeking to set a consistent preferRE for
                                // any slash found, so no longer need to track preferRE state.
                                // Find first previous significant lexed element and interpret.
-                // Test for HERE doc start '<<' shares this code, helps to
-                // determine if it should be an operator.
+                               // A few symbols shares this code for disambiguation.
                                bool preferRE = false;
-                bool isHereDoc = (ch == '<');
-                bool hereDocSpace = false;      // these are for corner case:
-                bool hereDocScalar = false;     // SCALAR [whitespace] '<<'
-                               unsigned int bk = (i > 0)? i - 1: 0;
-                unsigned int bkend;
-                               char bkch;
+                               bool isHereDoc = sc.Match('<', '<');
+                               bool hereDocSpace = false;              // for: SCALAR [whitespace] '<<'
+                               unsigned int bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0;
+                               unsigned int bkend;
+                               sc.Complete();
                                styler.Flush();
-                if (styler.StyleAt(bk) == SCE_PL_DEFAULT)
-                    hereDocSpace = true;
-                               while ((bk > 0) && (styler.StyleAt(bk) == SCE_PL_DEFAULT ||
-                                       styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) {
-                                       bk--;
-                               }
+                               if (styler.StyleAt(bk) == SCE_PL_DEFAULT)
+                                       hereDocSpace = true;
+                               skipWhitespaceComment(styler, bk);
                                if (bk == 0) {
-                                       // position 0 won't really be checked; rarely happens
-                                       // hard to fix due to an unsigned index i
+                                       // avoid backward scanning breakage
                                        preferRE = true;
                                } else {
                                        int bkstyle = styler.StyleAt(bk);
-                                       bkch = styler.SafeGetCharAt(bk);
+                                       int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
                                        switch(bkstyle) {
                                        case SCE_PL_OPERATOR:
                                                preferRE = true;
                                                if (bkch == ')' || bkch == ']') {
                                                        preferRE = false;
                                                } else if (bkch == '}') {
-                                                       // backtrack further, count balanced brace pairs
-                                                       // if a brace pair found, see if it's a variable
-                                                       int braceCount = 1;
-                                                       while (--bk > 0) {
-                                                               bkstyle = styler.StyleAt(bk);
-                                                               if (bkstyle == SCE_PL_OPERATOR) {
-                                                                       bkch = styler.SafeGetCharAt(bk);
-                                                                       if (bkch == ';') {      // early out
-                                                                               break;
-                                                                       } else if (bkch == '}') {
-                                                                               braceCount++;
-                                                                       } else if (bkch == '{') {
-                                                                               if (--braceCount == 0)
-                                                                                       break;
-                                                                       }
-                                                               }
-                                                       }
-                                                       if (bk == 0) {
-                                                               // at beginning, true
-                                                       } else if (braceCount == 0) {
-                                                               // balanced { found, bk>0, skip more whitespace
-                                                               if (styler.StyleAt(--bk) == SCE_PL_DEFAULT) {
-                                                                       while (bk > 0) {
-                                                                               bkstyle = styler.StyleAt(--bk);
-                                                                               if (bkstyle != SCE_PL_DEFAULT)
-                                                                                       break;
-                                                                       }
-                                                               }
-                                                               bkstyle = styler.StyleAt(bk);
-                                                               if (bkstyle == SCE_PL_SCALAR
-                                                                || bkstyle == SCE_PL_ARRAY
-                                                                || bkstyle == SCE_PL_HASH
-                                                                || bkstyle == SCE_PL_SYMBOLTABLE
-                                                                || bkstyle == SCE_PL_OPERATOR) {
-                                                                       preferRE = false;
-                                                               }
+                                                       // backtrack by counting balanced brace pairs
+                                                       // needed to test for variables like ${}, @{} etc.
+                                                       bkstyle = styleBeforeBracePair(styler, bk);
+                                                       if (bkstyle == SCE_PL_SCALAR
+                                                               || bkstyle == SCE_PL_ARRAY
+                                                               || bkstyle == SCE_PL_HASH
+                                                               || bkstyle == SCE_PL_SYMBOLTABLE
+                                                               || bkstyle == SCE_PL_OPERATOR) {
+                                                               preferRE = false;
                                                        }
+                                               } else if (bkch == '+' || bkch == '-') {
+                                                       if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1))
+                                                               && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
+                                                       // exceptions for operators: unary suffixes ++, --
+                                                       preferRE = false;
                                                }
                                                break;
                                        case SCE_PL_IDENTIFIER:
                                                preferRE = true;
-                                               if (bkch == '>') {      // inputsymbol
+                                               bkstyle = styleCheckIdentifier(styler, bk);
+                                               if ((bkstyle == 1) || (bkstyle == 2)) {
+                                                       // inputsymbol or var with "->" or "::" before identifier
                                                        preferRE = false;
-                                                       break;
-                                               }
-                                               // backtrack to find "->" or "::" before identifier
-                                               while (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) {
-                                                       bk--;
-                                               }
-                                               while (bk > 0) {
-                                                       bkstyle = styler.StyleAt(bk);
-                                                       if (bkstyle == SCE_PL_DEFAULT ||
-                                                           bkstyle == SCE_PL_COMMENTLINE) {
-                                                       } else if (bkstyle == SCE_PL_OPERATOR) {
-                                                               bkch = styler.SafeGetCharAt(bk);
-                                // test for "->" and "::"
-                                                               if ((bkch == '>' && styler.SafeGetCharAt(bk - 1) == '-')
-                                 || (bkch == ':' && styler.SafeGetCharAt(bk - 1) == ':')) {
-                                    preferRE = false;
-                                    break;
-                                                               }
-                                                       } else {
-                                // bare identifier, if '/', /PATTERN/ unless digit/space immediately after '/'
-                                                               if (!isHereDoc &&
-                                    (isspacechar(chNext) || isdigit(chNext)))
-                                    preferRE = false;
-                                                               // HERE docs cannot have a space after the >>
-                                if (isspacechar(chNext))
-                                    preferRE = false;
-                                                               break;
+                                               } else if (bkstyle == 3) {
+                                                       // bare identifier, test cases follows:
+                                                       if (sc.ch == '/') {
+                                                               // if '/', /PATTERN/ unless digit/space immediately after '/'
+                                                               // if '//', always expect defined-or operator to follow identifier
+                                                               if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')
+                                                                       preferRE = false;
+                                                       } else if (sc.ch == '*' || sc.ch == '%') {
+                                                               if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))
+                                                                       preferRE = false;
+                                                       } else if (sc.ch == '<') {
+                                                               if (IsASpace(sc.chNext) || sc.chNext == '=')
+                                                                       preferRE = false;
                                                        }
-                                                       bk--;
                                                }
                                                break;
-                    case SCE_PL_SCALAR:     // for $var<< case
-                        hereDocScalar = true;
-                        break;
-                    // for HERE docs, always true for preferRE
+                                       case SCE_PL_SCALAR:             // for $var<< case:
+                                               if (isHereDoc && hereDocSpace)  // if SCALAR whitespace '<<', *always* a HERE doc
+                                                       preferRE = true;
+                                               break;
                                        case SCE_PL_WORD:
-                        preferRE = true;
-                        if (isHereDoc)
-                            break;
-                        // adopt heuristics similar to vim-style rules:
-                        // keywords always forced as /PATTERN/: split, if, elsif, while
-                        // everything else /PATTERN/ unless digit/space immediately after '/'
-                        bkend = bk + 1;
-                                               while (bk > 0 && styler.StyleAt(bk-1) == SCE_PL_WORD) {
-                                                       bk--;
+                                               preferRE = true;
+                                               // for HERE docs, always true
+                                               if (sc.ch == '/') {
+                                                       // adopt heuristics similar to vim-style rules:
+                                                       // keywords always forced as /PATTERN/: split, if, elsif, while
+                                                       // everything else /PATTERN/ unless digit/space immediately after '/'
+                                                       // for '//', defined-or favoured unless special keywords
+                                                       bkend = bk + 1;
+                                                       while (bk > 0 && styler.StyleAt(bk - 1) == SCE_PL_WORD) {
+                                                               bk--;
+                                                       }
+                                                       if (isPerlKeyword(bk, bkend, reWords, styler))
+                                                               break;
+                                                       if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/')
+                                                               preferRE = false;
+                                               } else if (sc.ch == '*' || sc.ch == '%') {
+                                                       if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*'))
+                                                               preferRE = false;
+                                               } else if (sc.ch == '<') {
+                                                       if (IsASpace(sc.chNext) || sc.chNext == '=')
+                                                               preferRE = false;
                                                }
-                        if (isPerlKeyword(bk, bkend, reWords, styler))
-                            break;
-                        if (isspacechar(chNext) || isdigit(chNext))
-                            preferRE = false;
-                        break;
+                                               break;
                                        // other styles uses the default, preferRE=false
                                        case SCE_PL_POD:
-                                       case SCE_PL_POD_VERB:
                                        case SCE_PL_HERE_Q:
                                        case SCE_PL_HERE_QQ:
                                        case SCE_PL_HERE_QX:
@@ -707,550 +1056,115 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
                                                break;
                                        }
                                }
-                backflag = BACK_NONE;
-                if (isHereDoc) {    // handle HERE doc
-                    // if SCALAR whitespace '<<', *always* a HERE doc
-                    if (preferRE || (hereDocSpace && hereDocScalar)) {
-                        state = SCE_PL_HERE_DELIM;
-                        HereDoc.State = 0;
-                    } else {        // << operator
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
-                        goto handleOperator;
-                    }
-                } else {            // handle regexp
-                    if (preferRE) {
-                        state = SCE_PL_REGEX;
-                        Quote.New(1);
-                        Quote.Open(ch);
-                    } else {        // / operator
-                        goto handleOperator;
-                    }
-                }
-                       } else if (ch == '<') {
-                               // looks forward for matching > on same line
-                               unsigned int fw = i + 1;
-                               while (fw < lengthDoc) {
-                                       char fwch = styler.SafeGetCharAt(fw);
-                                       if (fwch == ' ') {
-                                               if (styler.SafeGetCharAt(fw-1) != '\\' ||
-                                                   styler.SafeGetCharAt(fw-2) != '\\')
-                                               goto handleOperator;
-                                       } else if (isEOLChar(fwch) || isspacechar(fwch)) {
-                                               goto handleOperator;
-                                       } else if (fwch == '>') {
-                                               if ((fw - i) == 2 &&    // '<=>' case
-                                                   styler.SafeGetCharAt(fw-1) == '=') {
-                            goto handleOperator;
-                                               }
-                        styler.ColourTo(fw, SCE_PL_IDENTIFIER);
-                                               i = fw;
-                                               ch = fwch;
-                                               chNext = styler.SafeGetCharAt(i+1);
-                                       }
-                                       fw++;
-                               }
-                if (fw == lengthDoc)
-                    goto handleOperator;
-                       } else if (ch == '='    // POD
-                                  && isalpha(chNext)
-                                  && (isEOLChar(chPrev))) {
-                               state = SCE_PL_POD;
-                backflag = BACK_NONE;
-                               //sookedpos = 0;
-                               //sooked[sookedpos] = '\0';
-                       } else if (ch == '-'    // file test operators
-                                  && isSingleCharOp(chNext)
-                                  && !isalnum((chNext2 = styler.SafeGetCharAt(i+2)))) {
-                               styler.ColourTo(i + 1, SCE_PL_WORD);
-                               state = SCE_PL_DEFAULT;
-                               i++;
-                               ch = chNext;
-                               chNext = chNext2;
-                backflag = BACK_NONE;
-            } else if (ch == '-'    // bareword promotion (-FOO cases)
-                       && ((isascii(chNext) && isalpha(chNext)) || chNext == '_')
-                       && backflag != BACK_NONE) {
-                               state = SCE_PL_IDENTIFIER;
-                backflag = BACK_NONE;
-            } else if (ch == '(' && i > 0) {
-                // backtrack to identify if we're starting a sub prototype
-                // for generality, we need to ignore whitespace/comments
-                               unsigned int bk = i - 1;    // i > 0 tested above
-                               styler.Flush();
-                               while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_DEFAULT ||
-                       styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) {
-                                       bk--;
-                               }
-                if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier
-                    goto handleOperator;
-                               while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) {
-                                       bk--;
-                               }
-                               while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_DEFAULT ||
-                       styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) {
-                                       bk--;
-                               }
-                if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword
-                    || !styler.Match(bk - 2, "sub"))    // assume suffix is unique!
-                    goto handleOperator;
-                state = SCE_PL_SUB_PROTOTYPE;
-                backflag = BACK_NONE;
-                backPos = i;    // needed for restart
-                       } else if (isPerlOperator(ch)) {
-                               if (ch == '.' && chNext == '.') { // .. and ...
-                                       i++;
-                                       if (chNext2 == '.') { i++; }
-                                       state = SCE_PL_DEFAULT;
-                                       ch = styler.SafeGetCharAt(i);
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               }
-        handleOperator:
-                               styler.ColourTo(i, SCE_PL_OPERATOR);
-                backflag = BACK_OPERATOR;
-                backPos = i;
-                       } else if (ch == 4 || ch == 26) {    // ^D and ^Z ends valid perl source
-                styler.ColourTo(i, SCE_PL_DATASECTION);
-                state = SCE_PL_DATASECTION;
-            } else {
-                               // keep colouring defaults to make restart easier
-                               styler.ColourTo(i, SCE_PL_DEFAULT);
-                       }
-               } else if (state == SCE_PL_NUMBER) {
-                       if (ch == '.') {
-                               if (chNext == '.') {
-                                       // double dot is always an operator
-                                       goto numAtEnd;
-                               } else if (numState <= PERLNUM_FLOAT) {
-                                       // non-decimal number or float exponent, consume next dot
-                                       styler.ColourTo(i - 1, SCE_PL_NUMBER);
-                                       state = SCE_PL_DEFAULT;
-                    goto handleOperator;
-                               } else { // decimal or vectors allows dots
-                                       dotCount++;
-                                       if (numState == PERLNUM_DECIMAL) {
-                                               if (dotCount > 1) {
-                                                       if (isdigit(chNext)) { // really a vector
-                                                               numState = PERLNUM_VECTOR;
-                                                       } else  // number then dot
-                                                               goto numAtEnd;
-                                               }
-                                       } else { // vectors
-                                               if (!isdigit(chNext))   // vector then dot
-                                                       goto numAtEnd;
-                                       }
-                               }
-                       } else if (ch == '_') {
-                // permissive underscoring for number and vector literals
-                       } else if (!isascii(ch) || isalnum(ch)) {
-                               if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
-                                       if (!isascii(ch) || isalpha(ch)) {
-                                               if (dotCount == 0) { // change to word
-                                                       state = SCE_PL_IDENTIFIER;
-                                               } else { // vector then word
-                                                       goto numAtEnd;
-                                               }
+                               backFlag = BACK_NONE;
+                               if (isHereDoc) {        // handle '<<', HERE doc
+                                       if (preferRE) {
+                                               sc.SetState(SCE_PL_HERE_DELIM);
+                                               HereDoc.State = 0;
+                                       } else {                // << operator
+                                               sc.SetState(SCE_PL_OPERATOR);
+                                               sc.Forward();
                                        }
-                               } else if (numState == PERLNUM_DECIMAL) {
-                                       if (ch == 'E' || ch == 'e') { // exponent
-                                               numState = PERLNUM_FLOAT;
-                                               if (chNext == '+' || chNext == '-') {
-                                                       i++;
-                                                       ch = chNext;
-                                                       chNext = chNext2;
+                               } else if (sc.ch == '*') {      // handle '*', typeglob
+                                       if (preferRE) {
+                                               sc.SetState(SCE_PL_SYMBOLTABLE);
+                                               if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
+                                                       sc.Forward(2);
+                                               } else if (sc.chNext == '{') {
+                                                       sc.ForwardSetState(SCE_PL_OPERATOR);
+                                               } else {
+                                                       sc.Forward();
                                                }
-                                       } else if (!isascii(ch) || !isdigit(ch)) { // number then word
-                                               goto numAtEnd;
-                                       }
-                               } else if (numState == PERLNUM_FLOAT) {
-                                       if (!isdigit(ch)) { // float then word
-                                               goto numAtEnd;
-                                       }
-                               } else if (numState == PERLNUM_OCTAL) {
-                    if (!isdigit(ch))
-                        goto numAtEnd;
-                    else if (ch > '7')
-                        numState = PERLNUM_BAD;
-                } else if (numState == PERLNUM_BINARY) {
-                    if (!isdigit(ch))
-                        goto numAtEnd;
-                    else if (ch > '1')
-                        numState = PERLNUM_BAD;
-                } else if (numState == PERLNUM_HEX) {
-                    int ch2 = toupper(ch);
-                    if (!isdigit(ch) && !(ch2 >= 'A' && ch2 <= 'F'))
-                        goto numAtEnd;
-                               } else {//(numState == PERLNUM_BAD) {
-                    if (!isdigit(ch))
-                        goto numAtEnd;
-                }
-                       } else {
-                               // complete current number or vector
-                       numAtEnd:
-                               styler.ColourTo(i - 1, actualNumStyle(numState));
-                               state = SCE_PL_DEFAULT;
-                               goto restartLexer;
-                       }
-               } else if (state == SCE_PL_IDENTIFIER) {
-                       if (!isWordStart(chNext) && chNext != '\'') {
-                               styler.ColourTo(i, SCE_PL_IDENTIFIER);
-                               state = SCE_PL_DEFAULT;
-                               ch = ' ';
-                       }
-               } else {
-                       if (state == SCE_PL_COMMENTLINE) {
-                               if (isEOLChar(ch)) {
-                                       styler.ColourTo(i - 1, state);
-                                       state = SCE_PL_DEFAULT;
-                                       goto restartLexer;
-                               } else if (isEOLChar(chNext)) {
-                                       styler.ColourTo(i, state);
-                                       state = SCE_PL_DEFAULT;
-                               }
-                       } else if (state == SCE_PL_HERE_DELIM) {
-                               //
-                               // From perldata.pod:
-                               // ------------------
-                               // A line-oriented form of quoting is based on the shell ``here-doc''
-                               // syntax.
-                               // Following a << you specify a string to terminate the quoted material,
-                               // and all lines following the current line down to the terminating
-                               // string are the value of the item.
-                               // The terminating string may be either an identifier (a word),
-                               // or some quoted text.
-                               // If quoted, the type of quotes you use determines the treatment of
-                               // the text, just as in regular quoting.
-                               // An unquoted identifier works like double quotes.
-                               // There must be no space between the << and the identifier.
-                               // (If you put a space it will be treated as a null identifier,
-                               // which is valid, and matches the first empty line.)
-                               // (This is deprecated, -w warns of this syntax)
-                               // The terminating string must appear by itself (unquoted and with no
-                               // surrounding whitespace) on the terminating line.
-                               //
-                               // From Bash info:
-                               // ---------------
-                               // Specifier format is: <<[-]WORD
-                               // Optional '-' is for removal of leading tabs from here-doc.
-                               // Whitespace acceptable after <<[-] operator.
-                               //
-                               if (HereDoc.State == 0) { // '<<' encountered
-                    bool gotspace = false;
-                    unsigned int oldi = i;
-                    if (chNext == ' ' || chNext == '\t') {
-                        // skip whitespace; legal for quoted delimiters
-                        gotspace = true;
-                        do {
-                            i++;
-                            chNext = styler.SafeGetCharAt(i + 1);
-                        } while ((i + 1 < lengthDoc) && (chNext == ' ' || chNext == '\t'));
-                        chNext2 = styler.SafeGetCharAt(i + 2);
-                    }
-                                       HereDoc.State = 1;
-                                       HereDoc.Quote = chNext;
-                                       HereDoc.Quoted = false;
-                                       HereDoc.DelimiterLength = 0;
-                                       HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
-                                       if (chNext == '\'' || chNext == '"' || chNext == '`') {
-                        // a quoted here-doc delimiter
-                                               i++;
-                                               ch = chNext;
-                                               chNext = chNext2;
-                                               HereDoc.Quoted = true;
-                                       } else if (isspacechar(chNext) || isdigit(chNext) || chNext == '\\'
-                                               || chNext == '=' || chNext == '$' || chNext == '@'
-                        || ((isalpha(chNext) || chNext == '_') && gotspace)) {
-                                               // left shift << or <<= operator cases
-                        // restore position if operator
-                        i = oldi;
-                                               styler.ColourTo(i, SCE_PL_OPERATOR);
-                                               state = SCE_PL_DEFAULT;
-                        backflag = BACK_OPERATOR;
-                        backPos = i;
-                                               HereDoc.State = 0;
-                        goto restartLexer;
                                        } else {
-                                               // an unquoted here-doc delimiter, no special handling
-                        // (cannot be prefixed by spaces/tabs), or
-                                               // symbols terminates; deprecated zero-length delimiter
+                                               sc.SetState(SCE_PL_OPERATOR);
+                                               if (sc.chNext == '*')   // exponentiation
+                                                       sc.Forward();
                                        }
-
-                               } else if (HereDoc.State == 1) { // collect the delimiter
-                    backflag = BACK_NONE;
-                                       if (HereDoc.Quoted) { // a quoted here-doc delimiter
-                                               if (ch == HereDoc.Quote) { // closing quote => end of delimiter
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_PL_DEFAULT;
+                               } else if (sc.ch == '%') {      // handle '%', hash
+                                       if (preferRE) {
+                                               sc.SetState(SCE_PL_HASH);
+                                               if (setHash.Contains(sc.chNext)) {
+                                                       sc.Forward();
+                                               } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') {
+                                                       sc.Forward(2);
+                                               } else if (sc.chNext == '{') {
+                                                       sc.ForwardSetState(SCE_PL_OPERATOR);
                                                } else {
-                                                       if (ch == '\\' && chNext == HereDoc.Quote) { // escaped quote
-                                                               i++;
-                                                               ch = chNext;
-                                                               chNext = chNext2;
-                                                       }
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+                                                       sc.ChangeState(SCE_PL_OPERATOR);
                                                }
-                                       } else { // an unquoted here-doc delimiter
-                                               if (isalnum(ch) || ch == '_') {
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
-                                                       HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+                                       } else {
+                                               sc.SetState(SCE_PL_OPERATOR);
+                                       }
+                               } else if (sc.ch == '<') {      // handle '<', inputsymbol
+                                       if (preferRE) {
+                                               // forward scan
+                                               int i = inputsymbolScan(styler, sc.currentPos, endPos);
+                                               if (i > 0) {
+                                                       sc.SetState(SCE_PL_IDENTIFIER);
+                                                       sc.Forward(i);
                                                } else {
-                                                       styler.ColourTo(i - 1, state);
-                                                       state = SCE_PL_DEFAULT;
-                                                       goto restartLexer;
+                                                       sc.SetState(SCE_PL_OPERATOR);
                                                }
-                                       }
-                                       if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_PL_ERROR;
-                                               goto restartLexer;
-                                       }
-                               }
-                       } else if (HereDoc.State == 2) {
-                               // state == SCE_PL_HERE_Q || state == SCE_PL_HERE_QQ || state == SCE_PL_HERE_QX
-                               if (isEOLChar(chPrev) && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
-                                       i += HereDoc.DelimiterLength;
-                                       chPrev = styler.SafeGetCharAt(i - 1);
-                                       ch = styler.SafeGetCharAt(i);
-                                       if (isEOLChar(ch)) {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_PL_DEFAULT;
-                        backflag = BACK_NONE;
-                                               HereDoc.State = 0;
-                                               goto restartLexer;
-                                       }
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               }
-                       } else if (state == SCE_PL_POD
-                               || state == SCE_PL_POD_VERB) {
-                               if (isEOLChar(chPrev)) {
-                                       if (ch == ' ' || ch == '\t') {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_PL_POD_VERB;
                                        } else {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_PL_POD;
-                                               if (ch == '=') {
-                                                       if (isMatch(styler, lengthDoc, i, "=cut")) {
-                                                               styler.ColourTo(i - 1 + 4, state);
-                                                               i += 4;
-                                                               state = SCE_PL_DEFAULT;
-                                                               ch = styler.SafeGetCharAt(i);
-                                                               //chNext = styler.SafeGetCharAt(i + 1);
-                                                               goto restartLexer;
-                                                       }
-                                               }
+                                               sc.SetState(SCE_PL_OPERATOR);
                                        }
-                               }
-                       } else if (state == SCE_PL_SCALAR       // variable names
-                               || state == SCE_PL_ARRAY
-                               || state == SCE_PL_HASH
-                               || state == SCE_PL_SYMBOLTABLE) {
-                               if (ch == ':' && chNext == ':') {       // skip ::
-                                       i++;
-                                       ch = chNext;
-                                       chNext = chNext2;
-                               }
-                               else if (isEndVar(ch)) {
-                                       if (i == (styler.GetStartSegment() + 1)) {
-                                               // Special variable: $(, $_ etc.
-                                               styler.ColourTo(i, state);
-                                               state = SCE_PL_DEFAULT;
-                                       } else {
-                                               styler.ColourTo(i - 1, state);
-                                               state = SCE_PL_DEFAULT;
-                                               goto restartLexer;
+                               } else {                        // handle '/', regexp
+                                       if (preferRE) {
+                                               sc.SetState(SCE_PL_REGEX);
+                                               Quote.New();
+                                               Quote.Open(sc.ch);
+                                       } else {                // / and // operators
+                                               sc.SetState(SCE_PL_OPERATOR);
+                                               if (sc.chNext == '/') {
+                                                       sc.Forward();
+                                               }
                                        }
                                }
-                       } else if (state == SCE_PL_REGEX
-                               || state == SCE_PL_STRING_QR
-                               ) {
-                               if (!Quote.Up && !isspacechar(ch)) {
-                                       Quote.Open(ch);
-                               } else if (ch == '\\' && Quote.Up != '\\') {
-                                       // SG: Is it save to skip *every* escaped char?
-                                       i++;
-                                       ch = chNext;
-                                       chNext = styler.SafeGetCharAt(i + 1);
+                       } else if (sc.ch == '='         // POD
+                                          && setPOD.Contains(sc.chNext)
+                                          && sc.atLineStart) {
+                               sc.SetState(SCE_PL_POD);
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) {  // extended '-' cases
+                               unsigned int bk = sc.currentPos;
+                               unsigned int fw = 2;
+                               if (setSingleCharOp.Contains(sc.chNext) &&      // file test operators
+                                       !setWord.Contains(sc.GetRelative(2))) {
+                                       sc.SetState(SCE_PL_WORD);
                                } else {
-                                       if (ch == Quote.Down /*&& chPrev != '\\'*/) {
-                                               Quote.Count--;
-                                               if (Quote.Count == 0) {
-                                                       Quote.Rep--;
-                                                       if (Quote.Up == Quote.Down) {
-                                                               Quote.Count++;
-                                                       }
-                                               }
-                                               if (!isalpha(chNext)) {
-                                                       if (Quote.Rep <= 0) {
-                                                               styler.ColourTo(i, state);
-                                                               state = SCE_PL_DEFAULT;
-                                                               ch = ' ';
-                                                       }
-                                               }
-                                       } else if (ch == Quote.Up /*&& chPrev != '\\'*/) {
-                                               Quote.Count++;
-                                       } else if (!isascii(chNext) || !isalpha(chNext)) {
-                                               if (Quote.Rep <= 0) {
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_PL_DEFAULT;
-                                                       ch = ' ';
-                                               }
-                                       }
+                                       // nominally a minus and bareword; find extent of bareword
+                                       while (setWord.Contains(sc.GetRelative(fw)))
+                                               fw++;
+                                       sc.SetState(SCE_PL_OPERATOR);
                                }
-                       } else if (state == SCE_PL_REGSUBST) {
-                               if (!Quote.Up && !isspacechar(ch)) {
-                                       Quote.Open(ch);
-                               } else if (ch == '\\' && Quote.Up != '\\') {
-                                       // SG: Is it save to skip *every* escaped char?
-                                       i++;
-                                       ch = chNext;
-                                       chNext = styler.SafeGetCharAt(i + 1);
+                               // force to bareword for hash key => or {variable literal} cases
+                               if (disambiguateBareword(styler, bk, bk + fw, backFlag, backPos, endPos) & 2) {
+                                       sc.ChangeState(SCE_PL_IDENTIFIER);
+                               }
+                               backFlag = BACK_NONE;
+                       } else if (sc.ch == '(' && sc.currentPos > 0) { // '(' or subroutine prototype
+                               sc.Complete();
+                               if (styleCheckSubPrototype(styler, sc.currentPos - 1)) {
+                                       sc.SetState(SCE_PL_SUB_PROTOTYPE);
+                                       backFlag = BACK_NONE;
                                } else {
-                                       if (Quote.Count == 0 && Quote.Rep == 1) {
-                                               /* We matched something like s(...) or tr{...}
-                                               * and are looking for the next matcher characters,
-                                               * which could be either bracketed ({...}) or non-bracketed
-                                               * (/.../).
-                                               *
-                                               * Number-signs are problematic.  If they occur after
-                                               * the close of the first part, treat them like
-                                               * a Quote.Up char, even if they actually start comments.
-                                               *
-                                               * If we find an alnum, we end the regsubst, and punt.
-                                               *
-                                               * Eric Promislow   ericp@activestate.com  Aug 9,2000
-                                               */
-                                               if (isspacechar(ch)) {
-                                                       // Keep going
-                                               }
-                                               else if (!isascii(ch) || isalnum(ch)) {
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_PL_DEFAULT;
-                                                       ch = ' ';
-                                               } else {
-                                                       Quote.Open(ch);
-                                               }
-                                       } else if (ch == Quote.Down /*&& chPrev != '\\'*/) {
-                                               Quote.Count--;
-                                               if (Quote.Count == 0) {
-                                                       Quote.Rep--;
-                                               }
-                                               if (!isascii(chNext) || !isalpha(chNext)) {
-                                                       if (Quote.Rep <= 0) {
-                                                               styler.ColourTo(i, state);
-                                                               state = SCE_PL_DEFAULT;
-                                                               ch = ' ';
-                                                       }
-                                               }
-                                               if (Quote.Up == Quote.Down) {
-                                                       Quote.Count++;
-                                               }
-                                       } else if (ch == Quote.Up /*&& chPrev != '\\'*/) {
-                                               Quote.Count++;
-                                       } else if (!isascii(chNext) || !isalpha(chNext)) {
-                                               if (Quote.Rep <= 0) {
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_PL_DEFAULT;
-                                                       ch = ' ';
-                                               }
-                                       }
+                                       sc.SetState(SCE_PL_OPERATOR);
                                }
-                       } else if (state == SCE_PL_STRING_Q
-                               || state == SCE_PL_STRING_QQ
-                               || state == SCE_PL_STRING_QX
-                               || state == SCE_PL_STRING_QW
-                               || state == SCE_PL_STRING
-                               || state == SCE_PL_CHARACTER
-                               || state == SCE_PL_BACKTICKS
-                               ) {
-                               if (!Quote.Down && !isspacechar(ch)) {
-                                       Quote.Open(ch);
-                               } else if (ch == '\\' && Quote.Up != '\\') {
-                                       i++;
-                                       ch = chNext;
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                               } else if (ch == Quote.Down) {
-                                       Quote.Count--;
-                                       if (Quote.Count == 0) {
-                                               Quote.Rep--;
-                                               if (Quote.Rep <= 0) {
-                                                       styler.ColourTo(i, state);
-                                                       state = SCE_PL_DEFAULT;
-                                                       ch = ' ';
-                                               }
-                                               if (Quote.Up == Quote.Down) {
-                                                       Quote.Count++;
-                                               }
-                                       }
-                               } else if (ch == Quote.Up) {
-                                       Quote.Count++;
+                       } else if (setPerlOperator.Contains(sc.ch)) {   // operators
+                               sc.SetState(SCE_PL_OPERATOR);
+                               if (sc.Match('.', '.')) {       // .. and ...
+                                       sc.Forward();
+                                       if (sc.chNext == '.') sc.Forward();
                                }
-                       } else if (state == SCE_PL_SUB_PROTOTYPE) {
-                char strch[2];
-                strch[0] = ch;
-                strch[1] = '\0';
-                if (NULL != strstr("\\[$@%&*];", strch)) {
-                    // keep going
-                } else if (ch == ')') {
-                    styler.ColourTo(i, state);
-                    state = SCE_PL_DEFAULT;
-                } else {
-                    // abandon prototype, restart from '('
-                    i = backPos;
-                    styler.ColourTo(i, SCE_PL_OPERATOR);
-                                       ch = styler.SafeGetCharAt(i);
-                                       chNext = styler.SafeGetCharAt(i + 1);
-                    state = SCE_PL_DEFAULT;
-                }
-            } else if (state == SCE_PL_FORMAT_IDENT) {
-                // occupies different HereDoc states to avoid clashing with HERE docs
-                if (HereDoc.State == 0) {
-                    if ((isascii(ch) && isalpha(ch)) || ch == '_'   // probable identifier
-                        || ch == '=') {                             // no identifier
-                        HereDoc.State = 3;
-                        HereDoc.Quoted = false; // whitespace flag
-                    } else if (ch == ' ' || ch == '\t') {
-                        styler.ColourTo(i, SCE_PL_DEFAULT);
-                    } else {
-                        state = SCE_PL_DEFAULT;
-                        HereDoc.State = 0;
-                        goto restartLexer;
-                    }
-                }
-                if (HereDoc.State == 3) {   // with just a '=', state goes 0->3->4
-                    if (ch == '=') {
-                        styler.ColourTo(i, SCE_PL_FORMAT_IDENT);
-                        state = SCE_PL_DEFAULT;
-                        HereDoc.State = 4;
-                    } else if (ch == ' ' || ch == '\t') {
-                        HereDoc.Quoted = true;
-                    } else if (isEOLChar(ch) || (HereDoc.Quoted && ch != '=')) {
-                        // abandon format, restart from after 'format'
-                        i = backPos + 1;
-                        ch = styler.SafeGetCharAt(i);
-                        chNext = styler.SafeGetCharAt(i + 1);
-                        state = SCE_PL_DEFAULT;
-                        HereDoc.State = 0;
-                    }
-                }
-            } else if (state == SCE_PL_FORMAT) {
-                if (isEOLChar(chPrev)) {
-                    styler.ColourTo(i - 1, state);
-                    if (ch == '.' && isEOLChar(chNext)) {
-                        styler.ColourTo(i, state);
-                        state = SCE_PL_DEFAULT;
-                    }
-                }
-            }
-               }
-               if (state == SCE_PL_ERROR) {
-                       break;
+                       } else if (sc.ch == 4 || sc.ch == 26) {         // ^D and ^Z ends valid perl source
+                               sc.SetState(SCE_PL_DATASECTION);
+                       } else {
+                               // keep colouring defaults
+                               sc.Complete();
+                       }
                }
-               chPrev = ch;
        }
-       styler.ColourTo(lengthDoc - 1, state);
+       sc.Complete();
 }
 
 static bool IsCommentLine(int line, Accessor &styler) {
@@ -1258,22 +1172,29 @@ static bool IsCommentLine(int line, Accessor &styler) {
        int eol_pos = styler.LineStart(line + 1) - 1;
        for (int i = pos; i < eol_pos; i++) {
                char ch = styler[i];
-        int style = styler.StyleAt(i);
+               int style = styler.StyleAt(i);
                if (ch == '#' && style == SCE_PL_COMMENTLINE)
                        return true;
-               else if (ch != ' ' && ch != '\t')
+               else if (!IsASpaceOrTab(ch))
                        return false;
        }
        return false;
 }
 
 static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
-                            Accessor &styler) {
+                        Accessor &styler) {
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
        // Custom folding of POD and packages
+
+       // property fold.perl.pod 
+       //      Enable folding Pod blocks when using the Perl lexer. 
        bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+
+       // property fold.perl.package 
+       //      Enable folding packages when using the Perl lexer. 
        bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
+
        unsigned int endPos = startPos + length;
        int visibleChars = 0;
        int lineCurrent = styler.GetLine(startPos);
@@ -1293,18 +1214,18 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
                int style = styleNext;
                styleNext = styler.StyleAt(i + 1);
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-               bool atLineStart = isEOLChar(chPrev) || i == 0;
-        // Comment folding
+               bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;
+               // Comment folding
                if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
-        {
-            if (!IsCommentLine(lineCurrent - 1, styler)
-                && IsCommentLine(lineCurrent + 1, styler))
-                levelCurrent++;
-            else if (IsCommentLine(lineCurrent - 1, styler)
-                     && !IsCommentLine(lineCurrent+1, styler))
-                levelCurrent--;
-        }
-               if (style == SCE_C_OPERATOR) {
+               {
+                       if (!IsCommentLine(lineCurrent - 1, styler)
+                               && IsCommentLine(lineCurrent + 1, styler))
+                               levelCurrent++;
+                       else if (IsCommentLine(lineCurrent - 1, styler)
+                                        && !IsCommentLine(lineCurrent+1, styler))
+                               levelCurrent--;
+               }
+               if (style == SCE_PL_OPERATOR) {
                        if (ch == '{') {
                                levelCurrent++;
                        } else if (ch == '}') {
@@ -1322,17 +1243,17 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
                                else if (styler.Match(i, "=head"))
                                        isPodHeading = true;
                        } else if (style == SCE_PL_DATASECTION) {
-                if (ch == '=' && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
-                    levelCurrent++;
-                else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
-                    levelCurrent--;
-                else if (styler.Match(i, "=head"))
+                               if (ch == '=' && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
+                                       levelCurrent++;
+                               else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
+                                       levelCurrent--;
+                               else if (styler.Match(i, "=head"))
                                        isPodHeading = true;
-                // if package used or unclosed brace, level > SC_FOLDLEVELBASE!
-                // reset needed as level test is vs. SC_FOLDLEVELBASE
-                else if (styler.Match(i, "__END__"))
-                    levelCurrent = SC_FOLDLEVELBASE;
-            }
+                               // if package used or unclosed brace, level > SC_FOLDLEVELBASE!
+                               // reset needed as level test is vs. SC_FOLDLEVELBASE
+                               else if (styler.Match(i, "__END__"))
+                                       levelCurrent = SC_FOLDLEVELBASE;
+                       }
                }
                // Custom package folding
                if (foldPackage && atLineStart) {
@@ -1344,9 +1265,9 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
                if (atEOL) {
                        int lev = levelPrev;
                        if (isPodHeading) {
-                lev = levelPrev - 1;
-                lev |= SC_FOLDLEVELHEADERFLAG;
-                isPodHeading = false;
+                               lev = levelPrev - 1;
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                               isPodHeading = false;
                        }
                        // Check if line was a package declaration
                        // because packages need "special" treatment
@@ -1355,7 +1276,7 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
                                levelCurrent = SC_FOLDLEVELBASE + 1;
                                isPackageLine = false;
                        }
-            lev |= levelCurrent << 16;
+                       lev |= levelCurrent << 16;
                        if (visibleChars == 0 && foldCompact)
                                lev |= SC_FOLDLEVELWHITEFLAG;
                        if ((levelCurrent > levelPrev) && (visibleChars > 0))
@@ -1382,4 +1303,3 @@ static const char * const perlWordListDesc[] = {
 };
 
 LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc, 8);
-
diff --git a/src/stc/scintilla/src/LexPowerPro.cxx b/src/stc/scintilla/src/LexPowerPro.cxx
new file mode 100644 (file)
index 0000000..9320baf
--- /dev/null
@@ -0,0 +1,600 @@
+// Scintilla source code edit control
+// @file LexPowerPro.cxx
+// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com
+// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net)
+//
+// Lexer code heavily borrowed from: 
+//     LexAU3.cxx by Jos van der Zande
+//     LexCPP.cxx by Neil Hodgson
+//     LexVB.cxx by Neil Hodgson
+//
+// Changes:
+//     2008-10-25 - Initial release
+//     2008-10-26 - Changed how <name> is hilighted in  'function <name>' so that 
+//                              local isFunction = "" and local functions = "" don't get falsely highlighted
+//     2008-12-14 - Added bounds checking for szKeyword and szDo
+//                        - Replaced SetOfCharacters with CharacterSet
+//                        - Made sure that CharacterSet::Contains is passed only positive values
+//                        - Made sure that the return value of Accessor::SafeGetCharAt is positive before 
+//                              passsing to functions that require positive values like isspacechar()
+//                        - Removed unused visibleChars processing from ColourisePowerProDoc()
+//                        - Fixed bug with folding logic where line continuations didn't end where 
+//                              they were supposed to
+//                        - Moved all helper functions to the top of the file
+//
+// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Platform.h"
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsStreamCommentStyle(int style) {
+       return style == SCE_POWERPRO_COMMENTBLOCK;
+}
+
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
+{
+       int nsPos = styler.LineStart(szLine);
+       int nePos = styler.LineStart(szLine + 1) - 2;
+       while (nsPos < nePos)
+       {
+               int stylech = styler.StyleAt(nsPos);
+               if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
+                       char ch = styler.SafeGetCharAt(nePos);
+                       char chPrev = styler.SafeGetCharAt(nePos-1);
+                       char chPrevPrev = styler.SafeGetCharAt(nePos-2);
+                       if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) {
+                               if (chPrevPrev == ';' && chPrev == ';' && ch == '+')
+                                       return true;
+                               else
+                                       return false;
+                       }
+               }
+               nePos--; // skip to next char
+       }
+       return false;
+}
+
+// Routine to find first none space on the current line and return its Style
+// needed for comment lines not starting on pos 1 
+static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
+{
+       int nsPos = styler.LineStart(szLine);
+       int nePos = styler.LineStart(szLine+1) - 1;
+       char ch = styler.SafeGetCharAt(nsPos);
+       
+       while (ch > 0 && isspacechar(ch) && nsPos < nePos)
+       {
+               nsPos++; // skip to next char
+               ch = styler.SafeGetCharAt(nsPos);
+
+       }
+       return styler.StyleAt(nsPos);
+}
+
+//returns true if there is a function to highlight
+//used to highlight <name> in 'function <name>'
+static bool HasFunction(Accessor &styler, unsigned int currentPos) {
+       
+       //check for presence of 'function '
+       return  (styler.SafeGetCharAt(currentPos) == ' '        
+       && tolower(styler.SafeGetCharAt(currentPos-1)) == 'n' 
+       && tolower(styler.SafeGetCharAt(currentPos-2)) == 'o'
+       && tolower(styler.SafeGetCharAt(currentPos-3)) == 'i'
+       && tolower(styler.SafeGetCharAt(currentPos-4)) == 't'
+       && tolower(styler.SafeGetCharAt(currentPos-5)) == 'c'
+       && tolower(styler.SafeGetCharAt(currentPos-6)) == 'n'
+       && tolower(styler.SafeGetCharAt(currentPos-7)) == 'u'
+       && tolower(styler.SafeGetCharAt(currentPos-8)) == 'f'
+       //only allow 'function ' to appear at the beginning of a line
+       && (styler.SafeGetCharAt(currentPos-9) == '\n'                  
+               || styler.SafeGetCharAt(currentPos-9) == '\r'
+               || (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line
+       );
+}
+
+static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler, bool caseSensitive) {
+
+       WordList &keywords  = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2];
+       WordList &keywords4 = *keywordlists[3];
+       
+       //define the character sets 
+       CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
+       CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+       StyleContext sc(startPos, length, initStyle, styler);
+       char s_save[100]; //for last line highlighting
+       
+       for (; sc.More(); sc.Forward()) {
+                       
+               // **********************************************
+               // save the total current word for eof processing
+               char s[100];
+               sc.GetCurrentLowered(s, sizeof(s));
+                
+               if ((sc.ch > 0) && setWord.Contains(sc.ch)) 
+               {
+                       strcpy(s_save,s);
+                       int tp = strlen(s_save);
+                       if (tp < 99) {
+                               s_save[tp] = static_cast<char>(tolower(sc.ch));
+                               s_save[tp+1] = '\0';
+                       }
+               }
+               // **********************************************
+               //
+
+               if (sc.atLineStart) {
+                       if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
+                               // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which
+                               // ends with a line continuation by locking in the state upto this position.
+                               sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
+                       }
+               }
+
+               // Determine if the current state should terminate.
+               switch (sc.state) {
+                       case SCE_POWERPRO_OPERATOR:
+                               sc.SetState(SCE_POWERPRO_DEFAULT);
+                               break;
+                       
+                       case SCE_POWERPRO_NUMBER:
+
+                               if (!IsADigit(sc.ch))
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               
+                               break;
+
+                       case SCE_POWERPRO_IDENTIFIER:
+                               //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized
+                               if ((sc.ch > 0) && !setWord.Contains(sc.ch)){  // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately
+                                       char s[1000];
+                                       if (caseSensitive) {
+                                               sc.GetCurrent(s, sizeof(s));
+                                       } else {
+                                               sc.GetCurrentLowered(s, sizeof(s));
+                                       }
+                                       if (keywords.InList(s)) {
+                                               sc.ChangeState(SCE_POWERPRO_WORD);
+                                       } else if (keywords2.InList(s)) {
+                                               sc.ChangeState(SCE_POWERPRO_WORD2);
+                                       } else if (keywords3.InList(s)) {
+                                               sc.ChangeState(SCE_POWERPRO_WORD3);
+                                       } else if (keywords4.InList(s)) {
+                                               sc.ChangeState(SCE_POWERPRO_WORD4);
+                                       }
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_LINECONTINUE:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               } else if (sc.Match('/', '*') || sc.Match('/', '/')) {
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_COMMENTBLOCK:
+                               if (sc.Match('*', '/')) {
+                                       sc.Forward();
+                                       sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_COMMENTLINE:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_DOUBLEQUOTEDSTRING:
+                               if (sc.atLineEnd) {
+                                       sc.ChangeState(SCE_POWERPRO_STRINGEOL);
+                               } else if (sc.ch == '\\') {
+                                       if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+                                               sc.Forward();
+                                       }
+                               } else if (sc.ch == '\"') {
+                                       sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_SINGLEQUOTEDSTRING:
+                               if (sc.atLineEnd) {
+                                       sc.ChangeState(SCE_POWERPRO_STRINGEOL);
+                               } else if (sc.ch == '\\') {
+                                       if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+                                               sc.Forward();
+                                       }
+                               } else if (sc.ch == '\'') {
+                                       sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_STRINGEOL:
+                               if (sc.atLineStart) {
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               }
+                               break;
+
+                       case SCE_POWERPRO_VERBATIM:
+                               if (sc.ch == '\"') {
+                                       if (sc.chNext == '\"') {
+                                               sc.Forward();
+                                       } else {
+                                               sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+                                       }
+                               }
+                               break;
+
+                       case SCE_POWERPRO_ALTQUOTE:
+                               if (sc.ch == '#') {
+                                       if (sc.chNext == '#') {
+                                               sc.Forward();
+                                       } else {
+                                               sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+                                       }
+                               }
+                               break;
+                               
+                       case SCE_POWERPRO_FUNCTION:
+                               if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
+                                       sc.SetState(SCE_POWERPRO_DEFAULT);
+                               }
+                       break;
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_POWERPRO_DEFAULT) {
+                       if (sc.Match('?', '\"')) {
+                               sc.SetState(SCE_POWERPRO_VERBATIM);
+                               sc.Forward();
+                       } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_POWERPRO_NUMBER);
+                       }else if (sc.Match('?','#')) {
+                               if (sc.ch == '?' && sc.chNext == '#') {
+                                       sc.SetState(SCE_POWERPRO_ALTQUOTE);
+                                       sc.Forward();
+                               }
+                       } else if (HasFunction(styler, sc.currentPos)) {        //highlight <name> in 'function <name>'
+                               sc.SetState(SCE_POWERPRO_FUNCTION); 
+                       } else if (sc.ch == '@' && sc.atLineStart) {            //alternate function definition [label]
+                               sc.SetState(SCE_POWERPRO_FUNCTION);
+                       } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
+                               sc.SetState(SCE_POWERPRO_IDENTIFIER);
+                       } else if (sc.Match(";;+")) { 
+                               sc.SetState(SCE_POWERPRO_LINECONTINUE);
+                       } else if (sc.Match('/', '*')) {
+                               sc.SetState(SCE_POWERPRO_COMMENTBLOCK);
+                               sc.Forward();   // Eat the * so it isn't used for the end of the comment
+                       } else if (sc.Match('/', '/')) {
+                               sc.SetState(SCE_POWERPRO_COMMENTLINE);
+                       } else if (sc.atLineStart && sc.ch == ';') {            //legacy comment that can only appear at the beginning of a line
+                               sc.SetState(SCE_POWERPRO_COMMENTLINE);
+                       } else if (sc.Match(";;")) {
+                               sc.SetState(SCE_POWERPRO_COMMENTLINE);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING);
+                       } else if (isoperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_POWERPRO_OPERATOR);
+                       }
+               }
+       }
+
+       //*************************************
+       // Colourize the last word correctly 
+       //*************************************
+       if (sc.state == SCE_POWERPRO_IDENTIFIER)
+       {
+               if (keywords.InList(s_save)) {
+                       sc.ChangeState(SCE_POWERPRO_WORD);
+                       sc.SetState(SCE_POWERPRO_DEFAULT);
+               }
+               else if (keywords2.InList(s_save)) {
+                       sc.ChangeState(SCE_POWERPRO_WORD2);
+                       sc.SetState(SCE_POWERPRO_DEFAULT);
+               }
+               else if (keywords3.InList(s_save)) {
+                       sc.ChangeState(SCE_POWERPRO_WORD3);
+                       sc.SetState(SCE_POWERPRO_DEFAULT);
+               }
+               else if (keywords4.InList(s_save)) {
+                       sc.ChangeState(SCE_POWERPRO_WORD4);
+                       sc.SetState(SCE_POWERPRO_DEFAULT);
+               }
+               else {
+                       sc.SetState(SCE_POWERPRO_DEFAULT);
+               }
+       }
+       sc.Complete();
+}
+
+static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+       //define the character sets
+       CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
+       CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+       bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
+       int endPos = startPos + length;
+       int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
+
+       // get settings from the config files for folding comments and preprocessor lines
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
+       bool foldCompact = true;
+       
+       // Backtrack to previous line in case need to fix its fold status
+       int lineCurrent = styler.GetLine(startPos);
+       if (startPos > 0) {
+               isFoldingAll = false;
+               if (lineCurrent > 0) {
+                       lineCurrent--;
+                       startPos = styler.LineStart(lineCurrent);
+               }
+       }
+       // vars for style of previous/current/next lines 
+       int style = GetStyleFirstWord(lineCurrent,styler);
+       int stylePrev = 0;
+       
+       // find the first previous line without continuation character at the end
+       while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
+              (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+               lineCurrent--;
+               startPos = styler.LineStart(lineCurrent);
+       }
+       if (lineCurrent > 0) {
+               stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
+       }
+       // vars for getting first word to check for keywords
+       bool FirstWordStart = false;
+       bool FirstWordEnd = false;
+               
+       const unsigned int KEYWORD_MAX = 10;
+       char szKeyword[KEYWORD_MAX]="";
+       unsigned int     szKeywordlen = 0;
+       
+       char szDo[3]="";
+       int      szDolen = 0;
+       bool DoFoundLast = false;
+       
+       // var for indentlevel
+       int levelCurrent = SC_FOLDLEVELBASE;
+       if (lineCurrent > 0) {
+               levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+       }
+       int levelNext = levelCurrent;
+       
+       int     visibleChars = 0;
+       int functionCount = 0;
+       
+       char chNext = styler.SafeGetCharAt(startPos);
+       char chPrev = '\0';
+       char chPrevPrev = '\0';
+       char chPrevPrevPrev = '\0';
+       
+       for (int i = startPos; i < endPos; i++) {
+
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               
+               if ((ch > 0) && setWord.Contains(ch)) {
+                       visibleChars++;
+               }
+               
+               // get the syle for the current character neede to check in comment
+               int stylech = styler.StyleAt(i);
+               
+               // get first word for the line for indent check max 9 characters
+               if (FirstWordStart && (!(FirstWordEnd))) {
+                       if ((ch > 0) && !setWord.Contains(ch)) {
+                               FirstWordEnd = true;
+                       }
+                       else if (szKeywordlen < KEYWORD_MAX - 1) {
+                               szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+                               szKeyword[szKeywordlen] = '\0';
+                       }
+               }
+               
+               // start the capture of the first word 
+               if (!(FirstWordStart)) {
+                       if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) {
+                               FirstWordStart = true;
+                               if (szKeywordlen < KEYWORD_MAX - 1) {
+                                       szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+                                       szKeyword[szKeywordlen] = '\0';
+                               }
+                       }
+               }
+               // only process this logic when not in comment section
+               if (stylech != SCE_POWERPRO_COMMENTLINE) {
+                       if (DoFoundLast) {
+                               if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) {
+                                       DoFoundLast = false;
+                               }               
+                       }
+                       // find out if the word "do" is the last on a "if" line
+                       if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
+                               if (szDolen == 2) {
+                                       szDo[0] = szDo[1];
+                                       szDo[1] = static_cast<char>(tolower(ch));
+                                       szDo[2] = '\0';
+                                       if (strcmp(szDo,"do") == 0 ) {
+                                               DoFoundLast = true;
+                                       }
+                               }
+                               else if (szDolen < 2) {
+                                       szDo[szDolen++] = static_cast<char>(tolower(ch));
+                                       szDo[szDolen] = '\0';
+                               }
+                       }
+               }
+
+               // End of Line found so process the information 
+                if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+                
+                       // **************************
+                       // Folding logic for Keywords
+                       // **************************
+                       
+                       // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
+                       //    and we are not inside a commentblock.
+                       if (szKeywordlen > 0 && 
+                               (!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) && 
+                               ((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
+                       
+                               // only fold "if" last keyword is "then"  (else its a one line if)
+                               if (strcmp(szKeyword,"if") == 0  && DoFoundLast) {
+                                               levelNext++;
+                               }
+                               // create new fold for these words 
+                               if (strcmp(szKeyword,"for") == 0) {
+                                       levelNext++;
+                               }
+                               
+                               //handle folding for functions/labels
+                               //Note: Functions and labels don't have an explicit end like [end function]
+                               //      1. functions/labels end at the start of another function
+                               //      2. functions/labels end at the end of the file
+                               if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) {
+                                       if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
+                                               
+                                               if (functionCount > 0) {
+                                                       levelCurrent--;
+                                               } else {
+                                                       levelNext++;
+                                               }
+                                               functionCount++;        
+                                               
+                                       } else { //if just folding a small piece (by clicking on the minus sign next to the word)
+                                               levelCurrent--;
+                                       }
+                               }
+                                                                                               
+                               // end the fold for these words before the current line
+                               if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) {
+                                               levelNext--;
+                                               levelCurrent--;
+                               }
+                               // end the fold for these words before the current line and Start new fold 
+                               if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) {
+                                               levelCurrent--;
+                               }
+                       }
+                       // Preprocessor and Comment folding
+                       int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
+
+                       // *********************************
+                       // Folding logic for Comment blocks
+                       // *********************************
+                       if (foldComment && IsStreamCommentStyle(style)) {
+                               // Start of a comment block
+                               if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
+                                   levelNext++;
+                               } 
+                               // fold till the last line for normal comment lines
+                               else if (IsStreamCommentStyle(stylePrev) 
+                                               && !(styleNext == SCE_POWERPRO_COMMENTLINE)
+                                               && stylePrev == SCE_POWERPRO_COMMENTLINE 
+                                               && style == SCE_POWERPRO_COMMENTLINE) {
+                                       levelNext--;
+                               }
+                               // fold till the one but last line for Blockcomment lines
+                               else if (IsStreamCommentStyle(stylePrev) 
+                                               && !(styleNext == SCE_POWERPRO_COMMENTBLOCK)
+                                               && style == SCE_POWERPRO_COMMENTBLOCK) {
+                                       levelNext--;
+                                       levelCurrent--;
+                               }
+                       }
+
+                       int levelUse = levelCurrent;
+                       int lev = levelUse | levelNext << 16;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if (levelUse < levelNext) {
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       }
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+
+                       // reset values for the next line
+                       lineCurrent++;
+                       stylePrev = style;
+                       style = styleNext;
+                       levelCurrent = levelNext;
+                       visibleChars = 0;
+                       
+                       // if the last characters are ;;+ then don't reset since the line continues on the next line.
+                       if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') {
+                               //do nothing
+                       } else {
+                               szKeywordlen = 0;
+                               szDolen = 0;
+                               FirstWordStart = false;
+                               FirstWordEnd = false;
+                               DoFoundLast = false;
+                               //blank out keyword
+                               for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
+                                       szKeyword[i] = '\0';
+                               }
+                       }
+               }
+
+               // save the last processed characters
+               if ((ch > 0) && !isspacechar(ch)) {
+                       chPrevPrevPrev = chPrevPrev;
+                       chPrevPrev = chPrev;
+                       chPrev = ch;
+                       visibleChars++;
+               }
+       }
+
+       //close folds on the last line - without this a 'phantom' 
+       //fold can appear when an open fold is on the last line
+       //this can occur because functions and labels don't have an explicit end
+       if (lineCurrent >= lastLine) {
+               int lev = 0;
+               lev |= SC_FOLDLEVELWHITEFLAG;
+               styler.SetLevel(lineCurrent, lev);
+       }
+
+}
+
+static const char * const powerProWordLists[] = {
+            "Keyword list 1",
+            "Keyword list 2",
+            "Keyword list 3",
+            "Keyword list 4",
+            0,
+        };
+
+static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                       Accessor &styler) {
+       ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);
diff --git a/src/stc/scintilla/src/LexPowerShell.cxx b/src/stc/scintilla/src/LexPowerShell.cxx
new file mode 100644 (file)
index 0000000..d16ba98
--- /dev/null
@@ -0,0 +1,175 @@
+// Scintilla source code edit control
+/** @file LexPowerShell.cxx
+ ** Lexer for PowerShell scripts.
+ **/
+// Copyright 2008 by Tim Gerundt <tim@gerundt.de>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+       return ch >= 0x80 || isalnum(ch) || ch == '-';
+}
+
+static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
+                           WordList *keywordlists[], Accessor &styler) {
+
+       WordList &keywords = *keywordlists[0];
+       WordList &keywords2 = *keywordlists[1];
+       WordList &keywords3 = *keywordlists[2];
+
+       styler.StartAt(startPos);
+
+       StyleContext sc(startPos, length, initStyle, styler);
+
+       for (; sc.More(); sc.Forward()) {
+
+               if (sc.state == SCE_POWERSHELL_COMMENT) {
+                       if (sc.atLineEnd) {
+                               sc.SetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POWERSHELL_STRING) {
+                       // This is a doubles quotes string
+                       if (sc.ch == '\"') {
+                               sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POWERSHELL_CHARACTER) {
+                       // This is a single quote string
+                       if (sc.ch == '\'') {
+                               sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POWERSHELL_NUMBER) {
+                       if (!IsADigit(sc.ch)) {
+                               sc.SetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POWERSHELL_VARIABLE) {
+                       if (!IsAWordChar(sc.ch)) {
+                               sc.SetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POWERSHELL_OPERATOR) {
+                       if (!isoperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               } else if (sc.state == SCE_POWERSHELL_IDENTIFIER) {
+                       if (!IsAWordChar(sc.ch)) {
+                               char s[100];
+                               sc.GetCurrentLowered(s, sizeof(s));
+
+                               if (keywords.InList(s)) {
+                                       sc.ChangeState(SCE_POWERSHELL_KEYWORD);
+                               } else if (keywords2.InList(s)) {
+                                       sc.ChangeState(SCE_POWERSHELL_CMDLET);
+                               } else if (keywords3.InList(s)) {
+                                       sc.ChangeState(SCE_POWERSHELL_ALIAS);
+                               }
+                               sc.SetState(SCE_POWERSHELL_DEFAULT);
+                       }
+               }
+
+               // Determine if a new state should be entered.
+               if (sc.state == SCE_POWERSHELL_DEFAULT) {
+                       if (sc.ch == '#') {
+                               sc.SetState(SCE_POWERSHELL_COMMENT);
+                       } else if (sc.ch == '\"') {
+                               sc.SetState(SCE_POWERSHELL_STRING);
+                       } else if (sc.ch == '\'') {
+                               sc.SetState(SCE_POWERSHELL_CHARACTER);
+                       } else if (sc.ch == '$') {
+                               sc.SetState(SCE_POWERSHELL_VARIABLE);
+                       } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+                               sc.SetState(SCE_POWERSHELL_NUMBER);
+                       } else if (isoperator(static_cast<char>(sc.ch))) {
+                               sc.SetState(SCE_POWERSHELL_OPERATOR);
+                       } else if (IsAWordChar(sc.ch)) {
+                               sc.SetState(SCE_POWERSHELL_IDENTIFIER);
+                       }
+               }
+       }
+       sc.Complete();
+}
+
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "} else {".
+static void FoldPowerShellDoc(unsigned int startPos, int length, int,
+                           WordList *[], Accessor &styler) {
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+       bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+       unsigned int endPos = startPos + length;
+       int visibleChars = 0;
+       int lineCurrent = styler.GetLine(startPos);
+       int levelCurrent = SC_FOLDLEVELBASE;
+       if (lineCurrent > 0)
+               levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+       int levelMinCurrent = levelCurrent;
+       int levelNext = levelCurrent;
+       char chNext = styler[startPos];
+       int styleNext = styler.StyleAt(startPos);
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+               if (style == SCE_POWERSHELL_OPERATOR) {
+                       if (ch == '{') {
+                               // Measure the minimum before a '{' to allow
+                               // folding on "} else {"
+                               if (levelMinCurrent > levelNext) {
+                                       levelMinCurrent = levelNext;
+                               }
+                               levelNext++;
+                       } else if (ch == '}') {
+                               levelNext--;
+                       }
+               }
+               if (!IsASpace(ch))
+                       visibleChars++;
+               if (atEOL || (i == endPos-1)) {
+                       int levelUse = levelCurrent;
+                       if (foldAtElse) {
+                               levelUse = levelMinCurrent;
+                       }
+                       int lev = levelUse | levelNext << 16;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if (levelUse < levelNext)
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelCurrent = levelNext;
+                       levelMinCurrent = levelCurrent;
+                       visibleChars = 0;
+               }
+       }
+}
+
+static const char * const powershellWordLists[] = {
+       "Commands",
+       "Cmdlets",
+       "Aliases",
+       0
+};
+
+LexerModule lmPowerShell(SCLEX_POWERSHELL, ColourisePowerShellDoc, "powershell", FoldPowerShellDoc, powershellWordLists);
+
index 3b3a44541f371d8e4f84ad909d6d2276a92533d5..9e1940e2987eac5110df24e7712c59b6c2c60548 100644 (file)
@@ -9,7 +9,6 @@
 /** TODO:
 WebSpeed support in html lexer
 Support "end triggers" expression of the triggers phrase
-change lmPS to lmProgress
 Support more than 6 comments levels
 **/
 #include <stdlib.h>
@@ -44,11 +43,11 @@ enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true
 static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                             Accessor &styler) {
 
-    WordList &keywords1 = *keywordlists[0];
-    WordList &keywords2 = *keywordlists[1];
-    WordList &keywords3 = *keywordlists[2];
-    //WordList &keywords4 = *keywordlists[3];
-    //WordList &keywords5 = *keywordlists[4];
+    WordList &keywords1 = *keywordlists[0];   // regular keywords
+    WordList &keywords2 = *keywordlists[1];   // block opening keywords, only when SentenceStart
+    WordList &keywords3 = *keywordlists[2];   // block opening keywords
+    //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented
+    
 
        int visibleChars = 0;
        int mask;
@@ -64,24 +63,29 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
                }
 
                // Handle line continuation generically.
+               if ((sc.state & 0xf) < SCE_4GL_COMMENT1) {
                if (sc.ch == '~') {
-                       // Skip whitespace between ~ and EOL
-       /*              do {
+                       if (sc.chNext > ' ') {
+                               // skip special char after ~
                                sc.Forward();
-                       } */
-                       while ((sc.chNext == ' ' || sc.chNext == '\t') ) {
-                               sc.Forward();
-                               sc.More();
+                               continue;
                        }
-                       if (sc.chNext == '\n' || sc.chNext == '\r') {
-                               sc.Forward();
-                               if (sc.ch == '\r' && sc.chNext == '\n') {
+                       else {
+                               // Skip whitespace between ~ and EOL
+                               while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) {
                                        sc.Forward();
                                }
-                               sc.Forward();
-                               continue;
+                               if (sc.chNext == '\n' || sc.chNext == '\r') {
+                                       sc.Forward();
+                                       if (sc.ch == '\r' && sc.chNext == '\n') {
+                                               sc.Forward();
+                                       }
+                                       sc.Forward();
+                                       continue;
+                               }
                        }
                }
+               }
                // Determine if a new state should be terminated.
                mask = sc.state & 0x10;
                switch (sc.state & 0xf) {
@@ -97,7 +101,7 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
                                if (!IsAWordChar(sc.ch) && sc.ch != '-') {
                                        char s[1000];
                                        sc.GetCurrentLowered(s, sizeof(s));
-                                       if (((sc.state & 0x10) == 0) && keywords2.InList(s) || keywords3.InList(s)) {
+                                       if ((((sc.state & 0x10) == 0) && keywords2.InList(s)) || keywords3.InList(s)) {
                                                sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);
                                        }
                                        else if (keywords1.InList(s)) {
@@ -119,9 +123,10 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
                        case SCE_4GL_PREPROCESSOR:
                                if (sc.atLineStart) {
                                        sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);
-                               } else if (sc.ch == '*' && sc.chNext == '/') {
-                                       sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
                                }
+                               /* code removed to allow comments inside preprocessor
+                                       else if (sc.ch == '*' && sc.chNext == '/') {
+                                       sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState); } */
                                break;
                        case SCE_4GL_STRING:
                                if (sc.ch == '\"') {
@@ -173,9 +178,12 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
                        } else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {
                                sc.SetState(sc.state & SetSentenceStart);
                        } else if (isoperator(static_cast<char>(sc.ch))) {
+               /*      This code allows highlight of handles. Alas, it would cause the phrase "last-event:function"
+                       to be recognized as a BlockBegin */
+                       
                                if (sc.ch == ':')
                                        sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
-                               else
+                               /* else */
                                        sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);
                        }
                }
@@ -268,4 +276,4 @@ static const char * const FglWordLists[] = {
             0,
         };
 
-LexerModule lmProgress(SCLEX_PS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
+LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
index 01d406d0d076701d562f0b5b1c86b72f9d0161e8..897a136e94e3c9cf7d2123113f4fec8ce84cb8c9 100644 (file)
 using namespace Scintilla;
 #endif
 
-enum kwType { kwOther, kwClass, kwDef, kwImport };
+/* kwCDef, kwCTypeName only used for Cython */
+enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
+
 static const int indicatorWhitespace = 1;
 
 static bool IsPyComment(Accessor &styler, int pos, int len) {
        return len > 0 && styler[pos] == '#';
 }
 
-static bool IsPyStringStart(int ch, int chNext, int chNext2) {
+enum literalsAllowed { litNone=0, litU=1, litB=2};
+
+static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
+       return 
+               ((allowed & litB) && (ch == 'b' || ch == 'B')) ||
+               ((allowed & litU) && (ch == 'u' || ch == 'U'));
+}
+
+static bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
        if (ch == '\'' || ch == '"')
                return true;
-       if (ch == 'u' || ch == 'U') {
+       if (IsPyStringTypeChar(ch, allowed)) {
                if (chNext == '"' || chNext == '\'')
                        return true;
                if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
@@ -47,16 +57,16 @@ 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, unsigned int *nextIndex) {
+static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex, literalsAllowed allowed) {
        char ch = styler.SafeGetCharAt(i);
        char chNext = styler.SafeGetCharAt(i + 1);
 
-       // Advance beyond r, u, or ur prefix, but bail if there are any unexpected chars
+       // Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
        if (ch == 'r' || ch == 'R') {
                i++;
                ch = styler.SafeGetCharAt(i);
                chNext = styler.SafeGetCharAt(i + 1);
-       } else if (ch == 'u' || ch == 'U') {
+       } else if (IsPyStringTypeChar(ch, allowed)) {
                if (chNext == 'r' || chNext == 'R')
                        i += 2;
                else
@@ -96,7 +106,7 @@ static inline bool IsAWordStart(int ch) {
 }
 
 static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
+        WordList *keywordlists[], Accessor &styler) {
 
        int endPos = startPos + length;
 
@@ -105,19 +115,53 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
        if (startPos > 0) {
                if (lineCurrent > 0) {
                        lineCurrent--;
+                       // Look for backslash-continued lines
+                       while (lineCurrent > 0) {
+                               int eolPos = styler.LineStart(lineCurrent) - 1;
+                               int eolStyle = styler.StyleAt(eolPos);
+                               if (eolStyle == SCE_P_STRING
+                                   || eolStyle == SCE_P_CHARACTER
+                                   || eolStyle == SCE_P_STRINGEOL) {
+                                       lineCurrent -= 1;
+                               } else {
+                                       break;
+                               }
+                       }
                        startPos = styler.LineStart(lineCurrent);
-                       if (startPos == 0)
-                               initStyle = SCE_P_DEFAULT;
-                       else
-                               initStyle = styler.StyleAt(startPos - 1);
                }
+               initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1);
        }
 
        WordList &keywords = *keywordlists[0];
        WordList &keywords2 = *keywordlists[1];
 
+       // property tab.timmy.whinge.level
+       //      For Python code, checks whether indenting is consistent. 
+       //      The default, 0 turns off indentation checking, 
+       //      1 checks whether each line is potentially inconsistent with the previous line, 
+       //      2 checks whether any space characters occur before a tab character in the indentation, 
+       //      3 checks whether any spaces are in the indentation, and 
+       //      4 checks for any tab characters in the indentation.
+       //      1 is a good level to use. 
        const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
 
+       // property lexer.python.literals.binary
+       //      Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.
+       bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0;
+
+       // property lexer.python.strings.u
+       //      Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.
+       literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone;
+
+       // property lexer.python.strings.b
+       //      Set to 0 to not recognise Python 3 bytes literals b"x".
+       if (styler.GetPropertyInt("lexer.python.strings.b", 1))
+               allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
+
+       // property lexer.python.strings.over.newline
+       //      Set to 1 to allow strings to span newline characters.
+       bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
+
        initStyle = initStyle & 31;
        if (initStyle == SCE_P_STRINGEOL) {
                initStyle = SCE_P_DEFAULT;
@@ -126,12 +170,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
        kwType kwLast = kwOther;
        int spaceFlags = 0;
        styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
-       bool hexadecimal = false;
+       bool base_n_number = false;
 
        StyleContext sc(startPos, endPos - startPos, initStyle, styler);
 
        bool indentGood = true;
        int startIndicator = sc.currentPos;
+       bool inContinuedString = false;
 
        for (; sc.More(); sc.Forward()) {
 
@@ -163,8 +208,12 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        }
                        lineCurrent++;
                        if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
-                               sc.ChangeState(SCE_P_STRINGEOL);
-                               sc.ForwardSetState(SCE_P_DEFAULT);
+                               if (inContinuedString || stringsOverNewline) {
+                                       inContinuedString = false;
+                               } else {
+                                       sc.ChangeState(SCE_P_STRINGEOL);
+                                       sc.ForwardSetState(SCE_P_DEFAULT);
+                               }
                        }
                        if (!sc.More())
                                break;
@@ -178,7 +227,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        sc.SetState(SCE_P_DEFAULT);
                } else if (sc.state == SCE_P_NUMBER) {
                        if (!IsAWordChar(sc.ch) &&
-                               !(!hexadecimal && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+                               !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
                                sc.SetState(SCE_P_DEFAULT);
                        }
                } else if (sc.state == SCE_P_IDENTIFIER) {
@@ -194,6 +243,23 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                        style = SCE_P_CLASSNAME;
                                } else if (kwLast == kwDef) {
                                        style = SCE_P_DEFNAME;
+                               } else if (kwLast == kwCDef) {
+                                       int pos = sc.currentPos;
+                                       unsigned char ch = styler.SafeGetCharAt(pos, '\0');
+                                       while (ch != '\0') {
+                                               if (ch == '(') {
+                                                       style = SCE_P_DEFNAME;
+                                                       break;
+                                               } else if (ch == ':') {
+                                                       style = SCE_P_CLASSNAME;
+                                                       break;
+                                               } else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
+                                                       pos++;
+                                                       ch = styler.SafeGetCharAt(pos, '\0');
+                                               } else {
+                                                       break;
+                                               }
+                                       }
                                } else if (keywords2.InList(s)) {
                                        style = SCE_P_WORD2;
                                }
@@ -206,9 +272,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                                kwLast = kwDef;
                                        else if (0 == strcmp(s, "import"))
                                                kwLast = kwImport;
-                                       else
+                                       else if (0 == strcmp(s, "cdef"))
+                                               kwLast = kwCDef;
+                                       else if (0 == strcmp(s, "cimport"))
+                                               kwLast = kwImport;
+                                       else if (kwLast != kwCDef)
                                                kwLast = kwOther;
-                               } else {
+                               } else if (kwLast != kwCDef) {
                                        kwLast = kwOther;
                                }
                        }
@@ -225,7 +295,12 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                                if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
                                        sc.Forward();
                                }
-                               sc.Forward();
+                               if (sc.chNext == '\n' || sc.chNext == '\r') {
+                                       inContinuedString = true;
+                               } else {
+                                       // Don't roll over the newline.
+                                       sc.Forward();
+                               }
                        } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
                                sc.ForwardSetState(SCE_P_DEFAULT);
                                needEOLCheck = true;
@@ -259,6 +334,11 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                        indentGood = true;
                }
 
+               // One cdef line, clear kwLast only at end of line
+               if (kwLast == kwCDef && sc.atLineEnd) {
+                       kwLast = kwOther;
+               }
+
                // State exit code may have moved on to end of line
                if (needEOLCheck && sc.atLineEnd) {
                        lineCurrent++;
@@ -271,20 +351,30 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
                if (sc.state == SCE_P_DEFAULT) {
                        if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
                                if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
-                                       hexadecimal = true;
+                                       base_n_number = true;
+                                       sc.SetState(SCE_P_NUMBER);
+                               } else if (sc.ch == '0' && 
+                                       (sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
+                                       if (base2or8Literals) {
+                                               base_n_number = true;
+                                               sc.SetState(SCE_P_NUMBER);
+                                       } else {
+                                               sc.SetState(SCE_P_NUMBER);
+                                               sc.ForwardSetState(SCE_P_IDENTIFIER);
+                                       }
                                } else {
-                                       hexadecimal = false;
+                                       base_n_number = false;
+                                       sc.SetState(SCE_P_NUMBER);
                                }
-                               sc.SetState(SCE_P_NUMBER);
-                       } else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch)) || sc.ch == '`') {
+                       } else if ((isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') {
                                sc.SetState(SCE_P_OPERATOR);
                        } else if (sc.ch == '#') {
                                sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
                        } else if (sc.ch == '@') {
                                sc.SetState(SCE_P_DECORATOR);
-                       } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2))) {
+                       } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) {
                                unsigned int nextIndex = 0;
-                               sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
+                               sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals));
                                while (nextIndex > (sc.currentPos + 1) && sc.More()) {
                                        sc.Forward();
                                }
@@ -321,9 +411,17 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
        const int maxPos = startPos + length;
        const int maxLines = styler.GetLine(maxPos - 1);             // Requested last line
        const int docLines = styler.GetLine(styler.Length() - 1);  // Available last line
+
+       // property fold.comment.python
+       //      This option enables folding multi-line comments when using the Python lexer.
        const bool foldComment = styler.GetPropertyInt("fold.comment.python") != 0;
+
+       // property fold.quotes.python
+       //      This option enables folding multi-line quoted strings when using the Python lexer.
        const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0;
 
+       const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
+
        // Backtrack to previous non-blank line so we can determine indent level
        // for any white space lines (needed esp. within triple quoted strings)
        // and so we can fix any preceding fold level (which is why we go back
@@ -422,12 +520,21 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
                while (--skipLine > lineCurrent) {
                        int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
 
-                       if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
-                               skipLevel = levelBeforeComments;
+                       if (foldCompact) {
+                               if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+                                       skipLevel = levelBeforeComments;
 
-                       int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+                               int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
 
-                       styler.SetLevel(skipLine, skipLevel | whiteFlag);
+                               styler.SetLevel(skipLine, skipLevel | whiteFlag);
+                       } else {
+                               if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
+                                       !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
+                                       !IsCommentLine(skipLine, styler))
+                                       skipLevel = levelBeforeComments;
+
+                               styler.SetLevel(skipLine, skipLevel);
+                       }
                }
 
                // Set fold header on non-quote/non-comment line
@@ -459,3 +566,4 @@ static const char * const pythonWordListDesc[] = {
 
 LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
                                         pythonWordListDesc);
+
index 18e94d4d82cdc18e65438259ec64a8fc9421b6c2..8d6dc90b8f6e67ce0fe2b347116308bccfdeeb07 100644 (file)
@@ -784,13 +784,13 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                                state = SCE_RB_COMMENTLINE;
                        } else if (ch == '=') {
                                // =begin indicates the start of a comment (doc) block
-                if (i == 0 || isEOLChar(chPrev)
+                if (i == 0 || (isEOLChar(chPrev)
                     && chNext == 'b'
                     && styler.SafeGetCharAt(i + 2) == 'e'
                     && styler.SafeGetCharAt(i + 3) == 'g'
                     && styler.SafeGetCharAt(i + 4) == 'i'
                     && styler.SafeGetCharAt(i + 5) == 'n'
-                    && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) {
+                    && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6)))) {
                     styler.ColourTo(i - 1, state);
                     state = SCE_RB_POD;
                                } else {
@@ -1641,7 +1641,7 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
             if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
                 if (chNext == '{') {
                                        levelCurrent++;
-                               } else if (chNext == '}') {
+                               } else if (chNext == '}' && levelCurrent > 0) {
                                        levelCurrent--;
                                }
             }
@@ -1692,6 +1692,7 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
                        visibleChars++;
             buffer_ends_with_eol = false;
         }
+               stylePrev = style;
     }
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
     if (!buffer_ends_with_eol) {
diff --git a/src/stc/scintilla/src/LexSML.cxx b/src/stc/scintilla/src/LexSML.cxx
new file mode 100644 (file)
index 0000000..a617530
--- /dev/null
@@ -0,0 +1,223 @@
+// Scintilla source code edit control
+/** @file LexSML.cxx
+ ** Lexer for SML.
+ **/
+// Copyright 2009 by James Moffatt and Yuzhou Xin
+// Modified from LexCaml.cxx by Robert Roessler <robertr@rftp.com> Copyright 2005
+// The License.txt file describes the conditions under which this software may be distributed.
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+inline int  issml(int c) {return isalnum(c) || c == '_';}
+inline int issmlf(int c) {return isalpha(c) || c == '_';}
+inline int issmld(int c) {return isdigit(c) || c == '_';}
+
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+void ColouriseSMLDoc(
+       unsigned int startPos, int length,
+       int initStyle,
+       WordList *keywordlists[],
+       Accessor &styler)
+{
+       StyleContext sc(startPos, length, initStyle, styler);
+       int nesting = 0;
+       if (sc.state < SCE_SML_STRING)
+               sc.state = SCE_SML_DEFAULT;
+       if (sc.state >= SCE_SML_COMMENT)
+               nesting = (sc.state & 0x0f) - SCE_SML_COMMENT;
+
+       int chBase = 0, chToken = 0, chLit = 0;
+       WordList& keywords  = *keywordlists[0];
+       WordList& keywords2 = *keywordlists[1];
+       WordList& keywords3 = *keywordlists[2];
+       const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
+
+       while (sc.More()) {
+               int state2 = -1;
+               int chColor = sc.currentPos - 1;
+               bool advance = true;
+
+               switch (sc.state & 0x0f) {
+               case SCE_SML_DEFAULT:
+                       chToken = sc.currentPos;
+                       if (issmlf(sc.ch))
+                               state2 = SCE_SML_IDENTIFIER;
+                       else if (sc.Match('`') && issmlf(sc.chNext))
+                               state2 = SCE_SML_TAGNAME;
+                       else if (sc.Match('#')&&isdigit(sc.chNext))
+                                       state2 = SCE_SML_LINENUM;
+                       else if (sc.Match('#','\"')){
+                                       state2 = SCE_SML_CHAR,chLit = 0;
+                                       sc.Forward();
+                                       
+                               }
+                       else if (isdigit(sc.ch)) {
+                               state2 = SCE_SML_NUMBER, chBase = 10;
+                               if (sc.Match('0') && strchr("xX", sc.chNext))
+                                       chBase = 16, sc.Forward();}
+                       else if (sc.Match('\"')&&sc.chPrev!='#')
+                               state2 = SCE_SML_STRING;
+                       else if (sc.Match('(', '*')){
+                               state2 = SCE_SML_COMMENT,
+                                       sc.ch = ' ',
+                                       sc.Forward();}
+                       else if (strchr("!~"
+                                       "=<>@^+-*/"
+                                       "()[];,:.#", sc.ch))
+                               state2 = SCE_SML_OPERATOR;
+                       break;
+
+               case SCE_SML_IDENTIFIER:
+                       if (!(issml(sc.ch) || sc.Match('\''))) {
+                               const int n = sc.currentPos - chToken;
+                               if (n < 24) {
+                                       char t[24];
+                                       for (int i = -n; i < 0; i++)
+                                               t[n + i] = static_cast<char>(sc.GetRelative(i));
+                                       t[n] = '\0';
+                                       if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
+                                               sc.ChangeState(SCE_SML_KEYWORD);
+                                       else if (keywords2.InList(t))
+                                               sc.ChangeState(SCE_SML_KEYWORD2);
+                                       else if (keywords3.InList(t))
+                                               sc.ChangeState(SCE_SML_KEYWORD3);
+                               }
+                               state2 = SCE_SML_DEFAULT, advance = false;
+                       }
+                       break;
+
+               case SCE_SML_TAGNAME:
+                       if (!(issml(sc.ch) || sc.Match('\'')))
+                               state2 = SCE_SML_DEFAULT, advance = false;
+                       break;
+
+               case SCE_SML_LINENUM:
+                       if (!isdigit(sc.ch))
+                               state2 = SCE_SML_DEFAULT, advance = false;
+                       break;
+
+               case SCE_SML_OPERATOR: {
+                       const char* o = 0;
+                       if (issml(sc.ch) || isspace(sc.ch)
+                               || (o = strchr(")]};,\'\"`#", sc.ch),o)
+                               || !strchr("!$%&*+-./:<=>?@^|~", sc.ch)) {
+                               if (o && strchr(")]};,", sc.ch)) {
+                                       if ((sc.Match(')') && sc.chPrev == '(')
+                                               || (sc.Match(']') && sc.chPrev == '['))
+                                               sc.ChangeState(SCE_SML_KEYWORD);
+                                       chColor++;
+                               } else
+                                       advance = false;
+                               state2 = SCE_SML_DEFAULT;
+                       }
+                       break;
+               }
+
+               case SCE_SML_NUMBER:
+                       if (issmld(sc.ch) || IsADigit(sc.ch, chBase))
+                               break;
+                       if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
+                               && (issmld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))
+                               break;
+                       if (chBase == 10) {
+                               if (sc.Match('.') && issmld(sc.chPrev))
+                                       break;
+                               if ((sc.Match('e') || sc.Match('E'))
+                                       && (issmld(sc.chPrev) || sc.chPrev == '.'))
+                                       break;
+                               if ((sc.Match('+') || sc.Match('-'))
+                                       && (sc.chPrev == 'e' || sc.chPrev == 'E'))
+                                       break;
+                       }
+                       state2 = SCE_SML_DEFAULT, advance = false;
+                       break;
+
+               case SCE_SML_CHAR:
+                       if (sc.Match('\\')) {
+                               chLit = 1;
+                               if (sc.chPrev == '\\')
+                                       sc.ch = ' ';
+                       } else if ((sc.Match('\"') && sc.chPrev != '\\') || sc.atLineEnd) {
+                               state2 = SCE_SML_DEFAULT;
+                               chLit = 1;
+                               if (sc.Match('\"'))
+                                       chColor++;
+                               else
+                                       sc.ChangeState(SCE_SML_IDENTIFIER);
+                       } else if (chLit < 1 && sc.currentPos - chToken >= 3)
+                               sc.ChangeState(SCE_SML_IDENTIFIER), advance = false;
+                       break;
+
+               case SCE_SML_STRING:
+                       if (sc.Match('\\') && sc.chPrev == '\\')
+                               sc.ch = ' ';
+                       else if (sc.Match('\"') && sc.chPrev != '\\')
+                               state2 = SCE_SML_DEFAULT, chColor++;
+                       break;
+
+               case SCE_SML_COMMENT:
+               case SCE_SML_COMMENT1:
+               case SCE_SML_COMMENT2:
+               case SCE_SML_COMMENT3:
+                       if (sc.Match('(', '*'))
+                               state2 = sc.state + 1, chToken = sc.currentPos,
+                                       sc.ch = ' ',
+                                       sc.Forward(), nesting++;
+                       else if (sc.Match(')') && sc.chPrev == '*') {
+                               if (nesting)
+                                       state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
+                               else
+                                       state2 = SCE_SML_DEFAULT;
+                               chColor++;
+                       } else if (useMagic && sc.currentPos - chToken == 4
+                               && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
+                               sc.state |= 0x10;
+                       break;
+               }
+
+               if (state2 >= 0)
+                       styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
+               if (advance)
+                       sc.Forward();
+       }
+
+       sc.Complete();
+}
+
+void FoldSMLDoc(
+       unsigned int startPos, int length,
+       int initStyle,
+       WordList *keywordlists[],
+       Accessor &styler)
+{
+       //supress "not used" warnings
+       startPos || length || initStyle || keywordlists[0] || styler.Length();
+}
+
+static const char * const SMLWordListDesc[] = {
+       "Keywords",
+       "Keywords2",
+       "Keywords3",
+       0
+};
+
+LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc);
+                
index eb1cddbdffc3e7c7f071efb982d29e46879db341..7a4335bd2ca618c94ff888bcdecef6c867488a7c 100644 (file)
@@ -61,7 +61,10 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 
        StyleContext sc(startPos, length, initStyle, styler);
 
+       // property sql.backslash.escapes 
+       //      Enables backslash as an escape character in SQL. 
        bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+
        bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
        int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
        for (; sc.More(); sc.Forward()) {
@@ -228,6 +231,10 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
        bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
 
+       // property fold.sql.exists 
+       //      Enables "EXISTS" to end a fold as is started by "IF" in "DROP TABLE IF EXISTS". 
+       bool foldSqlExists = styler.GetPropertyInt("fold.sql.exists", 1) != 0;
+
        unsigned int endPos = startPos + length;
        int visibleChars = 0;
        int lineCurrent = styler.GetLine(startPos);
@@ -300,9 +307,13 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
                                }
                        } else if (strcmp(s, "begin") == 0) {
                                levelNext++;
-                       } else if (strcmp(s, "end") == 0 ||
-                                               // DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
-                                               strcmp(s, "exists") == 0) {
+                       } else if ((strcmp(s, "end") == 0) ||
+//                                             // DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
+                                               (foldSqlExists && (strcmp(s, "exists") == 0)) ||
+//                                             //  SQL Anywhere permits IF ... ELSE ... ENDIF
+//                                             //      will only be active if "endif" appears in the 
+//                                             //              keyword list.
+                                               (strcmp(s, "endif") == 0)) {
                                endFound = true;
                                levelNext--;
                                if (levelNext < SC_FOLDLEVELBASE) {
diff --git a/src/stc/scintilla/src/LexSorcus.cxx b/src/stc/scintilla/src/LexSorcus.cxx
new file mode 100644 (file)
index 0000000..1d8ba27
--- /dev/null
@@ -0,0 +1,205 @@
+// Scintilla source code edit control
+/** @file LexSorcus.cxx
+** Lexer for SORCUS installation files
+** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany
+** Based on the ASM Lexer by The Black Horus
+**/
+
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+
+//each character a..z and A..Z + '_' can be part of a keyword
+//additionally numbers that follow 'M' can be contained in a keyword
+static inline bool IsSWordStart(const int ch, const int prev_ch)           
+{
+    if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
+        return true;
+
+    return false;
+}
+
+
+//only digits that are not preceded by 'M' count as a number
+static inline bool IsSorcusNumber(const int ch, const int prev_ch)         
+{
+    if ((isdigit(ch)) && (prev_ch != 'M'))
+        return true;
+
+    return false;
+}
+
+
+//only = is a valid operator
+static inline bool IsSorcusOperator(const int ch)           
+{
+    if (ch == '=')
+        return true;
+    
+    return false;
+}
+
+
+static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                               Accessor &styler)                                        
+{
+    
+    WordList &Command = *keywordlists[0];
+    WordList &Parameter = *keywordlists[1];
+    WordList &Constant = *keywordlists[2];
+    
+    // Do not leak onto next line
+    if (initStyle == SCE_SORCUS_STRINGEOL)              
+        initStyle = SCE_SORCUS_DEFAULT;
+    
+    StyleContext sc(startPos, length, initStyle, styler);
+    
+    for (; sc.More(); sc.Forward())
+    {
+        
+        // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
+        if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
+        {
+            sc.SetState(SCE_SORCUS_STRING);         
+        }       
+        
+        // Determine if the current state should terminate.
+        if (sc.state == SCE_SORCUS_OPERATOR)
+        {
+            if (!IsSorcusOperator(sc.ch)) 
+            {
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }       
+        else if(sc.state == SCE_SORCUS_NUMBER)
+        {
+            if(!IsSorcusNumber(sc.ch, sc.chPrev))
+            {
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }
+        else if (sc.state == SCE_SORCUS_IDENTIFIER)
+        {
+            if (!IsSWordStart(sc.ch, sc.chPrev))
+            {
+                char s[100];
+                
+                sc.GetCurrent(s, sizeof(s));
+                
+                if (Command.InList(s))
+                { 
+                    sc.ChangeState(SCE_SORCUS_COMMAND); 
+                }
+                else if (Parameter.InList(s))
+                { 
+                    sc.ChangeState(SCE_SORCUS_PARAMETER);
+                }
+                else if (Constant.InList(s))
+                { 
+                    sc.ChangeState(SCE_SORCUS_CONSTANT);
+                }
+                
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }       
+        else if (sc.state == SCE_SORCUS_COMMENTLINE )
+        {
+            if (sc.atLineEnd)
+            {
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }
+        else if (sc.state == SCE_SORCUS_STRING)
+        {
+            if (sc.ch == '\"')
+            {
+                sc.ForwardSetState(SCE_SORCUS_DEFAULT);
+            }
+            else if (sc.atLineEnd) 
+            {
+                sc.ChangeState(SCE_SORCUS_STRINGEOL);
+                sc.ForwardSetState(SCE_SORCUS_DEFAULT);
+            }
+        }
+        
+        // Determine if a new state should be entered.
+        if (sc.state == SCE_SORCUS_DEFAULT)
+        {
+            if ((sc.ch == ';') || (sc.ch == '\''))
+            {
+                sc.SetState(SCE_SORCUS_COMMENTLINE);
+            }   
+            else if (IsSWordStart(sc.ch, sc.chPrev))
+            {
+                sc.SetState(SCE_SORCUS_IDENTIFIER);
+            }   
+            else if (sc.ch == '\"')
+            {
+                sc.SetState(SCE_SORCUS_STRING);
+            }
+            else if (IsSorcusOperator(sc.ch))
+            {
+                sc.SetState(SCE_SORCUS_OPERATOR);
+            }
+            else if (IsSorcusNumber(sc.ch, sc.chPrev))
+            {
+                sc.SetState(SCE_SORCUS_NUMBER);
+            }
+        }
+        
+    }
+    sc.Complete();
+}
+
+
+static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
+  
+LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
index b2953c00146b3c0bd9809f64d4a09b150b975cc8..6aa2e8fdca6ff1e311e7d8c0dc7fedd14a51a41f 100644 (file)
@@ -10,6 +10,8 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <string>
+
 #include "Platform.h"
 
 #include "Accessor.h"
@@ -17,7 +19,6 @@
 #include "PropSet.h"
 #include "KeyWords.h"
 #include "SciLexer.h"
-#include "SString.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -75,7 +76,7 @@ static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute
 
 static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
     apostropheStartsAttribute = true;
-    SString number;
+    std::string number;
     sc.SetState(SCE_SPICE_NUMBER);
     // Get all characters up to a delimiter or a separator, including points, but excluding
     // double points (ranges).
@@ -104,7 +105,7 @@ static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
 static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
     apostropheStartsAttribute = true;
     sc.SetState(SCE_SPICE_IDENTIFIER);
-    SString word;
+    std::string word;
     while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
         word += static_cast<char>(tolower(sc.ch));
         sc.Forward();
diff --git a/src/stc/scintilla/src/LexTACL.cxx b/src/stc/scintilla/src/LexTACL.cxx
new file mode 100644 (file)
index 0000000..b0c1244
--- /dev/null
@@ -0,0 +1,397 @@
+// Scintilla source code edit control
+/** @file LexTAL.cxx
+ ** Lexer for TAL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to TACL
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+inline bool isTACLoperator(char ch)
+       {
+       return ch == '\'' || isoperator(ch);
+       }
+
+inline bool isTACLwordchar(char ch)
+       {
+       return ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch);
+       }
+
+inline bool isTACLwordstart(char ch)
+       {
+       return ch == '#' || ch == '|' || ch == '_' || iswordstart(ch);
+       }
+
+static void getRange(unsigned int start,
+               unsigned int end,
+               Accessor &styler,
+               char *s,
+               unsigned int len) {
+       unsigned int i = 0;
+       while ((i < end - start + 1) && (i < len-1)) {
+               s[i] = static_cast<char>(tolower(styler[start + i]));
+               i++;
+       }
+       s[i] = '\0';
+}
+
+static bool IsStreamCommentStyle(int style) {
+       return style == SCE_C_COMMENT ||
+               style == SCE_C_COMMENTDOC ||
+               style == SCE_C_COMMENTDOCKEYWORD ||
+               style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
+       if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
+               styler.ColourTo(end, SCE_C_REGEX);
+       } else
+               styler.ColourTo(end, attr);
+}
+
+// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
+static int classifyWordTACL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
+       int ret = 0;
+
+       WordList& keywords = *keywordlists[0];
+       WordList& builtins = *keywordlists[1];
+       WordList& commands = *keywordlists[2];
+
+       char s[100];
+       getRange(start, end, styler, s, sizeof(s));
+
+       char chAttr = SCE_C_IDENTIFIER;
+       if (isdigit(s[0]) || (s[0] == '.')) {
+               chAttr = SCE_C_NUMBER;
+       }
+       else {
+               if (s[0] == '#' || keywords.InList(s)) {
+                       chAttr = SCE_C_WORD;
+
+                       if (strcmp(s, "asm") == 0) {
+                               ret = 2;
+                       }
+                       else if (strcmp(s, "end") == 0) {
+                               ret = -1;
+                       }
+               }
+               else if (s[0] == '|' || builtins.InList(s)) {
+                       chAttr = SCE_C_WORD2;
+               }
+               else if (commands.InList(s)) {
+                       chAttr = SCE_C_UUID;
+               }
+               else if (strcmp(s, "comment") == 0) {
+                       chAttr = SCE_C_COMMENTLINE;
+                       ret = 3;
+               }
+       }
+       ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
+       return ret;
+}
+
+static int classifyFoldPointTACL(const char* s) {
+       int lev = 0;
+       if (s[0] == '[')
+               lev=1;
+       else if (s[0] == ']')
+               lev=-1;
+       return lev;
+}
+
+static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+       Accessor &styler) {
+
+       styler.StartAt(startPos);
+
+       int state = initStyle;
+       if (state == SCE_C_CHARACTER)   // Does not leak onto next line
+               state = SCE_C_DEFAULT;
+       char chPrev = ' ';
+       char chNext = styler[startPos];
+       unsigned int lengthDoc = startPos + length;
+
+       bool bInClassDefinition;
+
+       int currentLine = styler.GetLine(startPos);
+       if (currentLine > 0) {
+               styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+               bInClassDefinition = (styler.GetLineState(currentLine) == 1);
+       } else {
+               styler.SetLineState(currentLine, 0);
+               bInClassDefinition = false;
+       }
+
+       bool bInAsm = (state == SCE_C_REGEX);
+       if (bInAsm)
+               state = SCE_C_DEFAULT;
+
+       styler.StartSegment(startPos);
+       int visibleChars = 0;
+       unsigned int i;
+       for (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_C_CHARACTER) {
+                               ColourTo(styler, i, state, bInAsm);
+                               state = SCE_C_DEFAULT;
+                       }
+                       visibleChars = 0;
+                       currentLine++;
+                       styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+               }
+
+               if (styler.IsLeadByte(ch)) {
+                       chNext = styler.SafeGetCharAt(i + 2);
+                       chPrev = ' ';
+                       i += 1;
+                       continue;
+               }
+
+               if (state == SCE_C_DEFAULT) {
+                       if (isTACLwordstart(ch)) {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_IDENTIFIER;
+                       } else if (ch == '{') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_COMMENT;
+                       } else if (ch == '{' && chNext == '*') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_COMMENTDOC;
+                       } else if (ch == '=' && chNext == '=') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_COMMENTLINE;
+                       } else if (ch == '"') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_STRING;
+                       } else if (ch == '?' && visibleChars == 0) {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_PREPROCESSOR;
+                       } else if (isTACLoperator(ch)) {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+                       }
+               } else if (state == SCE_C_IDENTIFIER) {
+                       if (!isTACLwordchar(ch)) {
+                               int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+
+                               if(lStateChange == 1) {
+                                       styler.SetLineState(currentLine, 1);
+                                       bInClassDefinition = true;
+                               } else if(lStateChange == 2) {
+                                       bInAsm = true;
+                               } else if(lStateChange == -1) {
+                                       styler.SetLineState(currentLine, 0);
+                                       bInClassDefinition = false;
+                                       bInAsm = false;
+                               }
+
+                               if (lStateChange == 3) {
+                                        state = SCE_C_COMMENTLINE;
+                               }
+                               else {
+                                       state = SCE_C_DEFAULT;
+                                       chNext = styler.SafeGetCharAt(i + 1);
+                                       if (ch == '{') {
+                                               state = SCE_C_COMMENT;
+                                       } else if (ch == '{' && chNext == '*') {
+                                               ColourTo(styler, i-1, state, bInAsm);
+                                               state = SCE_C_COMMENTDOC;
+                                       } else if (ch == '=' && chNext == '=') {
+                                               state = SCE_C_COMMENTLINE;
+                                       } else if (ch == '"') {
+                                               state = SCE_C_STRING;
+                                       } else if (isTACLoperator(ch)) {
+                                               ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+                                       }
+                               }
+                       }
+               } else {
+                       if (state == SCE_C_PREPROCESSOR) {
+                               if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+                                       ColourTo(styler, i-1, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       } else if (state == SCE_C_COMMENT) {
+                               if (ch == '}' || (ch == '\r' || ch == '\n') ) {
+                                       ColourTo(styler, i, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       } else if (state == SCE_C_COMMENTDOC) {
+                               if (ch == '}' || (ch == '\r' || ch == '\n')) {
+                                       if (((i > styler.GetStartSegment() + 2) || (
+                                               (initStyle == SCE_C_COMMENTDOC) &&
+                                               (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+                                                       ColourTo(styler, i, state, bInAsm);
+                                                       state = SCE_C_DEFAULT;
+                                       }
+                               }
+                       } else if (state == SCE_C_COMMENTLINE) {
+                               if (ch == '\r' || ch == '\n') {
+                                       ColourTo(styler, i-1, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       } else if (state == SCE_C_STRING) {
+                               if (ch == '"' || ch == '\r' || ch == '\n') {
+                                       ColourTo(styler, i, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       }
+               }
+        if (!isspacechar(ch))
+            visibleChars++;
+               chPrev = ch;
+       }
+
+       // Process to end of document
+       if (state == SCE_C_IDENTIFIER) {
+               classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+               }
+       else
+               ColourTo(styler, lengthDoc - 1, state, bInAsm);
+}
+
+static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+                            Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 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;
+       bool section = false;
+
+       int lastStart = 0;
+
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+               if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))
+               {
+                       // Store last word start point.
+                       lastStart = i;
+               }
+
+               if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {
+                       if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {
+                               char s[100];
+                               getRange(lastStart, i, styler, s, sizeof(s));
+                               if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
+                                       {
+                                       section = true;
+                                       levelCurrent = 1;
+                                       levelPrev = 0;
+                                       }
+                               else if (stylePrev == SCE_C_WORD)
+                                       levelCurrent += classifyFoldPointTACL(s);
+                       }
+               }
+
+               if (style == SCE_C_OPERATOR) {
+                       if (ch == '[') {
+                               levelCurrent++;
+                       } else if (ch == ']') {
+                               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 == '{' && chNext == '$') {
+                               unsigned int j=i+2; // skip {$
+                               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 (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 (atEOL) {
+                       int lev = levelPrev | SC_FOLDLEVELBASE;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+                       section = false;
+               }
+
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const TACLWordListDesc[] = {
+       "Builtins",
+       "Labels",
+       "Commands",
+       0
+};
+
+LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, "TACL", FoldTACLDoc, TACLWordListDesc);
index 7cc85f1f99eeb5bac3e2dcde4735e0c0e652f5e2..ee16a0ac07d617a808dd81605b334db5ff486d31 100644 (file)
@@ -679,7 +679,7 @@ static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
 static inline bool IsStringTransition(int s1, int s2) {
         return s1 != s2
                 && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
-                        || s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)
+                        || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT))
                 && s2 != SCE_T3_LIB_DIRECTIVE
                 && s2 != SCE_T3_MSG_PARAM
                 && s2 != SCE_T3_HTML_TAG
diff --git a/src/stc/scintilla/src/LexTAL.cxx b/src/stc/scintilla/src/LexTAL.cxx
new file mode 100644 (file)
index 0000000..a76a296
--- /dev/null
@@ -0,0 +1,396 @@
+// Scintilla source code edit control
+/** @file LexTAL.cxx
+ ** Lexer for TAL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002
+ ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to TAL
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+inline bool isTALoperator(char ch)
+       {
+       return ch == '\'' || ch == '@' || ch == '#' || isoperator(ch);
+       }
+
+inline bool isTALwordchar(char ch)
+       {
+       return ch == '$' || ch == '^' || iswordchar(ch);
+       }
+
+inline bool isTALwordstart(char ch)
+       {
+       return ch == '$' || ch == '^' || iswordstart(ch);
+       }
+
+static void getRange(unsigned int start,
+               unsigned int end,
+               Accessor &styler,
+               char *s,
+               unsigned int len) {
+       unsigned int i = 0;
+       while ((i < end - start + 1) && (i < len-1)) {
+               s[i] = static_cast<char>(tolower(styler[start + i]));
+               i++;
+       }
+       s[i] = '\0';
+}
+
+static bool IsStreamCommentStyle(int style) {
+       return style == SCE_C_COMMENT ||
+               style == SCE_C_COMMENTDOC ||
+               style == SCE_C_COMMENTDOCKEYWORD ||
+               style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
+       if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
+               styler.ColourTo(end, SCE_C_REGEX);
+       } else
+               styler.ColourTo(end, attr);
+}
+
+// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
+static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
+       int ret = 0;
+
+       WordList& keywords = *keywordlists[0];
+       WordList& builtins = *keywordlists[1];
+       WordList& nonreserved_keywords = *keywordlists[2];
+
+       char s[100];
+       getRange(start, end, styler, s, sizeof(s));
+
+       char chAttr = SCE_C_IDENTIFIER;
+       if (isdigit(s[0]) || (s[0] == '.')) {
+               chAttr = SCE_C_NUMBER;
+       }
+       else {
+               if (keywords.InList(s)) {
+                       chAttr = SCE_C_WORD;
+
+                       if (strcmp(s, "asm") == 0) {
+                               ret = 2;
+                       }
+                       else if (strcmp(s, "end") == 0) {
+                               ret = -1;
+                       }
+               } 
+               else if (s[0] == '$' || builtins.InList(s)) {
+                       chAttr = SCE_C_WORD2;
+               }
+               else if (nonreserved_keywords.InList(s)) {
+                       chAttr = SCE_C_UUID;
+               }
+       }
+       ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
+       return ret;
+}
+
+static int classifyFoldPointTAL(const char* s) {
+       int lev = 0;
+       if (!(isdigit(s[0]) || (s[0] == '.'))) {
+               if (strcmp(s, "begin") == 0 ||
+                       strcmp(s, "block") == 0) {
+                       lev=1;
+               } else if (strcmp(s, "end") == 0) {
+                       lev=-1;
+               }
+       }
+       return lev;
+}
+
+static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+       Accessor &styler) {
+
+       styler.StartAt(startPos);
+
+       int state = initStyle;
+       if (state == SCE_C_CHARACTER)   // Does not leak onto next line
+               state = SCE_C_DEFAULT;
+       char chPrev = ' ';
+       char chNext = styler[startPos];
+       unsigned int lengthDoc = startPos + length;
+
+       bool bInClassDefinition;
+
+       int currentLine = styler.GetLine(startPos);
+       if (currentLine > 0) {
+               styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+               bInClassDefinition = (styler.GetLineState(currentLine) == 1);
+       } else {
+               styler.SetLineState(currentLine, 0);
+               bInClassDefinition = false;
+       }
+
+       bool bInAsm = (state == SCE_C_REGEX);
+       if (bInAsm)
+               state = SCE_C_DEFAULT;
+
+       styler.StartSegment(startPos);
+       int visibleChars = 0;
+       for (unsigned int i = startPos; i < lengthDoc; i++) {
+               char ch = chNext;
+
+               chNext = styler.SafeGetCharAt(i + 1);
+
+               if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+                       // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+                       // Avoid triggering two times on Dos/Win
+                       // End of line
+                       if (state == SCE_C_CHARACTER) {
+                               ColourTo(styler, i, state, bInAsm);
+                               state = SCE_C_DEFAULT;
+                       }
+                       visibleChars = 0;
+                       currentLine++;
+                       styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+               }
+
+               if (styler.IsLeadByte(ch)) {
+                       chNext = styler.SafeGetCharAt(i + 2);
+                       chPrev = ' ';
+                       i += 1;
+                       continue;
+               }
+
+               if (state == SCE_C_DEFAULT) {
+                       if (isTALwordstart(ch)) {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_IDENTIFIER;
+                       } else if (ch == '!' && chNext != '*') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_COMMENT;
+                       } else if (ch == '!' && chNext == '*') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_COMMENTDOC;
+                       } else if (ch == '-' && chNext == '-') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_COMMENTLINE;
+                       } else if (ch == '"') {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_STRING;
+                       } else if (ch == '?' && visibleChars == 0) {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               state = SCE_C_PREPROCESSOR;
+                       } else if (isTALoperator(ch)) {
+                               ColourTo(styler, i-1, state, bInAsm);
+                               ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+                       }
+               } else if (state == SCE_C_IDENTIFIER) {
+                       if (!isTALwordchar(ch)) {
+                               int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+
+                               if(lStateChange == 1) {
+                                       styler.SetLineState(currentLine, 1);
+                                       bInClassDefinition = true;
+                               } else if(lStateChange == 2) {
+                                       bInAsm = true;
+                               } else if(lStateChange == -1) {
+                                       styler.SetLineState(currentLine, 0);
+                                       bInClassDefinition = false;
+                                       bInAsm = false;
+                               }
+
+                               state = SCE_C_DEFAULT;
+                               chNext = styler.SafeGetCharAt(i + 1);
+                               if (ch == '!' && chNext != '*') {
+                                       state = SCE_C_COMMENT;
+                               } else if (ch == '!' && chNext == '*') {
+                                       ColourTo(styler, i-1, state, bInAsm);
+                                       state = SCE_C_COMMENTDOC;
+                               } else if (ch == '-' && chNext == '-') {
+                                       state = SCE_C_COMMENTLINE;
+                               } else if (ch == '"') {
+                                       state = SCE_C_STRING;
+                               } else if (isTALoperator(ch)) {
+                                       ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+                               }
+                       }
+               } else {
+                       if (state == SCE_C_PREPROCESSOR) {
+                               if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+                                       ColourTo(styler, i-1, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       } else if (state == SCE_C_COMMENT) {
+                               if (ch == '!' || (ch == '\r' || ch == '\n') ) {
+                                       ColourTo(styler, i, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       } else if (state == SCE_C_COMMENTDOC) {
+                               if (ch == '!' || (ch == '\r' || ch == '\n')) {
+                                       if (((i > styler.GetStartSegment() + 2) || (
+                                               (initStyle == SCE_C_COMMENTDOC) &&
+                                               (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+                                                       ColourTo(styler, i, state, bInAsm);
+                                                       state = SCE_C_DEFAULT;
+                                       }
+                               }
+                       } else if (state == SCE_C_COMMENTLINE) {
+                               if (ch == '\r' || ch == '\n') {
+                                       ColourTo(styler, i-1, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       } else if (state == SCE_C_STRING) {
+                               if (ch == '"') {
+                                       ColourTo(styler, i, state, bInAsm);
+                                       state = SCE_C_DEFAULT;
+                               }
+                       }
+               }
+        if (!isspacechar(ch))
+            visibleChars++;
+               chPrev = ch;
+       }
+       ColourTo(styler, lengthDoc - 1, state, bInAsm);
+}
+
+static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+                            Accessor &styler) {
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+       bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 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;
+       bool was_end = false;
+       bool section = false;
+
+       int lastStart = 0;
+
+       for (unsigned int i = startPos; i < endPos; i++) {
+               char ch = chNext;
+               chNext = styler.SafeGetCharAt(i + 1);
+               int stylePrev = style;
+               style = styleNext;
+               styleNext = styler.StyleAt(i + 1);
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+               if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR))
+               {
+                       // Store last word start point.
+                       lastStart = i;
+               }
+
+               if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) {
+                       if(isTALwordchar(ch) && !isTALwordchar(chNext)) {
+                               char s[100];
+                               getRange(lastStart, i, styler, s, sizeof(s));
+                               if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
+                                       {
+                                       section = true;
+                                       levelCurrent = 1;
+                                       levelPrev = 0;
+                                       }
+                               else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID)
+                                       {
+                                       if (strcmp(s, "block") == 0)
+                                               {
+                                               // block keyword is ignored immediately after end keyword
+                                               if (!was_end)
+                                                       levelCurrent++;
+                                               }
+                                       else
+                                               levelCurrent += classifyFoldPointTAL(s);
+                                       if (strcmp(s, "end") == 0)
+                                               {
+                                               was_end = true;
+                                               }
+                                       else
+                                               {
+                                               was_end = false;
+                                               }
+                                       }
+                       }
+               }
+
+               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 == '{' && chNext == '$') {
+                               unsigned int j=i+2; // skip {$
+                               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 (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 (atEOL) {
+                       int lev = levelPrev | SC_FOLDLEVELBASE;
+                       if (visibleChars == 0 && foldCompact)
+                               lev |= SC_FOLDLEVELWHITEFLAG;
+                       if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
+                               lev |= SC_FOLDLEVELHEADERFLAG;
+                       if (lev != styler.LevelAt(lineCurrent)) {
+                               styler.SetLevel(lineCurrent, lev);
+                       }
+                       lineCurrent++;
+                       levelPrev = levelCurrent;
+                       visibleChars = 0;
+                       section = false;
+               }
+
+               if (!isspacechar(ch))
+                       visibleChars++;
+       }
+
+       // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+       int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+       styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const TALWordListDesc[] = {
+       "Keywords",
+       "Builtins",
+       0
+};
+
+LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, "TAL", FoldTALDoc, TALWordListDesc);
index e28857a35d312c3dcf949df0240c3bec906cb6be..62ade1d75820fdc7dacd0c8bbd63ec8e34027126 100644 (file)
@@ -242,8 +242,11 @@ static void ColouriseTeXDoc(
                                        }
                                }
                                if (isTeXzero(sc.ch)) {
-                                       sc.SetState(SCE_TEX_SYMBOL) ;
-                                       sc.ForwardSetState(SCE_TEX_DEFAULT) ;
+                                       sc.SetState(SCE_TEX_SYMBOL);
+
+                                       if (!endOfLine(styler,sc.currentPos + 1))
+                                               sc.ForwardSetState(SCE_TEX_DEFAULT) ;
+
                                        inComment = ! processComment ;
                                        newifDone = false ;
                                } else if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {
@@ -395,7 +398,7 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
                        levelCurrent += classifyFoldPointTeXPaired(buffer)+classifyFoldPointTeXUnpaired(buffer);
                }
 
-               if((ch == '\r' || ch=='\n') && (chNext == '\\')){
+               if (levelCurrent > SC_FOLDLEVELBASE && ((ch == '\r' || ch=='\n') && (chNext == '\\'))) {
             ParseTeXCommand(i+1, styler, buffer);
                        levelCurrent -= classifyFoldPointTeXUnpaired(buffer);
                }
index a1f9ec7aeabda59df5751f05c6460578ae7314b6..c57a9ac49d7d536240ec0b87e3908bc80db9c211 100644 (file)
@@ -214,6 +214,40 @@ static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                        visibleChars++;
                }
        }
+
+       if (sc.state == SCE_B_IDENTIFIER && !IsAWordChar(sc.ch)) {
+               // In Basic (except VBScript), a variable name or a function name
+               // can end with a special character indicating the type of the value
+               // held or returned.
+               bool skipType = false;
+               if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
+                       sc.Forward();   // Skip it
+                       skipType = true;
+               }
+               if (sc.ch == ']') {
+                       sc.Forward();
+               }
+               char s[100];
+               sc.GetCurrentLowered(s, sizeof(s));
+               if (skipType) {
+                       s[strlen(s) - 1] = '\0';
+               }
+               if (strcmp(s, "rem") == 0) {
+                       sc.ChangeState(SCE_B_COMMENT);
+               } else {
+                       if (keywords.InList(s)) {
+                               sc.ChangeState(SCE_B_KEYWORD);
+                       } else if (keywords2.InList(s)) {
+                               sc.ChangeState(SCE_B_KEYWORD2);
+                       } else if (keywords3.InList(s)) {
+                               sc.ChangeState(SCE_B_KEYWORD3);
+                       } else if (keywords4.InList(s)) {
+                               sc.ChangeState(SCE_B_KEYWORD4);
+                       }       // Else, it is really an identifier...
+                       sc.SetState(SCE_B_DEFAULT);
+               }
+       }
+
        sc.Complete();
 }
 
index 16553734640fc7db6d35cc84b6b85a13b2ac0007..3fd0fc35c6a78d45c38e0f0d5d09b10a27b1dcd6 100644 (file)
@@ -97,7 +97,7 @@ static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle
                                sc.ForwardSetState(SCE_V_DEFAULT);
                        }
                } else if (sc.state == SCE_V_COMMENTLINE || sc.state == SCE_V_COMMENTLINEBANG) {
-                       if (sc.atLineEnd) {
+                       if (sc.atLineStart) {
                                sc.SetState(SCE_V_DEFAULT);
                        }
                 } else if (sc.state == SCE_V_STRING) {
@@ -164,11 +164,11 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
         //      Generally used methodology in verilog code is
         //      one module per file, so folding at module definition is useless.
         // fold_at_brace/parenthese -
-        //      Folding of long port lists can be convenient. 
+        //      Folding of long port lists can be convenient.
        bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0;
        bool foldAtBrace  = 1;
        bool foldAtParenthese  = 1;
-                                
+
        unsigned int endPos = startPos + length;
        int visibleChars = 0;
        int lineCurrent = styler.GetLine(startPos);
@@ -238,27 +238,29 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
                }
                 if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) {
                         unsigned int j = i;
-                        if (styler.Match(j, "case") || 
-                            styler.Match(j, "casex") || 
-                            styler.Match(j, "casez") || 
-                            styler.Match(j, "function") || 
-                            styler.Match(j, "fork") || 
-                            styler.Match(j, "table") || 
-                            styler.Match(j, "task") || 
-                            styler.Match(j, "specify") || 
-                            styler.Match(j, "primitive") || 
-                            styler.Match(j, "module") && foldAtModule || 
+                        if (styler.Match(j, "case") ||
+                            styler.Match(j, "casex") ||
+                            styler.Match(j, "casez") ||
+                            styler.Match(j, "function") ||
+                            styler.Match(j, "fork") ||
+                            styler.Match(j, "table") ||
+                            styler.Match(j, "task") ||
+                            styler.Match(j, "generate") ||
+                            styler.Match(j, "specify") ||
+                            styler.Match(j, "primitive") ||
+                            (styler.Match(j, "module") && foldAtModule) ||
                             styler.Match(j, "begin")) {
                                 levelNext++;
-                        } else if (styler.Match(j, "endcase") || 
+                        } else if (styler.Match(j, "endcase") ||
                                    styler.Match(j, "endfunction") ||
                                    styler.Match(j, "join") ||
                                    styler.Match(j, "endtask") ||
+                                   styler.Match(j, "endgenerate") ||
                                    styler.Match(j, "endtable") ||
                                    styler.Match(j, "endspecify") ||
                                    styler.Match(j, "endprimitive") ||
-                                   styler.Match(j, "endmodule") && foldAtModule ||
-                                   styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3))) {
+                                   (styler.Match(j, "endmodule") && foldAtModule) ||
+                                   (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
                                 levelNext--;
                         }
                }
index ef5315f247ce504757755c50c587aa6c88af0ec0..99f34da8895a527d8e11d46396814023a6071e94 100644 (file)
@@ -3,7 +3,7 @@
  ** Lexer for YAML.
  **/
 // Copyright 2003- by Sean O'Dell <sean@celsoft.com>
-// Release under the same license as Scintilla/SciTE.
+// The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 #include <string.h>
@@ -147,7 +147,7 @@ static void ColouriseYAMLLine(
                        } else {
                                unsigned int i2 = i;
                                while ((i < lengthLine) && lineBuffer[i]) {
-                                       if (!isdigit(lineBuffer[i]) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') {
+                                       if (!(isascii(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') {
                                                styler.ColourTo(endPos, SCE_YAML_DEFAULT);
                                                return;
                                        }
index ab0511654f0eaee557ee540f0608faa3a73d316e..0bfd479384aa872a99cea1d6ffe95974d54e8b7f 100644 (file)
@@ -154,7 +154,8 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
                rcSmall.bottom = rc.bottom - 2;
                surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
 
-       } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
+       } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND || 
+               markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
                // An invisible marker so don't draw anything
 
        } else if (markType == SC_MARK_VLINE) {
@@ -299,6 +300,10 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
                };
                surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
                                fore.allocated, back.allocated);
+       } else if (markType == SC_MARK_LEFTRECT) {
+               PRectangle rcLeft = rcWhole;
+               rcLeft.right = rcLeft.left + 4;
+               surface->FillRectangle(rcLeft, back.allocated);
        } else { // SC_MARK_FULLRECT
                surface->FillRectangle(rcWhole, back.allocated);
        }
index 24e22d905fcea6e28e2b85b8f25d9c293a74fa9f..3cb4139f08a2a4d5a0af8f8821f2eac729dafc12 100644 (file)
@@ -39,16 +39,14 @@ public:
        ~LineMarker() {
                delete pxpm;
        }
-       LineMarker &operator=(const LineMarker &other) {
+       LineMarker &operator=(const LineMarker &) {
                // Defined to avoid pxpm being blindly copied, not as real assignment operator
-               if ( &other != this ) {
-                       markType = SC_MARK_CIRCLE;
-                       fore = ColourDesired(0,0,0);
-                       back = ColourDesired(0xff,0xff,0xff);
-                       alpha = SC_ALPHA_NOALPHA;
-                       delete pxpm;
-                       pxpm = NULL;
-               }
+               markType = SC_MARK_CIRCLE;
+               fore = ColourDesired(0,0,0);
+               back = ColourDesired(0xff,0xff,0xff);
+               alpha = SC_ALPHA_NOALPHA;
+               delete pxpm;
+               pxpm = NULL;
                return *this;
        }
        void RefreshColourPalette(Palette &pal, bool want);
index 752e69614c5939e7d6eb71b47e45c2eb2958e4fa..225e350e030d73c3fec377f6dd3d1651cad90c32 100644 (file)
@@ -153,7 +153,7 @@ public:
                return pos;
        }
 
-       int PartitionFromPosition(int pos) {
+       int PartitionFromPosition(int pos) const {
                if (body->Length() <= 1)
                        return 0;
                if (pos >= (PositionFromPartition(body->Length()-1)))
diff --git a/src/stc/scintilla/src/PerLine.cxx b/src/stc/scintilla/src/PerLine.cxx
new file mode 100644 (file)
index 0000000..3e02d65
--- /dev/null
@@ -0,0 +1,486 @@
+// Scintilla source code edit control
+/** @file PerLine.cxx
+ ** Manages data associated with each line of the document
+ **/
+// Copyright 1998-2009 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 "SplitVector.h"
+#include "Partitioning.h"
+#include "CellBuffer.h"
+#include "PerLine.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+MarkerHandleSet::MarkerHandleSet() {
+       root = 0;
+}
+
+MarkerHandleSet::~MarkerHandleSet() {
+       MarkerHandleNumber *mhn = root;
+       while (mhn) {
+               MarkerHandleNumber *mhnToFree = mhn;
+               mhn = mhn->next;
+               delete mhnToFree;
+       }
+       root = 0;
+}
+
+int MarkerHandleSet::Length() const {
+       int c = 0;
+       MarkerHandleNumber *mhn = root;
+       while (mhn) {
+               c++;
+               mhn = mhn->next;
+       }
+       return c;
+}
+
+int MarkerHandleSet::NumberFromHandle(int handle) const {
+       MarkerHandleNumber *mhn = root;
+       while (mhn) {
+               if (mhn->handle == handle) {
+                       return mhn->number;
+               }
+               mhn = mhn->next;
+       }
+       return - 1;
+}
+
+int MarkerHandleSet::MarkValue() const {
+       unsigned int m = 0;
+       MarkerHandleNumber *mhn = root;
+       while (mhn) {
+               m |= (1 << mhn->number);
+               mhn = mhn->next;
+       }
+       return m;
+}
+
+bool MarkerHandleSet::Contains(int handle) const {
+       MarkerHandleNumber *mhn = root;
+       while (mhn) {
+               if (mhn->handle == handle) {
+                       return true;
+               }
+               mhn = mhn->next;
+       }
+       return false;
+}
+
+bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
+       MarkerHandleNumber *mhn = new MarkerHandleNumber;
+       if (!mhn)
+               return false;
+       mhn->handle = handle;
+       mhn->number = markerNum;
+       mhn->next = root;
+       root = mhn;
+       return true;
+}
+
+void MarkerHandleSet::RemoveHandle(int handle) {
+       MarkerHandleNumber **pmhn = &root;
+       while (*pmhn) {
+               MarkerHandleNumber *mhn = *pmhn;
+               if (mhn->handle == handle) {
+                       *pmhn = mhn->next;
+                       delete mhn;
+                       return;
+               }
+               pmhn = &((*pmhn)->next);
+       }
+}
+
+bool MarkerHandleSet::RemoveNumber(int markerNum) {
+       bool performedDeletion = false;
+       MarkerHandleNumber **pmhn = &root;
+       while (*pmhn) {
+               MarkerHandleNumber *mhn = *pmhn;
+               if (mhn->number == markerNum) {
+                       *pmhn = mhn->next;
+                       delete mhn;
+                       performedDeletion = true;
+               } else {
+                       pmhn = &((*pmhn)->next);
+               }
+       }
+       return performedDeletion;
+}
+
+void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
+       MarkerHandleNumber **pmhn = &root;
+       while (*pmhn) {
+               pmhn = &((*pmhn)->next);
+       }
+       *pmhn = other->root;
+       other->root = 0;
+}
+
+LineMarkers::~LineMarkers() {
+       Init();
+}
+
+void LineMarkers::Init() {
+       for (int line = 0; line < markers.Length(); line++) {
+               delete markers[line];
+               markers[line] = 0;
+       }
+       markers.DeleteAll();
+}
+
+void LineMarkers::InsertLine(int line) {
+       if (markers.Length()) {
+               markers.Insert(line, 0);
+       }
+}
+
+void LineMarkers::RemoveLine(int line) {
+       // Retain the markers from the deleted line by oring them into the previous line
+       if (markers.Length()) {
+               if (line > 0) {
+                       MergeMarkers(line - 1);
+               }
+               markers.Delete(line);
+       }
+}
+
+int LineMarkers::LineFromHandle(int markerHandle) {
+       if (markers.Length()) {
+               for (int line = 0; line < markers.Length(); line++) {
+                       if (markers[line]) {
+                               if (markers[line]->Contains(markerHandle)) {
+                                       return line;
+                               }
+                       }
+               }
+       }
+       return -1;
+}
+
+void LineMarkers::MergeMarkers(int pos) {
+       if (markers[pos + 1] != NULL) {
+               if (markers[pos] == NULL)
+                       markers[pos] = new MarkerHandleSet;
+               markers[pos]->CombineWith(markers[pos + 1]);
+               delete markers[pos + 1];
+               markers[pos + 1] = NULL;
+       }
+}
+
+int LineMarkers::MarkValue(int line) {
+       if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line])
+               return markers[line]->MarkValue();
+       else
+               return 0;
+}
+
+int LineMarkers::AddMark(int line, int markerNum, int lines) {
+       handleCurrent++;
+       if (!markers.Length()) {
+               // No existing markers so allocate one element per line
+               markers.InsertValue(0, lines, 0);
+       }
+       if (line >= markers.Length()) {
+               return -1;
+       }
+       if (!markers[line]) {
+               // Need new structure to hold marker handle
+               markers[line] = new MarkerHandleSet();
+               if (!markers[line])
+                       return -1;
+       }
+       markers[line]->InsertHandle(handleCurrent, markerNum);
+
+       return handleCurrent;
+}
+
+void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+       if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
+               if (markerNum == -1) {
+                       delete markers[line];
+                       markers[line] = NULL;
+               } else {
+                       bool performedDeletion = markers[line]->RemoveNumber(markerNum);
+                       while (all && performedDeletion) {
+                               performedDeletion = markers[line]->RemoveNumber(markerNum);
+                       }
+                       if (markers[line]->Length() == 0) {
+                               delete markers[line];
+                               markers[line] = NULL;
+                       }
+               }
+       }
+}
+
+void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
+       int line = LineFromHandle(markerHandle);
+       if (line >= 0) {
+               markers[line]->RemoveHandle(markerHandle);
+               if (markers[line]->Length() == 0) {
+                       delete markers[line];
+                       markers[line] = NULL;
+               }
+       }
+}
+
+LineLevels::~LineLevels() {
+}
+
+void LineLevels::Init() {
+       levels.DeleteAll();
+}
+
+void LineLevels::InsertLine(int line) {
+       if (levels.Length()) {
+               int level = SC_FOLDLEVELBASE;
+               if ((line > 0) && (line < levels.Length())) {   
+                       level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
+               }
+               levels.InsertValue(line, 1, level);
+       }
+}
+
+void LineLevels::RemoveLine(int line) {
+       if (levels.Length()) {
+               // Move up following lines but merge header flag from this line
+               // to line before to avoid a temporary disappearence causing expansion.
+               int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
+               levels.Delete(line);
+               if (line == levels.Length()-1) // Last line loses the header flag
+                       levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG;
+               else if (line > 0)
+                       levels[line-1] |= firstHeader;
+       }
+}
+
+void LineLevels::ExpandLevels(int sizeNew) {
+       levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
+}
+
+void LineLevels::ClearLevels() {
+       levels.DeleteAll();
+}
+
+int LineLevels::SetLevel(int line, int level, int lines) {
+       int prev = 0;
+       if ((line >= 0) && (line < lines)) {
+               if (!levels.Length()) {
+                       ExpandLevels(lines + 1);
+               }
+               prev = levels[line];
+               if (prev != level) {
+                       levels[line] = level;
+               }
+       }
+       return prev;
+}
+
+int LineLevels::GetLevel(int line) {
+       if (levels.Length() && (line >= 0) && (line < levels.Length())) {
+               return levels[line];
+       } else {
+               return SC_FOLDLEVELBASE;
+       }
+}
+
+LineState::~LineState() {
+}
+
+void LineState::Init() {
+       lineStates.DeleteAll();
+}
+
+void LineState::InsertLine(int line) {
+       if (lineStates.Length()) {
+               lineStates.EnsureLength(line);
+               lineStates.Insert(line, 0);
+       }
+}
+
+void LineState::RemoveLine(int line) {
+       if (lineStates.Length() > line) {
+               lineStates.Delete(line);
+       }
+}
+
+int LineState::SetLineState(int line, int state) {
+       lineStates.EnsureLength(line + 1);
+       int stateOld = lineStates[line];
+       lineStates[line] = state;
+       return stateOld;
+}
+
+int LineState::GetLineState(int line) {
+       lineStates.EnsureLength(line + 1);
+       return lineStates[line];
+}
+
+int LineState::GetMaxLineState() {
+       return lineStates.Length();
+}
+
+static int NumberLines(const char *text) {
+       if (text) {
+               int newLines = 0;
+               while (*text) {
+                       if (*text == '\n')
+                               newLines++;
+                       text++;
+               }
+               return newLines+1;
+       } else {
+               return 0;
+       }
+}
+
+// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader
+// and then has text and optional styles.
+
+static const int IndividualStyles = 0x100;
+
+struct AnnotationHeader {
+       short style;    // Style IndividualStyles implies array of styles
+       short lines;
+       int length;
+};
+
+LineAnnotation::~LineAnnotation() {
+       ClearAll();
+}
+
+void LineAnnotation::Init() {
+       ClearAll();
+}
+
+void LineAnnotation::InsertLine(int line) {
+       if (annotations.Length()) {
+               annotations.EnsureLength(line);
+               annotations.Insert(line, 0);
+       }
+}
+
+void LineAnnotation::RemoveLine(int line) {
+       if (annotations.Length() && (line < annotations.Length())) {
+               delete []annotations[line];
+               annotations.Delete(line);
+       }
+}
+
+bool LineAnnotation::AnySet() const {
+       return annotations.Length() > 0;
+}
+
+bool LineAnnotation::MultipleStyles(int line) const {
+       if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+               return reinterpret_cast<AnnotationHeader *>(annotations[line])->style == IndividualStyles;
+       else
+               return 0;
+}
+
+int LineAnnotation::Style(int line) {
+       if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+               return reinterpret_cast<AnnotationHeader *>(annotations[line])->style;
+       else
+               return 0;
+}
+
+const char *LineAnnotation::Text(int line) const {
+       if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+               return annotations[line]+sizeof(AnnotationHeader);
+       else
+               return 0;
+}
+
+const unsigned char *LineAnnotation::Styles(int line) const {
+       if (annotations.Length() && (line < annotations.Length()) && annotations[line] && MultipleStyles(line))
+               return reinterpret_cast<unsigned char *>(annotations[line] + sizeof(AnnotationHeader) + Length(line));
+       else
+               return 0;
+}
+
+static char *AllocateAnnotation(int length, int style) {
+       size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0);
+       char *ret = new char[len];
+       memset(ret, 0, len);
+       return ret;
+}
+
+void LineAnnotation::SetText(int line, const char *text) {
+       if (text) {
+               annotations.EnsureLength(line+1);
+               int style = Style(line);
+               if (annotations[line]) {
+                       delete []annotations[line];
+               }
+               annotations[line] = AllocateAnnotation(strlen(text), style);
+               AnnotationHeader *pah = reinterpret_cast<AnnotationHeader*>(annotations[line]);
+               pah->style = static_cast<short>(style);
+               pah->length = strlen(text);
+               pah->lines = static_cast<short>(NumberLines(text));
+               memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
+       } else {
+               if (annotations.Length() && (line < annotations.Length()) && annotations[line]) {
+                       delete []annotations[line];
+                       annotations[line] = 0;
+               }
+       }
+}
+
+void LineAnnotation::ClearAll() {
+       for (int line = 0; line < annotations.Length(); line++) {
+               delete []annotations[line];
+               annotations[line] = 0;
+       }
+       annotations.DeleteAll();
+}
+
+void LineAnnotation::SetStyle(int line, int style) {
+       annotations.EnsureLength(line+1);
+       if (!annotations[line]) {
+               annotations[line] = AllocateAnnotation(0, style);
+       }
+       reinterpret_cast<AnnotationHeader *>(annotations[line])->style = static_cast<short>(style);
+}
+
+void LineAnnotation::SetStyles(int line, const unsigned char *styles) {
+       annotations.EnsureLength(line+1);
+       if (!annotations[line]) {
+               annotations[line] = AllocateAnnotation(0, IndividualStyles);
+       } else {
+               AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+               if (pahSource->style != IndividualStyles) {
+                       char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles);
+                       AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation);
+                       pahAlloc->length = pahSource->length;
+                       pahAlloc->lines = pahSource->lines;
+                       memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length);
+                       delete []annotations[line];
+                       annotations[line] = allocation;
+               }
+       }
+       AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+       pah->style = IndividualStyles;
+       memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length);
+}
+
+int LineAnnotation::Length(int line) const {
+       if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+               return reinterpret_cast<AnnotationHeader *>(annotations[line])->length;
+       else
+               return 0;
+}
+
+int LineAnnotation::Lines(int line) const {
+       if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+               return reinterpret_cast<AnnotationHeader *>(annotations[line])->lines;
+       else
+               return 0;
+}
diff --git a/src/stc/scintilla/src/PerLine.h b/src/stc/scintilla/src/PerLine.h
new file mode 100644 (file)
index 0000000..ab34c46
--- /dev/null
@@ -0,0 +1,120 @@
+// Scintilla source code edit control
+/** @file PerLine.h
+ ** Manages data associated with each line of the document
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef PERLINE_H
+#define PERLINE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+       
+/**
+ * This holds the marker identifier and the marker type to display.
+ * MarkerHandleNumbers are members of lists.
+ */
+struct MarkerHandleNumber {
+       int handle;
+       int number;
+       MarkerHandleNumber *next;
+};
+
+/**
+ * A marker handle set contains any number of MarkerHandleNumbers.
+ */
+class MarkerHandleSet {
+       MarkerHandleNumber *root;
+
+public:
+       MarkerHandleSet();
+       ~MarkerHandleSet();
+       int Length() const;
+       int NumberFromHandle(int handle) const;
+       int MarkValue() const;  ///< Bit set of marker numbers.
+       bool Contains(int handle) const;
+       bool InsertHandle(int handle, int markerNum);
+       void RemoveHandle(int handle);
+       bool RemoveNumber(int markerNum);
+       void CombineWith(MarkerHandleSet *other);
+};
+
+class LineMarkers : public PerLine {
+       SplitVector<MarkerHandleSet *> markers;
+       /// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big.
+       int handleCurrent;
+public:
+       LineMarkers() : handleCurrent(0) {
+       }
+       virtual ~LineMarkers();
+       virtual void Init();
+       virtual void InsertLine(int line);
+       virtual void RemoveLine(int line);
+
+       int MarkValue(int line);
+       int AddMark(int line, int marker, int lines);
+       void MergeMarkers(int pos);
+       void DeleteMark(int line, int markerNum, bool all);
+       void DeleteMarkFromHandle(int markerHandle);
+       int LineFromHandle(int markerHandle);
+};
+
+class LineLevels : public PerLine {
+       SplitVector<int> levels;
+public:
+       virtual ~LineLevels();
+       virtual void Init();
+       virtual void InsertLine(int line);
+       virtual void RemoveLine(int line);
+
+       void ExpandLevels(int sizeNew=-1);
+       void ClearLevels();
+       int SetLevel(int line, int level, int lines);
+       int GetLevel(int line);
+};
+
+class LineState : public PerLine {
+       SplitVector<int> lineStates;
+public:
+       LineState() {
+       }
+       virtual ~LineState();
+       virtual void Init();
+       virtual void InsertLine(int line);
+       virtual void RemoveLine(int line);
+
+       int SetLineState(int line, int state);
+       int GetLineState(int line);
+       int GetMaxLineState();
+};
+
+class LineAnnotation : public PerLine {
+       SplitVector<char *> annotations;
+public:
+       LineAnnotation() {
+       }
+       virtual ~LineAnnotation();
+       virtual void Init();
+       virtual void InsertLine(int line);
+       virtual void RemoveLine(int line);
+
+       bool AnySet() const;
+       bool MultipleStyles(int line) const;
+       int Style(int line);
+       const char *Text(int line) const;
+       const unsigned char *Styles(int line) const;
+       void SetText(int line, const char *text);
+       void ClearAll();
+       void SetStyle(int line, int style);
+       void SetStyles(int line, const unsigned char *styles);
+       int Length(int line) const;
+       int Lines(int line) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
index f40a153789183a801a19e34e789e1e750662b3de..1d0bef93c5532d1da2e510f711c14d4da8adf527 100644 (file)
@@ -28,6 +28,7 @@
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 
 #ifdef SCI_NAMESPACE
@@ -46,11 +47,11 @@ LineLayout::LineLayout(int maxLineLength_) :
        inCache(false),
        maxLineLength(-1),
        numCharsInLine(0),
+       numCharsBeforeEOL(0),
        validity(llInvalid),
        xHighlightGuide(0),
        highlightColumn(0),
-       selStart(0),
-       selEnd(0),
+       psel(NULL),
        containsCaret(false),
        edgeColumn(0),
        chars(0),
@@ -61,7 +62,8 @@ LineLayout::LineLayout(int maxLineLength_) :
        hsStart(0),
        hsEnd(0),
        widthLine(wrapWidthInfinite),
-       lines(1) {
+       lines(1),
+       wrapIndent(0) {
        Resize(maxLineLength_);
 }
 
@@ -114,28 +116,21 @@ int LineLayout::LineLastVisible(int line) const {
        if (line < 0) {
                return 0;
        } else if ((line >= lines-1) || !lineStarts) {
-               int startLine = LineStart(line);
-               int endLine = numCharsInLine;
-               while ((endLine > startLine) && IsEOLChar(chars[endLine-1])) {
-                       endLine--;
-               }
-               return endLine;
+               return numCharsBeforeEOL;
        } else {
                return lineStarts[line+1];
        }
 }
 
 bool LineLayout::InLine(int offset, int line) const {
-       return ((offset >= LineStart(line)) && (offset < LineStart(line + 1)) ||
-               ((offset == numCharsInLine) && (line == (lines-1))));
+       return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) ||
+               ((offset == numCharsInLine) && (line == (lines-1)));
 }
 
 void LineLayout::SetLineStart(int line, int start) {
        if ((line >= lenLineStarts) && (line != 0)) {
                int newMaxLines = line + 20;
                int *newLineStarts = new int[newMaxLines];
-               if (!newLineStarts)
-                       return;
                for (int i = 0; i < newMaxLines; i++) {
                        if (i < lenLineStarts)
                                newLineStarts[i] = lineStarts[i];
@@ -200,6 +195,10 @@ int LineLayout::FindBefore(int x, int lower, int upper) const {
        return lower;
 }
 
+int LineLayout::EndLineStyle() const {
+       return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
+}
+
 LineLayoutCache::LineLayoutCache() :
        level(0), length(0), size(0), cache(0),
        allInvalidated(false), styleClock(-1), useCount(0) {
@@ -385,7 +384,7 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
        return -1;
 }
 
-BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart) :
+BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
        ll(ll_),
        lineStart(lineStart_),
        lineEnd(lineEnd_),
@@ -411,9 +410,19 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
                nextBreak--;
        }
 
-       if (ll->selStart != ll->selEnd) {
-               Insert(ll->selStart - posLineStart - 1);
-               Insert(ll->selEnd - posLineStart - 1);
+       if (breakForSelection) {
+               SelectionPosition posStart(posLineStart);
+               SelectionPosition posEnd(posLineStart + lineEnd);
+               SelectionSegment segmentLine(posStart, posEnd);
+               for (size_t r=0; r<ll->psel->Count(); r++) {
+                       SelectionSegment portion = ll->psel->Range(r).Intersect(segmentLine);
+                       if (!(portion.start == portion.end)) {
+                               if (portion.start.IsValid())
+                                       Insert(portion.start.Position() - posLineStart - 1);
+                               if (portion.end.IsValid())
+                                       Insert(portion.end.Position() - posLineStart - 1);
+                       }
+               }
        }
 
        Insert(ll->edgeColumn - 1);
@@ -440,6 +449,10 @@ int BreakFinder::First() {
        return nextBreak;
 }
 
+static bool IsTrailByte(int ch) {
+       return (ch >= 0x80) && (ch < (0x80 + 0x40));
+}
+
 int BreakFinder::Next() {
        if (subBreak == -1) {
                int prev = nextBreak;
@@ -472,15 +485,20 @@ int BreakFinder::Next() {
        } else {
                int lastGoodBreak = -1;
                int lastOKBreak = -1;
+               int lastUTF8Break = -1;
                int j;
                for (j = subBreak + 1; j <= nextBreak; j++) {
                        if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
                                lastGoodBreak = j;
                        }
-                       if (ll->chars[j] < 'A') {
+                       if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
                                lastOKBreak = j;
                        }
-                       if (((j - subBreak) >= lengthEachSubdivision) && ((lastGoodBreak >= 0) || (lastOKBreak >= 0))) {
+                       if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
+                               lastUTF8Break = j;
+                       }
+                       if (((j - subBreak) >= lengthEachSubdivision) &&
+                               ((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
                                break;
                        }
                }
@@ -488,6 +506,8 @@ int BreakFinder::Next() {
                        subBreak = lastGoodBreak;
                } else if (lastOKBreak >= 0) {
                        subBreak = lastOKBreak;
+               } else if (lastUTF8Break >= 0) {
+                       subBreak = lastUTF8Break;
                } else {
                        subBreak = nextBreak;
                }
index 5d486cb60194b458b89d51a6ad4b488a3adda2fb..e99ae587077738abb69be3cefab262be54f27fed 100644 (file)
@@ -2,7 +2,7 @@
 /** @file PositionCache.h
  ** Classes for caching layout information.
  **/
-// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef POSITIONCACHE_H
@@ -30,11 +30,11 @@ public:
        enum { wrapWidthInfinite = 0x7ffffff };
        int maxLineLength;
        int numCharsInLine;
+       int numCharsBeforeEOL;
        enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity;
        int xHighlightGuide;
        bool highlightColumn;
-       int selStart;
-       int selEnd;
+       Selection *psel;
        bool containsCaret;
        int edgeColumn;
        char *chars;
@@ -51,6 +51,7 @@ public:
        // Wrapped line support
        int widthLine;
        int lines;
+       int wrapIndent; // In pixels
 
        LineLayout(int maxLineLength_);
        virtual ~LineLayout();
@@ -65,6 +66,7 @@ public:
                char bracesMatchStyle, int xHighlight);
        void RestoreBracesHighlight(Range rangeLine, Position braces[]);
        int FindBefore(int x, int lower, int upper) const;
+       int EndLineStyle() const;
 };
 
 /**
@@ -134,7 +136,7 @@ class BreakFinder {
        int subBreak;
        void Insert(int val);
 public:
-       BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart);
+       BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
        ~BreakFinder();
        int First();
        int Next();
index a1c366c3be4e7b2c14a018af19e6e162f6bab2fd..9936c39d12779879f0ae737f8e959b74f3b9e308 100644 (file)
 #include <string.h>
 #include <stdio.h>
 
+#ifdef _MSC_VER
+// Visual C++ doesn't like unreachable code or long decorated names in its own headers.
+#pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702 4786)
+#endif
+
+#include <string>
+#include <map>
+
 #include "Platform.h"
 
 #include "PropSet.h"
+#include "PropSetSimple.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-// The comparison and case changing functions here assume ASCII
-// or extended ASCII such as the normal Windows code page.
-
-static inline char MakeUpperCase(char ch) {
-       if (ch < 'a' || ch > 'z')
-               return ch;
-       else
-               return static_cast<char>(ch - 'a' + 'A');
-}
-
-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) {
-                       char upperA = MakeUpperCase(*a);
-                       char upperB = MakeUpperCase(*b);
-                       if (upperA != upperB)
-                               return upperA - upperB;
-               }
-               a++;
-               b++;
-       }
-       // Either *a or *b is nul
-       return *a - *b;
-}
-
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
-       while (*a && *b && len) {
-               if (*a != *b) {
-                       char upperA = MakeUpperCase(*a);
-                       char upperB = MakeUpperCase(*b);
-                       if (upperA != upperB)
-                               return upperA - upperB;
-               }
-               a++;
-               b++;
-               len--;
-       }
-       if (len == 0)
-               return 0;
-       else
-               // Either *a or *b is nul
-               return *a - *b;
-}
-
-bool EqualCaseInsensitive(const char *a, const char *b) {
-       return 0 == CompareCaseInsensitive(a, b);
-}
-
-// Since the CaseInsensitive functions declared in SString
-// are implemented here, I will for now put the non-inline
-// implementations of the SString members here as well, so
-// that I can quickly see what effect this has.
-
-SString::SString(int i) : sizeGrowth(sizeGrowthDefault) {
-       char number[32];
-       sprintf(number, "%0d", i);
-       s = StringAllocate(number);
-       sSize = sLen = (s) ? strlen(s) : 0;
-}
-
-SString::SString(double d, int precision) : sizeGrowth(sizeGrowthDefault) {
-       char number[32];
-       sprintf(number, "%.*f", precision, d);
-       s = StringAllocate(number);
-       sSize = sLen = (s) ? strlen(s) : 0;
-}
-
-bool SString::grow(lenpos_t lenNew) {
-       while (sizeGrowth * 6 < lenNew) {
-               sizeGrowth *= 2;
-       }
-       char *sNew = new char[lenNew + sizeGrowth + 1];
-       if (sNew) {
-               if (s) {
-                       memcpy(sNew, s, sLen);
-                       delete []s;
-               }
-               s = sNew;
-               s[sLen] = '\0';
-               sSize = lenNew + sizeGrowth;
-       }
-       return sNew != 0;
-}
-
-SString &SString::assign(const char *sOther, lenpos_t sSize_) {
-       if (!sOther) {
-               sSize_ = 0;
-       } else if (sSize_ == measure_length) {
-               sSize_ = strlen(sOther);
-       }
-       if (sSize > 0 && sSize_ <= sSize) {     // Does not allocate new buffer if the current is big enough
-               if (s && sSize_) {
-                       memcpy(s, sOther, sSize_);
-               }
-               s[sSize_] = '\0';
-               sLen = sSize_;
-       } else {
-               delete []s;
-               s = StringAllocate(sOther, sSize_);
-               if (s) {
-                       sSize = sSize_; // Allow buffer bigger than real string, thus providing space to grow
-                       sLen = sSize_;
-               } else {
-                       sSize = sLen = 0;
-               }
-       }
-       return *this;
-}
-
-bool SString::operator==(const SString &sOther) const {
-       if ((s == 0) && (sOther.s == 0))
-               return true;
-       if ((s == 0) || (sOther.s == 0))
-               return false;
-       return strcmp(s, sOther.s) == 0;
-}
-
-bool SString::operator==(const char *sOther) const {
-       if ((s == 0) && (sOther == 0))
-               return true;
-       if ((s == 0) || (sOther == 0))
-               return false;
-       return strcmp(s, sOther) == 0;
-}
-
-SString SString::substr(lenpos_t subPos, lenpos_t subLen) const {
-       if (subPos >= sLen) {
-               return SString();                                       // return a null string if start index is out of bounds
-       }
-       if ((subLen == measure_length) || (subPos + subLen > sLen)) {
-               subLen = sLen - subPos;         // can't substr past end of source string
-       }
-       return SString(s, subPos, subPos + subLen);
-}
+typedef std::map<std::string, std::string> mapss;
 
-SString &SString::lowercase(lenpos_t subPos, lenpos_t subLen) {
-       if ((subLen == measure_length) || (subPos + subLen > sLen)) {
-               subLen = sLen - subPos;         // don't apply past end of string
-       }
-       for (lenpos_t i = subPos; i < subPos + subLen; i++) {
-               if (s[i] < 'A' || s[i] > 'Z')
-                       continue;
-               else
-                       s[i] = static_cast<char>(s[i] - 'A' + 'a');
-       }
-       return *this;
+PropSetSimple::PropSetSimple() {
+       mapss *props = new mapss;
+       impl = static_cast<void *>(props);
 }
 
-SString &SString::uppercase(lenpos_t subPos, lenpos_t subLen) {
-       if ((subLen == measure_length) || (subPos + subLen > sLen)) {
-               subLen = sLen - subPos;         // don't apply past end of string
-       }
-       for (lenpos_t i = subPos; i < subPos + subLen; i++) {
-               if (s[i] < 'a' || s[i] > 'z')
-                       continue;
-               else
-                       s[i] = static_cast<char>(s[i] - 'a' + 'A');
-       }
-       return *this;
-}
-
-SString &SString::append(const char *sOther, lenpos_t sLenOther, char sep) {
-       if (!sOther) {
-               return *this;
-       }
-       if (sLenOther == measure_length) {
-               sLenOther = strlen(sOther);
-       }
-       int lenSep = 0;
-       if (sLen && sep) {      // Only add a separator if not empty
-               lenSep = 1;
-       }
-       lenpos_t lenNew = sLen + sLenOther + lenSep;
-       // Conservative about growing the buffer: don't do it, unless really needed
-       if ((lenNew < sSize) || (grow(lenNew))) {
-               if (lenSep) {
-                       s[sLen] = sep;
-                       sLen++;
-               }
-               memcpy(&s[sLen], sOther, sLenOther);
-               sLen += sLenOther;
-               s[sLen] = '\0';
-       }
-       return *this;
-}
-
-SString &SString::insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther) {
-       if (!sOther || pos > sLen) {
-               return *this;
-       }
-       if (sLenOther == measure_length) {
-               sLenOther = strlen(sOther);
-       }
-       lenpos_t lenNew = sLen + sLenOther;
-       // Conservative about growing the buffer: don't do it, unless really needed
-       if ((lenNew < sSize) || grow(lenNew)) {
-               lenpos_t moveChars = sLen - pos + 1;
-               for (lenpos_t i = moveChars; i > 0; i--) {
-                       s[pos + sLenOther + i - 1] = s[pos + i - 1];
-               }
-               memcpy(s + pos, sOther, sLenOther);
-               sLen = lenNew;
-       }
-       return *this;
+PropSetSimple::~PropSetSimple() {
+       mapss *props = static_cast<mapss *>(impl);
+       delete props;
+       impl = 0;
 }
 
-/**
- * Remove @a len characters from the @a pos position, included.
- * Characters at pos + len and beyond replace characters at pos.
- * If @a len is 0, or greater than the length of the string
- * starting at @a pos, the string is just truncated at @a pos.
- */
-void SString::remove(lenpos_t pos, lenpos_t len) {
-       if (pos >= sLen) {
-               return;
-       }
-       if (len < 1 || pos + len >= sLen) {
-               s[pos] = '\0';
-               sLen = pos;
-       } else {
-               for (lenpos_t i = pos; i < sLen - len + 1; i++) {
-                       s[i] = s[i+len];
-               }
-               sLen -= len;
-       }
-}
-
-bool SString::startswith(const char *prefix) {
-       lenpos_t lenPrefix = strlen(prefix);
-       if (lenPrefix > sLen) {
-               return false;
-       }
-       return strncmp(s, prefix, lenPrefix) == 0;
-}
-
-bool SString::endswith(const char *suffix) {
-       lenpos_t lenSuffix = strlen(suffix);
-       if (lenSuffix > sLen) {
-               return false;
-       }
-       return strncmp(s + sLen - lenSuffix, suffix, lenSuffix) == 0;
-}
-
-int SString::search(const char *sFind, lenpos_t start) const {
-       if (start < sLen) {
-               const char *sFound = strstr(s + start, sFind);
-               if (sFound) {
-                       return sFound - s;
-               }
-       }
-       return -1;
-}
-
-int SString::substitute(char chFind, char chReplace) {
-       int c = 0;
-       char *t = s;
-       while (t) {
-               t = strchr(t, chFind);
-               if (t) {
-                       *t = chReplace;
-                       t++;
-                       c++;
-               }
-       }
-       return c;
-}
-
-int SString::substitute(const char *sFind, const char *sReplace) {
-       int c = 0;
-       lenpos_t lenFind = strlen(sFind);
-       lenpos_t lenReplace = strlen(sReplace);
-       int posFound = search(sFind);
-       while (posFound >= 0) {
-               remove(posFound, lenFind);
-               insert(posFound, sReplace, lenReplace);
-               posFound = search(sFind, posFound + lenReplace);
-               c++;
-       }
-       return c;
-}
-
-char *SContainer::StringAllocate(lenpos_t len) {
-       if (len != measure_length) {
-               return new char[len + 1];
-       } else {
-               return 0;
-       }
-}
-
-char *SContainer::StringAllocate(const char *s, lenpos_t len) {
-       if (s == 0) {
-               return 0;
-       }
-       if (len == measure_length) {
-               len = strlen(s);
-       }
-       char *sNew = new char[len + 1];
-       if (sNew) {
-               memcpy(sNew, s, len);
-               sNew[len] = '\0';
-       }
-       return sNew;
-}
-
-// End SString functions
-
-PropSet::PropSet() {
-       superPS = 0;
-       for (int root = 0; root < hashRoots; root++)
-               props[root] = 0;
-}
-
-PropSet::~PropSet() {
-       superPS = 0;
-       Clear();
-}
-
-void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
+void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
+       mapss *props = static_cast<mapss *>(impl);
        if (!*key)      // Empty keys are not supported
                return;
        if (lenKey == -1)
                lenKey = static_cast<int>(strlen(key));
        if (lenVal == -1)
                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)) &&
-                               (0 == strncmp(p->key, key, lenKey)))) {
-                       // Replace current value
-                       delete [](p->val);
-                       p->val = StringDup(val, lenVal);
-                       return;
-               }
-       }
-       // Not found
-       Property *pNew = new Property;
-       if (pNew) {
-               pNew->hash = hash;
-               pNew->key = StringDup(key, lenKey);
-               pNew->val = StringDup(val, lenVal);
-               pNew->next = props[hash % hashRoots];
-               props[hash % hashRoots] = pNew;
-       }
+       (*props)[std::string(key, lenKey)] = std::string(val, lenVal);
 }
 
-void PropSet::Set(const char *keyVal) {
-       while (IsASpace(*keyVal))
+static bool IsASpaceCharacter(unsigned int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+void PropSetSimple::Set(const char *keyVal) {
+       while (IsASpaceCharacter(*keyVal))
                keyVal++;
        const char *endVal = keyVal;
        while (*endVal && (*endVal != '\n'))
@@ -387,34 +70,7 @@ void PropSet::Set(const char *keyVal) {
        }
 }
 
-void PropSet::Unset(const char *key, int lenKey) {
-       if (!*key)      // Empty keys are not supported
-               return;
-       if (lenKey == -1)
-               lenKey = static_cast<int>(strlen(key));
-       unsigned int hash = HashString(key, lenKey);
-       Property *pPrev = NULL;
-       for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-               if ((hash == p->hash) &&
-                       ((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
-                               (0 == strncmp(p->key, key, lenKey)))) {
-                       if (pPrev)
-                               pPrev->next = p->next;
-                       else
-                               props[hash % hashRoots] = p->next;
-                       if (p == enumnext)
-                               enumnext = p->next; // Not that anyone should mix enum and Set / Unset.
-                       delete [](p->key);
-                       delete [](p->val);
-                       delete p;
-                       return;
-               } else {
-                       pPrev = p;
-               }
-       }
-}
-
-void PropSet::SetMultiple(const char *s) {
+void PropSetSimple::SetMultiple(const char *s) {
        const char *eol = strchr(s, '\n');
        while (eol) {
                Set(s);
@@ -424,16 +80,11 @@ void PropSet::SetMultiple(const char *s) {
        Set(s);
 }
 
-SString PropSet::Get(const char *key) const {
-       unsigned int hash = HashString(key, strlen(key));
-       for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-               if ((hash == p->hash) && (0 == strcmp(p->key, key))) {
-                       return p->val;
-               }
-       }
-       if (superPS) {
-               // Failed here, so try in base property set
-               return superPS->Get(key);
+const char *PropSetSimple::Get(const char *key) const {
+       mapss *props = static_cast<mapss *>(impl);
+       mapss::const_iterator keyPos = props->find(std::string(key));
+       if (keyPos != props->end()) {
+               return keyPos->second.c_str();
        } else {
                return "";
        }
@@ -456,300 +107,70 @@ struct VarChain {
        const VarChain *link;
 };
 
-static int ExpandAllInPlace(const PropSet &props, SString &withVars, int maxExpands, const VarChain &blankVars = VarChain()) {
-       int varStart = withVars.search("$(");
-       while ((varStart >= 0) && (maxExpands > 0)) {
-               int varEnd = withVars.search(")", varStart+2);
-               if (varEnd < 0) {
+static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
+       size_t varStart = withVars.find("$(");
+       while ((varStart != std::string::npos) && (maxExpands > 0)) {
+               size_t varEnd = withVars.find(")", varStart+2);
+               if (varEnd == std::string::npos) {
                        break;
                }
 
                // For consistency, when we see '$(ab$(cde))', expand the inner variable first,
                // regardless whether there is actually a degenerate variable named 'ab$(cde'.
-               int innerVarStart = withVars.search("$(", varStart+2);
-               while ((innerVarStart > varStart) && (innerVarStart < varEnd)) {
+               size_t innerVarStart = withVars.find("$(", varStart+2);
+               while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
                        varStart = innerVarStart;
-                       innerVarStart = withVars.search("$(", varStart+2);
+                       innerVarStart = withVars.find("$(", varStart+2);
                }
 
-               SString var(withVars.c_str(), varStart + 2, varEnd);
-               SString val = props.Get(var.c_str());
+               std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
+               std::string val = props.Get(var.c_str());
 
                if (blankVars.contains(var.c_str())) {
-                       val.clear(); // treat blankVar as an empty string (e.g. to block self-reference)
+                       val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
                }
 
                if (--maxExpands >= 0) {
                        maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
                }
 
-               withVars.remove(varStart, varEnd-varStart+1);
+               withVars.erase(varStart, varEnd-varStart+1);
                withVars.insert(varStart, val.c_str(), val.length());
 
-               varStart = withVars.search("$(");
+               varStart = withVars.find("$(");
        }
 
        return maxExpands;
 }
 
-SString PropSet::GetExpanded(const char *key) const {
-       SString val = Get(key);
+char *PropSetSimple::Expanded(const char *key) const {
+       std::string val = Get(key);
        ExpandAllInPlace(*this, val, 100, VarChain(key));
-       return val;
-}
-
-SString PropSet::Expand(const char *withVars, int maxExpands) const {
-       SString val = withVars;
-       ExpandAllInPlace(*this, val, maxExpands);
-       return val;
-}
-
-int PropSet::GetInt(const char *key, int defaultValue) const {
-       SString val = GetExpanded(key);
-       if (val.length())
-               return val.value();
-       return defaultValue;
-}
-
-bool isprefix(const char *target, const char *prefix) {
-       while (*target && *prefix) {
-               if (*target != *prefix)
-                       return false;
-               target++;
-               prefix++;
-       }
-       if (*prefix)
-               return false;
-       else
-               return true;
-}
-
-void PropSet::Clear() {
-       for (int root = 0; root < hashRoots; root++) {
-               Property *p = props[root];
-               while (p) {
-                       Property *pNext = p->next;
-                       p->hash = 0;
-                       delete []p->key;
-                       p->key = 0;
-                       delete []p->val;
-                       p->val = 0;
-                       delete p;
-                       p = pNext;
-               }
-               props[root] = 0;
-       }
-}
-
-char *PropSet::ToString() const {
-       size_t len=0;
-       for (int r = 0; r < hashRoots; r++) {
-               for (Property *p = props[r]; p; p = p->next) {
-                       len += strlen(p->key) + 1;
-                       len += strlen(p->val) + 1;
-               }
-       }
-       if (len == 0)
-               len = 1;        // Return as empty string
-       char *ret = new char [len];
-       if (ret) {
-               char *w = ret;
-               for (int root = 0; root < hashRoots; root++) {
-                       for (Property *p = props[root]; p; p = p->next) {
-                               strcpy(w, p->key);
-                               w += strlen(p->key);
-                               *w++ = '=';
-                               strcpy(w, p->val);
-                               w += strlen(p->val);
-                               *w++ = '\n';
-                       }
-               }
-               ret[len-1] = '\0';
-       }
+       char *ret = new char [val.size() + 1];
+       strcpy(ret, val.c_str());
        return ret;
 }
 
-/**
- * Creates an array that points into each word in the string and puts \0 terminators
- * after each word.
- */
-static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
-       int prev = '\n';
-       int words = 0;
-       // For rapid determination of whether a character is a separator, build
-       // a look up table.
-       bool wordSeparator[256];
-       for (int i=0;i<256; i++) {
-               wordSeparator[i] = false;
-       }
-       wordSeparator['\r'] = true;
-       wordSeparator['\n'] = true;
-       if (!onlyLineEnds) {
-               wordSeparator[' '] = true;
-               wordSeparator['\t'] = true;
-       }
-       for (int j = 0; wordlist[j]; j++) {
-               int curr = static_cast<unsigned char>(wordlist[j]);
-               if (!wordSeparator[curr] && wordSeparator[prev])
-                       words++;
-               prev = curr;
-       }
-       char **keywords = new char *[words + 1];
-       if (keywords) {
-               words = 0;
-               prev = '\0';
-               size_t slen = strlen(wordlist);
-               for (size_t k = 0; k < slen; k++) {
-                       if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
-                               if (!prev) {
-                                       keywords[words] = &wordlist[k];
-                                       words++;
-                               }
-                       } else {
-                               wordlist[k] = '\0';
-                       }
-                       prev = wordlist[k];
-               }
-               keywords[words] = &wordlist[slen];
-               *len = words;
-       } else {
-               *len = 0;
-       }
-       return keywords;
-}
-
-void WordList::Clear() {
-       if (words) {
-               delete []list;
-               delete []words;
-       }
-       words = 0;
-       list = 0;
-       len = 0;
-       sorted = false;
-}
-
-void WordList::Set(const char *s) {
-       list = StringDup(s);
-       sorted = false;
-       words = ArrayFromWordList(list, &len, onlyLineEnds);
-}
-
-extern "C" int cmpString(const void *a1, const void *a2) {
-       // Can't work out the correct incantation to use modern casts here
-       return strcmp(*(char**)(a1), *(char**)(a2));
-}
-
-static void SortWordList(char **words, unsigned int len) {
-       qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
-             cmpString);
-}
-
-bool WordList::InList(const char *s) {
-       if (0 == words)
-               return false;
-       if (!sorted) {
-               sorted = true;
-               SortWordList(words, len);
-               for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
-                       starts[k] = -1;
-               for (int l = len - 1; l >= 0; l--) {
-                       unsigned char indexChar = words[l][0];
-                       starts[indexChar] = l;
-               }
-       }
-       unsigned char firstChar = s[0];
-       int j = starts[firstChar];
-       if (j >= 0) {
-               while ((unsigned char)words[j][0] == firstChar) {
-                       if (s[1] == words[j][1]) {
-                               const char *a = words[j] + 1;
-                               const char *b = s + 1;
-                               while (*a && *a == *b) {
-                                       a++;
-                                       b++;
-                               }
-                               if (!*a && !*b)
-                                       return true;
-                       }
-                       j++;
-               }
-       }
-       j = starts['^'];
-       if (j >= 0) {
-               while (words[j][0] == '^') {
-                       const char *a = words[j] + 1;
-                       const char *b = s;
-                       while (*a && *a == *b) {
-                               a++;
-                               b++;
-                       }
-                       if (!*a)
-                               return true;
-                       j++;
-               }
+char *PropSetSimple::ToString() const {
+       mapss *props = static_cast<mapss *>(impl);
+       std::string sval;
+       for (mapss::const_iterator it=props->begin(); it != props->end(); it++) {
+               sval += it->first;
+               sval += "=";
+               sval += it->second;
+               sval += "\n";
        }
-       return false;
+       char *ret = new char [sval.size() + 1];
+       strcpy(ret, sval.c_str());
+       return ret;
 }
 
-/** similar to InList, but word s can be a substring of keyword.
- * eg. the keyword define is defined as def~ine. This means the word must start
- * with def to be a keyword, but also defi, defin and define are valid.
- * The marker is ~ in this case.
- */
-bool WordList::InListAbbreviated(const char *s, const char marker) {
-       if (0 == words)
-               return false;
-       if (!sorted) {
-               sorted = true;
-               SortWordList(words, len);
-               for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
-                       starts[k] = -1;
-               for (int l = len - 1; l >= 0; l--) {
-                       unsigned char indexChar = words[l][0];
-                       starts[indexChar] = l;
-               }
+int PropSetSimple::GetInt(const char *key, int defaultValue) const {
+       char *val = Expanded(key);
+       if (val) {
+               int retVal = val[0] ? atoi(val) : defaultValue;
+               delete []val;
+               return retVal;
        }
-       unsigned char firstChar = s[0];
-       int j = starts[firstChar];
-       if (j >= 0) {
-               while (words[j][0] == firstChar) {
-                       bool isSubword = false;
-                       int start = 1;
-                       if (words[j][1] == marker) {
-                               isSubword = true;
-                               start++;
-                       }
-                       if (s[1] == words[j][start]) {
-                               const char *a = words[j] + start;
-                               const char *b = s + 1;
-                               while (*a && *a == *b) {
-                                       a++;
-                                       if (*a == marker) {
-                                               isSubword = true;
-                                               a++;
-                                       }
-                                       b++;
-                               }
-                               if ((!*a || isSubword) && !*b)
-                                       return true;
-                       }
-                       j++;
-               }
-       }
-       j = starts['^'];
-       if (j >= 0) {
-               while (words[j][0] == '^') {
-                       const char *a = words[j] + 1;
-                       const char *b = s;
-                       while (*a && *a == *b) {
-                               a++;
-                               b++;
-                       }
-                       if (!*a)
-                               return true;
-                       j++;
-               }
-       }
-       return false;
+       return defaultValue;
 }
diff --git a/src/stc/scintilla/src/PropSetSimple.h b/src/stc/scintilla/src/PropSetSimple.h
new file mode 100644 (file)
index 0000000..1674cfb
--- /dev/null
@@ -0,0 +1,33 @@
+// Scintilla source code edit control
+/** @file PropSetSimple.h
+ ** A basic string to string map.
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef PROPSETSIMPLE_H
+#define PROPSETSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class PropSetSimple : public PropertyGet {
+       void *impl;
+       void Set(const char *keyVal);
+public:
+       PropSetSimple();
+       virtual ~PropSetSimple();
+       void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
+       void SetMultiple(const char *);
+       const char *Get(const char *key) const;
+       char *Expanded(const char *key) const;
+       char *ToString() const;
+       int GetInt(const char *key, int defaultValue=0) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
index b1b226a05c3a887b02173f64c87e43270d115514..0c400450eb80f42216c11d07c2e5f611ad1006f3 100644 (file)
@@ -33,7 +33,7 @@
  * Interfaces:
  *  RESearch::Compile:      compile a regular expression into a NFA.
  *
- *          const char *RESearch::Compile(const char *pat, int length,
+ *          const char *RESearch::Compile(const char *pattern, int length,
  *                                        bool caseSensitive, bool posix)
  *
  * Returns a short error string if they fail.
  *  matches:    foo-foo fo-fo fob-fob foobar-foobar ...
  */
 
+#include <stdlib.h>
+
 #include "CharClassify.h"
 #include "RESearch.h"
 
@@ -347,13 +349,13 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) {
 /**
  * Called when the parser finds a backslash not followed
  * by a valid expression (like \( in non-Posix mode).
- * @param pat: pointer on the char after the backslash.
+ * @param pattern: pointer on the char after the backslash.
  * @param incr: (out) number of chars to skip after expression evaluation.
  * @return the char if it resolves to a simple char,
  * or -1 for a char class. In this case, bittab is changed.
  */
 int RESearch::GetBackslashExpression(
-               const char *pat,
+               const char *pattern,
                int &incr) {
        // Since error reporting is primitive and messages are not used anyway,
        // I choose to interpret unexpected syntax in a logical way instead
@@ -361,7 +363,7 @@ int RESearch::GetBackslashExpression(
        incr = 0;       // Most of the time, will skip the char "naturally".
        int c;
        int result = -1;
-       unsigned char bsc = *pat;
+       unsigned char bsc = *pattern;
        if (!bsc) {
                // Avoid overrun
                result = '\\';  // \ at end of pattern, take it literally
@@ -379,8 +381,8 @@ int RESearch::GetBackslashExpression(
                result = escapeValue(bsc);
                break;
        case 'x': {
-                       unsigned char hd1 = *(pat + 1);
-                       unsigned char hd2 = *(pat + 2);
+                       unsigned char hd1 = *(pattern + 1);
+                       unsigned char hd2 = *(pattern + 2);
                        int hexValue = GetHexaChar(hd1, hd2);
                        if (hexValue >= 0) {
                                result = hexValue;
@@ -416,6 +418,7 @@ int RESearch::GetBackslashExpression(
                                ChSet(static_cast<unsigned char>(c));
                        }
                }
+               break;
        case 'w':
                for (c = 0; c < MAXCHR; c++) {
                        if (iswordc(static_cast<unsigned char>(c))) {
@@ -436,7 +439,7 @@ int RESearch::GetBackslashExpression(
        return result;
 }
 
-const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) {
+const char *RESearch::Compile(const char *pattern, int length, bool caseSensitive, bool posix) {
        char *mp=nfa;          /* nfa pointer       */
        char *lp;              /* saved pointer     */
        char *sp=nfa;          /* another one       */
@@ -449,14 +452,15 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
        char mask;             /* xor mask -CCL/NCL */
        int c1, c2, prevChar;
 
-       if (!pat || !length)
+       if (!pattern || !length) {
                if (sta)
                        return 0;
                else
                        return badpat("No previous regular expression");
+       }
        sta = NOP;
 
-       const char *p=pat;     /* pattern pointer   */
+       const char *p=pattern;     /* pattern pointer   */
        for (int i=0; i<length; i++, p++) {
                if (mp > mpMax)
                        return badpat("Pattern too long");
@@ -468,7 +472,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
                        break;
 
                case '^':               /* match beginning */
-                       if (p == pat)
+                       if (p == pattern)
                                *mp++ = BOL;
                        else {
                                *mp++ = CHR;
@@ -588,7 +592,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, b
 
                case '*':               /* match 0 or more... */
                case '+':               /* match 1 or more... */
-                       if (p == pat)
+                       if (p == pattern)
                                return badpat("Empty closure");
                        lp = sp;                /* previous opcode */
                        if (*lp == CLO)         /* equivalence... */
@@ -853,6 +857,8 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
                                return NOTFOUND;
                        break;
                case CCL:
+                       if (lp >= endp)
+                               return NOTFOUND;
                        c = ci.CharAt(lp++);
                        if (!isinset(ap,c))
                                return NOTFOUND;
@@ -873,7 +879,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
                        eopat[*ap++] = lp;
                        break;
                case BOW:
-                       if (lp!=bol && iswordc(ci.CharAt(lp-1)) || !iswordc(ci.CharAt(lp)))
+                       if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))
                                return NOTFOUND;
                        break;
                case EOW:
index 0944fc398ccb44ceae4c46c62d25b5096eecb14d..ef8c3e11b2ddac9afbc8bc5f2f1d68f2ee77e62e 100644 (file)
@@ -34,7 +34,7 @@ public:
        RESearch(CharClassify *charClassTable);
        ~RESearch();
        bool GrabMatches(CharacterIndexer &ci);
-       const char *Compile(const char *pat, int length, bool caseSensitive, bool posix);
+       const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix);
        int Execute(CharacterIndexer &ci, int lp, int endp);
        int Substitute(CharacterIndexer &ci, char *src, char *dst);
 
@@ -51,7 +51,7 @@ private:
        void Clear();
        void ChSet(unsigned char c);
        void ChSetWithCase(unsigned char c, bool caseSensitive);
-       int GetBackslashExpression(const char *pat, int &incr);
+       int GetBackslashExpression(const char *pattern, int &incr);
 
        int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap);
 
index dfff75412a863265a84abde304b53f1dd31cf294..ae32c7380de8de8d4711eaea61c9ee32677508fc 100644 (file)
@@ -77,11 +77,11 @@ RunStyles::~RunStyles() {
        styles = NULL;
 }
 
-int RunStyles::Length() {
+int RunStyles::Length() const {
        return starts->PositionFromPartition(starts->Partitions());
 }
 
-int RunStyles::ValueAt(int position) {
+int RunStyles::ValueAt(int position) const {
        return styles->ValueAt(starts->PartitionFromPosition(position));
 }
 
index bbf20b26245330a0ededb2aa7d3d946de3c083e0..0a333ca2aa39dc854bfc68655859f4caa8ae564a 100644 (file)
@@ -7,6 +7,9 @@
 /// Styling buffer using one element for each run rather than using
 /// a filled buffer.
 
+#ifndef RUNSTYLES_H
+#define RUNSTYLES_H
+
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
@@ -23,8 +26,8 @@ public:
 public:
        RunStyles();
        ~RunStyles();
-       int Length();
-       int ValueAt(int position);
+       int Length() const;
+       int ValueAt(int position) const;
        int FindNextChange(int position, int end);
        int StartRun(int position);
        int EndRun(int position);
@@ -39,3 +42,5 @@ public:
 #ifdef SCI_NAMESPACE
 }
 #endif
+
+#endif
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7b929190d5cdd70ea45ace95825d9d678d4f1d61 100644 (file)
@@ -0,0 +1,123 @@
+// Scintilla source code edit control
+/** @file SVector.h
+ ** A simple expandable vector.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh@hare.net.au>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SVECTOR_H
+#define SVECTOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+/**
+ * A simple expandable integer vector.
+ * Storage not allocated for elements until an element is used.
+ * This makes it very lightweight unless used so is a good match for optional features.
+ */
+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
+       
+       /** Internally allocate more elements than the user wants
+        * to avoid thrashing the memory allocator. */
+       void SizeTo(int newSize) {
+               if (newSize < allocSize)
+                       newSize += allocSize;
+               else 
+                       newSize = (newSize * 3) / 2;
+               int* newv = new int[newSize];
+               size = newSize;
+        unsigned int i=0;
+               for (; i<len; i++) {
+                       newv[i] = v[i];
+               }
+               for (; i<size; i++) {
+                       newv[i] = 0;
+               }
+               delete []v;
+               v = newv;
+       }
+       
+public:
+       SVector() {
+               v = 0;
+               len = 0;
+               size = 0;
+       }
+       ~SVector() {
+               Free();
+       }
+       /// Constructor from another vector.
+       SVector(const SVector &other) {
+               v = 0;
+               len = 0;
+               size = 0;
+               if (other.Length() > 0) {
+                       SizeTo(other.Length());
+                       for (int i=0;i<other.Length();i++)
+                               v[i] = other.v[i];
+                       len = other.Length();
+               }
+       }
+       /// Copy constructor.
+       SVector &operator=(const SVector &other) {
+               if (this != &other) {
+                       delete []v;
+                       v = 0;
+                       len = 0;
+                       size = 0;
+                       if (other.Length() > 0) {
+                               SizeTo(other.Length());
+                               for (int i=0;i<other.Length();i++)
+                                       v[i] = other.v[i];
+                               len = other.Length();
+                       }
+               }
+               return *this;
+       }
+       /** @brief Accessor.
+        * Allows to access values from the list, and grows it if accessing
+        * outside the current bounds. The returned value in this case is 0. */
+       int &operator[](unsigned int i) {
+               if (i >= len) {
+                       if (i >= size) {
+                               SizeTo(i);
+                       }
+                       len = i+1;
+               }
+               return v[i];
+       }
+       /// Reset vector.
+       void Free() {
+               delete []v;
+               v = 0;
+               size = 0;
+               len = 0;
+       }
+       /** @brief Grow vector size.
+        * Doesn't allow a vector to be shrinked. */
+       void SetLength(unsigned int newLength) {
+               if (newLength > len) {
+                       if (newLength >= size) {
+                               SizeTo(newLength);
+                       }
+               }
+               len = newLength;
+       }
+       /// Get the current length (number of used elements) of the vector.
+       int Length() const {
+               return len;
+       }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
index 679cc1d1fb0f1f9a693a324ae803916b5d5e47fa..cae6cff15c6ead00a0250ae2864eb1fc0a0843d8 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "Scintilla.h"
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
 #include "Accessor.h"
@@ -36,6 +37,7 @@
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 #include "Editor.h"
 #include "ScintillaBase.h"
@@ -173,7 +175,7 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
                        return 0;
 
                default:
-                       ac.Cancel();
+                       AutoCompleteCancel();
                }
        }
 
@@ -190,7 +192,7 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
                        ct.CallTipCancel();
                }
                if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
-                       if (currentPos <= ct.posStartCallTip) {
+                       if (sel.MainCaret() <= ct.posStartCallTip) {
                                ct.CallTipCancel();
                        }
                }
@@ -212,24 +214,24 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
                        const char *typeSep = strchr(list, ac.GetTypesep());
                        size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
                        if (ac.ignoreCase) {
-                               SetEmptySelection(currentPos - lenEntered);
-                               pdoc->DeleteChars(currentPos, lenEntered);
-                               SetEmptySelection(currentPos);
-                               pdoc->InsertString(currentPos, list, lenInsert);
-                               SetEmptySelection(currentPos + lenInsert);
+                               SetEmptySelection(sel.MainCaret() - lenEntered);
+                               pdoc->DeleteChars(sel.MainCaret(), lenEntered);
+                               SetEmptySelection(sel.MainCaret());
+                               pdoc->InsertString(sel.MainCaret(), list, lenInsert);
+                               SetEmptySelection(sel.MainCaret() + lenInsert);
                        } else {
-                               SetEmptySelection(currentPos);
-                               pdoc->InsertString(currentPos, list + lenEntered, lenInsert - lenEntered);
-                               SetEmptySelection(currentPos + lenInsert - lenEntered);
+                               SetEmptySelection(sel.MainCaret());
+                               pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert - lenEntered);
+                               SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered);
                        }
                        return;
                }
        }
-       ac.Start(wMain, idAutoComplete, currentPos, LocationFromPosition(currentPos),
+       ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
                                lenEntered, vs.lineHeight, IsUnicodeMode());
 
        PRectangle rcClient = GetClientRectangle();
-       Point pt = LocationFromPosition(currentPos - lenEntered);
+       Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
        PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
        if (rcPopupBounds.Height() == 0)
                rcPopupBounds = rcClient;
@@ -239,7 +241,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
        if (pt.x >= rcClient.right - widthLB) {
                HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB);
                Redraw();
-               pt = LocationFromPosition(currentPos);
+               pt = PointMainCaret();
        }
        PRectangle rcac;
        rcac.left = pt.x - ac.lb->CaretFromEdge();
@@ -287,6 +289,13 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
 }
 
 void ScintillaBase::AutoCompleteCancel() {
+       if (ac.Active()) {
+               SCNotification scn = {0};
+               scn.nmhdr.code = SCN_AUTOCCANCELLED;
+               scn.wParam = 0;
+               scn.listType = 0;
+               NotifyParent(scn);
+       }
        ac.Cancel();
 }
 
@@ -298,7 +307,7 @@ void ScintillaBase::AutoCompleteMoveToCurrentWord() {
        char wordCurrent[1000];
        int i;
        int startWord = ac.posStart - ac.startLen;
-       for (i = startWord; i < currentPos && i - startWord < 1000; i++)
+       for (i = startWord; i < sel.MainCaret() && i - startWord < 1000; i++)
                wordCurrent[i - startWord] = pdoc->CharAt(i);
        wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0';
        ac.Select(wordCurrent);
@@ -308,20 +317,25 @@ void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
        if (ac.IsFillUpChar(ch)) {
                AutoCompleteCompleted();
        } else if (ac.IsStopChar(ch)) {
-               ac.Cancel();
+               AutoCompleteCancel();
        } else {
                AutoCompleteMoveToCurrentWord();
        }
 }
 
 void ScintillaBase::AutoCompleteCharacterDeleted() {
-       if (currentPos < ac.posStart - ac.startLen) {
-               ac.Cancel();
-       } else if (ac.cancelAtStartPos && (currentPos <= ac.posStart)) {
-               ac.Cancel();
+       if (sel.MainCaret() < ac.posStart - ac.startLen) {
+               AutoCompleteCancel();
+       } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
+               AutoCompleteCancel();
        } else {
                AutoCompleteMoveToCurrentWord();
        }
+       SCNotification scn = {0};
+       scn.nmhdr.code = SCN_AUTOCCHARDELETED;
+       scn.wParam = 0;
+       scn.listType = 0;
+       NotifyParent(scn);
 }
 
 void ScintillaBase::AutoCompleteCompleted() {
@@ -331,13 +345,12 @@ void ScintillaBase::AutoCompleteCompleted() {
        if (item != -1) {
                ac.lb->GetValue(item, selected, sizeof(selected));
        } else {
-               ac.Cancel();
+               AutoCompleteCancel();
                return;
        }
 
        ac.Show(false);
 
-       listSelected = selected;
        SCNotification scn = {0};
        scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
        scn.message = 0;
@@ -345,7 +358,7 @@ void ScintillaBase::AutoCompleteCompleted() {
        scn.listType = listType;
        Position firstPos = ac.posStart - ac.startLen;
        scn.lParam = firstPos;
-       scn.text = listSelected.c_str();
+       scn.text = selected;
        NotifyParent(scn);
 
        if (!ac.Active())
@@ -355,30 +368,47 @@ void ScintillaBase::AutoCompleteCompleted() {
        if (listType > 0)
                return;
 
-       Position endPos = currentPos;
+       Position endPos = sel.MainCaret();
        if (ac.dropRestOfWord)
                endPos = pdoc->ExtendWordSelect(endPos, 1, true);
        if (endPos < firstPos)
                return;
-       pdoc->BeginUndoAction();
+       UndoGroup ug(pdoc);
        if (endPos != firstPos) {
                pdoc->DeleteChars(firstPos, endPos - firstPos);
        }
        SetEmptySelection(ac.posStart);
        if (item != -1) {
-               SString piece = selected;
-               pdoc->InsertCString(firstPos, piece.c_str());
-               SetEmptySelection(firstPos + static_cast<int>(piece.length()));
+               pdoc->InsertCString(firstPos, selected);
+               SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
        }
-       pdoc->EndUndoAction();
 }
 
 int ScintillaBase::AutoCompleteGetCurrent() {
+       if (!ac.Active())
+               return -1;
        return ac.lb->GetSelection();
 }
 
+int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
+       if (ac.Active()) {
+               int item = ac.lb->GetSelection();
+               char selected[1000];
+               selected[0] = '\0';
+               if (item != -1) {
+                       ac.lb->GetValue(item, selected, sizeof(selected));
+                       if (buffer != NULL)
+                               strcpy(buffer, selected);
+                       return strlen(selected);
+               }
+       }
+       if (buffer != NULL)
+               *buffer = '\0';
+       return 0;
+}
+
 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
-       AutoCompleteCancel();
+       ac.Cancel();
        pt.y += vs.lineHeight;
        // If container knows about STYLE_CALLTIP then use it in place of the
        // STYLE_DEFAULT for the face name, size and character set. Also use it
@@ -387,7 +417,7 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) {
        if (ct.UseStyleCallTip()) {
                ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
        }
-       PRectangle rc = ct.CallTipStart(currentPos, pt,
+       PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
                defn,
                vs.styles[ctStyle].fontName,
                vs.styles[ctStyle].sizeZoomed,
@@ -422,10 +452,10 @@ void ScintillaBase::ContextMenu(Point pt) {
                AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
                AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
                AddToPopUp("");
-               AddToPopUp("Cut", idcmdCut, writable && currentPos != anchor);
-               AddToPopUp("Copy", idcmdCopy, currentPos != anchor);
+               AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
+               AddToPopUp("Copy", idcmdCopy, !sel.Empty());
                AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
-               AddToPopUp("Delete", idcmdDelete, writable && currentPos != anchor);
+               AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
                AddToPopUp("");
                AddToPopUp("Select All", idcmdSelectAll);
                popup.Show(pt, wMain);
@@ -449,6 +479,8 @@ void ScintillaBase::SetLexer(uptr_t wParam) {
        lexCurrent = LexerModule::Find(lexLanguage);
        if (!lexCurrent)
                lexCurrent = LexerModule::Find(SCLEX_NULL);
+       int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+       vs.EnsureStyle((1 << bits) - 1);
 }
 
 void ScintillaBase::SetLexerLanguage(const char *languageName) {
@@ -458,6 +490,8 @@ void ScintillaBase::SetLexerLanguage(const char *languageName) {
                lexCurrent = LexerModule::Find(SCLEX_NULL);
        if (lexCurrent)
                lexLanguage = lexCurrent->GetLanguage();
+       int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+       vs.EnsureStyle((1 << bits) - 1);
 }
 
 void ScintillaBase::Colourise(int start, int end) {
@@ -518,7 +552,7 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
                break;
 
        case SCI_AUTOCCANCEL:
-               AutoCompleteCancel();
+               ac.Cancel();
                break;
 
        case SCI_AUTOCACTIVE:
@@ -549,6 +583,9 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
        case SCI_AUTOCGETCURRENT:
                return AutoCompleteGetCurrent();
 
+       case SCI_AUTOCGETCURRENTTEXT:
+               return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
+
        case SCI_AUTOCSETCANCELATSTART:
                ac.cancelAtStartPos = wParam != 0;
                break;
@@ -691,25 +728,17 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
                          reinterpret_cast<const char *>(lParam));
                break;
 
-       case SCI_GETPROPERTY: {
-                       SString val = props.Get(reinterpret_cast<const char *>(wParam));
-                       const int n = val.length();
-                       if (lParam != 0) {
-                               char *ptr = reinterpret_cast<char *>(lParam);
-                               memcpy(ptr, val.c_str(), n);
-                               ptr[n] = '\0';  // terminate
-                       }
-                       return n;       // Not including NUL
-               }
+       case SCI_GETPROPERTY:
+                       return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
 
        case SCI_GETPROPERTYEXPANDED: {
-                       SString val = props.GetExpanded(reinterpret_cast<const char *>(wParam));
-                       const int n = val.length();
+                       char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
+                       const int n = strlen(val);
                        if (lParam != 0) {
                                char *ptr = reinterpret_cast<char *>(lParam);
-                               memcpy(ptr, val.c_str(), n);
-                               ptr[n] = '\0';  // terminate
+                               strcpy(ptr, val);
                        }
+                       delete []val;
                        return n;       // Not including NUL
                }
 
@@ -727,8 +756,12 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
                SetLexerLanguage(reinterpret_cast<const char *>(lParam));
                break;
 
+       case SCI_GETLEXERLANGUAGE:
+               return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
+
        case SCI_GETSTYLEBITSNEEDED:
                return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+
 #endif
 
        default:
index 0554d9457a062a8e8188142468354ba8bbe95529..f1fdc5dfdb669a3bfc49f8d7626288c4aae0b9b6 100644 (file)
@@ -16,8 +16,8 @@ namespace Scintilla {
  */
 class ScintillaBase : public Editor {
        // Private so ScintillaBase objects can not be copied
-       ScintillaBase(const ScintillaBase &) : Editor() {}
-       ScintillaBase &operator=(const ScintillaBase &) { return *this; }
+       ScintillaBase(const ScintillaBase &);
+       ScintillaBase &operator=(const ScintillaBase &);
 
 protected:
        /** Enumeration of commands and child windows. */
@@ -41,15 +41,13 @@ protected:
        CallTip ct;
 
        int listType;                   ///< 0 is an autocomplete list
-       SString listSelected;   ///< Receives listbox selected string
        int maxListWidth;               /// Maximum width of list, in average character widths
 
-       bool performingStyle;   ///< Prevent reentrance
-
 #ifdef SCI_LEXER
+       bool performingStyle;   ///< Prevent reentrance
        int lexLanguage;
        const LexerModule *lexCurrent;
-       PropSet props;
+       PropSetSimple props;
        enum {numWordLists=KEYWORDSET_MAX+1};
        WordList *keyWordLists[numWordLists+1];
        void SetLexer(uptr_t wParam);
@@ -73,6 +71,7 @@ protected:
        void AutoCompleteCancel();
        void AutoCompleteMove(int delta);
        int AutoCompleteGetCurrent();
+       int AutoCompleteGetCurrentText(char *buffer);
        void AutoCompleteCharacterAdded(char ch);
        void AutoCompleteCharacterDeleted();
        void AutoCompleteCompleted();
diff --git a/src/stc/scintilla/src/Selection.cxx b/src/stc/scintilla/src/Selection.cxx
new file mode 100644 (file)
index 0000000..2cdbe60
--- /dev/null
@@ -0,0 +1,366 @@
+// Scintilla source code edit control
+/** @file Selection.cxx
+ ** Classes maintaining the selection.
+ **/
+// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+
+#include <vector>
+
+#include "Platform.h"
+
+#include "Scintilla.h"
+
+#include "Selection.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
+       if (insertion) {
+               if (position > startChange) {
+                       position += length;
+               }
+       } else {
+               if (position > startChange) {
+                       int endDeletion = startChange + length;
+                       if (position > endDeletion) {
+                               position -= length;
+                       } else {
+                               position = startChange;
+                       }
+               }
+       }
+}
+
+bool SelectionPosition::operator <(const SelectionPosition &other) const {
+       if (position == other.position)
+               return virtualSpace < other.virtualSpace;
+       else
+               return position < other.position;
+}
+
+bool SelectionPosition::operator >(const SelectionPosition &other) const {
+       if (position == other.position)
+               return virtualSpace > other.virtualSpace;
+       else
+               return position > other.position;
+}
+
+bool SelectionPosition::operator <=(const SelectionPosition &other) const {
+       if (position == other.position && virtualSpace == other.virtualSpace)
+               return true;
+       else
+               return other > *this;
+}
+
+bool SelectionPosition::operator >=(const SelectionPosition &other) const {
+       if (position == other.position && virtualSpace == other.virtualSpace)
+               return true;
+       else
+               return *this > other;
+}
+
+int SelectionRange::Length() const {
+       if (anchor > caret) {
+               return anchor.Position() - caret.Position();
+       } else {
+               return caret.Position() - anchor.Position();
+       }
+}
+
+bool SelectionRange::Contains(int pos) const {
+       if (anchor > caret)
+               return (pos >= caret.Position()) && (pos <= anchor.Position());
+       else
+               return (pos >= anchor.Position()) && (pos <= caret.Position());
+}
+
+bool SelectionRange::Contains(SelectionPosition sp) const {
+       if (anchor > caret)
+               return (sp >= caret) && (sp <= anchor);
+       else
+               return (sp >= anchor) && (sp <= caret);
+}
+
+bool SelectionRange::ContainsCharacter(int posCharacter) const {
+       if (anchor > caret)
+               return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position());
+       else
+               return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
+}
+
+SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
+       SelectionSegment inOrder(caret, anchor);
+       if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
+               SelectionSegment portion = check;
+               if (portion.start < inOrder.start)
+                       portion.start = inOrder.start;
+               if (portion.end > inOrder.end)
+                       portion.end = inOrder.end;
+               if (portion.start > portion.end)
+                       return SelectionSegment();
+               else
+                       return portion;
+       } else {
+               return SelectionSegment();
+       }
+}
+
+bool SelectionRange::Trim(SelectionRange range) {
+       SelectionPosition startRange = range.Start();
+       SelectionPosition endRange = range.End();
+       SelectionPosition start = Start();
+       SelectionPosition end = End();
+       PLATFORM_ASSERT(start <= end);
+       PLATFORM_ASSERT(startRange <= endRange);
+       if ((startRange <= end) && (endRange >= start)) {
+               if ((start > startRange) && (end < endRange)) {
+                       // Completely covered by range -> empty at start
+                       end = start;
+               } else if ((start < startRange) && (end > endRange)) {
+                       // Completely covers range -> empty at start
+                       end = start;
+               } else if (start <= startRange) {
+                       // Trim end
+                       end = startRange;
+               } else { // 
+                       PLATFORM_ASSERT(end >= endRange);
+                       // Trim start
+                       start = endRange;
+               }
+               if (anchor > caret) {
+                       caret = start;
+                       anchor = end;
+               } else {
+                       anchor = start;
+                       caret = end;
+               }
+               return Empty();
+       } else {
+               return false;
+       }
+}
+
+// If range is all virtual collapse to start of virtual space
+void SelectionRange::MinimizeVirtualSpace() {
+       if (caret.Position() == anchor.Position()) {
+               int virtualSpace = caret.VirtualSpace();
+               if (virtualSpace > anchor.VirtualSpace())
+                       virtualSpace = anchor.VirtualSpace();
+               caret.SetVirtualSpace(virtualSpace);
+               anchor.SetVirtualSpace(virtualSpace);
+       }
+}
+
+Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
+       AddSelection(SelectionPosition(0));
+}
+
+Selection::~Selection() {
+}
+
+bool Selection::IsRectangular() const {
+       return (selType == selRectangle) || (selType == selThin);
+}
+
+int Selection::MainCaret() const {
+       return ranges[mainRange].caret.Position();
+}
+
+int Selection::MainAnchor() const {
+       return ranges[mainRange].anchor.Position();
+}
+
+SelectionRange &Selection::Rectangular() {
+       return rangeRectangular;
+}
+
+SelectionSegment Selection::Limits() const {
+       if (ranges.empty()) {
+               return SelectionSegment();
+       } else {
+               SelectionSegment sr(ranges[0].anchor, ranges[0].caret);
+               for (size_t i=1; i<ranges.size(); i++) {
+                       sr.Extend(ranges[i].anchor);
+                       sr.Extend(ranges[i].caret);
+               }
+               return sr;
+       }
+}
+
+SelectionSegment Selection::LimitsForRectangularElseMain() const {
+       if (IsRectangular()) {
+               return Limits();
+       } else {
+               return SelectionSegment(ranges[mainRange].caret, ranges[mainRange].anchor);
+       }
+}
+
+size_t Selection::Count() const {
+       return ranges.size();
+}
+
+size_t Selection::Main() const {
+       return mainRange;
+}
+
+void Selection::SetMain(size_t r) {
+       PLATFORM_ASSERT(r < ranges.size());
+       mainRange = r;
+}
+
+SelectionRange &Selection::Range(size_t r) {
+       return ranges[r];
+}
+
+SelectionRange &Selection::RangeMain() {
+       return ranges[mainRange];
+}
+
+bool Selection::MoveExtends() const {
+       return moveExtends;
+}
+
+void Selection::SetMoveExtends(bool moveExtends_) {
+       moveExtends = moveExtends_;
+}
+
+bool Selection::Empty() const {
+       for (size_t i=0; i<ranges.size(); i++) {
+               if (!ranges[i].Empty())
+                       return false;
+       }
+       return true;
+}
+
+SelectionPosition Selection::Last() const {
+       SelectionPosition lastPosition;
+       for (size_t i=0; i<ranges.size(); i++) {
+               if (lastPosition < ranges[i].caret)
+                       lastPosition = ranges[i].caret;
+               if (lastPosition < ranges[i].anchor)
+                       lastPosition = ranges[i].anchor;
+       }
+       return lastPosition;
+}
+
+int Selection::Length() const {
+       int len = 0;
+       for (size_t i=0; i<ranges.size(); i++) {
+               len += ranges[i].Length();
+       }
+       return len;
+}
+
+void Selection::MovePositions(bool insertion, int startChange, int length) {
+       for (size_t i=0; i<ranges.size(); i++) {
+               ranges[i].caret.MoveForInsertDelete(insertion, startChange, length);
+               ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length);
+       }
+}
+
+void Selection::TrimSelection(SelectionRange range) {
+       for (size_t i=0; i<ranges.size();) {
+               if ((i != mainRange) && (ranges[i].Trim(range))) {
+                       // Trimmed to empty so remove
+                       for (size_t j=i;j<ranges.size()-1;j++) {
+                               ranges[j] = ranges[j+1];
+                               if (j == mainRange-1)
+                                       mainRange--;
+                       }
+                       ranges.pop_back();
+               } else {
+                       i++;
+               }
+       }
+}
+
+void Selection::SetSelection(SelectionRange range) {
+       ranges.clear();
+       ranges.push_back(range);
+       mainRange = ranges.size() - 1;
+}
+
+void Selection::AddSelection(SelectionRange range) {
+       TrimSelection(range);
+       ranges.push_back(range);
+       mainRange = ranges.size() - 1;
+}
+
+void Selection::TentativeSelection(SelectionRange range) {
+       if (!tentativeMain) {
+               rangesSaved = ranges;
+       }
+       ranges = rangesSaved;
+       AddSelection(range);
+       TrimSelection(ranges[mainRange]);
+       tentativeMain = true;
+}
+
+void Selection::CommitTentative() {
+       rangesSaved.clear();
+       tentativeMain = false;
+}
+
+int Selection::CharacterInSelection(int posCharacter) const {
+       for (size_t i=0; i<ranges.size(); i++) {
+               if (ranges[i].ContainsCharacter(posCharacter))
+                       return i == mainRange ? 1 : 2;
+       }
+       return 0;
+}
+
+int Selection::InSelectionForEOL(int pos) const {
+       for (size_t i=0; i<ranges.size(); i++) {
+               if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position()))
+                       return i == mainRange ? 1 : 2;
+       }
+       return 0;
+}
+
+int Selection::VirtualSpaceFor(int pos) const {
+       int virtualSpace = 0;
+       for (size_t i=0; i<ranges.size(); i++) {
+               if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace()))
+                       virtualSpace = ranges[i].caret.VirtualSpace();
+               if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace()))
+                       virtualSpace = ranges[i].anchor.VirtualSpace();
+       }
+       return virtualSpace;
+}
+
+void Selection::Clear() {
+       ranges.clear();
+       ranges.push_back(SelectionRange());
+       mainRange = ranges.size() - 1;
+       selType = selStream;
+       moveExtends = false;
+       ranges[mainRange].Reset();
+       rangeRectangular.Reset();
+}
+
+void Selection::RemoveDuplicates() {
+       for (size_t i=0; i<ranges.size()-1; i++) {
+               if (ranges[i].Empty()) {
+                       size_t j=i+1;
+                       while (j<ranges.size()) {
+                               if (ranges[i] == ranges[j]) {
+                                       ranges.erase(ranges.begin() + j);
+                                       if (mainRange >= j)
+                                               mainRange--;
+                               } else {
+                                       j++;
+                               }
+                       }
+               }
+       }
+}
+
+void Selection::RotateMain() {
+       mainRange = (mainRange + 1) % ranges.size();
+}
+
diff --git a/src/stc/scintilla/src/Selection.h b/src/stc/scintilla/src/Selection.h
new file mode 100644 (file)
index 0000000..e50e9db
--- /dev/null
@@ -0,0 +1,191 @@
+// Scintilla source code edit control
+/** @file Selection.h
+ ** Classes maintaining the selection.
+ **/
+// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SELECTION_H
+#define SELECTION_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class SelectionPosition {
+       int position;
+       int virtualSpace;
+public:
+       explicit SelectionPosition(int position_=INVALID_POSITION, int virtualSpace_=0) : position(position_), virtualSpace(virtualSpace_) {
+               PLATFORM_ASSERT(virtualSpace < 800000);
+               if (virtualSpace < 0)
+                       virtualSpace = 0;
+       }
+       void Reset() {
+               position = 0;
+               virtualSpace = 0;
+       }
+       void MoveForInsertDelete(bool insertion, int startChange, int length);
+       bool operator ==(const SelectionPosition &other) const {
+               return position == other.position && virtualSpace == other.virtualSpace;
+       }
+       bool operator <(const SelectionPosition &other) const;
+       bool operator >(const SelectionPosition &other) const;
+       bool operator <=(const SelectionPosition &other) const;
+       bool operator >=(const SelectionPosition &other) const;
+       int Position() const {
+               return position;
+       }
+       void SetPosition(int position_) {
+               position = position_;
+               virtualSpace = 0;
+       }
+       int VirtualSpace() const {
+               return virtualSpace;
+       }
+       void SetVirtualSpace(int virtualSpace_) {
+               PLATFORM_ASSERT(virtualSpace_ < 800000);
+               if (virtualSpace_ >= 0)
+                       virtualSpace = virtualSpace_;
+       }
+       void Add(int increment) {
+               position = position + increment;
+       }
+       bool IsValid() const {
+               return position >= 0;
+       }
+};
+
+// Ordered range to make drawing simpler
+struct SelectionSegment {      
+       SelectionPosition start;
+       SelectionPosition end;
+       SelectionSegment() {
+       }
+       SelectionSegment(SelectionPosition a, SelectionPosition b) {
+               if (a < b) {
+                       start = a;
+                       end = b;
+               } else {
+                       start = b;
+                       end = a;
+               }
+       }
+       bool Empty() const {
+               return start == end;
+       }
+       void Extend(SelectionPosition p) {
+               if (start > p)
+                       start = p;
+               if (end < p)
+                       end = p;
+       }
+};
+
+struct SelectionRange {
+       SelectionPosition caret;
+       SelectionPosition anchor;
+
+       SelectionRange() {
+       }
+       SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
+       }
+       SelectionRange(int single) : caret(single), anchor(single) {
+       }
+       SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) {
+       }
+       SelectionRange(int caret_, int anchor_) : caret(caret_), anchor(anchor_) {
+       }
+       bool Empty() const {
+               return anchor == caret;
+       }
+       int Length() const;
+       // int Width() const;   // Like Length but takes virtual space into account
+       bool operator ==(const SelectionRange &other) const {
+               return caret == other.caret && anchor == other.anchor;
+       }
+       bool operator <(const SelectionRange &other) const {
+               return caret < other.caret || ((caret == other.caret) && (anchor < other.anchor));
+       }
+       void Reset() {
+               anchor.Reset();
+               caret.Reset();
+       }
+       void ClearVirtualSpace() {
+               anchor.SetVirtualSpace(0);
+               caret.SetVirtualSpace(0);
+       }
+       bool Contains(int pos) const;
+       bool Contains(SelectionPosition sp) const;
+       bool ContainsCharacter(int posCharacter) const;
+       SelectionSegment Intersect(SelectionSegment check) const;
+       SelectionPosition Start() const {
+               return (anchor < caret) ? anchor : caret;
+       }
+       SelectionPosition End() const {
+               return (anchor < caret) ? caret : anchor;
+       }
+       bool Trim(SelectionRange range);
+       // If range is all virtual collapse to start of virtual space
+       void MinimizeVirtualSpace();
+};
+
+#include "Array.h"
+typedef Array SelRangeArray;
+#define SelRangeArraySort ArraySort
+
+class Selection {
+       SelRangeArray ranges;
+       SelRangeArray rangesSaved;
+       SelectionRange rangeRectangular;
+       size_t mainRange;
+       bool moveExtends;
+       bool tentativeMain;
+public:
+       enum selTypes { noSel, selStream, selRectangle, selLines, selThin };
+       selTypes selType;
+
+       Selection();
+       ~Selection();
+       bool IsRectangular() const;
+       int MainCaret() const;
+       int MainAnchor() const;
+       SelectionRange &Rectangular();
+       SelectionSegment Limits() const;
+       // This is for when you want to move the caret in response to a 
+       // user direction command - for rectangular selections, use the range
+       // that covers all selected text otherwise return the main selection.
+       SelectionSegment LimitsForRectangularElseMain() const;
+       size_t Count() const;
+       size_t Main() const;
+       void SetMain(size_t r);
+       SelectionRange &Range(size_t r);
+       SelectionRange &RangeMain();
+       bool MoveExtends() const;
+       void SetMoveExtends(bool moveExtends_);
+       bool Empty() const;
+       SelectionPosition Last() const;
+       int Length() const;
+       void MovePositions(bool insertion, int startChange, int length);
+       void TrimSelection(SelectionRange range);
+       void SetSelection(SelectionRange range);
+       void AddSelection(SelectionRange range);
+       void TentativeSelection(SelectionRange range);
+       void CommitTentative();
+       int CharacterInSelection(int posCharacter) const;
+       int InSelectionForEOL(int pos) const;
+       int VirtualSpaceFor(int pos) const;
+       void Clear();
+       void RemoveDuplicates();
+       void RotateMain();
+       bool Tentative() const { return tentativeMain; }
+       SelRangeArray RangesCopy() const {
+               return ranges;
+       }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
index 9d62aef7213555407a4a4e14466e44291aeb8f9b..af4e890e3afa1e11f1cbe832590f583ac5446d0f 100644 (file)
@@ -43,7 +43,7 @@ protected:
        /// reallocating if more space needed.
        void RoomFor(int insertionLength) {
                if (gapLength <= insertionLength) {
-                       if (growSize * 6 < size)
+                       while (growSize < size / 6)
                                growSize *= 2;
                        ReAllocate(size + insertionLength + growSize);
                }
@@ -238,6 +238,12 @@ public:
                DeleteRange(0, lengthBody);
        }
 
+       T* BufferPointer() {
+               RoomFor(1);
+               GapTo(lengthBody);
+               body[lengthBody] = 0;
+               return body;
+       }
 };
 
 #endif
index ad081a66ddc779774742f05ad9d8568f539170bb..4314dec0acff0d569dcc694b50d35a655383c4b1 100644 (file)
@@ -126,7 +126,7 @@ bool Style::EquivalentFontTo(const Style *other) const {
        return strcmp(fontName, other->fontName) == 0;
 }
 
-void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, bool extraFontFlag) {
+void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
        sizeZoomed = size + zoomLevel;
        if (sizeZoomed <= 2)    // Hangs if sizeZoomed <= 1
                sizeZoomed = 2;
index 1caecaee73ffe228f0521348320bee167a26c098..0be3d4f07a8e80d3a57a44dfed0ae225433a987e 100644 (file)
@@ -53,7 +53,7 @@ public:
                   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 extraFontFlag = false);
+       void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
        bool IsProtected() const { return !(changeable && visible);};
 };
 
index 463aab462afebdf8c208bc48f9e822ec1bc32d5d..9342ebd68e0de6328eab966ef6cc4d92cb4074a4 100644 (file)
@@ -16,9 +16,7 @@ namespace Scintilla {
 class StyleContext {
        Accessor &styler;
        unsigned int endPos;
-       StyleContext& operator=(const StyleContext&) {
-               return *this;
-       }
+       StyleContext& operator=(const StyleContext&);
        void GetNextChar(unsigned int pos) {
                chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
                if (styler.IsLeadByte(static_cast<char>(chNext))) {
index 863eb82cdc97586d480b0bdb3d77ac17c50ac478..7dbe9e23de87457dba6ddea3c113a38bd6126e5d 100644 (file)
@@ -48,7 +48,7 @@ void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned
                        i++;
                        unsigned int xch = 0x10000 + ((uch & 0x3ff) << 10) + (uptr[i] & 0x3ff);
                        putf[k++] = static_cast<char>(0xF0 | (xch >> 18));
-                       putf[k++] = static_cast<char>(0x80 | (xch >> 12) & 0x3f);
+                       putf[k++] = static_cast<char>(0x80 | ((xch >> 12) & 0x3f));
                        putf[k++] = static_cast<char>(0x80 | ((xch >> 6) & 0x3f));
                        putf[k++] = static_cast<char>(0x80 | (xch & 0x3f));
                } else {
index 15efea8cc5ca3bf59fbf54afc62b008f4e27e3de..8e9c4a4634a3858b96ceccb03f45c0e3223c5d41 100644 (file)
@@ -92,10 +92,13 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
 
        selforeset = source.selforeset;
        selforeground.desired = source.selforeground.desired;
+       selAdditionalForeground.desired = source.selAdditionalForeground.desired;
        selbackset = source.selbackset;
        selbackground.desired = source.selbackground.desired;
+       selAdditionalBackground.desired = source.selAdditionalBackground.desired;
        selbackground2.desired = source.selbackground2.desired;
        selAlpha = source.selAlpha;
+       selAdditionalAlpha = source.selAdditionalAlpha;
        selEOLFilled = source.selEOLFilled;
 
        foldmarginColourSet = source.foldmarginColourSet;
@@ -117,6 +120,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
        selbar.desired = source.selbar.desired;
        selbarlight.desired = source.selbarlight.desired;
        caretcolour.desired = source.caretcolour.desired;
+       additionalCaretColour.desired = source.additionalCaretColour.desired;
        showCaretLineBackground = source.showCaretLineBackground;
        caretLineBackground.desired = source.caretLineBackground.desired;
        caretLineAlpha = source.caretLineAlpha;
@@ -135,10 +139,16 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
        fixedColumnWidth = source.fixedColumnWidth;
        zoomLevel = source.zoomLevel;
        viewWhitespace = source.viewWhitespace;
+       whitespaceSize = source.whitespaceSize;
        viewIndentationGuides = source.viewIndentationGuides;
        viewEOL = source.viewEOL;
        showMarkedLines = source.showMarkedLines;
        extraFontFlag = source.extraFontFlag;
+       extraAscent = source.extraAscent;
+       extraDescent = source.extraDescent;
+       marginStyleOffset = source.marginStyleOffset;
+       annotationVisible = source.annotationVisible;
+       annotationStyleOffset = source.annotationStyleOffset;
 }
 
 ViewStyle::~ViewStyle() {
@@ -171,10 +181,13 @@ void ViewStyle::Init(size_t stylesSize_) {
 
        selforeset = false;
        selforeground.desired = ColourDesired(0xff, 0, 0);
+       selAdditionalForeground.desired = ColourDesired(0xff, 0, 0);
        selbackset = true;
        selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+       selAdditionalBackground.desired = ColourDesired(0xd7, 0xd7, 0xd7);
        selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0);
        selAlpha = SC_ALPHA_NOALPHA;
+       selAdditionalAlpha = SC_ALPHA_NOALPHA;
        selEOLFilled = false;
 
        foldmarginColourSet = false;
@@ -191,6 +204,7 @@ void ViewStyle::Init(size_t stylesSize_) {
        styles[STYLE_LINENUMBER].fore.desired = ColourDesired(0, 0, 0);
        styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
        caretcolour.desired = ColourDesired(0, 0, 0);
+       additionalCaretColour.desired = ColourDesired(0x7f, 0x7f, 0x7f);
        showCaretLineBackground = false;
        caretLineBackground.desired = ColourDesired(0xff, 0xff, 0);
        caretLineAlpha = SC_ALPHA_NOALPHA;
@@ -229,10 +243,16 @@ void ViewStyle::Init(size_t stylesSize_) {
        }
        zoomLevel = 0;
        viewWhitespace = wsInvisible;
+       whitespaceSize = 1;
        viewIndentationGuides = ivNone;
        viewEOL = false;
        showMarkedLines = true;
-       extraFontFlag = false;
+       extraFontFlag = 0;
+       extraAscent = 0;
+       extraDescent = 0;
+       marginStyleOffset = 0;
+       annotationVisible = ANNOTATION_HIDDEN;
+       annotationStyleOffset = 0;
 }
 
 void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@@ -248,7 +268,9 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
                markers[i].RefreshColourPalette(pal, want);
        }
        pal.WantFind(selforeground, want);
+       pal.WantFind(selAdditionalForeground, want);
        pal.WantFind(selbackground, want);
+       pal.WantFind(selAdditionalBackground, want);
        pal.WantFind(selbackground2, want);
 
        pal.WantFind(foldmarginColour, want);
@@ -259,6 +281,7 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
        pal.WantFind(selbar, want);
        pal.WantFind(selbarlight, want);
        pal.WantFind(caretcolour, want);
+       pal.WantFind(additionalCaretColour, want);
        pal.WantFind(caretLineBackground, want);
        pal.WantFind(edgecolour, want);
        pal.WantFind(hotspotForeground, want);
@@ -284,6 +307,8 @@ void ViewStyle::Refresh(Surface &surface) {
                        someStylesProtected = true;
                }
        }
+       maxAscent += extraAscent;
+       maxDescent += extraDescent;
 
        lineHeight = maxAscent + maxDescent;
        aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
@@ -322,7 +347,7 @@ void ViewStyle::AllocStyles(size_t sizeNew) {
 void ViewStyle::EnsureStyle(size_t index) {
        if (index >= stylesSize) {
                size_t sizeNew = stylesSize * 2;
-               while (sizeNew < index)
+               while (sizeNew <= index)
                        sizeNew *= 2;
                AllocStyles(sizeNew);
        }
@@ -357,3 +382,8 @@ void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
 bool ViewStyle::ProtectionActive() const {
        return someStylesProtected;
 }
+
+bool ViewStyle::ValidStyle(size_t styleIndex) const {
+       return styleIndex < stylesSize;
+}
+
index 2f2d524616a7f8dff106d5f86c1389dec88b2dc4..22e365b02dcf958e99ce63cf24f72800b113638f 100644 (file)
@@ -58,10 +58,13 @@ public:
        unsigned int spaceWidth;
        bool selforeset;
        ColourPair selforeground;
+       ColourPair selAdditionalForeground;
        bool selbackset;
        ColourPair selbackground;
+       ColourPair selAdditionalBackground;
        ColourPair selbackground2;
        int selAlpha;
+       int selAdditionalAlpha;
        bool selEOLFilled;
        bool whitespaceForegroundSet;
        ColourPair whitespaceForeground;
@@ -89,10 +92,12 @@ public:
        int fixedColumnWidth;
        int zoomLevel;
        WhiteSpaceVisibility viewWhitespace;
+       int whitespaceSize;
        IndentView viewIndentationGuides;
        bool viewEOL;
        bool showMarkedLines;
        ColourPair caretcolour;
+       ColourPair additionalCaretColour;
        bool showCaretLineBackground;
        ColourPair caretLineBackground;
        int caretLineAlpha;
@@ -101,7 +106,12 @@ public:
        int caretStyle;
        int caretWidth;
        bool someStylesProtected;
-       bool extraFontFlag;
+       int extraFontFlag;
+       int extraAscent;
+       int extraDescent;
+       int marginStyleOffset;
+       int annotationVisible;
+       int annotationStyleOffset;
 
        ViewStyle();
        ViewStyle(const ViewStyle &source);
@@ -115,6 +125,7 @@ public:
        void ClearStyles();
        void SetStyleFontName(int styleIndex, const char *name);
        bool ProtectionActive() const;
+       bool ValidStyle(size_t styleIndex) const;
 };
 
 #ifdef SCI_NAMESPACE
index 8093300bc05bc41471c2abb5a81f4a86a271fdef..9de106fb78e47b21b4a60be4158e57bd15ed89bb 100644 (file)
@@ -45,7 +45,7 @@ void WindowAccessor::Fill(int position) {
        if (endPos > lenDoc)
                endPos = lenDoc;
 
-       TextRange tr = {{startPos, endPos}, buf};
+       Sci_TextRange tr = {{startPos, endPos}, buf};
        Platform::SendScintillaPointer(id, SCI_GETTEXTRANGE, 0, &tr);
 }
 
index 0ee68c07204b1c00bd5ca0b8376e7861822a26a1..07cb5802bd3637b20f4c98fa6e8b89105e50babb 100644 (file)
@@ -16,7 +16,7 @@ namespace Scintilla {
  * Hold a pixmap in XPM format.
  */
 class XPM {
-       int id;         // Assigned by container
+       int pid;                // Assigned by container
        int height;
        int width;
        int nColours;
@@ -42,8 +42,8 @@ public:
        /// 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; }
+       void SetId(int pid_) { pid = pid_; }
+       int GetId() { return pid; }
        int GetHeight() { return height; }
        int GetWidth() { return width; }
        static const char **LinesFormFromTextForm(const char *textForm);
index aedb28e311c0565cd2bfe72ca32132f1e86bf191..54571bb3de8e99dd0fbc3577f763fef3b3480828 100644 (file)
@@ -124,6 +124,8 @@ wxDEFINE_EVENT( wxEVT_STC_CALLTIP_CLICK, wxStyledTextEvent );
 wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_SELECTION, wxStyledTextEvent );
 wxDEFINE_EVENT( wxEVT_STC_INDICATOR_CLICK, wxStyledTextEvent );
 wxDEFINE_EVENT( wxEVT_STC_INDICATOR_RELEASE, wxStyledTextEvent );
+wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_CANCELLED, wxStyledTextEvent );
+wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_CHAR_DELETED, wxStyledTextEvent );
 
 
 
@@ -283,7 +285,7 @@ void wxStyledTextCtrl::ClearDocumentStyle()
     SendMsg(2005, 0, 0);
 }
 
-// Returns the number of characters in the document.
+// Returns the number of bytes in the document.
 int wxStyledTextCtrl::GetLength() const
 {
     return SendMsg(2006, 0, 0);
@@ -815,13 +817,13 @@ void wxStyledTextCtrl::StyleSetHotSpot(int style, bool hotspot)
     SendMsg(2409, style, hotspot);
 }
 
-// Set the foreground colour of the selection and whether to use this setting.
+// Set the foreground colour of the main and additional selections and whether to use this setting.
 void wxStyledTextCtrl::SetSelForeground(bool useSetting, const wxColour& fore)
 {
     SendMsg(2067, useSetting, wxColourAsLong(fore));
 }
 
-// Set the background colour of the selection and whether to use this setting.
+// Set the background colour of the main and additional selections and whether to use this setting.
 void wxStyledTextCtrl::SetSelBackground(bool useSetting, const wxColour& back)
 {
     SendMsg(2068, useSetting, wxColourAsLong(back));
@@ -897,7 +899,7 @@ void wxStyledTextCtrl::SetCaretPeriod(int periodMilliseconds)
 }
 
 // Set the set of characters making up words for when moving or selecting by word.
-// First sets deaults like SetCharsDefault.
+// First sets defaults like SetCharsDefault.
 void wxStyledTextCtrl::SetWordChars(const wxString& characters)
 {
     SendMsg(2077, 0, (sptr_t)(const char*)wx2stc(characters));
@@ -965,6 +967,18 @@ void wxStyledTextCtrl::SetWhitespaceBackground(bool useSetting, const wxColour&
     SendMsg(2085, useSetting, wxColourAsLong(back));
 }
 
+// Set the size of the dots used to mark space characters.
+void wxStyledTextCtrl::SetWhitespaceSize(int size)
+{
+    SendMsg(2086, size, 0);
+}
+
+// Get the size of the dots used to mark space characters.
+int wxStyledTextCtrl::GetWhitespaceSize() const
+{
+    return SendMsg(2087, 0, 0);
+}
+
 // Divide each styling byte into lexical class bits (default: 5) and indicator
 // bits (default: 3). If a lexer requires more than 32 lexical states, then this
 // is used to expand the possible states.
@@ -1980,6 +1994,18 @@ int wxStyledTextCtrl::GetWrapStartIndent() const
     return SendMsg(2465, 0, 0);
 }
 
+// Sets how wrapped sublines are placed. Default is fixed.
+void wxStyledTextCtrl::SetWrapIndentMode(int mode)
+{
+    SendMsg(2472, mode, 0);
+}
+
+// Retrieve how wrapped sublines are placed. Default is fixed.
+int wxStyledTextCtrl::GetWrapIndentMode() const
+{
+    return SendMsg(2473, 0, 0);
+}
+
 // Sets the degree of caching of layout information.
 void wxStyledTextCtrl::SetLayoutCache(int mode)
 {
@@ -2076,6 +2102,12 @@ void wxStyledTextCtrl::SetTwoPhaseDraw(bool twoPhase)
     SendMsg(2284, twoPhase, 0);
 }
 
+// Scroll so that a display line is at the top of the display.
+void wxStyledTextCtrl::SetFirstVisibleLine(int lineDisplay)
+{
+    SendMsg(2613, lineDisplay, 0);
+}
+
 // Make the target range start and end be the same as the selection range start and end.
 void wxStyledTextCtrl::TargetFromSelection()
 {
@@ -2458,7 +2490,7 @@ void wxStyledTextCtrl::MoveCaretInsideView()
     SendMsg(2401, 0, 0);
 }
 
-// How many characters are on a line, not including end of line characters?
+// How many characters are on a line, including end of line characters?
 int wxStyledTextCtrl::LineLength(int line) const
 {
     return SendMsg(2350, line, 0);
@@ -2865,7 +2897,7 @@ void wxStyledTextCtrl::CopyText(int length, const wxString& text)
     SendMsg(2420, length, (sptr_t)(const char*)wx2stc(text));
 }
 
-// Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE) or
+// Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or
 // by lines (SC_SEL_LINES).
 void wxStyledTextCtrl::SetSelectionMode(int mode)
 {
@@ -3158,6 +3190,485 @@ int wxStyledTextCtrl::GetPositionCacheSize() const
     return SendMsg(2515, 0, 0);
 }
 
+// Copy the selection, if selection empty copy the line with the caret
+void wxStyledTextCtrl::CopyAllowLine()
+{
+    SendMsg(2519, 0, 0);
+}
+
+// Compact the document buffer and return a read-only pointer to the
+// characters in the document.
+const char* wxStyledTextCtrl::GetCharacterPointer() {
+    return (const char*)SendMsg(2520, 0, 0);
+}
+
+// Always interpret keyboard input as Unicode
+void wxStyledTextCtrl::SetKeysUnicode(bool keysUnicode)
+{
+    SendMsg(2521, keysUnicode, 0);
+}
+
+// Are keys always interpreted as Unicode?
+bool wxStyledTextCtrl::GetKeysUnicode() const
+{
+    return SendMsg(2522, 0, 0) != 0;
+}
+
+// Set the alpha fill colour of the given indicator.
+void wxStyledTextCtrl::IndicatorSetAlpha(int indicator, int alpha)
+{
+    SendMsg(2523, indicator, alpha);
+}
+
+// Get the alpha fill colour of the given indicator.
+int wxStyledTextCtrl::IndicatorGetAlpha(int indicator) const
+{
+    return SendMsg(2524, indicator, 0);
+}
+
+// Set extra ascent for each line
+void wxStyledTextCtrl::SetExtraAscent(int extraAscent)
+{
+    SendMsg(2525, extraAscent, 0);
+}
+
+// Get extra ascent for each line
+int wxStyledTextCtrl::GetExtraAscent() const
+{
+    return SendMsg(2526, 0, 0);
+}
+
+// Set extra descent for each line
+void wxStyledTextCtrl::SetExtraDescent(int extraDescent)
+{
+    SendMsg(2527, extraDescent, 0);
+}
+
+// Get extra descent for each line
+int wxStyledTextCtrl::GetExtraDescent() const
+{
+    return SendMsg(2528, 0, 0);
+}
+
+// Which symbol was defined for markerNumber with MarkerDefine
+int wxStyledTextCtrl::GetMarkerSymbolDefined(int markerNumber)
+{
+    return SendMsg(2529, markerNumber, 0);
+}
+
+// Set the text in the text margin for a line
+void wxStyledTextCtrl::MarginSetText(int line, const wxString& text)
+{
+    SendMsg(2530, line, (sptr_t)(const char*)wx2stc(text));
+}
+
+// Get the text in the text margin for a line
+wxString wxStyledTextCtrl::MarginGetText(int line) const {
+         long msg = 2531;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
+}
+
+// Set the style number for the text margin for a line
+void wxStyledTextCtrl::MarginSetStyle(int line, int style)
+{
+    SendMsg(2532, line, style);
+}
+
+// Get the style number for the text margin for a line
+int wxStyledTextCtrl::MarginGetStyle(int line) const
+{
+    return SendMsg(2533, line, 0);
+}
+
+// Set the style in the text margin for a line
+void wxStyledTextCtrl::MarginSetStyles(int line, const wxString& styles)
+{
+    SendMsg(2534, line, (sptr_t)(const char*)wx2stc(styles));
+}
+
+// Get the styles in the text margin for a line
+wxString wxStyledTextCtrl::MarginGetStyles(int line) const {
+         long msg = 2535;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
+}
+
+// Clear the margin text on all lines
+void wxStyledTextCtrl::MarginTextClearAll()
+{
+    SendMsg(2536, 0, 0);
+}
+
+// Get the start of the range of style numbers used for margin text
+void wxStyledTextCtrl::MarginSetStyleOffset(int style)
+{
+    SendMsg(2537, style, 0);
+}
+
+// Get the start of the range of style numbers used for margin text
+int wxStyledTextCtrl::MarginGetStyleOffset() const
+{
+    return SendMsg(2538, 0, 0);
+}
+
+// Set the annotation text for a line
+void wxStyledTextCtrl::AnnotationSetText(int line, const wxString& text)
+{
+    SendMsg(2540, line, (sptr_t)(const char*)wx2stc(text));
+}
+
+// Get the annotation text for a line
+wxString wxStyledTextCtrl::AnnotationGetText(int line) const {
+         long msg = 2541;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
+}
+
+// Set the style number for the annotations for a line
+void wxStyledTextCtrl::AnnotationSetStyle(int line, int style)
+{
+    SendMsg(2542, line, style);
+}
+
+// Get the style number for the annotations for a line
+int wxStyledTextCtrl::AnnotationGetStyle(int line) const
+{
+    return SendMsg(2543, line, 0);
+}
+
+// Set the annotation styles for a line
+void wxStyledTextCtrl::AnnotationSetStyles(int line, const wxString& styles)
+{
+    SendMsg(2544, line, (sptr_t)(const char*)wx2stc(styles));
+}
+
+// Get the annotation styles for a line
+wxString wxStyledTextCtrl::AnnotationGetStyles(int line) const {
+         long msg = 2545;
+         long len = SendMsg(msg, line, 0);
+
+         wxMemoryBuffer mbuf(len+1);
+         char* buf = (char*)mbuf.GetWriteBuf(len+1);
+         SendMsg(msg, line, (sptr_t)buf);
+         mbuf.UngetWriteBuf(len);
+         mbuf.AppendByte(0);
+         return stc2wx(buf);
+}
+
+// Get the number of annotation lines for a line
+int wxStyledTextCtrl::AnnotationGetLines(int line) const
+{
+    return SendMsg(2546, line, 0);
+}
+
+// Clear the annotations from all lines
+void wxStyledTextCtrl::AnnotationClearAll()
+{
+    SendMsg(2547, 0, 0);
+}
+
+// Set the visibility for the annotations for a view
+void wxStyledTextCtrl::AnnotationSetVisible(int visible)
+{
+    SendMsg(2548, visible, 0);
+}
+
+// Get the visibility for the annotations for a view
+int wxStyledTextCtrl::AnnotationGetVisible() const
+{
+    return SendMsg(2549, 0, 0);
+}
+
+// Get the start of the range of style numbers used for annotations
+void wxStyledTextCtrl::AnnotationSetStyleOffset(int style)
+{
+    SendMsg(2550, style, 0);
+}
+
+// Get the start of the range of style numbers used for annotations
+int wxStyledTextCtrl::AnnotationGetStyleOffset() const
+{
+    return SendMsg(2551, 0, 0);
+}
+
+// Add a container action to the undo stack
+void wxStyledTextCtrl::AddUndoAction(int token, int flags)
+{
+    SendMsg(2560, token, flags);
+}
+
+// Find the position of a character from a point within the window.
+int wxStyledTextCtrl::CharPositionFromPoint(int x, int y)
+{
+    return SendMsg(2561, x, y);
+}
+
+// Find the position of a character from a point within the window.
+// Return INVALID_POSITION if not close to text.
+int wxStyledTextCtrl::CharPositionFromPointClose(int x, int y)
+{
+    return SendMsg(2562, x, y);
+}
+
+// Set whether multiple selections can be made
+void wxStyledTextCtrl::SetMultipleSelection(bool multipleSelection)
+{
+    SendMsg(2563, multipleSelection, 0);
+}
+
+// Whether multiple selections can be made
+bool wxStyledTextCtrl::GetMultipleSelection() const
+{
+    return SendMsg(2564, 0, 0) != 0;
+}
+
+// Set whether typing can be performed into multiple selections
+void wxStyledTextCtrl::SetAdditionalSelectionTyping(bool additionalSelectionTyping)
+{
+    SendMsg(2565, additionalSelectionTyping, 0);
+}
+
+// Whether typing can be performed into multiple selections
+bool wxStyledTextCtrl::GetAdditionalSelectionTyping() const
+{
+    return SendMsg(2566, 0, 0) != 0;
+}
+
+// Set whether additional carets will blink
+void wxStyledTextCtrl::SetAdditionalCaretsBlink(bool additionalCaretsBlink)
+{
+    SendMsg(2567, additionalCaretsBlink, 0);
+}
+
+// Whether additional carets will blink
+bool wxStyledTextCtrl::GetAdditionalCaretsBlink() const
+{
+    return SendMsg(2568, 0, 0) != 0;
+}
+
+// Set whether additional carets are visible
+void wxStyledTextCtrl::SetAdditionalCaretsVisible(bool additionalCaretsBlink)
+{
+    SendMsg(2608, additionalCaretsBlink, 0);
+}
+
+// Whether additional carets are visible
+bool wxStyledTextCtrl::GetAdditionalCaretsVisible() const
+{
+    return SendMsg(2609, 0, 0) != 0;
+}
+
+// How many selections are there?
+int wxStyledTextCtrl::GetSelections() const
+{
+    return SendMsg(2570, 0, 0);
+}
+
+// Clear selections to a single empty stream selection
+void wxStyledTextCtrl::ClearSelections()
+{
+    SendMsg(2571, 0, 0);
+}
+
+// Add a selection
+int wxStyledTextCtrl::AddSelection(int caret, int anchor)
+{
+    return SendMsg(2573, caret, anchor);
+}
+
+// Set the main selection
+void wxStyledTextCtrl::SetMainSelection(int selection)
+{
+    SendMsg(2574, selection, 0);
+}
+
+// Which selection is the main selection
+int wxStyledTextCtrl::GetMainSelection() const
+{
+    return SendMsg(2575, 0, 0);
+}
+void wxStyledTextCtrl::SetSelectionNCaret(int selection, int pos)
+{
+    SendMsg(2576, selection, pos);
+}
+int wxStyledTextCtrl::GetSelectionNCaret(int selection) const
+{
+    return SendMsg(2577, selection, 0);
+}
+void wxStyledTextCtrl::SetSelectionNAnchor(int selection, int posAnchor)
+{
+    SendMsg(2578, selection, posAnchor);
+}
+int wxStyledTextCtrl::GetSelectionNAnchor(int selection) const
+{
+    return SendMsg(2579, selection, 0);
+}
+void wxStyledTextCtrl::SetSelectionNCaretVirtualSpace(int selection, int space)
+{
+    SendMsg(2580, selection, space);
+}
+int wxStyledTextCtrl::GetSelectionNCaretVirtualSpace(int selection) const
+{
+    return SendMsg(2581, selection, 0);
+}
+void wxStyledTextCtrl::SetSelectionNAnchorVirtualSpace(int selection, int space)
+{
+    SendMsg(2582, selection, space);
+}
+int wxStyledTextCtrl::GetSelectionNAnchorVirtualSpace(int selection) const
+{
+    return SendMsg(2583, selection, 0);
+}
+
+// Sets the position that starts the selection - this becomes the anchor.
+void wxStyledTextCtrl::SetSelectionNStart(int selection, int pos)
+{
+    SendMsg(2584, selection, pos);
+}
+
+// Returns the position at the start of the selection.
+int wxStyledTextCtrl::GetSelectionNStart(int selection) const
+{
+    return SendMsg(2585, selection, 0);
+}
+
+// Sets the position that ends the selection - this becomes the currentPosition.
+void wxStyledTextCtrl::SetSelectionNEnd(int selection, int pos)
+{
+    SendMsg(2586, selection, pos);
+}
+
+// Returns the position at the end of the selection.
+int wxStyledTextCtrl::GetSelectionNEnd(int selection) const
+{
+    return SendMsg(2587, selection, 0);
+}
+void wxStyledTextCtrl::SetRectangularSelectionCaret(int pos)
+{
+    SendMsg(2588, pos, 0);
+}
+int wxStyledTextCtrl::GetRectangularSelectionCaret() const
+{
+    return SendMsg(2589, 0, 0);
+}
+void wxStyledTextCtrl::SetRectangularSelectionAnchor(int posAnchor)
+{
+    SendMsg(2590, posAnchor, 0);
+}
+int wxStyledTextCtrl::GetRectangularSelectionAnchor() const
+{
+    return SendMsg(2591, 0, 0);
+}
+void wxStyledTextCtrl::SetRectangularSelectionCaretVirtualSpace(int space)
+{
+    SendMsg(2592, space, 0);
+}
+int wxStyledTextCtrl::GetRectangularSelectionCaretVirtualSpace() const
+{
+    return SendMsg(2593, 0, 0);
+}
+void wxStyledTextCtrl::SetRectangularSelectionAnchorVirtualSpace(int space)
+{
+    SendMsg(2594, space, 0);
+}
+int wxStyledTextCtrl::GetRectangularSelectionAnchorVirtualSpace() const
+{
+    return SendMsg(2595, 0, 0);
+}
+void wxStyledTextCtrl::SetVirtualSpaceOptions(int virtualSpaceOptions)
+{
+    SendMsg(2596, virtualSpaceOptions, 0);
+}
+int wxStyledTextCtrl::GetVirtualSpaceOptions() const
+{
+    return SendMsg(2597, 0, 0);
+}
+
+// On GTK+, allow selecting the modifier key to use for mouse-based
+// rectangular selection. Often the window manager requires Alt+Mouse Drag
+// for moving windows.
+// Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER.
+void wxStyledTextCtrl::SetRectangularSelectionModifier(int modifier)
+{
+    SendMsg(2598, modifier, 0);
+}
+
+// Get the modifier key used for rectangular selection.
+int wxStyledTextCtrl::GetRectangularSelectionModifier() const
+{
+    return SendMsg(2599, 0, 0);
+}
+
+// Set the foreground colour of additional selections.
+// Must have previously called SetSelFore with non-zero first argument for this to have an effect.
+void wxStyledTextCtrl::SetAdditionalSelForeground(const wxColour& fore)
+{
+    SendMsg(2600, wxColourAsLong(fore), 0);
+}
+
+// Set the background colour of additional selections.
+// Must have previously called SetSelBack with non-zero first argument for this to have an effect.
+void wxStyledTextCtrl::SetAdditionalSelBackground(const wxColour& back)
+{
+    SendMsg(2601, wxColourAsLong(back), 0);
+}
+
+// Set the alpha of the selection.
+void wxStyledTextCtrl::SetAdditionalSelAlpha(int alpha)
+{
+    SendMsg(2602, alpha, 0);
+}
+
+// Get the alpha of the selection.
+int wxStyledTextCtrl::GetAdditionalSelAlpha() const
+{
+    return SendMsg(2603, 0, 0);
+}
+
+// Set the foreground colour of additional carets.
+void wxStyledTextCtrl::SetAdditionalCaretForeground(const wxColour& fore)
+{
+    SendMsg(2604, wxColourAsLong(fore), 0);
+}
+
+// Get the foreground colour of additional carets.
+wxColour wxStyledTextCtrl::GetAdditionalCaretForeground() const
+{
+    long c = SendMsg(2605, 0, 0);
+    return wxColourFromLong(c);
+}
+
+// Set the main selection to the next selection.
+void wxStyledTextCtrl::RotateSelection()
+{
+    SendMsg(2606, 0, 0);
+}
+
+// Swap that caret and anchor of the main selection.
+void wxStyledTextCtrl::SwapMainAnchorCaret()
+{
+    SendMsg(2607, 0, 0);
+}
+
 // Start notifying the container of all key presses and commands.
 void wxStyledTextCtrl::StartRecord()
 {
@@ -4023,6 +4534,14 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
         evt.SetEventType(wxEVT_STC_INDICATOR_RELEASE);
         break;
 
+    case SCN_AUTOCCANCELLED:
+        evt.SetEventType(wxEVT_STC_AUTOCOMP_CANCELLED);
+        break;
+
+    case SCN_AUTOCCHARDELETED:
+        evt.SetEventType(wxEVT_STC_AUTOCOMP_CHAR_DELETED);
+        break;
+
     default:
         return;
     }
index fa51a690f7888a9ba18afec2c26350542bd92646..dbdbafde109fd8cc40b409fcfd2818430e90e1f6 100644 (file)
@@ -124,6 +124,8 @@ wxDEFINE_EVENT( wxEVT_STC_CALLTIP_CLICK, wxStyledTextEvent );
 wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_SELECTION, wxStyledTextEvent );
 wxDEFINE_EVENT( wxEVT_STC_INDICATOR_CLICK, wxStyledTextEvent );
 wxDEFINE_EVENT( wxEVT_STC_INDICATOR_RELEASE, wxStyledTextEvent );
+wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_CANCELLED, wxStyledTextEvent );
+wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_CHAR_DELETED, wxStyledTextEvent );
 
 
 
@@ -1032,6 +1034,14 @@ void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
         evt.SetEventType(wxEVT_STC_INDICATOR_RELEASE);
         break;
 
+    case SCN_AUTOCCANCELLED:
+        evt.SetEventType(wxEVT_STC_AUTOCOMP_CANCELLED);
+        break;
+
+    case SCN_AUTOCCHARDELETED:
+        evt.SetEventType(wxEVT_STC_AUTOCOMP_CHAR_DELETED);
+        break;
+
     default:
         return;
     }
index 046e8983514e1f7f0b8d3b71588b8343029230e3..4414ebc6686392c68da2c0c9dd8cd8dd4b33d55b 100644 (file)
@@ -624,6 +624,8 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_CALLTIP_CLICK, wxStyledText
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_SELECTION, wxStyledTextEvent );
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_INDICATOR_CLICK, wxStyledTextEvent );
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_INDICATOR_RELEASE, wxStyledTextEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_CANCELLED, wxStyledTextEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_CHAR_DELETED, wxStyledTextEvent );
 #else
     enum {
         wxEVT_STC_CHANGE,
@@ -653,7 +655,9 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_STC, wxEVT_STC_INDICATOR_RELEASE, wxStyled
         wxEVT_STC_CALLTIP_CLICK,
         wxEVT_STC_AUTOCOMP_SELECTION,
         wxEVT_STC_INDICATOR_CLICK,
-        wxEVT_STC_INDICATOR_RELEASE
+        wxEVT_STC_INDICATOR_RELEASE,
+        wxEVT_STC_AUTOCOMP_CANCELLED,
+        wxEVT_STC_AUTOCOMP_CHAR_DELETED
     };
 #endif
 
@@ -693,6 +697,8 @@ typedef void (wxEvtHandler::*wxStyledTextEventFunction)(wxStyledTextEvent&);
 #define EVT_STC_AUTOCOMP_SELECTION(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_SELECTION,    id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
 #define EVT_STC_INDICATOR_CLICK(id, fn)    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_INDICATOR_CLICK,       id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
 #define EVT_STC_INDICATOR_RELEASE(id, fn)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_INDICATOR_RELEASE,     id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
+#define EVT_STC_AUTOCOMP_CANCELLED(id, fn)    DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_CANCELLED,    id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
+#define EVT_STC_AUTOCOMP_CHAR_DELETED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_CHAR_DELETED, id, wxID_ANY, wxStyledTextEventHandler( fn ), (wxObject *) NULL ),
 
 #endif