wxscintilla_LexCSS.o \
wxscintilla_LexCaml.o \
wxscintilla_LexCsound.o \
+ wxscintilla_LexCOBOL.o \
wxscintilla_LexConf.o \
wxscintilla_LexCrontab.o \
wxscintilla_LexD.o \
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 \
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 \
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 \
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
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
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
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
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
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
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
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
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
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>
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
$(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
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
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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
#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.
#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.
#define wxSTC_FOLDLEVELBASE 0x400
#define wxSTC_FOLDLEVELWHITEFLAG 0x1000
#define wxSTC_FOLDLEVELHEADERFLAG 0x2000
-#define wxSTC_FOLDLEVELBOXHEADERFLAG 0x4000
-#define wxSTC_FOLDLEVELBOXFOOTERFLAG 0x8000
-#define wxSTC_FOLDLEVELCONTRACTED 0x10000
-#define wxSTC_FOLDLEVELUNINDENT 0x20000
#define wxSTC_FOLDLEVELNUMBERMASK 0x0FFF
#define wxSTC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002
#define wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004
#define wxSTC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
#define wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
#define wxSTC_FOLDFLAG_LEVELNUMBERS 0x0040
-#define wxSTC_FOLDFLAG_BOX 0x0001
#define wxSTC_TIME_FOREVER 10000000
#define wxSTC_WRAP_NONE 0
#define wxSTC_WRAP_WORD 1
#define wxSTC_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
// 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
#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.
#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
#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.
#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
#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
#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
#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
#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
#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
#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
+
//}}}
//----------------------------------------------------------------------
// 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.
// 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.
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.
// 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.
// 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);
// 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();
// 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.
// 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);
// 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();
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,
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
#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
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}
int GetLayoutCache() const;
/**
- Returns the number of characters in the document.
+ Returns the number of bytes in the document.
*/
int GetLength() const;
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;
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);
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);
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);
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();
+
};
// 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,
Clear ();
}
+void Edit::OnKey (wxStyledTextEvent &event)
+{
+ wxMessageBox("OnKey");
+}
+
void Edit::OnEditCut (wxCommandEvent &WXUNUSED(event)) {
if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return;
Cut ();
// stc
void OnMarginClick (wxStyledTextEvent &event);
void OnCharAdded (wxStyledTextEvent &event);
+ void OnKey (wxStyledTextEvent &event);
//! language/lexer
wxString DeterminePrefs (const wxString &filename);
// 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();
stcdll_PropSet.o \
stcdll_RESearch.o \
stcdll_ScintillaBase.o \
+ stcdll_Selection.o \
stcdll_Style.o \
stcdll_StyleContext.o \
stcdll_UniConversion.o \
stclib_PropSet.o \
stclib_RESearch.o \
stclib_ScintillaBase.o \
+ stcdll_Selection.o \
stclib_Style.o \
stclib_StyleContext.o \
stclib_UniConversion.o \
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
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
#include "wx/stc/private.h"
-
Point Point::FromLong(long lpoint) {
return Point(lpoint & 0xFFFF, lpoint >> 16);
}
//----------------------------------------------------------------------
Font::Font() {
- id = 0;
+ fid = 0;
ascent = 0;
}
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
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;
}
//----------------------------------------------------------------------
}
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) {
}
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) {
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));
#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
{
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));
}
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) -
void ListBoxImpl::SetFont(Font &font) {
- GETLB(id)->SetFont(*((wxFont*)font.GetID()));
+ GETLB(wid)->SetFont(*((wxFont*)font.GetID()));
}
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);
}
// 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;
int ListBoxImpl::CaretFromEdge() {
- return 4 + GETLBW(id)->IconWidth();
+ return 4 + GETLBW(wid)->IconWidth();
}
void ListBoxImpl::Clear() {
- GETLB(id)->DeleteAllItems();
+ GETLB(wid)->DeleteAllItems();
}
}
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() ) {
}
Append(token, (int)type);
}
- GETLB(id)->Thaw();
+ GETLB(wid)->Thaw();
}
int ListBoxImpl::Length() {
- return GETLB(id)->GetItemCount();
+ return GETLB(wid)->GetItemCount();
}
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();
}
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';
}
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);
}
//----------------------------------------------------------------------
-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();
}
if (result == wxDragMove && dropWentOutside)
ClearSelection();
inDragDrop = ddNone;
- SetDragPosition(invalidPosition);
+ SetDragPosition(SelectionPosition(invalidPosition));
}
#endif // wxUSE_DRAG_AND_DROP
}
void ScintillaWX::Copy() {
- if (currentPos != anchor) {
+ if (!sel.Empty()) {
SelectionText st;
CopySelectionRange(&st);
CopyToClipboard(st);
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
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);
DestroySystemCaret();
CreateSystemCaret();
}
- Point pos = LocationFromPosition(currentPos);
+ Point pos = PointMainCaret();
::SetCaretPos(pos.x, pos.y);
}
#endif
{
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,
// 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;
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();
#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));
dragResult = evt.GetDragResult();
if (dragResult == wxDragMove || dragResult == wxDragCopy) {
- DropAt(evt.GetPosition(),
+ DropAt(SelectionPosition(evt.GetPosition()),
wx2stc(evt.GetDragText()),
dragResult == wxDragMove,
false); // TODO: rectangular?
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());
void ScintillaWX::DoDragLeave() {
- SetDragPosition(invalidPosition);
+ SetDragPosition(SelectionPosition(invalidPosition));
}
#endif // wxUSE_DRAG_AND_DROP
//----------------------------------------------------------------------
#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__
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
('SC_', ''),
('SCN_', None), # just toss these out...
('SCEN_', None),
+ ('SC_EFF', None),
('SCE_', ''),
('SCLEX_', 'LEX_'),
('SCK_', 'KEY_'),
'MarkerSetFore' : ('MarkerSetForeground', 0, 0, 0),
'MarkerSetBack' : ('MarkerSetBackground', 0, 0, 0),
+ 'MarkerSymbolDefined' : ('GetMarkerSymbolDefined', 0, 0, 0),
+
'MarkerDefine' :
(0,
'''void %s(int markerNumber, int markerSymbol,
'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),
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),
'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),
'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),
'\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):
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
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);
** 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
}
int Width() { return right - left; }
int Height() { return bottom - top; }
- bool Empty() {
+ bool Empty() {
return (Height() <= 0) || (Width() <= 0);
}
};
*/
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;
};
*/
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();
* 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);
// 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 ©);
- 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
-// 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
-// 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;
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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
# 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.
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
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)
# 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.
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.
# 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.
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.
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,)
# 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
# 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(,)
# 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.
# 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.
# 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.
# 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,)
# 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,)
# 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
# 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(,)
# 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.
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.
val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
+val SCMOD_SUPER=8
################################################
# For SciLexer.h
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
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
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
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
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
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_
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
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
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
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)
-// 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
/**
*/
+
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];
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) {
}
--- /dev/null
+/** 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 );
+}
--- /dev/null
+/** 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
#include "Platform.h"
-#include "PropSet.h"
+#include "CharClassify.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE
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);
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();
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);
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) {
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);
}
}
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() {
// 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;
}
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,
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
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;
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;
style.ReAllocate(newSize);
}
+void CellBuffer::SetPerLine(PerLine *pl) {
+ lv.SetPerLine(pl);
+}
+
int CellBuffer::Lines() const {
return lv.Lines();
}
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) {
uh.EndUndoAction();
}
+void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
+ bool startSequence;
+ uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
+}
+
void CellBuffer::DeleteUndoHistory() {
uh.DeleteUndoHistory();
}
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();
-}
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;
};
/**
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);
int Lines() const {
return starts.Partitions();
}
- int LineFromPosition(int pos);
+ int LineFromPosition(int pos) const;
int LineStart(int line) const {
return starts.PositionFromPartition(line);
}
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.
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();
LineVector lv;
- SplitVector<int> lineStates;
-
public:
CellBuffer();
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);
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);
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
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
// 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"
}
}
}
+
+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;
+}
/** @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
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
#include "Partitioning.h"
#include "RunStyles.h"
#include "CellBuffer.h"
+#include "PerLine.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
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() {
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.
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);
}
}
}
-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++;
}
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);
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;
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)
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)
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();
}
}
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') {
}
void Document::ConvertLineEnds(int eolModeSet) {
- BeginUndoAction();
+ UndoGroup ug(this);
for (int pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
}
}
- EndUndoAction();
}
bool Document::IsWhiteLine(int line) const {
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;
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;
}
if (found) {
if ((!word && !wordStart) ||
- word && IsWordAt(pos, pos + lengthFind) ||
- wordStart && IsWordStartAt(pos))
+ (word && IsWordAt(pos, pos + lengthFind)) ||
+ (wordStart && IsWordStartAt(pos)))
return pos;
}
}
}
if (found) {
if ((!word && !wordStart) ||
- word && IsWordAt(pos, pos + lengthFind) ||
- wordStart && IsWordStartAt(pos))
+ (word && IsWordAt(pos, pos + lengthFind)) ||
+ (wordStart && IsWordStartAt(pos)))
return pos;
}
}
}
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 {
}
}
-bool Document::SetStyles(int length, char *styles) {
+bool Document::SetStyles(int length, const char *styles) {
if (enteredStyling != 0) {
return false;
} else {
}
}
-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);
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;
}
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;
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];
}
}
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
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. */
};
enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
-
private:
int refCount;
CellBuffer cb;
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;
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);
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);
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);
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;
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; }
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);
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.
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) :
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_),
text(act.data),
line(0),
foldLevelNow(0),
- foldLevelPrev(0) {}
+ foldLevelPrev(0),
+ annotationLinesAdded(0),
+ token(0) {}
};
/**
/**
*/
+
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;
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),
#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"
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
+#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
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;
verticalScrollBarVisible = true;
endAtLastLine = true;
caretSticky = false;
+ multipleSelection = false;
+ additionalSelectionTyping = false;
+ additionalCaretsBlink = true;
+ additionalCaretsVisible = true;
+ virtualSpaceOptions = SCVS_NONE;
pixmapLine = Surface::Allocate();
pixmapSelMargin = Surface::Allocate();
pixmapIndentGuide = Surface::Allocate();
pixmapIndentGuideHighlight = Surface::Allocate();
- currentPos = 0;
- anchor = 0;
-
targetStart = 0;
targetEnd = 0;
searchFlags = 0;
wrapVisualFlags = 0;
wrapVisualFlagsLocation = 0;
wrapVisualStartIndent = 0;
- actualWrapVisualStartIndent = 0;
+ wrapIndentMode = SC_WRAPINDENT_FIXED;
+ wrapAddIndent = 0;
convertPastes = true;
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() {
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();
}
}
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() {
}
};
-#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);
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)];
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)) {
}
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);
}
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) {
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));
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);
}
/**
}
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 {
}
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);
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 {
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;
}
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);
}
}
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
//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
}
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();
}
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
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;
}
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))) {
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) {
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));
}
lineEnd = pdoc->LineFromPosition(targetEnd);
}
- pdoc->EndUndoAction();
}
}
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;
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) {
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());
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) {
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;
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
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;
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;
}
}
}
-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) &&
}
}
+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);
} 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);
}
}
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
}
}
-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,
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;
}
}
- if (actualWrapVisualStartIndent != 0) {
+ if (ll->wrapIndent != 0) {
bool continuedWrapLine = false;
if (subLine < ll->lines) {
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 :
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
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') {
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 {
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) {
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);
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);
}
}
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;
}
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) {
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));
+ }
}
}
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);
+ }
+ }
}
}
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);
}
}
}
-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;
}
// 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.
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) {
}
}
+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);
//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;
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
// 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.
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.
//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);
//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;
//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;
}
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);
rcClient.right, yposScreen + vs.lineHeight);
surfaceWindow->Copy(rcCopyArea, from, *pixmapLine);
}
+
+ lineWidthMaxSeen = Platform::Maximum(
+ lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
//durCopy += et.Duration(true);
}
yposScreen += vs.lineHeight;
visibleLine++;
- lineWidthMaxSeen = Platform::Maximum(
- lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
//gdk_flush();
}
ll.Set(0);
// 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;
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;
LineLayout ll(8000);
LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
- ll.selStart = -1;
- ll.selEnd = -1;
ll.containsCaret = false;
PRectangle rcLine;
}
}
+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;
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();
}
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()) {
}
}
-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))
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);
}
}
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();
}
}
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();
}
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) {
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);
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);
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);
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);
}
}
} 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);
}
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
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
scn.line = mh.line;
scn.foldLevelNow = mh.foldLevelNow;
scn.foldLevelPrev = mh.foldLevelPrev;
+ scn.token = mh.token;
+ scn.annotationLinesAdded = mh.annotationLinesAdded;
NotifyParent(scn);
}
}
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
case SCI_SELECTIONDUPLICATE:
+ case SCI_COPYALLOWLINE:
break;
// Filter out all others like display changes. Also, newlines are redundant
* 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(
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());
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);
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() {
} 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++;
}
}
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;
}
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);
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;
SetLastXChosen();
break;
case SCI_DOCUMENTSTARTEXTEND:
- MovePositionTo(0, selStream);
+ MovePositionTo(0, Selection::selStream);
SetLastXChosen();
break;
case SCI_DOCUMENTEND:
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;
SetLastXChosen();
}
EnsureCaretVisible();
+ ShowCaretAtCurrentPosition(); // Avoid blinking
break;
case SCI_BACKTAB:
Indent(false);
SetLastXChosen();
}
EnsureCaretVisible();
+ ShowCaretAtCurrentPosition(); // Avoid blinking
break;
case SCI_NEWLINE:
NewLine();
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);
}
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;
}
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);
}
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);
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;
}
}
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));
- }
}
}
///< @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;
* operation is self-contained.
*/
void Editor::SearchAnchor() {
- searchAnchor = SelectionStart();
+ searchAnchor = SelectionStart().Position();
}
/**
(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,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
- (wParam & SCFIND_POSIX) != 0,
+ wParam,
&lengthFound);
}
(searchFlags & SCFIND_WHOLEWORD) != 0,
(searchFlags & SCFIND_WORDSTART) != 0,
(searchFlags & SCFIND_REGEXP) != 0,
- (searchFlags & SCFIND_POSIX) != 0,
+ searchFlags,
&lengthFound);
if (pos != -1) {
targetStart = pos;
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);
}
}
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();
//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();
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;
}
}
}
+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) {
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) {
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;
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())
}
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();
}
}
}
bool Editor::PointIsHotspot(Point pt) {
- int pos = PositionFromLocationClose(pt);
+ int pos = PositionFromLocation(pt, true);
if (pos == INVALID_POSITION)
return false;
return PositionIsHotspot(pos);
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)) {
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
// 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 {
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();
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 {
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)) {
}
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();
}
}
} 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;
}
}
+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);
pdoc->AddRef();
// Ensure all positions within document
- selType = selStream;
- currentPos = 0;
- anchor = 0;
+ sel.Clear();
targetStart = 0;
targetEnd = 0;
// Reset the contraction state to fully shown.
cs.Clear();
cs.InsertLines(0, pdoc->LinesTotal() - 1);
+ SetAnnotationHeights(0, pdoc->LinesTotal());
llc.Deallocate();
NeedWrapping();
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.
*/
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();
}
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;
}
}
targetEnd = targetStart;
pdoc->InsertString(targetStart, text, length);
targetEnd = targetStart + length;
- pdoc->EndUndoAction();
return length;
}
// 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) {
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);
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);
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;
}
Copy();
break;
+ case SCI_COPYALLOWLINE:
+ CopyAllowLine();
+ break;
+
case SCI_COPYRANGE:
CopyRangeToClipboard(wParam, lParam);
break;
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);
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:
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())
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;
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;
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();
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;
if (lParam == 0)
return 0;
pdoc->InsertString(CurrentPosition(), CharPtrFromSPtr(lParam), wParam);
- SetEmptySelection(currentPos + wParam);
+ SetEmptySelection(sel.MainCaret() + wParam);
return 0;
}
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;
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);
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);
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) {
ptr[iPlace++] = pdoc->CharAt(iChar);
}
ptr[iPlace] = '\0';
- return currentPos - lineStart;
+ return sel.MainCaret() - lineStart;
}
case SCI_GETENDSTYLED:
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;
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;
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;
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;
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);
break;
case SCI_HIDELINES:
- cs.SetVisible(wParam, lParam, false);
+ if (wParam > 0)
+ cs.SetVisible(wParam, lParam, false);
SetScrollBars();
Redraw();
break;
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;
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;
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;
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:
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:
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);
}
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)
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);
}
};
*/
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
bool hasFocus;
bool hideSelection;
bool inOverstrike;
- int errorStatus;
bool mouseDownCaptures;
/** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
bool verticalScrollBarVisible;
bool endAtLastLine;
bool caretSticky;
+ bool multipleSelection;
+ bool additionalSelectionTyping;
+ bool additionalCaretsBlink;
+ bool additionalCaretsVisible;
+
+ int virtualSpaceOptions;
Surface *pixmapLine;
Surface *pixmapSelMargin;
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;
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;
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;
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);
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);
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,
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;
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();
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);
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*/);
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_);
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);
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;
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;
};
#include <string.h>
#include <ctype.h>
+#include <string>
+
#include "Platform.h"
#include "Scintilla.h"
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];
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;
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,
void Release();
LexerLibrary *next;
- SString m_sModuleName;
+ std::string m_sModuleName;
};
/// LexerManager manages external lexers, contains LexerLibrarys.
--- /dev/null
+// 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
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);
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);
};
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;
LINK_LEXER(lmAns1);
LINK_LEXER(lmAPDL);
LINK_LEXER(lmAsm);
- LINK_LEXER(lmASP);
LINK_LEXER(lmASY);
LINK_LEXER(lmAU3);
LINK_LEXER(lmAVE);
LINK_LEXER(lmClw);
LINK_LEXER(lmClwNoCase);
LINK_LEXER(lmCmake);
+ LINK_LEXER(lmCOBOL);
LINK_LEXER(lmConf);
LINK_LEXER(lmCPP);
LINK_LEXER(lmCPPNoCase);
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);
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);
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);
//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
/** @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.
#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) {
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();
}
//------------------------------------------------------------------------------
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[] = {
#include <string.h>
#include <stdio.h>
+#include <string>
+
#include "Platform.h"
#include "Accessor.h"
#include "PropSet.h"
#include "KeyWords.h"
#include "SciLexer.h"
-#include "SString.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
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);
sc.Forward();
sc.Forward();
- SString identifier;
+ std::string identifier;
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
identifier += static_cast<char>(tolower(sc.ch));
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
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));
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;
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;
return false; // Just in case
// Decimal number
- if (hashPos == -1) {
+ if (hashPos == std::string::npos) {
bool canBeSpecial = false;
for (; i < length; i++) {
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 == '+' ||
// 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) {
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);
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);
}
}
/** @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') {
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
// 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) {
}
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;
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++;
--- /dev/null
+// 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);
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('$');
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 '\'
// if different sets of lines lexed.
visibleChars = 0;
lastWordWasUUID = false;
+ isIncludePreprocessor = false;
}
// Handle line continuation generically.
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();
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) {
} 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);
// 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);
levelNext--;
}
}
- if (atEOL) {
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
int levelUse = levelCurrent;
if (foldAtElse) {
levelUse = levelMinCurrent;
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++;
}
}
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 */
}
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('*', '/')) {
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)
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)
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 ']':
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;
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));
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)
}
}
- 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('/', '*')) {
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 == '{')
lastState = sc.state;
sc.SetState(SCE_CSS_OPERATOR);
op = sc.ch;
+ opPrev = sc.chPrev;
}
}
}
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
};
/** @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.
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>
#include "Platform.h"
#include "PropSet.h"
+#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
// 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 */
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)
{
// 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) {
// 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;
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 == '(')
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;
}
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:
// 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)
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
#include "Platform.h"
+#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
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) {
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);
// 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>
#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);
// 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>
#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];
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);
+
+
// 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);
// 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);
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
--- /dev/null
+# 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()
#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) {
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));
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;
// 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,
case eScriptSGML:
Result = SCE_H_SGML_DEFAULT;
break;
+ case eScriptComment:
+ Result = SCE_H_COMMENT;
+ break;
default :
Result = SCE_HJ_START;
break;
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) ||
(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[],
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)) {
}
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));
} 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
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);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
int visibleChars = 0;
+ int lineStartVisibleChars = 0;
int chPrev = ' ';
int ch = ' ';
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);
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:
levelPrev = levelCurrent;
}
lineCurrent++;
+ lineStartVisibleChars = 0;
styler.SetLineState(lineCurrent,
((inScriptType & 0x03) << 0) |
((tagOpened & 0x01) << 2) |
((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)
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);
(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
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)
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,
}
break;
case SCE_H_COMMENT:
- if ((chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
+ if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
styler.ColourTo(i, StateToPrint);
state = SCE_H_DEFAULT;
levelCurrent--;
}
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);
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
+ if (!tagDontFold) {
if (tagClosing) {
levelCurrent--;
} else {
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
- if (tagClosing){
+ if (!tagDontFold) {
+ if (tagClosing) {
levelCurrent--;
} else {
levelCurrent++;
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
- if (tagClosing){
+ if (!tagDontFold) {
+ if (tagClosing) {
levelCurrent--;
} else {
levelCurrent++;
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
- if (tagClosing){
+ if (!tagDontFold) {
+ if (tagClosing) {
levelCurrent--;
} else {
levelCurrent++;
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)) {
}
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:
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;
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)) {
}
}
- 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) {
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[] = {
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);
#include "Platform.h"
#include "PropSet.h"
+#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
// 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("--")) {
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);
#include "Platform.h"
+#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
char *buffer = new char[length];
int bufferCount = 0;
bool isBOL, isEOL, isWS, isBOLWS = 0;
+ bool isCode = false;
+ bool isCStyleComment = false;
WordList §ionKeywords = *keywordLists[0];
WordList &standardKeywords = *keywordLists[1];
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) {
} 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;
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);
// 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);
}
}
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);
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;
};
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);
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;
}
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;
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--;
}
}
#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.
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,
// 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') {
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)) {
}
} 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 == '\"') {
}
} 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 == '\'') {
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);
}
} 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();
}
#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
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 {
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
--- /dev/null
+// 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);
+
--- /dev/null
+/******************************************************************
+ * 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");
// 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
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) {
--- /dev/null
+/**
+ * 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);
--- /dev/null
+// 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);
#include "Platform.h"
+#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
}
}
- 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++ )
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--;
}
// 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
#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');
}
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
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]))) {
// 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
// Read up to %, Operator or Separator
while ((wbo < wbl) &&
(wordBuffer[wbo] != '%') &&
+ (wordBuffer[wbo] != '!') &&
(!IsBOperator(wordBuffer[wbo])) &&
(!IsBSeparator(wordBuffer[wbo]))) {
wbo++;
// Read up to %, Operator or Separator
while ((wbo < wbl) &&
(wordBuffer[wbo] != '%') &&
+ (wordBuffer[wbo] != '!') &&
(!IsBOperator(wordBuffer[wbo])) &&
(!IsBSeparator(wordBuffer[wbo]))) {
wbo++;
(!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) {
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] == '%')) {
// 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
// Read up to %, Operator or Separator
while ((wbo < wbl) &&
(wordBuffer[wbo] != '%') &&
+ (wordBuffer[wbo] != '!') &&
(!IsBOperator(wordBuffer[wbo])) &&
(!IsBSeparator(wordBuffer[wbo]))) {
wbo++;
// 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);
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 {
}
}
-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);
} while (static_cast<int>(startPos) + length > curLineStart);
}
-
-static void ColourisePropsLine(
+static void ColourisePoLine(
char *lineBuffer,
unsigned int lengthLine,
unsigned int startLine,
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);
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);
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);
}
}
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(
}
}
-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
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;
}
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];
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);
** 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,
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;
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;
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;
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
};
// 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);
};
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:
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) {
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);
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 == '}') {
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) {
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
levelCurrent = SC_FOLDLEVELBASE + 1;
isPackageLine = false;
}
- lev |= levelCurrent << 16;
+ lev |= levelCurrent << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
};
LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc, 8);
-
--- /dev/null
+// 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);
--- /dev/null
+// 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);
+
/** 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>
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;
}
// 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) {
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)) {
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 == '\"') {
} 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);
}
}
0,
};
-LexerModule lmProgress(SCLEX_PS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
+LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
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 == '\''))
}
/* 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
}
static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
+ WordList *keywordlists[], Accessor &styler) {
int endPos = startPos + length;
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;
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()) {
}
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;
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) {
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;
}
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;
}
}
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;
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++;
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();
}
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
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
LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
pythonWordListDesc);
+
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 {
if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
if (chNext == '{') {
levelCurrent++;
- } else if (chNext == '}') {
+ } else if (chNext == '}' && levelCurrent > 0) {
levelCurrent--;
}
}
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) {
--- /dev/null
+// 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);
+
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()) {
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);
}
} 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) {
--- /dev/null
+// 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);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include <string.h>
#include <stdio.h>
+#include <string>
+
#include "Platform.h"
#include "Accessor.h"
#include "PropSet.h"
#include "KeyWords.h"
#include "SciLexer.h"
-#include "SString.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
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).
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();
--- /dev/null
+// 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);
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
--- /dev/null
+// 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);
}
}
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)) {
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);
}
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();
}
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) {
// 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);
}
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--;
}
}
** 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>
} 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;
}
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) {
};
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);
}
~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);
return pos;
}
- int PartitionFromPosition(int pos) {
+ int PartitionFromPosition(int pos) const {
if (body->Length() <= 1)
return 0;
if (pos >= (PositionFromPartition(body->Length()-1)))
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
+#include "Selection.h"
#include "PositionCache.h"
#ifdef SCI_NAMESPACE
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),
hsStart(0),
hsEnd(0),
widthLine(wrapWidthInfinite),
- lines(1) {
+ lines(1),
+ wrapIndent(0) {
Resize(maxLineLength_);
}
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];
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) {
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_),
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);
return nextBreak;
}
+static bool IsTrailByte(int ch) {
+ return (ch >= 0x80) && (ch < (0x80 + 0x40));
+}
+
int BreakFinder::Next() {
if (subBreak == -1) {
int prev = nextBreak;
} 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;
}
}
subBreak = lastGoodBreak;
} else if (lastOKBreak >= 0) {
subBreak = lastOKBreak;
+ } else if (lastUTF8Break >= 0) {
+ subBreak = lastUTF8Break;
} else {
subBreak = nextBreak;
}
/** @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
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;
// Wrapped line support
int widthLine;
int lines;
+ int wrapIndent; // In pixels
LineLayout(int maxLineLength_);
virtual ~LineLayout();
char bracesMatchStyle, int xHighlight);
void RestoreBracesHighlight(Range rangeLine, Position braces[]);
int FindBefore(int x, int lower, int upper) const;
+ int EndLineStyle() const;
};
/**
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();
#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'))
}
}
-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);
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 "";
}
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;
}
--- /dev/null
+// 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
* 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"
/**
* 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
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
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;
ChSet(static_cast<unsigned char>(c));
}
}
+ break;
case 'w':
for (c = 0; c < MAXCHR; c++) {
if (iswordc(static_cast<unsigned char>(c))) {
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 */
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");
break;
case '^': /* match beginning */
- if (p == pat)
+ if (p == pattern)
*mp++ = BOL;
else {
*mp++ = CHR;
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... */
return NOTFOUND;
break;
case CCL:
+ if (lp >= endp)
+ return NOTFOUND;
c = ci.CharAt(lp++);
if (!isinset(ap,c))
return NOTFOUND;
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:
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);
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);
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));
}
/// 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
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);
#ifdef SCI_NAMESPACE
}
#endif
+
+#endif
+// 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
#include "Scintilla.h"
#include "PropSet.h"
+#include "PropSetSimple.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "Accessor.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
+#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
#include "ScintillaBase.h"
return 0;
default:
- ac.Cancel();
+ AutoCompleteCancel();
}
}
ct.CallTipCancel();
}
if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
- if (currentPos <= ct.posStartCallTip) {
+ if (sel.MainCaret() <= ct.posStartCallTip) {
ct.CallTipCancel();
}
}
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;
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();
}
void ScintillaBase::AutoCompleteCancel() {
+ if (ac.Active()) {
+ SCNotification scn = {0};
+ scn.nmhdr.code = SCN_AUTOCCANCELLED;
+ scn.wParam = 0;
+ scn.listType = 0;
+ NotifyParent(scn);
+ }
ac.Cancel();
}
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);
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() {
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;
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())
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
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,
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);
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) {
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) {
break;
case SCI_AUTOCCANCEL:
- AutoCompleteCancel();
+ ac.Cancel();
break;
case SCI_AUTOCACTIVE:
case SCI_AUTOCGETCURRENT:
return AutoCompleteGetCurrent();
+ case SCI_AUTOCGETCURRENTTEXT:
+ return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
+
case SCI_AUTOCSETCANCELATSTART:
ac.cancelAtStartPos = wParam != 0;
break;
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
}
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:
*/
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. */
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);
void AutoCompleteCancel();
void AutoCompleteMove(int delta);
int AutoCompleteGetCurrent();
+ int AutoCompleteGetCurrentText(char *buffer);
void AutoCompleteCharacterAdded(char ch);
void AutoCompleteCharacterDeleted();
void AutoCompleteCompleted();
--- /dev/null
+// 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();
+}
+
--- /dev/null
+// 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
/// 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);
}
DeleteRange(0, lengthBody);
}
+ T* BufferPointer() {
+ RoomFor(1);
+ GapTo(lengthBody);
+ body[lengthBody] = 0;
+ return body;
+ }
};
#endif
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;
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);};
};
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))) {
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 {
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;
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;
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() {
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;
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;
}
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) {
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);
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);
someStylesProtected = true;
}
}
+ maxAscent += extraAscent;
+ maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
void ViewStyle::EnsureStyle(size_t index) {
if (index >= stylesSize) {
size_t sizeNew = stylesSize * 2;
- while (sizeNew < index)
+ while (sizeNew <= index)
sizeNew *= 2;
AllocStyles(sizeNew);
}
bool ViewStyle::ProtectionActive() const {
return someStylesProtected;
}
+
+bool ViewStyle::ValidStyle(size_t styleIndex) const {
+ return styleIndex < stylesSize;
+}
+
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;
int fixedColumnWidth;
int zoomLevel;
WhiteSpaceVisibility viewWhitespace;
+ int whitespaceSize;
IndentView viewIndentationGuides;
bool viewEOL;
bool showMarkedLines;
ColourPair caretcolour;
+ ColourPair additionalCaretColour;
bool showCaretLineBackground;
ColourPair caretLineBackground;
int caretLineAlpha;
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);
void ClearStyles();
void SetStyleFontName(int styleIndex, const char *name);
bool ProtectionActive() const;
+ bool ValidStyle(size_t styleIndex) const;
};
#ifdef SCI_NAMESPACE
if (endPos > lenDoc)
endPos = lenDoc;
- TextRange tr = {{startPos, endPos}, buf};
+ Sci_TextRange tr = {{startPos, endPos}, buf};
Platform::SendScintillaPointer(id, SCI_GETTEXTRANGE, 0, &tr);
}
* Hold a pixmap in XPM format.
*/
class XPM {
- int id; // Assigned by container
+ int pid; // Assigned by container
int height;
int width;
int nColours;
/// 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);
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 );
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);
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));
}
// 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));
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.
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)
{
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()
{
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);
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)
{
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()
{
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;
}
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 );
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;
}
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,
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
#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