$(OBJS)\stcdll_LexAsn1.obj \
$(OBJS)\stcdll_LexBaan.obj \
$(OBJS)\stcdll_LexBash.obj \
+ $(OBJS)\stcdll_LexBasic.obj \
$(OBJS)\stcdll_LexBullant.obj \
$(OBJS)\stcdll_LexCLW.obj \
$(OBJS)\stcdll_LexCPP.obj \
$(OBJS)\stcdll_LexCSS.obj \
+ $(OBJS)\stcdll_LexCaml.obj \
+ $(OBJS)\stcdll_LexCsound.obj \
$(OBJS)\stcdll_LexConf.obj \
$(OBJS)\stcdll_LexCrontab.obj \
$(OBJS)\stcdll_LexEScript.obj \
$(OBJS)\stcdll_LexEiffel.obj \
$(OBJS)\stcdll_LexErlang.obj \
+ $(OBJS)\stcdll_LexFlagship.obj \
$(OBJS)\stcdll_LexForth.obj \
$(OBJS)\stcdll_LexFortran.obj \
$(OBJS)\stcdll_LexGui4Cli.obj \
$(OBJS)\stcdll_LexHTML.obj \
+ $(OBJS)\stcdll_LexHaskell.obj \
$(OBJS)\stcdll_LexKix.obj \
$(OBJS)\stcdll_LexLisp.obj \
$(OBJS)\stcdll_LexLout.obj \
$(OBJS)\stcdll_LexPascal.obj \
$(OBJS)\stcdll_LexPerl.obj \
$(OBJS)\stcdll_LexPython.obj \
+ $(OBJS)\stcdll_LexRebol.obj \
$(OBJS)\stcdll_LexRuby.obj \
$(OBJS)\stcdll_LexSQL.obj \
+ $(OBJS)\stcdll_LexSmalltalk.obj \
+ $(OBJS)\stcdll_LexTADS3.obj \
$(OBJS)\stcdll_LexScriptol.obj \
$(OBJS)\stcdll_LexSpecman.obj \
$(OBJS)\stcdll_LexTeX.obj \
$(OBJS)\stclib_LexAsn1.obj \
$(OBJS)\stclib_LexBaan.obj \
$(OBJS)\stclib_LexBash.obj \
+ $(OBJS)\stclib_LexBasic.obj \
$(OBJS)\stclib_LexBullant.obj \
$(OBJS)\stclib_LexCLW.obj \
$(OBJS)\stclib_LexCPP.obj \
$(OBJS)\stclib_LexCSS.obj \
+ $(OBJS)\stclib_LexCaml.obj \
+ $(OBJS)\stclib_LexCsound.obj \
$(OBJS)\stclib_LexConf.obj \
$(OBJS)\stclib_LexCrontab.obj \
$(OBJS)\stclib_LexEScript.obj \
$(OBJS)\stclib_LexEiffel.obj \
$(OBJS)\stclib_LexErlang.obj \
+ $(OBJS)\stclib_LexFlagship.obj \
$(OBJS)\stclib_LexForth.obj \
$(OBJS)\stclib_LexFortran.obj \
$(OBJS)\stclib_LexGui4Cli.obj \
$(OBJS)\stclib_LexHTML.obj \
+ $(OBJS)\stclib_LexHaskell.obj \
$(OBJS)\stclib_LexKix.obj \
$(OBJS)\stclib_LexLisp.obj \
$(OBJS)\stclib_LexLout.obj \
$(OBJS)\stclib_LexPascal.obj \
$(OBJS)\stclib_LexPerl.obj \
$(OBJS)\stclib_LexPython.obj \
+ $(OBJS)\stclib_LexRebol.obj \
$(OBJS)\stclib_LexRuby.obj \
$(OBJS)\stclib_LexSQL.obj \
+ $(OBJS)\stclib_LexSmalltalk.obj \
+ $(OBJS)\stclib_LexTADS3.obj \
$(OBJS)\stclib_LexScriptol.obj \
$(OBJS)\stclib_LexSpecman.obj \
$(OBJS)\stclib_LexTeX.obj \
$(OBJS)\stcdll_LexBash.obj: ../../src/stc\scintilla\src\LexBash.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexBasic.obj: ../../src/stc\scintilla\src\LexBasic.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexBullant.obj: ../../src/stc\scintilla\src\LexBullant.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexCSS.obj: ../../src/stc\scintilla\src\LexCSS.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexCaml.obj: ../../src/stc\scintilla\src\LexCaml.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
+$(OBJS)\stcdll_LexCsound.obj: ../../src/stc\scintilla\src\LexCsound.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexConf.obj: ../../src/stc\scintilla\src\LexConf.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexErlang.obj: ../../src/stc\scintilla\src\LexErlang.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexFlagship.obj: ../../src/stc\scintilla\src\LexFlagship.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexForth.obj: ../../src/stc\scintilla\src\LexForth.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexHTML.obj: ../../src/stc\scintilla\src\LexHTML.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexHaskell.obj: ../../src/stc\scintilla\src\LexHaskell.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexKix.obj: ../../src/stc\scintilla\src\LexKix.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexPython.obj: ../../src/stc\scintilla\src\LexPython.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexRebol.obj: ../../src/stc\scintilla\src\LexRebol.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexRuby.obj: ../../src/stc\scintilla\src\LexRuby.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexSQL.obj: ../../src/stc\scintilla\src\LexSQL.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexSmalltalk.obj: ../../src/stc\scintilla\src\LexSmalltalk.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
+$(OBJS)\stcdll_LexTADS3.obj: ../../src/stc\scintilla\src\LexTADS3.cxx
+ $(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexScriptol.obj: ../../src/stc\scintilla\src\LexScriptol.cxx
$(CXX) -q -c -P -o$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stclib_LexBash.obj: ../../src/stc\scintilla\src\LexBash.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexBasic.obj: ../../src/stc\scintilla\src\LexBasic.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexBullant.obj: ../../src/stc\scintilla\src\LexBullant.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexCSS.obj: ../../src/stc\scintilla\src\LexCSS.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexCaml.obj: ../../src/stc\scintilla\src\LexCaml.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
+$(OBJS)\stclib_LexCsound.obj: ../../src/stc\scintilla\src\LexCsound.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexConf.obj: ../../src/stc\scintilla\src\LexConf.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexErlang.obj: ../../src/stc\scintilla\src\LexErlang.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexFlagship.obj: ../../src/stc\scintilla\src\LexFlagship.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexForth.obj: ../../src/stc\scintilla\src\LexForth.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexHTML.obj: ../../src/stc\scintilla\src\LexHTML.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexHaskell.obj: ../../src/stc\scintilla\src\LexHaskell.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexKix.obj: ../../src/stc\scintilla\src\LexKix.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexPython.obj: ../../src/stc\scintilla\src\LexPython.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexRebol.obj: ../../src/stc\scintilla\src\LexRebol.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexRuby.obj: ../../src/stc\scintilla\src\LexRuby.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexSQL.obj: ../../src/stc\scintilla\src\LexSQL.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexSmalltalk.obj: ../../src/stc\scintilla\src\LexSmalltalk.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
+$(OBJS)\stclib_LexTADS3.obj: ../../src/stc\scintilla\src\LexTADS3.cxx
+ $(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexScriptol.obj: ../../src/stc\scintilla\src\LexScriptol.cxx
$(CXX) -q -c -P -o$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stcdll_LexAsn1.o \
$(OBJS)\stcdll_LexBaan.o \
$(OBJS)\stcdll_LexBash.o \
+ $(OBJS)\stcdll_LexBasic.o \
$(OBJS)\stcdll_LexBullant.o \
$(OBJS)\stcdll_LexCLW.o \
$(OBJS)\stcdll_LexCPP.o \
$(OBJS)\stcdll_LexCSS.o \
+ $(OBJS)\stcdll_LexCaml.o \
+ $(OBJS)\stcdll_LexCsound.o \
$(OBJS)\stcdll_LexConf.o \
$(OBJS)\stcdll_LexCrontab.o \
$(OBJS)\stcdll_LexEScript.o \
$(OBJS)\stcdll_LexEiffel.o \
$(OBJS)\stcdll_LexErlang.o \
+ $(OBJS)\stcdll_LexFlagship.o \
$(OBJS)\stcdll_LexForth.o \
$(OBJS)\stcdll_LexFortran.o \
$(OBJS)\stcdll_LexGui4Cli.o \
$(OBJS)\stcdll_LexHTML.o \
+ $(OBJS)\stcdll_LexHaskell.o \
$(OBJS)\stcdll_LexKix.o \
$(OBJS)\stcdll_LexLisp.o \
$(OBJS)\stcdll_LexLout.o \
$(OBJS)\stcdll_LexPascal.o \
$(OBJS)\stcdll_LexPerl.o \
$(OBJS)\stcdll_LexPython.o \
+ $(OBJS)\stcdll_LexRebol.o \
$(OBJS)\stcdll_LexRuby.o \
$(OBJS)\stcdll_LexSQL.o \
+ $(OBJS)\stcdll_LexSmalltalk.o \
+ $(OBJS)\stcdll_LexTADS3.o \
$(OBJS)\stcdll_LexScriptol.o \
$(OBJS)\stcdll_LexSpecman.o \
$(OBJS)\stcdll_LexTeX.o \
$(OBJS)\stclib_LexAsn1.o \
$(OBJS)\stclib_LexBaan.o \
$(OBJS)\stclib_LexBash.o \
+ $(OBJS)\stclib_LexBasic.o \
$(OBJS)\stclib_LexBullant.o \
$(OBJS)\stclib_LexCLW.o \
$(OBJS)\stclib_LexCPP.o \
$(OBJS)\stclib_LexCSS.o \
+ $(OBJS)\stclib_LexCaml.o \
+ $(OBJS)\stclib_LexCsound.o \
$(OBJS)\stclib_LexConf.o \
$(OBJS)\stclib_LexCrontab.o \
$(OBJS)\stclib_LexEScript.o \
$(OBJS)\stclib_LexEiffel.o \
$(OBJS)\stclib_LexErlang.o \
+ $(OBJS)\stclib_LexFlagship.o \
$(OBJS)\stclib_LexForth.o \
$(OBJS)\stclib_LexFortran.o \
$(OBJS)\stclib_LexGui4Cli.o \
$(OBJS)\stclib_LexHTML.o \
+ $(OBJS)\stclib_LexHaskell.o \
$(OBJS)\stclib_LexKix.o \
$(OBJS)\stclib_LexLisp.o \
$(OBJS)\stclib_LexLout.o \
$(OBJS)\stclib_LexPascal.o \
$(OBJS)\stclib_LexPerl.o \
$(OBJS)\stclib_LexPython.o \
+ $(OBJS)\stclib_LexRebol.o \
$(OBJS)\stclib_LexRuby.o \
$(OBJS)\stclib_LexSQL.o \
+ $(OBJS)\stclib_LexSmalltalk.o \
+ $(OBJS)\stclib_LexTADS3.o \
$(OBJS)\stclib_LexScriptol.o \
$(OBJS)\stclib_LexSpecman.o \
$(OBJS)\stclib_LexTeX.o \
$(OBJS)\stcdll_LexBash.o: ../../src/stc/scintilla/src/LexBash.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stcdll_LexBasic.o: ../../src/stc/scintilla/src/LexBasic.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stcdll_LexBullant.o: ../../src/stc/scintilla/src/LexBullant.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stcdll_LexCSS.o: ../../src/stc/scintilla/src/LexCSS.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stcdll_LexCaml.o: ../../src/stc/scintilla/src/LexCaml.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
+$(OBJS)\stcdll_LexCsound.o: ../../src/stc/scintilla/src/LexCsound.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stcdll_LexConf.o: ../../src/stc/scintilla/src/LexConf.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stcdll_LexErlang.o: ../../src/stc/scintilla/src/LexErlang.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stcdll_LexFlagship.o: ../../src/stc/scintilla/src/LexFlagship.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stcdll_LexForth.o: ../../src/stc/scintilla/src/LexForth.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stcdll_LexHTML.o: ../../src/stc/scintilla/src/LexHTML.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stcdll_LexHaskell.o: ../../src/stc/scintilla/src/LexHaskell.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stcdll_LexKix.o: ../../src/stc/scintilla/src/LexKix.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stcdll_LexPython.o: ../../src/stc/scintilla/src/LexPython.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stcdll_LexRebol.o: ../../src/stc/scintilla/src/LexRebol.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stcdll_LexRuby.o: ../../src/stc/scintilla/src/LexRuby.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stcdll_LexSQL.o: ../../src/stc/scintilla/src/LexSQL.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stcdll_LexSmalltalk.o: ../../src/stc/scintilla/src/LexSmalltalk.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
+$(OBJS)\stcdll_LexTADS3.o: ../../src/stc/scintilla/src/LexTADS3.cxx
+ $(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stcdll_LexScriptol.o: ../../src/stc/scintilla/src/LexScriptol.cxx
$(CXX) -c -o $@ $(STCDLL_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stclib_LexBash.o: ../../src/stc/scintilla/src/LexBash.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stclib_LexBasic.o: ../../src/stc/scintilla/src/LexBasic.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stclib_LexBullant.o: ../../src/stc/scintilla/src/LexBullant.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stclib_LexCSS.o: ../../src/stc/scintilla/src/LexCSS.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stclib_LexCaml.o: ../../src/stc/scintilla/src/LexCaml.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
+$(OBJS)\stclib_LexCsound.o: ../../src/stc/scintilla/src/LexCsound.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stclib_LexConf.o: ../../src/stc/scintilla/src/LexConf.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stclib_LexErlang.o: ../../src/stc/scintilla/src/LexErlang.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stclib_LexFlagship.o: ../../src/stc/scintilla/src/LexFlagship.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stclib_LexForth.o: ../../src/stc/scintilla/src/LexForth.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stclib_LexHTML.o: ../../src/stc/scintilla/src/LexHTML.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stclib_LexHaskell.o: ../../src/stc/scintilla/src/LexHaskell.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stclib_LexKix.o: ../../src/stc/scintilla/src/LexKix.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stclib_LexPython.o: ../../src/stc/scintilla/src/LexPython.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stclib_LexRebol.o: ../../src/stc/scintilla/src/LexRebol.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stclib_LexRuby.o: ../../src/stc/scintilla/src/LexRuby.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stclib_LexSQL.o: ../../src/stc/scintilla/src/LexSQL.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\stclib_LexSmalltalk.o: ../../src/stc/scintilla/src/LexSmalltalk.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
+$(OBJS)\stclib_LexTADS3.o: ../../src/stc/scintilla/src/LexTADS3.cxx
+ $(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\stclib_LexScriptol.o: ../../src/stc/scintilla/src/LexScriptol.cxx
$(CXX) -c -o $@ $(STCLIB_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\stcdll_LexAsn1.obj \
$(OBJS)\stcdll_LexBaan.obj \
$(OBJS)\stcdll_LexBash.obj \
+ $(OBJS)\stcdll_LexBasic.obj \
$(OBJS)\stcdll_LexBullant.obj \
$(OBJS)\stcdll_LexCLW.obj \
$(OBJS)\stcdll_LexCPP.obj \
$(OBJS)\stcdll_LexCSS.obj \
+ $(OBJS)\stcdll_LexCaml.obj \
+ $(OBJS)\stcdll_LexCsound.obj \
$(OBJS)\stcdll_LexConf.obj \
$(OBJS)\stcdll_LexCrontab.obj \
$(OBJS)\stcdll_LexEScript.obj \
$(OBJS)\stcdll_LexEiffel.obj \
$(OBJS)\stcdll_LexErlang.obj \
+ $(OBJS)\stcdll_LexFlagship.obj \
$(OBJS)\stcdll_LexForth.obj \
$(OBJS)\stcdll_LexFortran.obj \
$(OBJS)\stcdll_LexGui4Cli.obj \
$(OBJS)\stcdll_LexHTML.obj \
+ $(OBJS)\stcdll_LexHaskell.obj \
$(OBJS)\stcdll_LexKix.obj \
$(OBJS)\stcdll_LexLisp.obj \
$(OBJS)\stcdll_LexLout.obj \
$(OBJS)\stcdll_LexPascal.obj \
$(OBJS)\stcdll_LexPerl.obj \
$(OBJS)\stcdll_LexPython.obj \
+ $(OBJS)\stcdll_LexRebol.obj \
$(OBJS)\stcdll_LexRuby.obj \
$(OBJS)\stcdll_LexSQL.obj \
+ $(OBJS)\stcdll_LexSmalltalk.obj \
+ $(OBJS)\stcdll_LexTADS3.obj \
$(OBJS)\stcdll_LexScriptol.obj \
$(OBJS)\stcdll_LexSpecman.obj \
$(OBJS)\stcdll_LexTeX.obj \
$(OBJS)\stclib_LexAsn1.obj \
$(OBJS)\stclib_LexBaan.obj \
$(OBJS)\stclib_LexBash.obj \
+ $(OBJS)\stclib_LexBasic.obj \
$(OBJS)\stclib_LexBullant.obj \
$(OBJS)\stclib_LexCLW.obj \
$(OBJS)\stclib_LexCPP.obj \
$(OBJS)\stclib_LexCSS.obj \
+ $(OBJS)\stclib_LexCaml.obj \
+ $(OBJS)\stclib_LexCsound.obj \
$(OBJS)\stclib_LexConf.obj \
$(OBJS)\stclib_LexCrontab.obj \
$(OBJS)\stclib_LexEScript.obj \
$(OBJS)\stclib_LexEiffel.obj \
$(OBJS)\stclib_LexErlang.obj \
+ $(OBJS)\stclib_LexFlagship.obj \
$(OBJS)\stclib_LexForth.obj \
$(OBJS)\stclib_LexFortran.obj \
$(OBJS)\stclib_LexGui4Cli.obj \
$(OBJS)\stclib_LexHTML.obj \
+ $(OBJS)\stclib_LexHaskell.obj \
$(OBJS)\stclib_LexKix.obj \
$(OBJS)\stclib_LexLisp.obj \
$(OBJS)\stclib_LexLout.obj \
$(OBJS)\stclib_LexPascal.obj \
$(OBJS)\stclib_LexPerl.obj \
$(OBJS)\stclib_LexPython.obj \
+ $(OBJS)\stclib_LexRebol.obj \
$(OBJS)\stclib_LexRuby.obj \
$(OBJS)\stclib_LexSQL.obj \
+ $(OBJS)\stclib_LexSmalltalk.obj \
+ $(OBJS)\stclib_LexTADS3.obj \
$(OBJS)\stclib_LexScriptol.obj \
$(OBJS)\stclib_LexSpecman.obj \
$(OBJS)\stclib_LexTeX.obj \
$(OBJS)\stcdll_LexBash.obj: ../../src/stc\scintilla\src\LexBash.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexBasic.obj: ../../src/stc\scintilla\src\LexBasic.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexBullant.obj: ../../src/stc\scintilla\src\LexBullant.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexCSS.obj: ../../src/stc\scintilla\src\LexCSS.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexCaml.obj: ../../src/stc\scintilla\src\LexCaml.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
+$(OBJS)\stcdll_LexCsound.obj: ../../src/stc\scintilla\src\LexCsound.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexConf.obj: ../../src/stc\scintilla\src\LexConf.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexErlang.obj: ../../src/stc\scintilla\src\LexErlang.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexFlagship.obj: ../../src/stc\scintilla\src\LexFlagship.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexForth.obj: ../../src/stc\scintilla\src\LexForth.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexHTML.obj: ../../src/stc\scintilla\src\LexHTML.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexHaskell.obj: ../../src/stc\scintilla\src\LexHaskell.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexKix.obj: ../../src/stc\scintilla\src\LexKix.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexPython.obj: ../../src/stc\scintilla\src\LexPython.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexRebol.obj: ../../src/stc\scintilla\src\LexRebol.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexRuby.obj: ../../src/stc\scintilla\src\LexRuby.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stcdll_LexSQL.obj: ../../src/stc\scintilla\src\LexSQL.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+$(OBJS)\stcdll_LexSmalltalk.obj: ../../src/stc\scintilla\src\LexSmalltalk.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
+$(OBJS)\stcdll_LexTADS3.obj: ../../src/stc\scintilla\src\LexTADS3.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
+
$(OBJS)\stcdll_LexScriptol.obj: ../../src/stc\scintilla\src\LexScriptol.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCDLL_CXXFLAGS) $**
$(OBJS)\stclib_LexBash.obj: ../../src/stc\scintilla\src\LexBash.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexBasic.obj: ../../src/stc\scintilla\src\LexBasic.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexBullant.obj: ../../src/stc\scintilla\src\LexBullant.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexCSS.obj: ../../src/stc\scintilla\src\LexCSS.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexCaml.obj: ../../src/stc\scintilla\src\LexCaml.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
+$(OBJS)\stclib_LexCsound.obj: ../../src/stc\scintilla\src\LexCsound.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexConf.obj: ../../src/stc\scintilla\src\LexConf.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexErlang.obj: ../../src/stc\scintilla\src\LexErlang.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexFlagship.obj: ../../src/stc\scintilla\src\LexFlagship.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexForth.obj: ../../src/stc\scintilla\src\LexForth.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexHTML.obj: ../../src/stc\scintilla\src\LexHTML.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexHaskell.obj: ../../src/stc\scintilla\src\LexHaskell.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexKix.obj: ../../src/stc\scintilla\src\LexKix.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexPython.obj: ../../src/stc\scintilla\src\LexPython.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexRebol.obj: ../../src/stc\scintilla\src\LexRebol.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexRuby.obj: ../../src/stc\scintilla\src\LexRuby.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stclib_LexSQL.obj: ../../src/stc\scintilla\src\LexSQL.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+$(OBJS)\stclib_LexSmalltalk.obj: ../../src/stc\scintilla\src\LexSmalltalk.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
+$(OBJS)\stclib_LexTADS3.obj: ../../src/stc\scintilla\src\LexTADS3.cxx
+ $(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
+
$(OBJS)\stclib_LexScriptol.obj: ../../src/stc\scintilla\src\LexScriptol.cxx
$(CXX) /c /nologo /TP /Fo$@ $(STCLIB_CXXFLAGS) $**
$(OBJS)\stcdll_LexAsn1.obj &
$(OBJS)\stcdll_LexBaan.obj &
$(OBJS)\stcdll_LexBash.obj &
+ $(OBJS)\stcdll_LexBasic.obj &
$(OBJS)\stcdll_LexBullant.obj &
$(OBJS)\stcdll_LexCLW.obj &
$(OBJS)\stcdll_LexCPP.obj &
$(OBJS)\stcdll_LexCSS.obj &
+ $(OBJS)\stcdll_LexCaml.obj &
+ $(OBJS)\stcdll_LexCsound.obj &
$(OBJS)\stcdll_LexConf.obj &
$(OBJS)\stcdll_LexCrontab.obj &
$(OBJS)\stcdll_LexEScript.obj &
$(OBJS)\stcdll_LexEiffel.obj &
$(OBJS)\stcdll_LexErlang.obj &
+ $(OBJS)\stcdll_LexFlagship.obj &
$(OBJS)\stcdll_LexForth.obj &
$(OBJS)\stcdll_LexFortran.obj &
$(OBJS)\stcdll_LexGui4Cli.obj &
$(OBJS)\stcdll_LexHTML.obj &
+ $(OBJS)\stcdll_LexHaskell.obj &
$(OBJS)\stcdll_LexKix.obj &
$(OBJS)\stcdll_LexLisp.obj &
$(OBJS)\stcdll_LexLout.obj &
$(OBJS)\stcdll_LexPascal.obj &
$(OBJS)\stcdll_LexPerl.obj &
$(OBJS)\stcdll_LexPython.obj &
+ $(OBJS)\stcdll_LexRebol.obj &
$(OBJS)\stcdll_LexRuby.obj &
$(OBJS)\stcdll_LexSQL.obj &
+ $(OBJS)\stcdll_LexSmalltalk.obj &
+ $(OBJS)\stcdll_LexTADS3.obj &
$(OBJS)\stcdll_LexScriptol.obj &
$(OBJS)\stcdll_LexSpecman.obj &
$(OBJS)\stcdll_LexTeX.obj &
$(OBJS)\stclib_LexAsn1.obj &
$(OBJS)\stclib_LexBaan.obj &
$(OBJS)\stclib_LexBash.obj &
+ $(OBJS)\stclib_LexBasic.obj &
$(OBJS)\stclib_LexBullant.obj &
$(OBJS)\stclib_LexCLW.obj &
$(OBJS)\stclib_LexCPP.obj &
$(OBJS)\stclib_LexCSS.obj &
+ $(OBJS)\stclib_LexCaml.obj &
+ $(OBJS)\stclib_LexCsound.obj &
$(OBJS)\stclib_LexConf.obj &
$(OBJS)\stclib_LexCrontab.obj &
$(OBJS)\stclib_LexEScript.obj &
$(OBJS)\stclib_LexEiffel.obj &
$(OBJS)\stclib_LexErlang.obj &
+ $(OBJS)\stclib_LexFlagship.obj &
$(OBJS)\stclib_LexForth.obj &
$(OBJS)\stclib_LexFortran.obj &
$(OBJS)\stclib_LexGui4Cli.obj &
$(OBJS)\stclib_LexHTML.obj &
+ $(OBJS)\stclib_LexHaskell.obj &
$(OBJS)\stclib_LexKix.obj &
$(OBJS)\stclib_LexLisp.obj &
$(OBJS)\stclib_LexLout.obj &
$(OBJS)\stclib_LexPascal.obj &
$(OBJS)\stclib_LexPerl.obj &
$(OBJS)\stclib_LexPython.obj &
+ $(OBJS)\stclib_LexRebol.obj &
$(OBJS)\stclib_LexRuby.obj &
$(OBJS)\stclib_LexSQL.obj &
+ $(OBJS)\stclib_LexSmalltalk.obj &
+ $(OBJS)\stclib_LexTADS3.obj &
$(OBJS)\stclib_LexScriptol.obj &
$(OBJS)\stclib_LexSpecman.obj &
$(OBJS)\stclib_LexTeX.obj &
$(OBJS)\stcdll_LexBash.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexBash.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+$(OBJS)\stcdll_LexBasic.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexBasic.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
$(OBJS)\stcdll_LexBullant.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexBullant.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
$(OBJS)\stcdll_LexCSS.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexCSS.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+$(OBJS)\stcdll_LexCaml.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexCaml.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
+$(OBJS)\stcdll_LexCsound.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexCsound.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
$(OBJS)\stcdll_LexConf.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexConf.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
$(OBJS)\stcdll_LexErlang.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexErlang.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+$(OBJS)\stcdll_LexFlagship.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexFlagship.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
$(OBJS)\stcdll_LexForth.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexForth.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
$(OBJS)\stcdll_LexHTML.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexHTML.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+$(OBJS)\stcdll_LexHaskell.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexHaskell.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
$(OBJS)\stcdll_LexKix.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexKix.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
$(OBJS)\stcdll_LexPython.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexPython.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+$(OBJS)\stcdll_LexRebol.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexRebol.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
$(OBJS)\stcdll_LexRuby.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexRuby.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
$(OBJS)\stcdll_LexSQL.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexSQL.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+$(OBJS)\stcdll_LexSmalltalk.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexSmalltalk.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
+$(OBJS)\stcdll_LexTADS3.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexTADS3.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
+
$(OBJS)\stcdll_LexScriptol.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexScriptol.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCDLL_CXXFLAGS) $<
$(OBJS)\stclib_LexBash.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexBash.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+$(OBJS)\stclib_LexBasic.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexBasic.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
$(OBJS)\stclib_LexBullant.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexBullant.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
$(OBJS)\stclib_LexCSS.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexCSS.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+$(OBJS)\stclib_LexCaml.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexCaml.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
+$(OBJS)\stclib_LexCsound.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexCsound.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
$(OBJS)\stclib_LexConf.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexConf.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
$(OBJS)\stclib_LexErlang.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexErlang.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+$(OBJS)\stclib_LexFlagship.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexFlagship.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
$(OBJS)\stclib_LexForth.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexForth.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
$(OBJS)\stclib_LexHTML.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexHTML.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+$(OBJS)\stclib_LexHaskell.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexHaskell.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
$(OBJS)\stclib_LexKix.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexKix.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
$(OBJS)\stclib_LexPython.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexPython.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+$(OBJS)\stclib_LexRebol.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexRebol.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
$(OBJS)\stclib_LexRuby.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexRuby.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
$(OBJS)\stclib_LexSQL.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexSQL.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+$(OBJS)\stclib_LexSmalltalk.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexSmalltalk.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
+$(OBJS)\stclib_LexTADS3.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexTADS3.cxx
+ $(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
+
$(OBJS)\stclib_LexScriptol.obj : .AUTODEPEND ../../src/stc\scintilla\src\LexScriptol.cxx
$(CXX) -bt=nt -zq -fo=$^@ $(STCLIB_CXXFLAGS) $<
scintilla/src/LexAsn1.cxx
scintilla/src/LexBaan.cxx
scintilla/src/LexBash.cxx
+ scintilla/src/LexBasic.cxx
scintilla/src/LexBullant.cxx
scintilla/src/LexCLW.cxx
scintilla/src/LexCPP.cxx
scintilla/src/LexCSS.cxx
+ scintilla/src/LexCaml.cxx
+ scintilla/src/LexCsound.cxx
scintilla/src/LexConf.cxx
scintilla/src/LexCrontab.cxx
scintilla/src/LexEScript.cxx
scintilla/src/LexEiffel.cxx
scintilla/src/LexErlang.cxx
+ scintilla/src/LexFlagship.cxx
scintilla/src/LexForth.cxx
scintilla/src/LexFortran.cxx
scintilla/src/LexGui4Cli.cxx
scintilla/src/LexHTML.cxx
+ scintilla/src/LexHaskell.cxx
scintilla/src/LexKix.cxx
scintilla/src/LexLisp.cxx
scintilla/src/LexLout.cxx
scintilla/src/LexPascal.cxx
scintilla/src/LexPerl.cxx
scintilla/src/LexPython.cxx
+ scintilla/src/LexRebol.cxx
scintilla/src/LexRuby.cxx
scintilla/src/LexSQL.cxx
+ scintilla/src/LexSmalltalk.cxx
+ scintilla/src/LexTADS3.cxx
scintilla/src/LexScriptol.cxx
scintilla/src/LexSpecman.cxx
scintilla/src/LexTeX.cxx
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexBasic.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexBullant.cxx
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexCaml.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexConf.cxx
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexCsound.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexEScript.cxx
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexFlagship.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexForth.cxx
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexHaskell.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexKix.cxx
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexRebol.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexRuby.cxx
# End Source File
# Begin Source File
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexSmalltalk.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexSpecman.cxx
# End Source File
# Begin Source File
+SOURCE=../../src/stc\scintilla\src\LexTADS3.cxx
+# End Source File
+# Begin Source File
+
SOURCE=../../src/stc\scintilla\src\LexTeX.cxx
# End Source File
# Begin Source File
#define wxSTC_MARK_DOTDOTDOT 23
#define wxSTC_MARK_ARROWS 24
#define wxSTC_MARK_PIXMAP 25
+#define wxSTC_MARK_FULLRECT 26
#define wxSTC_MARK_CHARACTER 10000
// Markers used for outlining column.
#define wxSTC_CHARSET_MAC 77
#define wxSTC_CHARSET_OEM 255
#define wxSTC_CHARSET_RUSSIAN 204
+#define wxSTC_CHARSET_CYRILLIC 1251
#define wxSTC_CHARSET_SHIFTJIS 128
#define wxSTC_CHARSET_SYMBOL 2
#define wxSTC_CHARSET_TURKISH 162
#define wxSTC_CHARSET_ARABIC 178
#define wxSTC_CHARSET_VIETNAMESE 163
#define wxSTC_CHARSET_THAI 222
+#define wxSTC_CHARSET_8859_15 1000
#define wxSTC_CASE_MIXED 0
#define wxSTC_CASE_UPPER 1
#define wxSTC_CASE_LOWER 2
#define wxSTC_TIME_FOREVER 10000000
#define wxSTC_WRAP_NONE 0
#define wxSTC_WRAP_WORD 1
+#define wxSTC_WRAP_CHAR 2
#define wxSTC_WRAPVISUALFLAG_NONE 0x0000
#define wxSTC_WRAPVISUALFLAG_END 0x0001
#define wxSTC_WRAPVISUALFLAG_START 0x0002
#define wxSTC_PERFORMED_USER 0x10
#define wxSTC_PERFORMED_UNDO 0x20
#define wxSTC_PERFORMED_REDO 0x40
+#define wxSTC_MULTISTEPUNDOREDO 0x80
#define wxSTC_LASTSTEPINUNDOREDO 0x100
#define wxSTC_MOD_CHANGEMARKER 0x200
#define wxSTC_MOD_BEFOREINSERT 0x400
#define wxSTC_MOD_BEFOREDELETE 0x800
-#define wxSTC_MODEVENTMASKALL 0xF77
+#define wxSTC_MULTILINEUNDOREDO 0x1000
+#define wxSTC_MODEVENTMASKALL 0x1FFF
// Symbolic key codes and modifier flags.
// ASCII and other printable characters below 256.
#define wxSTC_KEY_ADD 310
#define wxSTC_KEY_SUBTRACT 311
#define wxSTC_KEY_DIVIDE 312
+#define wxSTC_SCMOD_NORM 0
#define wxSTC_SCMOD_SHIFT 1
#define wxSTC_SCMOD_CTRL 2
#define wxSTC_SCMOD_ALT 4
#define wxSTC_LEX_NNCRONTAB 26
#define wxSTC_LEX_BULLANT 27
#define wxSTC_LEX_VBSCRIPT 28
-#define wxSTC_LEX_ASP 29
-#define wxSTC_LEX_PHP 30
#define wxSTC_LEX_BAAN 31
#define wxSTC_LEX_MATLAB 32
#define wxSTC_LEX_SCRIPTOL 33
#define wxSTC_LEX_BASH 62
#define wxSTC_LEX_ASN1 63
#define wxSTC_LEX_VHDL 64
+#define wxSTC_LEX_CAML 65
+#define wxSTC_LEX_BLITZBASIC 66
+#define wxSTC_LEX_PUREBASIC 67
+#define wxSTC_LEX_HASKELL 68
+#define wxSTC_LEX_PHPSCRIPT 69
+#define wxSTC_LEX_TADS3 70
+#define wxSTC_LEX_REBOL 71
+#define wxSTC_LEX_SMALLTALK 72
+#define wxSTC_LEX_FLAGSHIP 73
+#define wxSTC_LEX_CSOUND 74
+#define wxSTC_LEX_FREEBASIC 75
// When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
// value assigned in sequence from SCLEX_AUTOMATIC+1.
#define wxSTC_P_IDENTIFIER 11
#define wxSTC_P_COMMENTBLOCK 12
#define wxSTC_P_STRINGEOL 13
+#define wxSTC_P_WORD2 14
+#define wxSTC_P_DECORATOR 15
// Lexical states for SCLEX_CPP
#define wxSTC_C_DEFAULT 0
#define wxSTC_PL_ARRAY 13
#define wxSTC_PL_HASH 14
#define wxSTC_PL_SYMBOLTABLE 15
+#define wxSTC_PL_VARIABLE_INDEXER 16
#define wxSTC_PL_REGEX 17
#define wxSTC_PL_REGSUBST 18
#define wxSTC_PL_LONGQUOTE 19
#define wxSTC_PL_STRING_QX 28
#define wxSTC_PL_STRING_QR 29
#define wxSTC_PL_STRING_QW 30
+#define wxSTC_PL_POD_VERB 31
+
+// Lexical states for SCLEX_RUBY
+#define wxSTC_RB_DEFAULT 0
+#define wxSTC_RB_ERROR 1
+#define wxSTC_RB_COMMENTLINE 2
+#define wxSTC_RB_POD 3
+#define wxSTC_RB_NUMBER 4
+#define wxSTC_RB_WORD 5
+#define wxSTC_RB_STRING 6
+#define wxSTC_RB_CHARACTER 7
+#define wxSTC_RB_CLASSNAME 8
+#define wxSTC_RB_DEFNAME 9
+#define wxSTC_RB_OPERATOR 10
+#define wxSTC_RB_IDENTIFIER 11
+#define wxSTC_RB_REGEX 12
+#define wxSTC_RB_GLOBAL 13
+#define wxSTC_RB_SYMBOL 14
+#define wxSTC_RB_MODULE_NAME 15
+#define wxSTC_RB_INSTANCE_VAR 16
+#define wxSTC_RB_CLASS_VAR 17
+#define wxSTC_RB_BACKTICKS 18
+#define wxSTC_RB_DATASECTION 19
+#define wxSTC_RB_HERE_DELIM 20
+#define wxSTC_RB_HERE_Q 21
+#define wxSTC_RB_HERE_QQ 22
+#define wxSTC_RB_HERE_QX 23
+#define wxSTC_RB_STRING_Q 24
+#define wxSTC_RB_STRING_QQ 25
+#define wxSTC_RB_STRING_QX 26
+#define wxSTC_RB_STRING_QR 27
+#define wxSTC_RB_STRING_QW 28
+#define wxSTC_RB_WORD_DEMOTED 29
+#define wxSTC_RB_STDIN 30
+#define wxSTC_RB_STDOUT 31
+#define wxSTC_RB_STDERR 40
+#define wxSTC_RB_UPPER_BOUND 41
// Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC
#define wxSTC_B_DEFAULT 0
#define wxSTC_B_KEYWORD4 12
#define wxSTC_B_CONSTANT 13
#define wxSTC_B_ASM 14
+#define wxSTC_B_LABEL 15
+#define wxSTC_B_ERROR 16
+#define wxSTC_B_HEXNUMBER 17
+#define wxSTC_B_BINNUMBER 18
// Lexical states for SCLEX_PROPERTIES
#define wxSTC_PROPS_DEFAULT 0
#define wxSTC_LISP_COMMENT 1
#define wxSTC_LISP_NUMBER 2
#define wxSTC_LISP_KEYWORD 3
+#define wxSTC_LISP_KEYWORD_KW 4
+#define wxSTC_LISP_SYMBOL 5
#define wxSTC_LISP_STRING 6
#define wxSTC_LISP_STRINGEOL 8
#define wxSTC_LISP_IDENTIFIER 9
#define wxSTC_LISP_OPERATOR 10
+#define wxSTC_LISP_SPECIAL 11
+#define wxSTC_LISP_MULTI_COMMENT 12
// Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW
#define wxSTC_EIFFEL_DEFAULT 0
#define wxSTC_CSS_DOUBLESTRING 13
#define wxSTC_CSS_SINGLESTRING 14
#define wxSTC_CSS_IDENTIFIER2 15
+#define wxSTC_CSS_ATTRIBUTE 16
// Lexical states for SCLEX_POV
#define wxSTC_POV_DEFAULT 0
#define wxSTC_NSIS_MACRODEF 12
#define wxSTC_NSIS_STRINGVAR 13
#define wxSTC_NSIS_NUMBER 14
+#define wxSTC_NSIS_SECTIONGROUP 15
+#define wxSTC_NSIS_PAGEEX 16
+#define wxSTC_NSIS_FUNCTIONDEF 17
+#define wxSTC_NSIS_COMMENTBOX 18
// Lexical states for SCLEX_MMIXAL
#define wxSTC_MMIXAL_LEADWS 0
#define wxSTC_CLW_PICTURE_STRING 7
#define wxSTC_CLW_KEYWORD 8
#define wxSTC_CLW_COMPILER_DIRECTIVE 9
-#define wxSTC_CLW_BUILTIN_PROCEDURES_FUNCTION 10
-#define wxSTC_CLW_STRUCTURE_DATA_TYPE 11
-#define wxSTC_CLW_ATTRIBUTE 12
-#define wxSTC_CLW_STANDARD_EQUATE 13
-#define wxSTC_CLW_ERROR 14
+#define wxSTC_CLW_RUNTIME_EXPRESSIONS 10
+#define wxSTC_CLW_BUILTIN_PROCEDURES_FUNCTION 11
+#define wxSTC_CLW_STRUCTURE_DATA_TYPE 12
+#define wxSTC_CLW_ATTRIBUTE 13
+#define wxSTC_CLW_STANDARD_EQUATE 14
+#define wxSTC_CLW_ERROR 15
+#define wxSTC_CLW_DEPRECATED 16
// Lexical states for SCLEX_LOT
#define wxSTC_LOT_DEFAULT 0
#define wxSTC_AU3_SENT 10
#define wxSTC_AU3_PREPROCESSOR 11
#define wxSTC_AU3_SPECIAL 12
+#define wxSTC_AU3_EXPAND 13
+#define wxSTC_AU3_COMOBJ 14
// Lexical states for SCLEX_APDL
#define wxSTC_APDL_DEFAULT 0
#define wxSTC_VHDL_STDTYPE 13
#define wxSTC_VHDL_USERWORD 14
+// Lexical states for SCLEX_CAML
+#define wxSTC_CAML_DEFAULT 0
+#define wxSTC_CAML_IDENTIFIER 1
+#define wxSTC_CAML_TAGNAME 2
+#define wxSTC_CAML_KEYWORD 3
+#define wxSTC_CAML_KEYWORD2 4
+#define wxSTC_CAML_KEYWORD3 5
+#define wxSTC_CAML_LINENUM 6
+#define wxSTC_CAML_OPERATOR 7
+#define wxSTC_CAML_NUMBER 8
+#define wxSTC_CAML_CHAR 9
+#define wxSTC_CAML_STRING 11
+#define wxSTC_CAML_COMMENT 12
+#define wxSTC_CAML_COMMENT1 13
+#define wxSTC_CAML_COMMENT2 14
+#define wxSTC_CAML_COMMENT3 15
+
+// Lexical states for SCLEX_HASKELL
+#define wxSTC_HA_DEFAULT 0
+#define wxSTC_HA_IDENTIFIER 1
+#define wxSTC_HA_KEYWORD 2
+#define wxSTC_HA_NUMBER 3
+#define wxSTC_HA_STRING 4
+#define wxSTC_HA_CHARACTER 5
+#define wxSTC_HA_CLASS 6
+#define wxSTC_HA_MODULE 7
+#define wxSTC_HA_CAPITAL 8
+#define wxSTC_HA_DATA 9
+#define wxSTC_HA_IMPORT 10
+#define wxSTC_HA_OPERATOR 11
+#define wxSTC_HA_INSTANCE 12
+#define wxSTC_HA_COMMENTLINE 13
+#define wxSTC_HA_COMMENTBLOCK 14
+#define wxSTC_HA_COMMENTBLOCK2 15
+#define wxSTC_HA_COMMENTBLOCK3 16
+
+// Lexical states of SCLEX_TADS3
+#define wxSTC_T3_DEFAULT 0
+#define wxSTC_T3_X_DEFAULT 1
+#define wxSTC_T3_PREPROCESSOR 2
+#define wxSTC_T3_BLOCK_COMMENT 3
+#define wxSTC_T3_LINE_COMMENT 4
+#define wxSTC_T3_OPERATOR 5
+#define wxSTC_T3_KEYWORD 6
+#define wxSTC_T3_NUMBER 7
+#define wxSTC_T3_IDENTIFIER 8
+#define wxSTC_T3_S_STRING 9
+#define wxSTC_T3_D_STRING 10
+#define wxSTC_T3_X_STRING 11
+#define wxSTC_T3_LIB_DIRECTIVE 12
+#define wxSTC_T3_MSG_PARAM 13
+#define wxSTC_T3_HTML_TAG 14
+#define wxSTC_T3_HTML_DEFAULT 15
+#define wxSTC_T3_HTML_STRING 16
+#define wxSTC_T3_USER1 17
+#define wxSTC_T3_USER2 18
+#define wxSTC_T3_USER3 19
+
+// Lexical states for SCLEX_REBOL
+#define wxSTC_REBOL_DEFAULT 0
+#define wxSTC_REBOL_COMMENTLINE 1
+#define wxSTC_REBOL_COMMENTBLOCK 2
+#define wxSTC_REBOL_PREFACE 3
+#define wxSTC_REBOL_OPERATOR 4
+#define wxSTC_REBOL_CHARACTER 5
+#define wxSTC_REBOL_QUOTEDSTRING 6
+#define wxSTC_REBOL_BRACEDSTRING 7
+#define wxSTC_REBOL_NUMBER 8
+#define wxSTC_REBOL_PAIR 9
+#define wxSTC_REBOL_TUPLE 10
+#define wxSTC_REBOL_BINARY 11
+#define wxSTC_REBOL_MONEY 12
+#define wxSTC_REBOL_ISSUE 13
+#define wxSTC_REBOL_TAG 14
+#define wxSTC_REBOL_FILE 15
+#define wxSTC_REBOL_EMAIL 16
+#define wxSTC_REBOL_URL 17
+#define wxSTC_REBOL_DATE 18
+#define wxSTC_REBOL_TIME 19
+#define wxSTC_REBOL_IDENTIFIER 20
+#define wxSTC_REBOL_WORD 21
+#define wxSTC_REBOL_WORD2 22
+#define wxSTC_REBOL_WORD3 23
+#define wxSTC_REBOL_WORD4 24
+#define wxSTC_REBOL_WORD5 25
+#define wxSTC_REBOL_WORD6 26
+#define wxSTC_REBOL_WORD7 27
+#define wxSTC_REBOL_WORD8 28
+
+// Lexical states for SCLEX_SQL
+#define wxSTC_SQL_DEFAULT 0
+#define wxSTC_SQL_COMMENT 1
+#define wxSTC_SQL_COMMENTLINE 2
+#define wxSTC_SQL_COMMENTDOC 3
+#define wxSTC_SQL_NUMBER 4
+#define wxSTC_SQL_WORD 5
+#define wxSTC_SQL_STRING 6
+#define wxSTC_SQL_CHARACTER 7
+#define wxSTC_SQL_SQLPLUS 8
+#define wxSTC_SQL_SQLPLUS_PROMPT 9
+#define wxSTC_SQL_OPERATOR 10
+#define wxSTC_SQL_IDENTIFIER 11
+#define wxSTC_SQL_SQLPLUS_COMMENT 13
+#define wxSTC_SQL_COMMENTLINEDOC 15
+#define wxSTC_SQL_WORD2 16
+#define wxSTC_SQL_COMMENTDOCKEYWORD 17
+#define wxSTC_SQL_COMMENTDOCKEYWORDERROR 18
+#define wxSTC_SQL_USER1 19
+#define wxSTC_SQL_USER2 20
+#define wxSTC_SQL_USER3 21
+#define wxSTC_SQL_USER4 22
+#define wxSTC_SQL_QUOTEDIDENTIFIER 23
+
+// Lexical states for SCLEX_SMALLTALK
+#define wxSTC_ST_DEFAULT 0
+#define wxSTC_ST_STRING 1
+#define wxSTC_ST_NUMBER 2
+#define wxSTC_ST_COMMENT 3
+#define wxSTC_ST_SYMBOL 4
+#define wxSTC_ST_BINARY 5
+#define wxSTC_ST_BOOL 6
+#define wxSTC_ST_SELF 7
+#define wxSTC_ST_SUPER 8
+#define wxSTC_ST_NIL 9
+#define wxSTC_ST_GLOBAL 10
+#define wxSTC_ST_RETURN 11
+#define wxSTC_ST_SPECIAL 12
+#define wxSTC_ST_KWSEND 13
+#define wxSTC_ST_ASSIGN 14
+#define wxSTC_ST_CHARACTER 15
+#define wxSTC_ST_SPEC_SEL 16
+
+// Lexical states for SCLEX_FLAGSHIP (clipper)
+#define wxSTC_FS_DEFAULT 0
+#define wxSTC_FS_COMMENT 1
+#define wxSTC_FS_COMMENTLINE 2
+#define wxSTC_FS_COMMENTDOC 3
+#define wxSTC_FS_COMMENTLINEDOC 4
+#define wxSTC_FS_COMMENTDOCKEYWORD 5
+#define wxSTC_FS_COMMENTDOCKEYWORDERROR 6
+#define wxSTC_FS_KEYWORD 7
+#define wxSTC_FS_KEYWORD2 8
+#define wxSTC_FS_KEYWORD3 9
+#define wxSTC_FS_KEYWORD4 10
+#define wxSTC_FS_NUMBER 11
+#define wxSTC_FS_STRING 12
+#define wxSTC_FS_PREPROCESSOR 13
+#define wxSTC_FS_OPERATOR 14
+#define wxSTC_FS_IDENTIFIER 15
+#define wxSTC_FS_DATE 16
+#define wxSTC_FS_STRINGEOL 17
+#define wxSTC_FS_CONSTANT 18
+#define wxSTC_FS_ASM 19
+#define wxSTC_FS_LABEL 20
+#define wxSTC_FS_ERROR 21
+#define wxSTC_FS_HEXNUMBER 22
+#define wxSTC_FS_BINNUMBER 23
+
+// Lexical states for SCLEX_CSOUND
+#define wxSTC_CSOUND_DEFAULT 0
+#define wxSTC_CSOUND_COMMENT 1
+#define wxSTC_CSOUND_NUMBER 2
+#define wxSTC_CSOUND_OPERATOR 3
+#define wxSTC_CSOUND_INSTR 4
+#define wxSTC_CSOUND_IDENTIFIER 5
+#define wxSTC_CSOUND_OPCODE 6
+#define wxSTC_CSOUND_HEADERSTMT 7
+#define wxSTC_CSOUND_USERKEYWORD 8
+#define wxSTC_CSOUND_COMMENTBLOCK 9
+#define wxSTC_CSOUND_PARAM 10
+#define wxSTC_CSOUND_ARATE_VAR 11
+#define wxSTC_CSOUND_KRATE_VAR 12
+#define wxSTC_CSOUND_IRATE_VAR 13
+#define wxSTC_CSOUND_GLOBAL_VAR 14
+#define wxSTC_CSOUND_STRINGEOL 15
+
//-----------------------------------------
// Commands that can be bound to keystrokes
// Define a marker from a bitmap
void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp);
+ // Add a set of markers to a line.
+ void MarkerAddSet(int line, int set);
+
// Set a margin to be either numeric or symbolic.
void SetMarginType(int margin, int marginType);
// Default is '?' but can be changed if items contain '?'.
void AutoCompSetTypeSeparator(int separatorCharacter);
+ // Set the maximum width, in characters, of auto-completion and user lists.
+ // Set to 0 to autosize to fit longest item, which is the default.
+ void AutoCompSetMaxWidth(int characterCount);
+
+ // Get the maximum width, in characters, of auto-completion and user lists.
+ int AutoCompGetMaxWidth();
+
+ // Set the maximum height, in rows, of auto-completion and user lists.
+ // The default is 5 rows.
+ void AutoCompSetMaxHeight(int rowCount);
+
+ // Set the maximum height, in rows, of auto-completion and user lists.
+ int AutoCompGetMaxHeight();
+
// Set the number of spaces used for one level of indentation.
void SetIndent(int indentSize);
// Find the document line of a display line taking hidden lines into account.
int DocLineFromVisible(int lineDisplay);
+ // The number of display lines needed to wrap a document line
+ int WrapCount(int line);
+
// Set the fold level of a line.
// This encodes an integer level along with flags indicating whether the
// line is a header and whether it is effectively white space.
// Retrieve whether the maximum scroll position has the last
// line at the bottom of the view.
- int GetEndAtLastLine();
+ bool GetEndAtLastLine();
// Retrieve the height of a particular line of text in pixels.
int TextHeight(int line);
// Enlarge the document to a particular size of text bytes.
void Allocate(int bytes);
- // Find the position of a column on a line taking into account tabs and
+ // Find the position of a column on a line taking into account tabs and
// multi-byte characters. If beyond end of line, return line end position.
int FindColumn(int line, int column);
+ // Can the caret preferred x position only be changed by explicit movement commands?
+ bool GetCaretSticky();
+
+ // Stop the caret preferred x position changing when the user types.
+ void SetCaretSticky(bool useCaretStickyBehaviour);
+
+ // Switch between sticky and non-sticky: meant to be bound to a key.
+ void ToggleCaretSticky();
+
+ // Enable/Disable convert-on-paste for line endings
+ void SetPasteConvertEndings(bool convert);
+
+ // Get convert-on-paste setting
+ bool GetPasteConvertEndings();
+
+ // Duplicate the selection. If selection empty duplicate the line containing the caret.
+ void SelectionDuplicate();
+
// Start notifying the container of all key presses and commands.
void StartRecord();
// Set the lexing language of the document based on string name.
void SetLexerLanguage(const wxString& language);
+ // Retrieve a 'property' value previously set with SetProperty.
+ wxString GetProperty(const wxString& key);
+
+ // Retrieve a 'property' value previously set with SetProperty,
+ // with '$()' variable replacement on returned buffer.
+ wxString GetPropertyExpanded(const wxString& key);
+
+ // Retrieve a 'property' value previously set with SetProperty,
+ // interpreted as an int AFTER any '$()' variable replacement.
+ int GetPropertyInt(const wxString& key);
+
+ // Retrieve the number of bits the current lexer needs for styling.
+ int GetStyleBitsNeeded();
+
// END of generated section
//----------------------------------------------------------------------
// Others...
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_CLICK, 1673)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_DCLICK, 1674)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_CALLTIP_CLICK, 1675)
+ DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_SELECTION, 1676)
END_DECLARE_EVENT_TYPES()
#else
enum {
wxEVT_STC_ZOOM,
wxEVT_STC_HOTSPOT_CLICK,
wxEVT_STC_HOTSPOT_DCLICK,
- wxEVT_STC_CALLTIP_CLICK
+ wxEVT_STC_CALLTIP_CLICK,
+ wxEVT_STC_AUTOCOMP_SELECTION
};
#endif
#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
-
+#define EVT_STC_AUTOCOMP_SELECTION(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_SELECTION id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#endif
//----------------------------------------------------------------------
stcdll_LexAsn1.o \
stcdll_LexBaan.o \
stcdll_LexBash.o \
+ stcdll_LexBasic.o \
stcdll_LexBullant.o \
stcdll_LexCLW.o \
stcdll_LexCPP.o \
stcdll_LexCSS.o \
+ stcdll_LexCaml.o \
+ stcdll_LexCsound.o \
stcdll_LexConf.o \
stcdll_LexCrontab.o \
stcdll_LexEScript.o \
stcdll_LexEiffel.o \
stcdll_LexErlang.o \
+ stcdll_LexFlagship.o \
stcdll_LexForth.o \
stcdll_LexFortran.o \
stcdll_LexGui4Cli.o \
stcdll_LexHTML.o \
+ stcdll_LexHaskell.o \
stcdll_LexKix.o \
stcdll_LexLisp.o \
stcdll_LexLout.o \
stcdll_LexPascal.o \
stcdll_LexPerl.o \
stcdll_LexPython.o \
+ stcdll_LexRebol.o \
stcdll_LexRuby.o \
stcdll_LexSQL.o \
+ stcdll_LexSmalltalk.o \
+ stcdll_LexTADS3.o \
stcdll_LexScriptol.o \
stcdll_LexSpecman.o \
stcdll_LexTeX.o \
stclib_LexAsn1.o \
stclib_LexBaan.o \
stclib_LexBash.o \
+ stclib_LexBasic.o \
stclib_LexBullant.o \
stclib_LexCLW.o \
stclib_LexCPP.o \
stclib_LexCSS.o \
+ stclib_LexCaml.o \
+ stclib_LexCsound.o \
stclib_LexConf.o \
stclib_LexCrontab.o \
stclib_LexEScript.o \
stclib_LexEiffel.o \
stclib_LexErlang.o \
+ stclib_LexFlagship.o \
stclib_LexForth.o \
stclib_LexFortran.o \
stclib_LexGui4Cli.o \
stclib_LexHTML.o \
+ stclib_LexHaskell.o \
stclib_LexKix.o \
stclib_LexLisp.o \
stclib_LexLout.o \
stclib_LexPascal.o \
stclib_LexPerl.o \
stclib_LexPython.o \
+ stclib_LexRebol.o \
stclib_LexRuby.o \
stclib_LexSQL.o \
+ stclib_LexSmalltalk.o \
+ stclib_LexTADS3.o \
stclib_LexScriptol.o \
stclib_LexSpecman.o \
stclib_LexTeX.o \
stcdll_LexBash.o: $(srcdir)/scintilla/src/LexBash.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexBash.cxx
+stcdll_LexBasic.o: $(srcdir)/scintilla/src/LexBasic.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexBasic.cxx
+
stcdll_LexBullant.o: $(srcdir)/scintilla/src/LexBullant.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexBullant.cxx
stcdll_LexCSS.o: $(srcdir)/scintilla/src/LexCSS.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexCSS.cxx
+stcdll_LexCaml.o: $(srcdir)/scintilla/src/LexCaml.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexCaml.cxx
+
+stcdll_LexCsound.o: $(srcdir)/scintilla/src/LexCsound.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexCsound.cxx
+
stcdll_LexConf.o: $(srcdir)/scintilla/src/LexConf.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexConf.cxx
stcdll_LexErlang.o: $(srcdir)/scintilla/src/LexErlang.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexErlang.cxx
+stcdll_LexFlagship.o: $(srcdir)/scintilla/src/LexFlagship.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexFlagship.cxx
+
stcdll_LexForth.o: $(srcdir)/scintilla/src/LexForth.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexForth.cxx
stcdll_LexHTML.o: $(srcdir)/scintilla/src/LexHTML.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexHTML.cxx
+stcdll_LexHaskell.o: $(srcdir)/scintilla/src/LexHaskell.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexHaskell.cxx
+
stcdll_LexKix.o: $(srcdir)/scintilla/src/LexKix.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexKix.cxx
stcdll_LexPython.o: $(srcdir)/scintilla/src/LexPython.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexPython.cxx
+stcdll_LexRebol.o: $(srcdir)/scintilla/src/LexRebol.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexRebol.cxx
+
stcdll_LexRuby.o: $(srcdir)/scintilla/src/LexRuby.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexRuby.cxx
stcdll_LexSQL.o: $(srcdir)/scintilla/src/LexSQL.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexSQL.cxx
+stcdll_LexSmalltalk.o: $(srcdir)/scintilla/src/LexSmalltalk.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexSmalltalk.cxx
+
+stcdll_LexTADS3.o: $(srcdir)/scintilla/src/LexTADS3.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexTADS3.cxx
+
stcdll_LexScriptol.o: $(srcdir)/scintilla/src/LexScriptol.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexScriptol.cxx
stclib_LexBash.o: $(srcdir)/scintilla/src/LexBash.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexBash.cxx
+stclib_LexBasic.o: $(srcdir)/scintilla/src/LexBasic.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexBasic.cxx
+
stclib_LexBullant.o: $(srcdir)/scintilla/src/LexBullant.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexBullant.cxx
stclib_LexCSS.o: $(srcdir)/scintilla/src/LexCSS.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexCSS.cxx
+stclib_LexCaml.o: $(srcdir)/scintilla/src/LexCaml.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexCaml.cxx
+
+stclib_LexCsound.o: $(srcdir)/scintilla/src/LexCsound.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexCsound.cxx
+
stclib_LexConf.o: $(srcdir)/scintilla/src/LexConf.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexConf.cxx
stclib_LexErlang.o: $(srcdir)/scintilla/src/LexErlang.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexErlang.cxx
+stclib_LexFlagship.o: $(srcdir)/scintilla/src/LexFlagship.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexFlagship.cxx
+
stclib_LexForth.o: $(srcdir)/scintilla/src/LexForth.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexForth.cxx
stclib_LexHTML.o: $(srcdir)/scintilla/src/LexHTML.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexHTML.cxx
+stclib_LexHaskell.o: $(srcdir)/scintilla/src/LexHaskell.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexHaskell.cxx
+
stclib_LexKix.o: $(srcdir)/scintilla/src/LexKix.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexKix.cxx
stclib_LexPython.o: $(srcdir)/scintilla/src/LexPython.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexPython.cxx
+stclib_LexRebol.o: $(srcdir)/scintilla/src/LexRebol.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexRebol.cxx
+
stclib_LexRuby.o: $(srcdir)/scintilla/src/LexRuby.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexRuby.cxx
stclib_LexSQL.o: $(srcdir)/scintilla/src/LexSQL.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexSQL.cxx
+stclib_LexSmalltalk.o: $(srcdir)/scintilla/src/LexSmalltalk.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexSmalltalk.cxx
+
+stclib_LexTADS3.o: $(srcdir)/scintilla/src/LexTADS3.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexTADS3.cxx
+
stclib_LexScriptol.o: $(srcdir)/scintilla/src/LexScriptol.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexScriptol.cxx
#include "wx/mstream.h"
#include "wx/image.h"
#include "wx/imaglist.h"
+#include "wx/tokenzr.h"
#include "Platform.h"
#include "PlatWX.h"
CallBackAction doubleClickAction;
void* doubleClickActionData;
public:
- wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
+ wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point location) :
wxPopupWindow(parent, wxBORDER_NONE)
{
SetBackgroundColour(*wxBLACK); // for our simple border
CallBackAction doubleClickAction;
void* doubleClickActionData;
public:
- wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
- wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxSIMPLE_BORDER )
+ wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point location) :
+ wxWindow(parent, id, wxPoint(location.x, location.y), wxSize(0,0), wxSIMPLE_BORDER )
{
lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
int desiredVisibleRows;
int aveCharWidth;
int maxStrWidth;
+ Point location; // Caret location at which the list is opened
wxImageList* imgList;
wxArrayInt* imgTypeMap;
~ListBoxImpl();
virtual void SetFont(Font &font);
- virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_);
+ virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_);
virtual void SetAverageCharWidth(int width);
virtual void SetVisibleRows(int rows);
+ virtual int GetVisibleRows() const;
virtual PRectangle GetDesiredRect();
virtual int CaretFromEdge();
virtual void Clear();
virtual void Append(char *s, int type = -1);
+ void Append(const wxString& text, int type);
virtual int Length();
virtual void Select(int n);
virtual int GetSelection();
virtual void RegisterImage(int type, const char *xpm_data);
virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(CallBackAction, void *);
-
+ virtual void SetList(const char* list, char separator, char typesep);
};
}
-void ListBoxImpl::Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_) {
+void ListBoxImpl::Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_) {
+ location = location_;
lineHeight = lineHeight_;
unicodeMode = unicodeMode_;
maxStrWidth = 0;
- id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
+ id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID, location);
if (imgList != NULL)
GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
}
}
+int ListBoxImpl::GetVisibleRows() const {
+ return desiredVisibleRows;
+}
+
PRectangle ListBoxImpl::GetDesiredRect() {
// wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
// the max size in Append and calculate it here...
- int maxw = maxStrWidth;
+ int maxw = maxStrWidth * aveCharWidth;
int maxh ;
// give it a default if there are no lines, and/or add a bit more
void ListBoxImpl::Append(char *s, int type) {
- wxString text = stc2wx(s);
+ Append(stc2wx(s), type);
+}
+
+void ListBoxImpl::Append(const wxString& text, int type) {
long count = GETLB(id)->GetItemCount();
long itemID = GETLB(id)->InsertItem(count, wxEmptyString);
GETLB(id)->SetItem(itemID, 1, text);
- int itemWidth = 0;
- GETLB(id)->GetTextExtent(text, &itemWidth, NULL);
- maxStrWidth = wxMax(maxStrWidth, itemWidth);
+ maxStrWidth = wxMax(maxStrWidth, text.Length());
if (type != -1) {
wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
long idx = imgTypeMap->Item(type);
}
}
+void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
+ GETLB(id)->Freeze();
+ Clear();
+ wxStringTokenizer tkzr(stc2wx(list), (wxChar)separator);
+ while ( tkzr.HasMoreTokens() ) {
+ wxString token = tkzr.GetNextToken();
+ long type = -1;
+ int pos = token.Find(typesep);
+ if (pos != -1) {
+ token.Mid(pos+1).ToLong(&type);
+ token.Truncate(pos);
+ }
+ Append(token, (int)type);
+ }
+ GETLB(id)->Thaw();
+}
+
int ListBoxImpl::Length() {
return GETLB(id)->GetItemCount();
}
-
ListBox::ListBox() {
}
'AutoCGetTypeSeparator' : ('AutoCompGetTypeSeparator', 0, 0, 0),
'AutoCSetTypeSeparator' : ('AutoCompSetTypeSeparator', 0, 0, 0),
'AutoCGetCurrent' : ('AutoCompGetCurrent', 0, 0, 0),
-
+ 'AutoCSetMaxWidth' : ('AutoCompSetMaxWidth', 0, 0, 0),
+ 'AutoCGetMaxWidth' : ('AutoCompGetMaxWidth', 0, 0, 0),
+ 'AutoCSetMaxHeight' : ('AutoCompSetMaxHeight', 0, 0, 0),
+ 'AutoCGetMaxHeight' : ('AutoCompGetMaxHeight', 0, 0, 0),
+ 'AutoCGetMaxHeight' : ('AutoCompGetMaxHeight', 0, 0, 0),
+
'RegisterImage' :
(0,
'''void %s(int type, const wxBitmap& bmp);''',
'TargetAsUTF8' : ( None, 0, 0, 0),
'SetLengthForEncode' : ( None, 0, 0, 0),
'EncodedFromUTF8' : ( None, 0, 0, 0),
-
+
+
+ 'GetProperty' :
+ (0,
+ 'wxString %s(const wxString& key);',
+
+ '''wxString %s(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTY, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(%s, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);''',
+ ("Retrieve a 'property' value previously set with SetProperty.",)),
+
+ 'GetPropertyExpanded' :
+ (0,
+ 'wxString %s(const wxString& key);',
+
+ '''wxString %s(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTYEXPANDED, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(%s, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);''',
+ ("Retrieve a 'property' value previously set with SetProperty,",
+ "with '$()' variable replacement on returned buffer.")),
+
+ 'GetPropertyInt' : (0, 0, 0,
+ ("Retrieve a 'property' value previously set with SetProperty,",
+ "interpreted as an int AFTER any '$()' variable replacement.")),
+
'GetDocPointer' :
(0,
distribution. All other code needed to implement Scintilla on top of
wxWindows is located in the directory above this one.
-The current version of the Scintilla code is 1.62
+The current version of the Scintilla code is 1.67
LexerFunction fnLexer;
LexerFunction fnFolder;
const char * const * wordListDescriptions;
+ int styleBits;
static const LexerModule *base;
static int nextLanguage;
public:
const char *languageName;
- LexerModule(int language_, LexerFunction fnLexer_,
- const char *languageName_=0, LexerFunction fnFolder_=0,
- const char * const wordListDescriptions_[] = NULL);
+ LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_=0,
+ LexerFunction fnFolder_=0,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=5);
+ virtual ~LexerModule() {
+ }
int GetLanguage() const { return language; }
// -1 is returned if no WordList information is available
int GetNumWordLists() const;
const char *GetWordListDescription(int index) const;
+ int GetStyleBitsNeeded() const;
+
virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
static ListBox *Allocate();
virtual void SetFont(Font &font)=0;
- virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_)=0;
+ virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0;
virtual void SetAverageCharWidth(int width)=0;
virtual void SetVisibleRows(int rows)=0;
+ virtual int GetVisibleRows() const=0;
virtual PRectangle GetDesiredRect()=0;
virtual int CaretFromEdge()=0;
virtual void Clear()=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
+ virtual void SetList(const char* list, char separator, char typesep)=0;
};
/**
Property *props[hashRoots];
Property *enumnext;
int enumhash;
+ static bool caseSensitiveFilenames;
static unsigned int HashString(const char *s, size_t len) {
unsigned int ret = 0;
while (len--) {
char *ToString(); // Caller must delete[] the return value
bool GetFirst(char **key, char **val);
bool GetNext(char **key, char **val);
+ static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) {
+ caseSensitiveFilenames = caseSensitiveFilenames_;
+ }
private:
- // copy-value semantics not implemented
+ // copy-value semantics not implemented
PropSet(const PropSet ©);
void operator=(const PropSet &assign);
};
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
bool sorted;
+ bool sortedNoCase;
int starts[256];
WordList(bool onlyLineEnds_ = false) :
- words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), sorted(false) {}
+ words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
+ sorted(false), sortedNoCase(false) {}
~WordList() { Clear(); }
operator bool() { return len ? true : false; }
char *operator[](int ind) { return words[ind]; }
char *Allocate(int size);
void SetFromAllocated();
bool InList(const char *s);
+ bool InListAbbreviated(const char *s, const char marker);
const char *GetNearestWord(const char *wordStart, int searchLen,
bool ignoreCase = false, SString wordCharacters="", int wordIndex = -1);
char *GetNearestWords(const char *wordStart, int searchLen,
bool operator!=(const char *sOther) const {
return !operator==(sOther);
}
- bool contains(char ch) {
+ bool contains(char ch) const {
return (s && *s) ? strchr(s, ch) != 0 : false;
}
void setsizegrowth(lenpos_t sizeGrowth_) {
bool startswith(const char *prefix);
bool endswith(const char *suffix);
int search(const char *sFind, lenpos_t start=0) const;
- bool contains(const char *sFind) {
+ bool contains(const char *sFind) const {
return search(sFind) >= 0;
}
int substitute(char chFind, char chReplace);
#define SCLEX_NNCRONTAB 26
#define SCLEX_BULLANT 27
#define SCLEX_VBSCRIPT 28
-#define SCLEX_ASP 29
-#define SCLEX_PHP 30
#define SCLEX_BAAN 31
#define SCLEX_MATLAB 32
#define SCLEX_SCRIPTOL 33
#define SCLEX_BASH 62
#define SCLEX_ASN1 63
#define SCLEX_VHDL 64
+#define SCLEX_CAML 65
+#define SCLEX_BLITZBASIC 66
+#define SCLEX_PUREBASIC 67
+#define SCLEX_HASKELL 68
+#define SCLEX_PHPSCRIPT 69
+#define SCLEX_TADS3 70
+#define SCLEX_REBOL 71
+#define SCLEX_SMALLTALK 72
+#define SCLEX_FLAGSHIP 73
+#define SCLEX_CSOUND 74
+#define SCLEX_FREEBASIC 75
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
#define SCE_P_IDENTIFIER 11
#define SCE_P_COMMENTBLOCK 12
#define SCE_P_STRINGEOL 13
+#define SCE_P_WORD2 14
+#define SCE_P_DECORATOR 15
#define SCE_C_DEFAULT 0
#define SCE_C_COMMENT 1
#define SCE_C_COMMENTLINE 2
#define SCE_PL_ARRAY 13
#define SCE_PL_HASH 14
#define SCE_PL_SYMBOLTABLE 15
+#define SCE_PL_VARIABLE_INDEXER 16
#define SCE_PL_REGEX 17
#define SCE_PL_REGSUBST 18
#define SCE_PL_LONGQUOTE 19
#define SCE_PL_STRING_QX 28
#define SCE_PL_STRING_QR 29
#define SCE_PL_STRING_QW 30
+#define SCE_PL_POD_VERB 31
+#define SCE_RB_DEFAULT 0
+#define SCE_RB_ERROR 1
+#define SCE_RB_COMMENTLINE 2
+#define SCE_RB_POD 3
+#define SCE_RB_NUMBER 4
+#define SCE_RB_WORD 5
+#define SCE_RB_STRING 6
+#define SCE_RB_CHARACTER 7
+#define SCE_RB_CLASSNAME 8
+#define SCE_RB_DEFNAME 9
+#define SCE_RB_OPERATOR 10
+#define SCE_RB_IDENTIFIER 11
+#define SCE_RB_REGEX 12
+#define SCE_RB_GLOBAL 13
+#define SCE_RB_SYMBOL 14
+#define SCE_RB_MODULE_NAME 15
+#define SCE_RB_INSTANCE_VAR 16
+#define SCE_RB_CLASS_VAR 17
+#define SCE_RB_BACKTICKS 18
+#define SCE_RB_DATASECTION 19
+#define SCE_RB_HERE_DELIM 20
+#define SCE_RB_HERE_Q 21
+#define SCE_RB_HERE_QQ 22
+#define SCE_RB_HERE_QX 23
+#define SCE_RB_STRING_Q 24
+#define SCE_RB_STRING_QQ 25
+#define SCE_RB_STRING_QX 26
+#define SCE_RB_STRING_QR 27
+#define SCE_RB_STRING_QW 28
+#define SCE_RB_WORD_DEMOTED 29
+#define SCE_RB_STDIN 30
+#define SCE_RB_STDOUT 31
+#define SCE_RB_STDERR 40
+#define SCE_RB_UPPER_BOUND 41
#define SCE_B_DEFAULT 0
#define SCE_B_COMMENT 1
#define SCE_B_NUMBER 2
#define SCE_B_KEYWORD4 12
#define SCE_B_CONSTANT 13
#define SCE_B_ASM 14
+#define SCE_B_LABEL 15
+#define SCE_B_ERROR 16
+#define SCE_B_HEXNUMBER 17
+#define SCE_B_BINNUMBER 18
#define SCE_PROPS_DEFAULT 0
#define SCE_PROPS_COMMENT 1
#define SCE_PROPS_SECTION 2
#define SCE_LISP_COMMENT 1
#define SCE_LISP_NUMBER 2
#define SCE_LISP_KEYWORD 3
+#define SCE_LISP_KEYWORD_KW 4
+#define SCE_LISP_SYMBOL 5
#define SCE_LISP_STRING 6
#define SCE_LISP_STRINGEOL 8
#define SCE_LISP_IDENTIFIER 9
#define SCE_LISP_OPERATOR 10
+#define SCE_LISP_SPECIAL 11
+#define SCE_LISP_MULTI_COMMENT 12
#define SCE_EIFFEL_DEFAULT 0
#define SCE_EIFFEL_COMMENTLINE 1
#define SCE_EIFFEL_NUMBER 2
#define SCE_CSS_DOUBLESTRING 13
#define SCE_CSS_SINGLESTRING 14
#define SCE_CSS_IDENTIFIER2 15
+#define SCE_CSS_ATTRIBUTE 16
#define SCE_POV_DEFAULT 0
#define SCE_POV_COMMENT 1
#define SCE_POV_COMMENTLINE 2
#define SCE_NSIS_MACRODEF 12
#define SCE_NSIS_STRINGVAR 13
#define SCE_NSIS_NUMBER 14
+#define SCE_NSIS_SECTIONGROUP 15
+#define SCE_NSIS_PAGEEX 16
+#define SCE_NSIS_FUNCTIONDEF 17
+#define SCE_NSIS_COMMENTBOX 18
#define SCE_MMIXAL_LEADWS 0
#define SCE_MMIXAL_COMMENT 1
#define SCE_MMIXAL_LABEL 2
#define SCE_CLW_PICTURE_STRING 7
#define SCE_CLW_KEYWORD 8
#define SCE_CLW_COMPILER_DIRECTIVE 9
-#define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 10
-#define SCE_CLW_STRUCTURE_DATA_TYPE 11
-#define SCE_CLW_ATTRIBUTE 12
-#define SCE_CLW_STANDARD_EQUATE 13
-#define SCE_CLW_ERROR 14
+#define SCE_CLW_RUNTIME_EXPRESSIONS 10
+#define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 11
+#define SCE_CLW_STRUCTURE_DATA_TYPE 12
+#define SCE_CLW_ATTRIBUTE 13
+#define SCE_CLW_STANDARD_EQUATE 14
+#define SCE_CLW_ERROR 15
+#define SCE_CLW_DEPRECATED 16
#define SCE_LOT_DEFAULT 0
#define SCE_LOT_HEADER 1
#define SCE_LOT_BREAK 2
#define SCE_AU3_SENT 10
#define SCE_AU3_PREPROCESSOR 11
#define SCE_AU3_SPECIAL 12
+#define SCE_AU3_EXPAND 13
+#define SCE_AU3_COMOBJ 14
#define SCE_APDL_DEFAULT 0
#define SCE_APDL_COMMENT 1
#define SCE_APDL_COMMENTBLOCK 2
#define SCE_VHDL_STDPACKAGE 12
#define SCE_VHDL_STDTYPE 13
#define SCE_VHDL_USERWORD 14
+#define SCE_CAML_DEFAULT 0
+#define SCE_CAML_IDENTIFIER 1
+#define SCE_CAML_TAGNAME 2
+#define SCE_CAML_KEYWORD 3
+#define SCE_CAML_KEYWORD2 4
+#define SCE_CAML_KEYWORD3 5
+#define SCE_CAML_LINENUM 6
+#define SCE_CAML_OPERATOR 7
+#define SCE_CAML_NUMBER 8
+#define SCE_CAML_CHAR 9
+#define SCE_CAML_STRING 11
+#define SCE_CAML_COMMENT 12
+#define SCE_CAML_COMMENT1 13
+#define SCE_CAML_COMMENT2 14
+#define SCE_CAML_COMMENT3 15
+#define SCE_HA_DEFAULT 0
+#define SCE_HA_IDENTIFIER 1
+#define SCE_HA_KEYWORD 2
+#define SCE_HA_NUMBER 3
+#define SCE_HA_STRING 4
+#define SCE_HA_CHARACTER 5
+#define SCE_HA_CLASS 6
+#define SCE_HA_MODULE 7
+#define SCE_HA_CAPITAL 8
+#define SCE_HA_DATA 9
+#define SCE_HA_IMPORT 10
+#define SCE_HA_OPERATOR 11
+#define SCE_HA_INSTANCE 12
+#define SCE_HA_COMMENTLINE 13
+#define SCE_HA_COMMENTBLOCK 14
+#define SCE_HA_COMMENTBLOCK2 15
+#define SCE_HA_COMMENTBLOCK3 16
+#define SCE_T3_DEFAULT 0
+#define SCE_T3_X_DEFAULT 1
+#define SCE_T3_PREPROCESSOR 2
+#define SCE_T3_BLOCK_COMMENT 3
+#define SCE_T3_LINE_COMMENT 4
+#define SCE_T3_OPERATOR 5
+#define SCE_T3_KEYWORD 6
+#define SCE_T3_NUMBER 7
+#define SCE_T3_IDENTIFIER 8
+#define SCE_T3_S_STRING 9
+#define SCE_T3_D_STRING 10
+#define SCE_T3_X_STRING 11
+#define SCE_T3_LIB_DIRECTIVE 12
+#define SCE_T3_MSG_PARAM 13
+#define SCE_T3_HTML_TAG 14
+#define SCE_T3_HTML_DEFAULT 15
+#define SCE_T3_HTML_STRING 16
+#define SCE_T3_USER1 17
+#define SCE_T3_USER2 18
+#define SCE_T3_USER3 19
+#define SCE_REBOL_DEFAULT 0
+#define SCE_REBOL_COMMENTLINE 1
+#define SCE_REBOL_COMMENTBLOCK 2
+#define SCE_REBOL_PREFACE 3
+#define SCE_REBOL_OPERATOR 4
+#define SCE_REBOL_CHARACTER 5
+#define SCE_REBOL_QUOTEDSTRING 6
+#define SCE_REBOL_BRACEDSTRING 7
+#define SCE_REBOL_NUMBER 8
+#define SCE_REBOL_PAIR 9
+#define SCE_REBOL_TUPLE 10
+#define SCE_REBOL_BINARY 11
+#define SCE_REBOL_MONEY 12
+#define SCE_REBOL_ISSUE 13
+#define SCE_REBOL_TAG 14
+#define SCE_REBOL_FILE 15
+#define SCE_REBOL_EMAIL 16
+#define SCE_REBOL_URL 17
+#define SCE_REBOL_DATE 18
+#define SCE_REBOL_TIME 19
+#define SCE_REBOL_IDENTIFIER 20
+#define SCE_REBOL_WORD 21
+#define SCE_REBOL_WORD2 22
+#define SCE_REBOL_WORD3 23
+#define SCE_REBOL_WORD4 24
+#define SCE_REBOL_WORD5 25
+#define SCE_REBOL_WORD6 26
+#define SCE_REBOL_WORD7 27
+#define SCE_REBOL_WORD8 28
+#define SCE_SQL_DEFAULT 0
+#define SCE_SQL_COMMENT 1
+#define SCE_SQL_COMMENTLINE 2
+#define SCE_SQL_COMMENTDOC 3
+#define SCE_SQL_NUMBER 4
+#define SCE_SQL_WORD 5
+#define SCE_SQL_STRING 6
+#define SCE_SQL_CHARACTER 7
+#define SCE_SQL_SQLPLUS 8
+#define SCE_SQL_SQLPLUS_PROMPT 9
+#define SCE_SQL_OPERATOR 10
+#define SCE_SQL_IDENTIFIER 11
+#define SCE_SQL_SQLPLUS_COMMENT 13
+#define SCE_SQL_COMMENTLINEDOC 15
+#define SCE_SQL_WORD2 16
+#define SCE_SQL_COMMENTDOCKEYWORD 17
+#define SCE_SQL_COMMENTDOCKEYWORDERROR 18
+#define SCE_SQL_USER1 19
+#define SCE_SQL_USER2 20
+#define SCE_SQL_USER3 21
+#define SCE_SQL_USER4 22
+#define SCE_SQL_QUOTEDIDENTIFIER 23
+#define SCE_ST_DEFAULT 0
+#define SCE_ST_STRING 1
+#define SCE_ST_NUMBER 2
+#define SCE_ST_COMMENT 3
+#define SCE_ST_SYMBOL 4
+#define SCE_ST_BINARY 5
+#define SCE_ST_BOOL 6
+#define SCE_ST_SELF 7
+#define SCE_ST_SUPER 8
+#define SCE_ST_NIL 9
+#define SCE_ST_GLOBAL 10
+#define SCE_ST_RETURN 11
+#define SCE_ST_SPECIAL 12
+#define SCE_ST_KWSEND 13
+#define SCE_ST_ASSIGN 14
+#define SCE_ST_CHARACTER 15
+#define SCE_ST_SPEC_SEL 16
+#define SCE_FS_DEFAULT 0
+#define SCE_FS_COMMENT 1
+#define SCE_FS_COMMENTLINE 2
+#define SCE_FS_COMMENTDOC 3
+#define SCE_FS_COMMENTLINEDOC 4
+#define SCE_FS_COMMENTDOCKEYWORD 5
+#define SCE_FS_COMMENTDOCKEYWORDERROR 6
+#define SCE_FS_KEYWORD 7
+#define SCE_FS_KEYWORD2 8
+#define SCE_FS_KEYWORD3 9
+#define SCE_FS_KEYWORD4 10
+#define SCE_FS_NUMBER 11
+#define SCE_FS_STRING 12
+#define SCE_FS_PREPROCESSOR 13
+#define SCE_FS_OPERATOR 14
+#define SCE_FS_IDENTIFIER 15
+#define SCE_FS_DATE 16
+#define SCE_FS_STRINGEOL 17
+#define SCE_FS_CONSTANT 18
+#define SCE_FS_ASM 19
+#define SCE_FS_LABEL 20
+#define SCE_FS_ERROR 21
+#define SCE_FS_HEXNUMBER 22
+#define SCE_FS_BINNUMBER 23
+#define SCE_CSOUND_DEFAULT 0
+#define SCE_CSOUND_COMMENT 1
+#define SCE_CSOUND_NUMBER 2
+#define SCE_CSOUND_OPERATOR 3
+#define SCE_CSOUND_INSTR 4
+#define SCE_CSOUND_IDENTIFIER 5
+#define SCE_CSOUND_OPCODE 6
+#define SCE_CSOUND_HEADERSTMT 7
+#define SCE_CSOUND_USERKEYWORD 8
+#define SCE_CSOUND_COMMENTBLOCK 9
+#define SCE_CSOUND_PARAM 10
+#define SCE_CSOUND_ARATE_VAR 11
+#define SCE_CSOUND_KRATE_VAR 12
+#define SCE_CSOUND_IRATE_VAR 13
+#define SCE_CSOUND_GLOBAL_VAR 14
+#define SCE_CSOUND_STRINGEOL 15
+#define SCLEX_ASP 29
+#define SCLEX_PHP 30
//--Autogenerated -- end of section automatically generated from Scintilla.iface
#endif
#ifndef SCINTILLA_H
#define SCINTILLA_H
-#ifdef PLAT_WIN
+#if LCCWIN
+typedef BOOL bool;
+#endif
+
#if PLAT_WIN
// Return false on failure:
bool Scintilla_RegisterClasses(void *hInstance);
bool Scintilla_ReleaseResources();
#endif
-#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 _MSC_VER
#if _MSC_VER >= 1300
#include <BaseTsd.h>
#endif
-#endif
#ifdef MAXULONG_PTR
typedef ULONG_PTR uptr_t;
typedef LONG_PTR sptr_t;
#define SC_MARK_DOTDOTDOT 23
#define SC_MARK_ARROWS 24
#define SC_MARK_PIXMAP 25
+#define SC_MARK_FULLRECT 26
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
#define SCI_MARKERNEXT 2047
#define SCI_MARKERPREVIOUS 2048
#define SCI_MARKERDEFINEPIXMAP 2049
+#define SCI_MARKERADDSET 2466
#define SC_MARGIN_SYMBOL 0
#define SC_MARGIN_NUMBER 1
#define SCI_SETMARGINTYPEN 2240
#define SC_CHARSET_MAC 77
#define SC_CHARSET_OEM 255
#define SC_CHARSET_RUSSIAN 204
+#define SC_CHARSET_CYRILLIC 1251
#define SC_CHARSET_SHIFTJIS 128
#define SC_CHARSET_SYMBOL 2
#define SC_CHARSET_TURKISH 162
#define SC_CHARSET_ARABIC 178
#define SC_CHARSET_VIETNAMESE 163
#define SC_CHARSET_THAI 222
+#define SC_CHARSET_8859_15 1000
#define SCI_STYLECLEARALL 2050
#define SCI_STYLESETFORE 2051
#define SCI_STYLESETBACK 2052
#define SCI_CLEARREGISTEREDIMAGES 2408
#define SCI_AUTOCGETTYPESEPARATOR 2285
#define SCI_AUTOCSETTYPESEPARATOR 2286
+#define SCI_AUTOCSETMAXWIDTH 2208
+#define SCI_AUTOCGETMAXWIDTH 2209
+#define SCI_AUTOCSETMAXHEIGHT 2210
+#define SCI_AUTOCGETMAXHEIGHT 2211
#define SCI_SETINDENT 2122
#define SCI_GETINDENT 2123
#define SCI_SETUSETABS 2124
#define SCI_CALLTIPSETFOREHLT 2207
#define SCI_VISIBLEFROMDOCLINE 2220
#define SCI_DOCLINEFROMVISIBLE 2221
+#define SCI_WRAPCOUNT 2235
#define SC_FOLDLEVELBASE 0x400
#define SC_FOLDLEVELWHITEFLAG 0x1000
#define SC_FOLDLEVELHEADERFLAG 0x2000
#define SCI_WORDENDPOSITION 2267
#define SC_WRAP_NONE 0
#define SC_WRAP_WORD 1
+#define SC_WRAP_CHAR 2
#define SCI_SETWRAPMODE 2268
#define SCI_GETWRAPMODE 2269
#define SC_WRAPVISUALFLAG_NONE 0x0000
#define SCI_SETLENGTHFORENCODE 2448
#define SCI_ENCODEDFROMUTF8 2449
#define SCI_FINDCOLUMN 2456
+#define SCI_GETCARETSTICKY 2457
+#define SCI_SETCARETSTICKY 2458
+#define SCI_TOGGLECARETSTICKY 2459
+#define SCI_SETPASTECONVERTENDINGS 2467
+#define SCI_GETPASTECONVERTENDINGS 2468
+#define SCI_SELECTIONDUPLICATE 2469
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
#define SCI_SETKEYWORDS 4005
#define SCI_SETLEXERLANGUAGE 4006
#define SCI_LOADLEXERLIBRARY 4007
+#define SCI_GETPROPERTY 4008
+#define SCI_GETPROPERTYEXPANDED 4009
+#define SCI_GETPROPERTYINT 4010
+#define SCI_GETSTYLEBITSNEEDED 4011
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
#define SC_PERFORMED_USER 0x10
#define SC_PERFORMED_UNDO 0x20
#define SC_PERFORMED_REDO 0x40
+#define SC_MULTISTEPUNDOREDO 0x80
#define SC_LASTSTEPINUNDOREDO 0x100
#define SC_MOD_CHANGEMARKER 0x200
#define SC_MOD_BEFOREINSERT 0x400
#define SC_MOD_BEFOREDELETE 0x800
-#define SC_MODEVENTMASKALL 0xF77
+#define SC_MULTILINEUNDOREDO 0x1000
+#define SC_MODEVENTMASKALL 0x1FFF
#define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256
#define SCK_ADD 310
#define SCK_SUBTRACT 311
#define SCK_DIVIDE 312
+#define SCMOD_NORM 0
#define SCMOD_SHIFT 1
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCN_HOTSPOTCLICK 2019
#define SCN_HOTSPOTDOUBLECLICK 2020
#define SCN_CALLTIPCLICK 2021
+#define SCN_AUTOCSELECTION 2022
//--Autogenerated -- end of section automatically generated from Scintilla.iface
// These structures are defined to be exactly the same shape as the Win32
#endif
struct NotifyHeader {
- // hwndFrom is really an environment specifc window handle or pointer
+ // 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.
- //WindowID hwndFrom;
void *hwndFrom;
- unsigned int idFrom;
+ uptr_t idFrom;
unsigned int code;
};
int ch; // SCN_CHARADDED, SCN_KEY
int modifiers; // SCN_KEY
int modificationType; // SCN_MODIFIED
- const char *text; // SCN_MODIFIED
+ const char *text; // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION
int length; // SCN_MODIFIED
int linesAdded; // SCN_MODIFIED
int message; // SCN_MACRORECORD
val SC_MARK_DOTDOTDOT=23
val SC_MARK_ARROWS=24
val SC_MARK_PIXMAP=25
+val SC_MARK_FULLRECT=26
val SC_MARK_CHARACTER=10000
# Define a marker from a pixmap.
fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
+# Add a set of markers to a line.
+fun void MarkerAddSet=2466(int line, int set)
+
enu MarginType=SC_MARGIN_
val SC_MARGIN_SYMBOL=0
val SC_MARGIN_NUMBER=1
val SC_CHARSET_MAC=77
val SC_CHARSET_OEM=255
val SC_CHARSET_RUSSIAN=204
+val SC_CHARSET_CYRILLIC=1251
val SC_CHARSET_SHIFTJIS=128
val SC_CHARSET_SYMBOL=2
val SC_CHARSET_TURKISH=162
val SC_CHARSET_ARABIC=178
val SC_CHARSET_VIETNAMESE=163
val SC_CHARSET_THAI=222
+val SC_CHARSET_8859_15=1000
# Clear all the styles and make equivalent to the global default style.
set void StyleClearAll=2050(,)
# Default is '?' but can be changed if items contain '?'.
set void AutoCSetTypeSeparator=2286(int separatorCharacter,)
+# Set the maximum width, in characters, of auto-completion and user lists.
+# Set to 0 to autosize to fit longest item, which is the default.
+set void AutoCSetMaxWidth=2208(int characterCount,)
+
+# Get the maximum width, in characters, of auto-completion and user lists.
+get int AutoCGetMaxWidth=2209(,)
+
+# Set the maximum height, in rows, of auto-completion and user lists.
+# The default is 5 rows.
+set void AutoCSetMaxHeight=2210(int rowCount,)
+
+# Set the maximum height, in rows, of auto-completion and user lists.
+get int AutoCGetMaxHeight=2211(,)
+
# Set the number of spaces used for one level of indentation.
set void SetIndent=2122(int indentSize,)
# Find the document line of a display line taking hidden lines into account.
fun int DocLineFromVisible=2221(int lineDisplay,)
+# The number of display lines needed to wrap a document line
+fun int WrapCount=2235(int line,)
+
enu FoldLevel=SC_FOLDLEVEL
val SC_FOLDLEVELBASE=0x400
val SC_FOLDLEVELWHITEFLAG=0x1000
enu Wrap=SC_WRAP_
val SC_WRAP_NONE=0
val SC_WRAP_WORD=1
+val SC_WRAP_CHAR=2
# Sets whether text is word wrapped.
set void SetWrapMode=2268(int mode,)
# Retrieve whether the maximum scroll position has the last
# line at the bottom of the view.
-get int GetEndAtLastLine=2278(,)
+get bool GetEndAtLastLine=2278(,)
# Retrieve the height of a particular line of text in pixels.
fun int TextHeight=2279(int line,)
fun int TargetAsUTF8=2447(, stringresult s)
# Set the length of the utf8 argument for calling EncodedFromUTF8.
-# Set to 0 and the string will be measured to the first nul.
+# Set to -1 and the string will be measured to the first nul.
fun void SetLengthForEncode=2448(int bytes,)
# Translates a UTF8 string into the document encoding.
# On error return 0.
fun int EncodedFromUTF8=2449(string utf8, stringresult encoded)
-# Find the position of a column on a line taking into account tabs and
+# Find the position of a column on a line taking into account tabs and
# multi-byte characters. If beyond end of line, return line end position.
fun int FindColumn=2456(int line, int column)
+# Can the caret preferred x position only be changed by explicit movement commands?
+get bool GetCaretSticky=2457(,)
+
+# Stop the caret preferred x position changing when the user types.
+set void SetCaretSticky=2458(bool useCaretStickyBehaviour,)
+
+# Switch between sticky and non-sticky: meant to be bound to a key.
+fun void ToggleCaretSticky=2459(,)
+
+# Enable/Disable convert-on-paste for line endings
+set void SetPasteConvertEndings=2467(bool convert,)
+
+# Get convert-on-paste setting
+get bool GetPasteConvertEndings=2468(,)
+
+# Duplicate the selection. If selection empty duplicate the line containing the caret.
+fun void SelectionDuplicate=2469(,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
# Load a lexer library (dll / so).
fun void LoadLexerLibrary=4007(, string path)
+# Retrieve a "property" value previously set with SetProperty.
+fun int GetProperty=4008(string key, stringresult buf)
+
+# Retrieve a "property" value previously set with SetProperty,
+# with "$()" variable replacement on returned buffer.
+fun int GetPropertyExpanded=4009(string key, stringresult buf)
+
+# Retrieve a "property" value previously set with SetProperty,
+# interpreted as an int AFTER any "$()" variable replacement.
+get int GetPropertyInt=4010(string key,)
+
+# Retrieve the number of bits the current lexer needs for styling.
+get int GetStyleBitsNeeded=4011(,)
+
# 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_PERFORMED_USER=0x10
val SC_PERFORMED_UNDO=0x20
val SC_PERFORMED_REDO=0x40
+val SC_MULTISTEPUNDOREDO=0x80
val SC_LASTSTEPINUNDOREDO=0x100
val SC_MOD_CHANGEMARKER=0x200
val SC_MOD_BEFOREINSERT=0x400
val SC_MOD_BEFOREDELETE=0x800
-val SC_MODEVENTMASKALL=0xF77
+val SC_MULTILINEUNDOREDO=0x1000
+val SC_MODEVENTMASKALL=0x1FFF
# For compatibility, these go through the COMMAND notification rather than NOTIFY
# and should have had exactly the same values as the EN_* constants.
val SCK_DIVIDE=312
enu KeyMod=SCMOD_
+val SCMOD_NORM=0
val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCLEX_NNCRONTAB=26
val SCLEX_BULLANT=27
val SCLEX_VBSCRIPT=28
-val SCLEX_ASP=29
-val SCLEX_PHP=30
val SCLEX_BAAN=31
val SCLEX_MATLAB=32
val SCLEX_SCRIPTOL=33
val SCLEX_BASH=62
val SCLEX_ASN1=63
val SCLEX_VHDL=64
+val SCLEX_CAML=65
+val SCLEX_BLITZBASIC=66
+val SCLEX_PUREBASIC=67
+val SCLEX_HASKELL=68
+val SCLEX_PHPSCRIPT=69
+val SCLEX_TADS3=70
+val SCLEX_REBOL=71
+val SCLEX_SMALLTALK=72
+val SCLEX_FLAGSHIP=73
+val SCLEX_CSOUND=74
+val SCLEX_FREEBASIC=75
# 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 Ruby=SCLEX_RUBY SCE_P_
val SCE_P_DEFAULT=0
val SCE_P_COMMENTLINE=1
val SCE_P_NUMBER=2
val SCE_P_IDENTIFIER=11
val SCE_P_COMMENTBLOCK=12
val SCE_P_STRINGEOL=13
+val SCE_P_WORD2=14
+val SCE_P_DECORATOR=15
# Lexical states for SCLEX_CPP
lex Cpp=SCLEX_CPP SCE_C_
-lex SQL=SCLEX_SQL SCE_C_
lex Pascal=SCLEX_PASCAL SCE_C_
lex TCL=SCLEX_TCL SCE_C_
lex BullAnt=SCLEX_BULLANT SCE_C_
val SCE_PL_ARRAY=13
val SCE_PL_HASH=14
val SCE_PL_SYMBOLTABLE=15
+val SCE_PL_VARIABLE_INDEXER=16
val SCE_PL_REGEX=17
val SCE_PL_REGSUBST=18
val SCE_PL_LONGQUOTE=19
val SCE_PL_STRING_QX=28
val SCE_PL_STRING_QR=29
val SCE_PL_STRING_QW=30
+val SCE_PL_POD_VERB=31
+# Lexical states for SCLEX_RUBY
+lex Ruby=SCLEX_RUBY SCE_RB_
+val SCE_RB_DEFAULT=0
+val SCE_RB_ERROR=1
+val SCE_RB_COMMENTLINE=2
+val SCE_RB_POD=3
+val SCE_RB_NUMBER=4
+val SCE_RB_WORD=5
+val SCE_RB_STRING=6
+val SCE_RB_CHARACTER=7
+val SCE_RB_CLASSNAME=8
+val SCE_RB_DEFNAME=9
+val SCE_RB_OPERATOR=10
+val SCE_RB_IDENTIFIER=11
+val SCE_RB_REGEX=12
+val SCE_RB_GLOBAL=13
+val SCE_RB_SYMBOL=14
+val SCE_RB_MODULE_NAME=15
+val SCE_RB_INSTANCE_VAR=16
+val SCE_RB_CLASS_VAR=17
+val SCE_RB_BACKTICKS=18
+val SCE_RB_DATASECTION=19
+val SCE_RB_HERE_DELIM=20
+val SCE_RB_HERE_Q=21
+val SCE_RB_HERE_QQ=22
+val SCE_RB_HERE_QX=23
+val SCE_RB_STRING_Q=24
+val SCE_RB_STRING_QQ=25
+val SCE_RB_STRING_QX=26
+val SCE_RB_STRING_QR=27
+val SCE_RB_STRING_QW=28
+val SCE_RB_WORD_DEMOTED=29
+val SCE_RB_STDIN=30
+val SCE_RB_STDOUT=31
+val SCE_RB_STDERR=40
+val SCE_RB_UPPER_BOUND=41
# Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC
lex VB=SCLEX_VB SCE_B_
lex VBScript=SCLEX_VBSCRIPT SCE_B_
val SCE_B_KEYWORD4=12
val SCE_B_CONSTANT=13
val SCE_B_ASM=14
+val SCE_B_LABEL=15
+val SCE_B_ERROR=16
+val SCE_B_HEXNUMBER=17
+val SCE_B_BINNUMBER=18
# Lexical states for SCLEX_PROPERTIES
lex Properties=SCLEX_PROPERTIES SCE_PROPS_
val SCE_PROPS_DEFAULT=0
val SCE_LISP_COMMENT=1
val SCE_LISP_NUMBER=2
val SCE_LISP_KEYWORD=3
+val SCE_LISP_KEYWORD_KW=4
+val SCE_LISP_SYMBOL=5
val SCE_LISP_STRING=6
val SCE_LISP_STRINGEOL=8
val SCE_LISP_IDENTIFIER=9
val SCE_LISP_OPERATOR=10
+val SCE_LISP_SPECIAL=11
+val SCE_LISP_MULTI_COMMENT=12
# Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW
lex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_
lex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_
val SCE_CSS_DOUBLESTRING=13
val SCE_CSS_SINGLESTRING=14
val SCE_CSS_IDENTIFIER2=15
+val SCE_CSS_ATTRIBUTE=16
# Lexical states for SCLEX_POV
lex POV=SCLEX_POV SCE_POV_
val SCE_POV_DEFAULT=0
val SCE_NSIS_MACRODEF=12
val SCE_NSIS_STRINGVAR=13
val SCE_NSIS_NUMBER=14
+val SCE_NSIS_SECTIONGROUP=15
+val SCE_NSIS_PAGEEX=16
+val SCE_NSIS_FUNCTIONDEF=17
+val SCE_NSIS_COMMENTBOX=18
# Lexical states for SCLEX_MMIXAL
lex MMIXAL=SCLEX_MMIXAL SCE_MMIXAL_
val SCE_MMIXAL_LEADWS=0
val SCE_CLW_PICTURE_STRING=7
val SCE_CLW_KEYWORD=8
val SCE_CLW_COMPILER_DIRECTIVE=9
-val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=10
-val SCE_CLW_STRUCTURE_DATA_TYPE=11
-val SCE_CLW_ATTRIBUTE=12
-val SCE_CLW_STANDARD_EQUATE=13
-val SCE_CLW_ERROR=14
+val SCE_CLW_RUNTIME_EXPRESSIONS=10
+val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=11
+val SCE_CLW_STRUCTURE_DATA_TYPE=12
+val SCE_CLW_ATTRIBUTE=13
+val SCE_CLW_STANDARD_EQUATE=14
+val SCE_CLW_ERROR=15
+val SCE_CLW_DEPRECATED=16
# Lexical states for SCLEX_LOT
lex LOT=SCLEX_LOT SCE_LOT_
val SCE_LOT_DEFAULT=0
val SCE_AU3_SENT=10
val SCE_AU3_PREPROCESSOR=11
val SCE_AU3_SPECIAL=12
+val SCE_AU3_EXPAND=13
+val SCE_AU3_COMOBJ=14
# Lexical states for SCLEX_APDL
lex APDL=SCLEX_APDL SCE_APDL_
val SCE_APDL_DEFAULT=0
val SCE_VHDL_STDPACKAGE=12
val SCE_VHDL_STDTYPE=13
val SCE_VHDL_USERWORD=14
+# Lexical states for SCLEX_CAML
+lex Caml=SCLEX_CAML SCE_CAML_
+val SCE_CAML_DEFAULT=0
+val SCE_CAML_IDENTIFIER=1
+val SCE_CAML_TAGNAME=2
+val SCE_CAML_KEYWORD=3
+val SCE_CAML_KEYWORD2=4
+val SCE_CAML_KEYWORD3=5
+val SCE_CAML_LINENUM=6
+val SCE_CAML_OPERATOR=7
+val SCE_CAML_NUMBER=8
+val SCE_CAML_CHAR=9
+val SCE_CAML_STRING=11
+val SCE_CAML_COMMENT=12
+val SCE_CAML_COMMENT1=13
+val SCE_CAML_COMMENT2=14
+val SCE_CAML_COMMENT3=15
+# Lexical states for SCLEX_HASKELL
+lex Haskell=SCLEX_HASKELL SCE_HA_
+val SCE_HA_DEFAULT=0
+val SCE_HA_IDENTIFIER=1
+val SCE_HA_KEYWORD=2
+val SCE_HA_NUMBER=3
+val SCE_HA_STRING=4
+val SCE_HA_CHARACTER=5
+val SCE_HA_CLASS=6
+val SCE_HA_MODULE=7
+val SCE_HA_CAPITAL=8
+val SCE_HA_DATA=9
+val SCE_HA_IMPORT=10
+val SCE_HA_OPERATOR=11
+val SCE_HA_INSTANCE=12
+val SCE_HA_COMMENTLINE=13
+val SCE_HA_COMMENTBLOCK=14
+val SCE_HA_COMMENTBLOCK2=15
+val SCE_HA_COMMENTBLOCK3=16
+# Lexical states of SCLEX_TADS3
+lex TADS3=SCLEX_TADS3 SCE_T3_
+val SCE_T3_DEFAULT=0
+val SCE_T3_X_DEFAULT=1
+val SCE_T3_PREPROCESSOR=2
+val SCE_T3_BLOCK_COMMENT=3
+val SCE_T3_LINE_COMMENT=4
+val SCE_T3_OPERATOR=5
+val SCE_T3_KEYWORD=6
+val SCE_T3_NUMBER=7
+val SCE_T3_IDENTIFIER=8
+val SCE_T3_S_STRING=9
+val SCE_T3_D_STRING=10
+val SCE_T3_X_STRING=11
+val SCE_T3_LIB_DIRECTIVE=12
+val SCE_T3_MSG_PARAM=13
+val SCE_T3_HTML_TAG=14
+val SCE_T3_HTML_DEFAULT=15
+val SCE_T3_HTML_STRING=16
+val SCE_T3_USER1=17
+val SCE_T3_USER2=18
+val SCE_T3_USER3=19
+# Lexical states for SCLEX_REBOL
+lex Rebol=SCLEX_REBOL SCE_REBOL_
+val SCE_REBOL_DEFAULT=0
+val SCE_REBOL_COMMENTLINE=1
+val SCE_REBOL_COMMENTBLOCK=2
+val SCE_REBOL_PREFACE=3
+val SCE_REBOL_OPERATOR=4
+val SCE_REBOL_CHARACTER=5
+val SCE_REBOL_QUOTEDSTRING=6
+val SCE_REBOL_BRACEDSTRING=7
+val SCE_REBOL_NUMBER=8
+val SCE_REBOL_PAIR=9
+val SCE_REBOL_TUPLE=10
+val SCE_REBOL_BINARY=11
+val SCE_REBOL_MONEY=12
+val SCE_REBOL_ISSUE=13
+val SCE_REBOL_TAG=14
+val SCE_REBOL_FILE=15
+val SCE_REBOL_EMAIL=16
+val SCE_REBOL_URL=17
+val SCE_REBOL_DATE=18
+val SCE_REBOL_TIME=19
+val SCE_REBOL_IDENTIFIER=20
+val SCE_REBOL_WORD=21
+val SCE_REBOL_WORD2=22
+val SCE_REBOL_WORD3=23
+val SCE_REBOL_WORD4=24
+val SCE_REBOL_WORD5=25
+val SCE_REBOL_WORD6=26
+val SCE_REBOL_WORD7=27
+val SCE_REBOL_WORD8=28
+# Lexical states for SCLEX_SQL
+lex SQL=SCLEX_SQL SCE_SQL_
+val SCE_SQL_DEFAULT=0
+val SCE_SQL_COMMENT=1
+val SCE_SQL_COMMENTLINE=2
+val SCE_SQL_COMMENTDOC=3
+val SCE_SQL_NUMBER=4
+val SCE_SQL_WORD=5
+val SCE_SQL_STRING=6
+val SCE_SQL_CHARACTER=7
+val SCE_SQL_SQLPLUS=8
+val SCE_SQL_SQLPLUS_PROMPT=9
+val SCE_SQL_OPERATOR=10
+val SCE_SQL_IDENTIFIER=11
+val SCE_SQL_SQLPLUS_COMMENT=13
+val SCE_SQL_COMMENTLINEDOC=15
+val SCE_SQL_WORD2=16
+val SCE_SQL_COMMENTDOCKEYWORD=17
+val SCE_SQL_COMMENTDOCKEYWORDERROR=18
+val SCE_SQL_USER1=19
+val SCE_SQL_USER2=20
+val SCE_SQL_USER3=21
+val SCE_SQL_USER4=22
+val SCE_SQL_QUOTEDIDENTIFIER=23
+# Lexical states for SCLEX_SMALLTALK
+lex Smalltalk=SCLEX_SMALLTALK SCE_ST_
+val SCE_ST_DEFAULT=0
+val SCE_ST_STRING=1
+val SCE_ST_NUMBER=2
+val SCE_ST_COMMENT=3
+val SCE_ST_SYMBOL=4
+val SCE_ST_BINARY=5
+val SCE_ST_BOOL=6
+val SCE_ST_SELF=7
+val SCE_ST_SUPER=8
+val SCE_ST_NIL=9
+val SCE_ST_GLOBAL=10
+val SCE_ST_RETURN=11
+val SCE_ST_SPECIAL=12
+val SCE_ST_KWSEND=13
+val SCE_ST_ASSIGN=14
+val SCE_ST_CHARACTER=15
+val SCE_ST_SPEC_SEL=16
+# Lexical states for SCLEX_FLAGSHIP (clipper)
+lex FlagShip=SCLEX_FLAGSHIP SCE_B_
+val SCE_FS_DEFAULT=0
+val SCE_FS_COMMENT=1
+val SCE_FS_COMMENTLINE=2
+val SCE_FS_COMMENTDOC=3
+val SCE_FS_COMMENTLINEDOC=4
+val SCE_FS_COMMENTDOCKEYWORD=5
+val SCE_FS_COMMENTDOCKEYWORDERROR=6
+val SCE_FS_KEYWORD=7
+val SCE_FS_KEYWORD2=8
+val SCE_FS_KEYWORD3=9
+val SCE_FS_KEYWORD4=10
+val SCE_FS_NUMBER=11
+val SCE_FS_STRING=12
+val SCE_FS_PREPROCESSOR=13
+val SCE_FS_OPERATOR=14
+val SCE_FS_IDENTIFIER=15
+val SCE_FS_DATE=16
+val SCE_FS_STRINGEOL=17
+val SCE_FS_CONSTANT=18
+val SCE_FS_ASM=19
+val SCE_FS_LABEL=20
+val SCE_FS_ERROR=21
+val SCE_FS_HEXNUMBER=22
+val SCE_FS_BINNUMBER=23
+# Lexical states for SCLEX_CSOUND
+lex Csound=SCLEX_CSOUND SCE_CSOUND_
+val SCE_CSOUND_DEFAULT=0
+val SCE_CSOUND_COMMENT=1
+val SCE_CSOUND_NUMBER=2
+val SCE_CSOUND_OPERATOR=3
+val SCE_CSOUND_INSTR=4
+val SCE_CSOUND_IDENTIFIER=5
+val SCE_CSOUND_OPCODE=6
+val SCE_CSOUND_HEADERSTMT=7
+val SCE_CSOUND_USERKEYWORD=8
+val SCE_CSOUND_COMMENTBLOCK=9
+val SCE_CSOUND_PARAM=10
+val SCE_CSOUND_ARATE_VAR=11
+val SCE_CSOUND_KRATE_VAR=12
+val SCE_CSOUND_IRATE_VAR=13
+val SCE_CSOUND_GLOBAL_VAR=14
+val SCE_CSOUND_STRINGEOL=15
# Events
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
+evt void AutoCSelection=2022(string text)
cat Deprecated
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
void (* notify) (ScintillaObject *ttt);
};
-guint scintilla_get_type (void);
+GtkType scintilla_get_type (void);
GtkWidget* scintilla_new (void);
-void scintilla_set_id (ScintillaObject *sci,int id);
+void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);
return active;
}
-void AutoComplete::Start(Window &parent, int ctrlID, int position,
- int startLen_, int lineHeight, bool unicodeMode) {
+void AutoComplete::Start(Window &parent, int ctrlID,
+ int position, Point location, int startLen_,
+ int lineHeight, bool unicodeMode) {
if (active) {
Cancel();
}
- lb->Create(parent, ctrlID, lineHeight, unicodeMode);
+ lb->Create(parent, ctrlID, location, lineHeight, unicodeMode);
lb->Clear();
active = true;
startLen = startLen_;
}
void AutoComplete::SetList(const char *list) {
- lb->Clear();
- char *words = new char[strlen(list) + 1];
- if (words) {
- strcpy(words, list);
- char *startword = words;
- char *numword = NULL;
- int i = 0;
- for (; words && words[i]; i++) {
- if (words[i] == separator) {
- words[i] = '\0';
- if (numword)
- *numword = '\0';
- lb->Append(startword, numword?atoi(numword + 1):-1);
- startword = words + i + 1;
- numword = NULL;
- } else if (words[i] == typesep) {
- numword = words + i;
- }
- }
- if (startword) {
- if (numword)
- *numword = '\0';
- lb->Append(startword, numword?atoi(numword + 1):-1);
- }
- delete []words;
- }
+ lb->SetList(list, separator, typesep);
}
-void AutoComplete::Show() {
- lb->Show();
- lb->Select(0);
+void AutoComplete::Show(bool show) {
+ lb->Show(show);
+ if (show)
+ lb->Select(0);
}
void AutoComplete::Cancel() {
if (lb->Created()) {
+ lb->Clear();
lb->Destroy();
active = false;
}
--pivot;
}
location = pivot;
+ if (ignoreCase) {
+ // Check for exact-case match
+ for (; pivot <= end; pivot++) {
+ lb->GetValue(pivot, item, maxItemLen);
+ if (!strncmp(word, item, lenWord)) {
+ location = pivot;
+ break;
+ }
+ if (CompareNCaseInsensitive(word, item, lenWord))
+ break;
+ }
+ }
} else if (cond < 0) {
end = pivot - 1;
} else if (cond > 0) {
char stopChars[256];
char fillUpChars[256];
char separator;
- char typesep; // Type separator
+ char typesep; // Type seperator
public:
bool ignoreCase;
bool Active();
/// Display the auto completion list positioned to be near a character position
- void Start(Window &parent, int ctrlID, int position,
+ void Start(Window &parent, int ctrlID, int position, Point location,
int startLen_, int lineHeight, bool unicodeMode);
/// The stop chars are characters which, when typed, cause the auto completion list to disappear
void SetSeparator(char separator_);
char GetSeparator();
- /// The typesep character is used for separating the word from the type
+ /// The typesep character is used for seperating the word from the type
void SetTypesep(char separator_);
char GetTypesep();
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
- void Show();
+ void Show(bool show);
void Cancel();
/// Move the current list element by delta, scrolling appropriately
inCallTipMode = false;
posStartCallTip = 0;
val = 0;
- xUp = -100;
- xDown = -100;
+ rectUp = PRectangle(0,0,0,0);
+ rectDown = PRectangle(0,0,0,0);
lineHeight = 1;
startHighlight = 0;
endHighlight = 0;
if (IsArrowCharacter(s[startSeg])) {
xEnd = x + widthArrow;
offsetMain = xEnd;
+ rcClient.left = x;
+ rcClient.right = xEnd;
if (draw) {
const int halfWidth = widthArrow / 2 - 3;
const int centreX = x + widthArrow / 2 - 1;
const int centreY = (rcClient.top + rcClient.bottom) / 2;
- rcClient.left = x;
- rcClient.right = xEnd;
surface->FillRectangle(rcClient, colourBG.allocated);
PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
surface->FillRectangle(rcClientInner, colourUnSel.allocated);
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
colourBG.allocated, colourBG.allocated);
}
- } else {
- if (s[startSeg] == '\001') {
- xUp = x+1;
- } else {
- xDown = x+1;
- }
+ }
+ if (s[startSeg] == '\001') {
+ rectUp = rcClient;
+ } else if (s[startSeg] == '\002') {
+ rectDown = rcClient;
}
} else {
xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
void CallTip::MouseClick(Point pt) {
clickPlace = 0;
- if (pt.y < lineHeight) {
- if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
- clickPlace = 1;
- } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
- clickPlace = 2;
- }
- }
+ if (rectUp.Contains(pt))
+ clickPlace = 1;
+ if (rectDown.Contains(pt))
+ clickPlace = 2;
}
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
int numLines = 1;
const char *newline;
const char *look = val;
- xUp = -100;
- xDown = -100;
+ rectUp = PRectangle(0,0,0,0);
+ rectDown = PRectangle(0,0,0,0);
offsetMain = 5;
int width = PaintContents(surfaceMeasure, false) + 5;
while ((newline = strchr(look, '\n')) != NULL) {
int endHighlight;
char *val;
Font font;
- int xUp;
- int xDown;
+ PRectangle rectUp;
+ PRectangle rectDown;
int lineHeight;
int offsetMain;
// Private so CallTip objects can not be copied
linesData[i] = linesData[i + 1];
}
if (levels) {
- // Level information merges back onto previous line
- int posAbove = pos - 1;
- if (posAbove < 0)
- posAbove = 0;
- for (int j = posAbove; j < lines; j++) {
+ // Move up following lines but merge header flag from this line
+ // to line before to avoid a temporary disappearence causing expansion.
+ int firstHeader = levels[pos] & SC_FOLDLEVELHEADERFLAG;
+ for (int j = pos; j < lines; j++) {
levels[j] = levels[j + 1];
}
+ if (pos > 0)
+ levels[pos-1] |= firstHeader;
}
lines--;
}
} else if (currentAction == savePoint) {
currentAction++;
} else if ((at == insertAction) &&
- (position != (actPrevious.position + actPrevious.lenData*2))) {
+ (position != (actPrevious.position + actPrevious.lenData))) {
// Insertions must be immediately after to coalesce
currentAction++;
} else if (!actions[currentAction].mayCoalesce) {
currentAction++;
} else if (at == removeAction) {
if ((lengthData == 1) || (lengthData == 2)){
- if ((position + lengthData * 2) == actPrevious.position) {
+ if ((position + lengthData) == actPrevious.position) {
; // Backspace -> OK
} else if (position == actPrevious.position) {
; // Delete -> OK
for (int i = 0; i < insertLength / 2; i++) {
data[i] = s[i * 2];
}
- uh.AppendAction(insertAction, position, data, insertLength / 2);
+ uh.AppendAction(insertAction, position / 2, data, insertLength / 2);
}
BasicInsertString(position, s, insertLength);
return data;
}
-void CellBuffer::InsertCharStyle(int position, char ch, char style) {
- char s[2];
- s[0] = ch;
- s[1] = style;
- InsertString(position*2, s, 2);
-}
-
bool CellBuffer::SetStyleAt(int position, char style, char mask) {
style &= mask;
char curVal = ByteAt(position * 2 + 1);
const char *CellBuffer::DeleteChars(int position, int deleteLength) {
// InsertString and DeleteChars are the bottleneck though which all changes occur
+ PLATFORM_ASSERT(deleteLength > 0);
char *data = 0;
if (!readOnly) {
if (collectingUndo) {
for (int i = 0; i < deleteLength / 2; i++) {
data[i] = ByteAt(position + i * 2);
}
- uh.AppendAction(removeAction, position, data, deleteLength / 2);
+ uh.AppendAction(removeAction, position / 2, data, deleteLength / 2);
}
BasicDeleteChars(position, deleteLength);
//Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength);
if (insertLength == 0)
return ;
+ PLATFORM_ASSERT(insertLength > 0);
RoomFor(insertLength);
GapTo(position);
}
bool CellBuffer::CanUndo() {
- return (!readOnly) && (uh.CanUndo());
+ return uh.CanUndo();
}
int CellBuffer::StartUndo() {
void CellBuffer::PerformUndoStep() {
const Action &actionStep = uh.GetUndoStep();
if (actionStep.at == insertAction) {
- BasicDeleteChars(actionStep.position, actionStep.lenData*2);
+ BasicDeleteChars(actionStep.position*2, actionStep.lenData*2);
} else if (actionStep.at == removeAction) {
char *styledData = new char[actionStep.lenData * 2];
for (int i = 0; i < actionStep.lenData; i++) {
styledData[i*2] = actionStep.data[i];
styledData[i*2 + 1] = 0;
}
- BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
+ BasicInsertString(actionStep.position*2, styledData, actionStep.lenData*2);
delete []styledData;
}
uh.CompletedUndoStep();
}
bool CellBuffer::CanRedo() {
- return (!readOnly) && (uh.CanRedo());
+ return uh.CanRedo();
}
int CellBuffer::StartRedo() {
styledData[i*2] = actionStep.data[i];
styledData[i*2 + 1] = 0;
}
- BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
+ BasicInsertString(actionStep.position*2, styledData, actionStep.lenData*2);
delete []styledData;
} else if (actionStep.at == removeAction) {
- BasicDeleteChars(actionStep.position, actionStep.lenData*2);
+ BasicDeleteChars(actionStep.position*2, actionStep.lenData*2);
}
uh.CompletedRedoStep();
}
int LineStart(int line);
int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
const char *InsertString(int position, char *s, int insertLength);
- void InsertCharStyle(int position, char ch, char style);
/// Setting styles for positions outside the range of the buffer is safe and has no effect.
/// @return true if the style of a character is changed.
int Document::AddMark(int line, int markerNum) {
int prev = cb.AddMark(line, markerNum);
- DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0);
+ DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+ mh.line = line;
NotifyModified(mh);
return prev;
}
+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);
+ DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+ mh.line = line;
+ NotifyModified(mh);
+}
+
void Document::DeleteMark(int line, int markerNum) {
cb.DeleteMark(line, markerNum);
- DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0);
+ DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+ mh.line = line;
NotifyModified(mh);
}
void Document::DeleteMarkFromHandle(int markerHandle) {
cb.DeleteMarkFromHandle(markerHandle);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+ mh.line = -1;
NotifyModified(mh);
}
void Document::DeleteAllMarks(int markerNum) {
cb.DeleteAllMarks(markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+ mh.line = -1;
NotifyModified(mh);
}
return 1;
}
}
-#include <assert.h>
+
// Normalise a position so that it is not halfway through a two byte character.
// This can occur in two situations -
// When lines are terminated with \r\n pairs which should be treated as one character.
if (pos >= Length())
return Length();
- // assert pos > 0 && pos < Length()
+ // PLATFORM_ASSERT(pos > 0 && pos < Length());
if (checkLineEnd && IsCrLf(pos - 1)) {
if (moveDir > 0)
return pos + 1;
endStyled = pos;
}
+void Document::CheckReadOnly() {
+ if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
+ enteredReadOnlyCount++;
+ NotifyModifyAttempt();
+ enteredReadOnlyCount--;
+ }
+}
+
// Document only modified by gateways DeleteChars, InsertStyledString, Undo, Redo, and SetStyleAt.
// SetStyleAt does not change the persistent state of a document
return false;
if ((pos + len) > Length())
return false;
- if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
- enteredReadOnlyCount++;
- NotifyModifyAttempt();
- enteredReadOnlyCount--;
- }
+ CheckReadOnly();
if (enteredCount != 0) {
return false;
} else {
* Insert a styled string (char/style pairs) with a length.
*/
bool Document::InsertStyledString(int position, char *s, int insertLength) {
- if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
- enteredReadOnlyCount++;
- NotifyModifyAttempt();
- enteredReadOnlyCount--;
- }
+ CheckReadOnly();
if (enteredCount != 0) {
return false;
} else {
}
int Document::Undo() {
- int newPos = 0;
+ int newPos = -1;
+ CheckReadOnly();
if (enteredCount == 0) {
enteredCount++;
- bool startSavePoint = cb.IsSavePoint();
- int steps = cb.StartUndo();
- //Platform::DebugPrintf("Steps=%d\n", steps);
- for (int step = 0; step < steps; step++) {
- int prevLinesTotal = LinesTotal();
- const Action &action = cb.GetUndoStep();
- if (action.at == removeAction) {
- NotifyModified(DocModification(
- SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
- } else {
- NotifyModified(DocModification(
- SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
- }
- cb.PerformUndoStep();
- int cellPosition = action.position / 2;
- 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 {
- modFlags |= SC_MOD_DELETETEXT;
+ if (!cb.IsReadOnly()) {
+ bool startSavePoint = cb.IsSavePoint();
+ bool multiLine = false;
+ int steps = cb.StartUndo();
+ //Platform::DebugPrintf("Steps=%d\n", steps);
+ for (int step = 0; step < steps; step++) {
+ const int prevLinesTotal = LinesTotal();
+ const Action &action = cb.GetUndoStep();
+ if (action.at == removeAction) {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
+ } else {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
+ }
+ cb.PerformUndoStep();
+ int cellPosition = action.position;
+ 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 {
+ modFlags |= SC_MOD_DELETETEXT;
+ }
+ if (steps > 1)
+ modFlags |= SC_MULTISTEPUNDOREDO;
+ const int linesAdded = LinesTotal() - prevLinesTotal;
+ if (linesAdded != 0)
+ multiLine = true;
+ if (step == steps - 1) {
+ modFlags |= SC_LASTSTEPINUNDOREDO;
+ if (multiLine)
+ modFlags |= SC_MULTILINEUNDOREDO;
+ }
+ NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
+ linesAdded, action.data));
}
- if (step == steps - 1)
- modFlags |= SC_LASTSTEPINUNDOREDO;
- NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
- LinesTotal() - prevLinesTotal, action.data));
- }
- bool endSavePoint = cb.IsSavePoint();
- if (startSavePoint != endSavePoint)
- NotifySavePoint(endSavePoint);
+ bool endSavePoint = cb.IsSavePoint();
+ if (startSavePoint != endSavePoint)
+ NotifySavePoint(endSavePoint);
+ }
enteredCount--;
}
return newPos;
}
int Document::Redo() {
- int newPos = 0;
+ int newPos = -1;
+ CheckReadOnly();
if (enteredCount == 0) {
enteredCount++;
- bool startSavePoint = cb.IsSavePoint();
- int steps = cb.StartRedo();
- for (int step = 0; step < steps; step++) {
- int prevLinesTotal = LinesTotal();
- const Action &action = cb.GetRedoStep();
- if (action.at == insertAction) {
- NotifyModified(DocModification(
- SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
- } else {
- NotifyModified(DocModification(
- SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
- }
- cb.PerformRedoStep();
- ModifiedAt(action.position / 2);
- newPos = action.position / 2;
-
- int modFlags = SC_PERFORMED_REDO;
- if (action.at == insertAction) {
- newPos += action.lenData;
- modFlags |= SC_MOD_INSERTTEXT;
- } else {
- modFlags |= SC_MOD_DELETETEXT;
+ if (!cb.IsReadOnly()) {
+ bool startSavePoint = cb.IsSavePoint();
+ bool multiLine = false;
+ int steps = cb.StartRedo();
+ for (int step = 0; step < steps; step++) {
+ const int prevLinesTotal = LinesTotal();
+ const Action &action = cb.GetRedoStep();
+ if (action.at == insertAction) {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
+ } else {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
+ }
+ cb.PerformRedoStep();
+ ModifiedAt(action.position);
+ newPos = action.position;
+
+ int modFlags = SC_PERFORMED_REDO;
+ if (action.at == insertAction) {
+ newPos += action.lenData;
+ modFlags |= SC_MOD_INSERTTEXT;
+ } else {
+ modFlags |= SC_MOD_DELETETEXT;
+ }
+ if (steps > 1)
+ modFlags |= SC_MULTISTEPUNDOREDO;
+ const int linesAdded = LinesTotal() - prevLinesTotal;
+ if (linesAdded != 0)
+ multiLine = true;
+ if (step == steps - 1) {
+ modFlags |= SC_LASTSTEPINUNDOREDO;
+ if (multiLine)
+ modFlags |= SC_MULTILINEUNDOREDO;
+ }
+ NotifyModified(
+ DocModification(modFlags, action.position, action.lenData,
+ linesAdded, action.data));
}
- if (step == steps - 1)
- modFlags |= SC_LASTSTEPINUNDOREDO;
- NotifyModified(
- DocModification(modFlags, action.position / 2, action.lenData,
- LinesTotal() - prevLinesTotal, action.data));
- }
- bool endSavePoint = cb.IsSavePoint();
- if (startSavePoint != endSavePoint)
- NotifySavePoint(endSavePoint);
+ bool endSavePoint = cb.IsSavePoint();
+ if (startSavePoint != endSavePoint)
+ NotifySavePoint(endSavePoint);
+ }
enteredCount--;
}
return newPos;
*/
bool Document::InsertString(int position, const char *s, size_t insertLength) {
bool changed = false;
- char *sWithStyle = new char[insertLength * 2];
- if (sWithStyle) {
- for (size_t i = 0; i < insertLength; i++) {
- sWithStyle[i*2] = s[i];
- sWithStyle[i*2 + 1] = 0;
+ if (insertLength > 0) {
+ char *sWithStyle = new char[insertLength * 2];
+ if (sWithStyle) {
+ for (size_t i = 0; i < insertLength; i++) {
+ sWithStyle[i*2] = s[i];
+ sWithStyle[i*2 + 1] = 0;
+ }
+ changed = InsertStyledString(position*2, sWithStyle,
+ static_cast<int>(insertLength*2));
+ delete []sWithStyle;
}
- changed = InsertStyledString(position*2, sWithStyle,
- static_cast<int>(insertLength*2));
- delete []sWithStyle;
}
return changed;
}
CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
+ BeginUndoAction();
DeleteChars(thisLineStart, indentPos - thisLineStart);
InsertString(thisLineStart, linebuf);
+ EndUndoAction();
}
}
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab
for (int line = lineBottom; line >= lineTop; line--) {
int indentOfLine = GetLineIndentation(line);
- if (forwards)
- SetLineIndentation(line, indentOfLine + IndentSize());
- else
+ if (forwards) {
+ if (LineStart(line) < LineEnd(line)) {
+ SetLineIndentation(line, indentOfLine + IndentSize());
+ }
+ } else {
SetLineIndentation(line, indentOfLine - IndentSize());
+ }
}
}
for (int pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
- if (cb.CharAt(pos + 1) == '\n') {
+ if (cb.CharAt(pos + 1) == '\n') {
// CRLF
if (eolModeSet == SC_EOL_CR) {
DeleteChars(pos + 1, 1); // Delete the LF
} else {
pos++;
}
- } else {
+ } else {
// CR
if (eolModeSet == SC_EOL_CRLF) {
InsertString(pos + 1, "\n", 1); // Insert LF
EndUndoAction();
}
-int Document::ParaDown(int pos) {
- int line = LineFromPosition(pos);
- while (line < LinesTotal() && LineStart(line) != LineEnd(line)) { // skip non-empty lines
- line++;
- }
- while (line < LinesTotal() && LineStart(line) == LineEnd(line)) { // skip empty lines
- line++;
+bool Document::IsWhiteLine(int line) {
+ int currentChar = LineStart(line);
+ int endLine = LineEnd(line);
+ while (currentChar < endLine) {
+ if (cb.CharAt(currentChar) != ' ' && cb.CharAt(currentChar) != '\t') {
+ return false;
+ }
+ ++currentChar;
}
- if (line < LinesTotal())
- return LineStart(line);
- else // end of a document
- return LineEnd(line-1);
+ return true;
}
int Document::ParaUp(int pos) {
int line = LineFromPosition(pos);
line--;
- while (line >= 0 && LineStart(line) == LineEnd(line)) { // skip empty lines
+ while (line >= 0 && IsWhiteLine(line)) { // skip empty lines
line--;
}
- while (line >= 0 && LineStart(line) != LineEnd(line)) { // skip non-empty lines
+ while (line >= 0 && !IsWhiteLine(line)) { // skip non-empty lines
line--;
}
line++;
return LineStart(line);
}
+int Document::ParaDown(int pos) {
+ int line = LineFromPosition(pos);
+ while (line < LinesTotal() && !IsWhiteLine(line)) { // skip non-empty lines
+ line++;
+ }
+ while (line < LinesTotal() && IsWhiteLine(line)) { // skip empty lines
+ line++;
+ }
+ if (line < LinesTotal())
+ return LineStart(line);
+ else // end of a document
+ return LineEnd(line-1);
+}
+
Document::charClassification Document::WordCharClass(unsigned char ch) {
if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))
return ccWord;
pdoc(pdoc_), end(end_) {
}
+ virtual ~DocumentIndexer() {
+ }
+
virtual char CharAt(int index) {
if (index < 0 || index >= end)
return 0;
if (line == lineRangeStart) {
if ((startPos != endOfLine) && (searchEnd == '$'))
continue; // Can't match end of line if start position before end of line
- endOfLine = startPos+1;
+ endOfLine = startPos;
}
}
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+1)) && (repetitions--)) {
- success = pre->Execute(di, pos+1, endOfLine+1);
+ while (success && (pre->eopat[0] <= endOfLine) && (repetitions--)) {
+ success = pre->Execute(di, pos+1, endOfLine);
if (success) {
- if (pre->eopat[0] <= (minPos+1)) {
+ if (pre->eopat[0] <= minPos) {
pos = pre->bopat[0];
lenRet = pre->eopat[0] - pre->bopat[0];
} else {
char firstChar = s[0];
if (!caseSensitive)
firstChar = static_cast<char>(MakeUpperCase(firstChar));
- int pos = startPos;
+ int pos = forward ? startPos : (startPos - 1);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
char ch = CharAt(pos);
if (caseSensitive) {
if (ch == firstChar) {
bool found = true;
+ if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
ch = CharAt(pos + posMatch);
if (ch != s[posMatch])
} else {
if (MakeUpperCase(ch) == firstChar) {
bool found = true;
+ if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
ch = CharAt(pos + posMatch);
if (MakeUpperCase(ch) != MakeUpperCase(s[posMatch]))
}
void Document::ChangeCase(Range r, bool makeUpperCase) {
- for (int pos = r.start; pos < r.end; pos++) {
+ for (int pos = r.start; pos < r.end;) {
int len = LenChar(pos);
- if (dbcsCodePage && (len > 1)) {
- pos += len;
- } else {
+ if (len == 1) {
char ch = CharAt(pos);
if (makeUpperCase) {
if (IsLowerCase(ch)) {
}
}
}
+ pos += len;
}
}
return false;
} else {
enteredCount++;
- int prevEndStyled = endStyled;
bool didChange = false;
- int lastChange = 0;
+ int startMod = 0;
+ int endMod = 0;
for (int iPos = 0; iPos < length; iPos++, endStyled++) {
PLATFORM_ASSERT(endStyled < Length());
if (cb.SetStyleAt(endStyled, styles[iPos], stylingMask)) {
+ if (!didChange) {
+ startMod = endStyled;
+ }
didChange = true;
- lastChange = iPos;
+ endMod = endStyled;
}
}
if (didChange) {
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
- prevEndStyled, lastChange);
+ startMod, endMod - startMod + 1);
NotifyModified(mh);
}
enteredCount--;
}
return pos;
}
+
+static char BraceOpposite(char ch) {
+ switch (ch) {
+ case '(':
+ return ')';
+ case ')':
+ return '(';
+ case '[':
+ return ']';
+ case ']':
+ return '[';
+ case '{':
+ return '}';
+ case '}':
+ return '{';
+ case '<':
+ return '>';
+ case '>':
+ return '<';
+ default:
+ return '\0';
+ }
+}
+
+// TODO: should be able to extend styled region to find matching brace
+int Document::BraceMatch(int position, int /*maxReStyle*/) {
+ char chBrace = CharAt(position);
+ char chSeek = BraceOpposite(chBrace);
+ if (chSeek == '\0')
+ return - 1;
+ char styBrace = static_cast<char>(StyleAt(position) & stylingBitsMask);
+ int direction = -1;
+ if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
+ direction = 1;
+ int depth = 1;
+ position = position + direction;
+ while ((position >= 0) && (position < Length())) {
+ position = MovePositionOutsideChar(position, direction);
+ char chAtPos = CharAt(position);
+ char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
+ if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
+ if (chAtPos == chBrace)
+ depth++;
+ if (chAtPos == chSeek)
+ depth--;
+ if (depth == 0)
+ return position;
+ }
+ position = position + direction;
+ }
+ return - 1;
+}
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
// Gateways to modifying document
+ void ModifiedAt(int pos);
bool DeleteChars(int pos, int len);
bool InsertStyledString(int position, char *s, int insertLength);
int Undo();
char StyleAt(int position) { return cb.StyleAt(position); }
int GetMark(int line) { return cb.GetMark(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 WordPartLeft(int pos);
int WordPartRight(int pos);
int ExtendStyleRange(int pos, int delta, bool singleLine = false);
+ bool IsWhiteLine(int line);
int ParaUp(int pos);
int ParaDown(int pos);
int IndentSize() { return actualIndentInChars; }
+ int BraceMatch(int position, int maxReStyle);
private:
+ void CheckReadOnly();
+
charClassification WordCharClass(unsigned char ch);
bool IsWordStartAt(int pos);
bool IsWordEndAt(int pos);
bool IsWordAt(int start, int end);
- void ModifiedAt(int pos);
void NotifyModifyAttempt();
void NotifySavePoint(bool atSavePoint);
int foldLevelPrev;
DocModification(int modificationType_, int position_=0, int length_=0,
- int linesAdded_=0, const char *text_=0) :
+ int linesAdded_=0, const char *text_=0, int line_=0) :
modificationType(modificationType_),
position(position_),
length(length_),
linesAdded(linesAdded_),
text(text_),
- line(0),
+ line(line_),
foldLevelNow(0),
foldLevelPrev(0) {}
- DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
+ DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
- position(act.position / 2),
+ position(act.position),
length(act.lenData),
linesAdded(linesAdded_),
text(act.data),
}
char DocumentAccessor::StyleAt(int position) {
- return pdoc->StyleAt(position);
+ // Mask off all bits which aren't in the 'mask'.
+ return static_cast<char>(pdoc->StyleAt(position) & mask);
}
int DocumentAccessor::GetLine(int position) {
}
void DocumentAccessor::StartAt(unsigned int start, char chMask) {
+ // Store the mask specified for use with StyleAt.
+ mask = chMask;
pdoc->StartStyling(start, chMask);
startPosStyling = start;
}
char chWhile;
unsigned int startSeg;
int startPosStyling;
+ int mask;
bool InternalIsLeadByte(char ch);
void Fill(int position);
DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) :
Accessor(), pdoc(pdoc_), props(props_), id(id_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
- startSeg(0), startPosStyling(0) {
+ startSeg(0), startPosStyling(0),
+ mask(127) { // Initialize the mask to be big enough for any lexer.
}
~DocumentAccessor();
bool Match(int pos, const char *s);
#include "Document.h"
#include "Editor.h"
+/*
+ return whether this modification represents an operation that
+ may reasonably be deferred (not done now OR [possibly] at all)
+*/
+static bool CanDeferToLastStep(const DocModification& mh) {
+ if (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE))
+ return true; // CAN skip
+ if (!(mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)))
+ return false; // MUST do
+ if (mh.modificationType & SC_MULTISTEPUNDOREDO)
+ return true; // CAN skip
+ return false; // PRESUMABLY must do
+}
+
+static bool CanEliminate(const DocModification& mh) {
+ return
+ (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE)) != 0;
+}
+
+/*
+ return whether this modification represents the FINAL step
+ in a [possibly lengthy] multi-step Undo/Redo sequence
+*/
+static bool IsLastStep(const DocModification& mh) {
+ return
+ (mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)) != 0
+ && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
+ && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0
+ && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0;
+}
+
Caret::Caret() :
active(false), on(false), period(500) {}
edgeColumn(0),
chars(0),
styles(0),
+ styleBitsSet(0),
indicators(0),
positions(0),
hsStart(0),
LineLayoutCache::LineLayoutCache() :
level(0), length(0), size(0), cache(0),
- allInvalidated(false), styleClock(-1) {
+ allInvalidated(false), styleClock(-1), useCount(0) {
Allocate(0);
}
}
void LineLayoutCache::Allocate(int length_) {
+ PLATFORM_ASSERT(cache == NULL);
allInvalidated = false;
length = length_;
size = length;
}
void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
+ PLATFORM_ASSERT(useCount == 0);
int lengthForLevel = 0;
if (level == llcCaret) {
lengthForLevel = 1;
}
if (lengthForLevel > size) {
Deallocate();
- } else if (lengthForLevel < length) {
- for (int i = lengthForLevel; i < length; i++) {
- delete cache[i];
- cache[i] = 0;
- }
- }
- if (!cache) {
Allocate(lengthForLevel);
+ } else {
+ if (lengthForLevel < length) {
+ for (int i = lengthForLevel; i < length; i++) {
+ delete cache[i];
+ cache[i] = 0;
+ }
+ }
+ length = lengthForLevel;
}
+ PLATFORM_ASSERT(length == lengthForLevel);
+ PLATFORM_ASSERT(cache != NULL || length == 0);
}
void LineLayoutCache::Deallocate() {
+ PLATFORM_ASSERT(useCount == 0);
for (int i = 0; i < length; i++)
delete cache[i];
delete []cache;
cache = 0;
length = 0;
+ size = 0;
}
void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
pos = 0;
} else if (level == llcPage) {
if (lineNumber == lineCaret) {
- pos = length;
+ pos = 0;
} else {
- pos = lineNumber % length;
+ pos = 1 + (lineNumber % (length - 1));
}
} else if (level == llcDocument) {
pos = lineNumber;
}
if (pos >= 0) {
+ PLATFORM_ASSERT(useCount == 0);
if (cache && (pos < length)) {
if (cache[pos]) {
if ((cache[pos]->lineNumber != lineNumber) ||
cache[pos]->lineNumber = lineNumber;
cache[pos]->inCache = true;
ret = cache[pos];
+ useCount++;
}
}
}
if (ll) {
if (!ll->inCache) {
delete ll;
- }
+ } else {
+ useCount--;
+ }
}
}
scrollWidth = 2000;
verticalScrollBarVisible = true;
endAtLastLine = true;
+ caretSticky = false;
pixmapLine = Surface::Allocate();
pixmapSelMargin = Surface::Allocate();
topLine = 0;
posTopLine = 0;
- lengthForEncode = 0;
+ lengthForEncode = -1;
needUpdateUI = true;
braces[0] = invalidPosition;
wrapVisualStartIndent = 0;
actualWrapVisualStartIndent = 0;
+ convertPastes = true;
+
hsStart = -1;
hsEnd = -1;
pixmapSelMargin->Release();
pixmapSelPattern->Release();
pixmapIndentGuide->Release();
+ pixmapIndentGuideHighlight->Release();
}
void Editor::InvalidateStyleData() {
//wMain.InvalidateAll();
}
-void Editor::RedrawSelMargin() {
+void Editor::RedrawSelMargin(int line) {
if (!AbandonPaint()) {
if (vs.maskInLine) {
Redraw();
} else {
PRectangle rcSelMargin = GetClientRectangle();
rcSelMargin.right = vs.fixedColumnWidth;
+ if (line != -1) {
+ int position = pdoc->LineStart(line);
+ PRectangle rcLine = RectangleFromRange(position, position);
+ rcSelMargin.top = rcLine.top;
+ rcSelMargin.bottom = rcLine.bottom;
+ }
wMain.InvalidateRectangle(rcSelMargin);
}
}
return Platform::Maximum(currentPos, anchor);
}
+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)
currentPos = currentPos_;
anchor = anchor_;
}
- if (selType == selRectangle) {
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
- }
+ SetRectangularRange();
ClaimSelection();
}
InvalidateSelection(currentPos_, currentPos_);
currentPos = currentPos_;
}
- if (selType == selRectangle) {
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
- }
+ SetRectangularRange();
ClaimSelection();
}
SetTopLine(topLineNew);
ShowCaretAtCurrentPosition();
// Perform redraw rather than scroll if many lines would be redrawn anyway.
+#ifndef UNDER_CE
if (abs(linesToMove) <= 10) {
ScrollText(linesToMove);
} else {
Redraw();
}
+#else
+ Redraw();
+#endif
if (moveThumb) {
SetVerticalScrollPos();
}
posLineEnd = posLineStart + ll->maxLineLength;
}
if (ll->validity == LineLayout::llCheckTextAndStyle) {
- int lineLength = 0;
- for (int cid = posLineStart; cid < posLineEnd; cid++) {
- char chDoc = pdoc->CharAt(cid);
- if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
- lineLength++;
+ int lineLength = posLineEnd - posLineStart;
+ if (!vstyle.viewEOL) {
+ int cid = posLineEnd - 1;
+ while ((cid > posLineStart) && IsEOLChar(pdoc->CharAt(cid))) {
+ cid--;
+ lineLength--;
}
}
if (lineLength == ll->numCharsInLine) {
- int numCharsInLine = 0;
// See if chars, styles, indicators, are all the same
bool allSame = true;
const int styleMask = pdoc->stylingBitsMask;
// Check base line layout
- for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) {
+ char styleByte = 0;
+ int numCharsInLine = 0;
+ while (numCharsInLine < lineLength) {
+ int charInDoc = numCharsInLine + posLineStart;
char chDoc = pdoc->CharAt(charInDoc);
- if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
- char styleByte = pdoc->StyleAt(charInDoc);
+ styleByte = pdoc->StyleAt(charInDoc);
+ allSame = allSame &&
+ (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask));
+ allSame = allSame &&
+ (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+ if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed)
allSame = allSame &&
- (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
+ (ll->chars[numCharsInLine] == chDoc);
+ else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
allSame = allSame &&
- (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
- if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
- else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
- else
- allSame = allSame &&
- (ll->chars[numCharsInLine] == chDoc);
- numCharsInLine++;
- }
+ (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+ else // Style::caseUpper
+ allSame = allSame &&
+ (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+ numCharsInLine++;
}
+ allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled
if (allSame) {
ll->validity = LineLayout::llPositions;
} else {
char styleByte = 0;
int styleMask = pdoc->stylingBitsMask;
+ ll->styleBitsSet = 0;
// Fill base line layout
for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
char chDoc = pdoc->CharAt(charInDoc);
styleByte = pdoc->StyleAt(charInDoc);
+ ll->styleBitsSet |= styleByte;
if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
ll->chars[numCharsInLine] = chDoc;
ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
bool lastSegItalics = false;
Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font;
+ int ctrlCharWidth[32] = {0};
bool isControlNext = IsControlCharacter(ll->chars[0]);
for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) {
bool isControl = isControlNext;
ll->positions[charInLine + 1] = ((((startsegx + 2) /
tabWidth) + 1) * tabWidth) - startsegx;
} else if (controlCharSymbol < 32) {
- const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
- // +3 For a blank on front and rounded edge each side:
- ll->positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
+ if (ctrlCharWidth[ll->chars[charInLine]] == 0) {
+ const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
+ // +3 For a blank on front and rounded edge each side:
+ ctrlCharWidth[ll->chars[charInLine]] =
+ surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
+ }
+ ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]];
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->MeasureWidths(ctrlCharsFont, cc, 1,
continue;
}
if (p > 0) {
- if (ll->styles[p] != ll->styles[p - 1]) {
+ if (wrapState == eWrapChar){
+ lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1)
+ - posLineStart;
+ p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart;
+ continue;
+ } else if (ll->styles[p] != ll->styles[p - 1]) {
lastGoodBreak = p;
} else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) {
lastGoodBreak = p;
}
}
}
+ } else if (rcSegment.left > rcLine.right) {
+ break;
}
startseg = i + 1;
}
rcUL.bottom = rcUL.top + 1;
surface->FillRectangle(rcUL, textFore);
}
+ } else if (rcSegment.left > rcLine.right) {
+ break;
}
startseg = i + 1;
}
}
// Draw indicators
- int indStart[INDIC_MAX + 1] = {0};
- for (int indica = 0; indica <= INDIC_MAX; indica++)
- indStart[indica] = 0;
-
- for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) {
- if ((indicPos == lineStart) || (indicPos == lineEnd) ||
- (ll->indicators[indicPos] != ll->indicators[indicPos + 1])) {
- int mask = 1 << pdoc->stylingBits;
- for (int indicnum = 0; mask < 0x100; indicnum++) {
- if ((indicPos == lineStart) || (indicPos == lineEnd)) {
- indStart[indicnum] = ll->positions[indicPos];
- } else if ((ll->indicators[indicPos + 1] & mask) && !(ll->indicators[indicPos] & mask)) {
- indStart[indicnum] = ll->positions[indicPos + 1];
- }
- if ((ll->indicators[indicPos] & mask) &&
- ((indicPos == lineEnd) || !(ll->indicators[indicPos + 1] & mask))) {
- int endIndicator = indicPos;
- if (endIndicator >= lineEnd)
- endIndicator = lineEnd-1;
+ // foreach indicator...
+ for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) {
+ if (!(mask & ll->styleBitsSet)) {
+ mask <<= 1;
+ continue;
+ }
+ int startPos = -1;
+ // foreach style pos in line...
+ for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) {
+ // look for starts...
+ if (startPos < 0) {
+ // NOT in indicator run, looking for START
+ if (indicPos < lineEnd && (ll->indicators[indicPos] & mask))
+ startPos = indicPos;
+ }
+ // ... or ends
+ if (startPos >= 0) {
+ // IN indicator run, looking for END
+ if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) {
+ // AT end of indicator run, DRAW it!
PRectangle rcIndic(
- indStart[indicnum] + xStart - subLineStart,
+ ll->positions[startPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent,
- ll->positions[endIndicator + 1] + xStart - subLineStart,
+ ll->positions[indicPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent + 3);
vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine);
+ // RESET control var
+ startPos = -1;
}
- mask = mask << 1;
}
}
+ mask <<= 1;
}
// End of the drawing of the current line
if (!twoPhaseDraw) {
if (bufferedDraw) {
if (!pixmapLine->Initialised()) {
PRectangle rcClient = GetClientRectangle();
- pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(),
+ pixmapLine->InitPixMap(rcClient.Width(), vs.lineHeight,
surfaceWindow, wMain.GetID());
pixmapSelMargin->InitPixMap(vs.fixedColumnWidth,
rcClient.Height(), surfaceWindow, wMain.GetID());
//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;
ll->selStart = SelectionStart();
ll->selEnd = SelectionEnd();
} else {
- lineIterator.SetAt(lineDoc);
ll->selStart = lineIterator.startPos;
ll->selEnd = lineIterator.endPos;
}
visibleLine++;
//gdk_flush();
}
+ ll.Set(0);
//if (durPaint < 0.00000001)
// durPaint = 0.00000001;
int nMax = MaxScrollPos();
int nPage = LinesOnScreen();
bool modified = ModifyScrollBars(nMax + nPage - 1, nPage);
+ if (modified) {
+ DwellEnd(true);
+ }
// TODO: ensure always showing as many lines as possible
// May not be, if, for example, window made larger
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);
}
}
if (pdoc->InsertString(currentPos, s, len)) {
SetEmptySelection(currentPos + len);
}
+ if (charReplaceAction) {
+ pdoc->EndUndoAction();
+ }
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
if (treatAsDBCS) {
NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
currentPos = 0;
SetTopLine(0);
SetVerticalScrollPos();
- InvalidateStyleRedraw(); // RPD: patch #1106564
+ InvalidateStyleRedraw();
}
void Editor::ClearDocumentStyle() {
if (pdoc->CanUndo()) {
InvalidateCaret();
int newPos = pdoc->Undo();
- SetEmptySelection(newPos);
+ if (newPos >= 0)
+ SetEmptySelection(newPos);
EnsureCaretVisible();
}
}
void Editor::Redo() {
if (pdoc->CanRedo()) {
int newPos = pdoc->Redo();
- SetEmptySelection(newPos);
+ if (newPos >= 0)
+ SetEmptySelection(newPos);
EnsureCaretVisible();
}
}
void Editor::NotifyFocus(bool) {}
void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_STYLENEEDED;
scn.position = endStyleNeeded;
NotifyParent(scn);
}
void Editor::NotifyChar(int ch) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_CHARADDED;
scn.ch = ch;
NotifyParent(scn);
}
void Editor::NotifySavePoint(bool isSavePoint) {
- SCNotification scn;
+ SCNotification scn = {0};
if (isSavePoint) {
scn.nmhdr.code = SCN_SAVEPOINTREACHED;
} else {
}
void Editor::NotifyModifyAttempt() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MODIFYATTEMPTRO;
NotifyParent(scn);
}
void Editor::NotifyDoubleClick(Point, bool) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_DOUBLECLICK;
NotifyParent(scn);
}
void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
}
void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_HOTSPOTCLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
}
void Editor::NotifyUpdateUI() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_UPDATEUI;
NotifyParent(scn);
}
void Editor::NotifyPainted() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_PAINTED;
NotifyParent(scn);
}
x += vs.ms[margin].width;
}
if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MARGINCLICK;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0);
}
void Editor::NotifyNeedShown(int pos, int len) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_NEEDSHOWN;
scn.position = pos;
scn.length = len;
}
void Editor::NotifyDwelling(Point pt, bool state) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND;
scn.position = PositionFromLocationClose(pt);
scn.x = pt.x;
}
void Editor::NotifyZoom() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_ZOOM;
NotifyParent(scn);
}
}
void Editor::NotifyMove(int position) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_POSCHANGED;
scn.position = position;
NotifyParent(scn);
}
void Editor::CheckModificationForWrap(DocModification mh) {
- if ((mh.modificationType & SC_MOD_INSERTTEXT) ||
- (mh.modificationType & SC_MOD_DELETETEXT)) {
+ if (mh.modificationType & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT)) {
llc.Invalidate(LineLayout::llCheckTextAndStyle);
if (wrapState != eWrapNone) {
int lineDoc = pdoc->LineFromPosition(mh.position);
// Some lines are hidden so may need shown.
// TODO: check if the modified area is hidden.
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
- NotifyNeedShown(mh.position, mh.length);
+ NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length);
}
CheckModificationForWrap(mh);
if (mh.linesAdded != 0) {
// Avoid scrolling of display if change before current display
- if (mh.position < posTopLine) {
+ if (mh.position < posTopLine && !CanDeferToLastStep(mh)) {
int newTop = Platform::Clamp(topLine + mh.linesAdded, 0, MaxScrollPos());
if (newTop != topLine) {
SetTopLine(newTop);
//Platform::DebugPrintf("** %x Doc Changed\n", this);
// TODO: could invalidate from mh.startModification to end of screen
//InvalidateRange(mh.position, mh.position + mh.length);
- if (paintState == notPainting) {
+ if (paintState == notPainting && !CanDeferToLastStep(mh)) {
Redraw();
}
} else {
//Platform::DebugPrintf("** %x Line Changed %d .. %d\n", this,
// mh.position, mh.position + mh.length);
- if (paintState == notPainting) {
+ if (paintState == notPainting && mh.length && !CanEliminate(mh)) {
InvalidateRange(mh.position, mh.position + mh.length);
}
}
}
- if (mh.linesAdded != 0) {
+ if (mh.linesAdded != 0 && !CanDeferToLastStep(mh)) {
SetScrollBars();
}
if (mh.modificationType & SC_MOD_CHANGEMARKER) {
- if (paintState == notPainting) {
- RedrawSelMargin();
+ if ((paintState == notPainting) || !PaintContainsMargin()) {
+ if (mh.modificationType & SC_MOD_CHANGEFOLD) {
+ // Fold changes can affect the drawing of following lines so redraw whole margin
+ RedrawSelMargin();
+ } else {
+ RedrawSelMargin(mh.line);
+ }
}
}
+ // NOW pay the piper WRT "deferred" visual updates
+ if (IsLastStep(mh)) {
+ SetScrollBars();
+ Redraw();
+ }
+
// If client wants to see this modification
if (mh.modificationType & modEventMask) {
if ((mh.modificationType & SC_MOD_CHANGESTYLE) == 0) {
NotifyChange(); // Send EN_CHANGE
}
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MODIFIED;
scn.position = mh.position;
scn.modificationType = mh.modificationType;
/* Do nothing */
}
-void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam) {
+void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
// Enumerates all macroable messages
switch (iMessage) {
case SCI_LINEENDRECTEXTEND:
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
+ case SCI_SELECTIONDUPLICATE:
break;
// Filter out all others like display changes. Also, newlines are redundant
}
// Send notification
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MACRORECORD;
scn.message = iMessage;
scn.wParam = wParam;
}
}
-void Editor::LineDuplicate() {
- int line = pdoc->LineFromPosition(currentPos);
- int start = pdoc->LineStart(line);
- int end = pdoc->LineEnd(line);
- char *thisLine = CopyRange(start, end);
- const char *eol = StringFromEOLMode(pdoc->eolMode);
- pdoc->InsertString(end, eol);
- pdoc->InsertString(end + istrlen(eol), thisLine, end - start);
- delete []thisLine;
+void Editor::Duplicate(bool forLine) {
+ int start = SelectionStart();
+ int end = SelectionEnd();
+ if (start == end) {
+ forLine = true;
+ }
+ if (forLine) {
+ int line = pdoc->LineFromPosition(currentPos);
+ start = pdoc->LineStart(line);
+ end = pdoc->LineEnd(line);
+ }
+ char *text = CopyRange(start, end);
+ if (forLine) {
+ const char *eol = StringFromEOLMode(pdoc->eolMode);
+ pdoc->InsertString(end, eol);
+ pdoc->InsertString(end + istrlen(eol), text, end - start);
+ } else {
+ pdoc->InsertString(end, text, end - start);
+ }
+ delete []text;
}
void Editor::CancelModes() {
}
SetLastXChosen();
EnsureCaretVisible();
+ // Avoid blinking during rapid typing:
+ ShowCaretAtCurrentPosition();
}
void Editor::CursorUpOrDown(int direction, selTypes sel) {
MovePositionTo(posNew, sel);
}
+void Editor::ParaUpOrDown(int direction, selTypes sel) {
+ int lineDoc, savedPos = currentPos;
+ do {
+ MovePositionTo(direction > 0 ? pdoc->ParaDown(currentPos) : pdoc->ParaUp(currentPos), sel);
+ lineDoc = pdoc->LineFromPosition(currentPos);
+ if (direction > 0) {
+ if (currentPos >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
+ if (sel == noSel) {
+ MovePositionTo(pdoc->LineEndPosition(savedPos));
+ }
+ break;
+ }
+ }
+ } while (!cs.GetVisible(lineDoc));
+}
+
int Editor::StartEndDisplayLine(int pos, bool start) {
RefreshStyleData();
int line = pdoc->LineFromPosition(pos);
CursorUpOrDown(1, selRectangle);
break;
case SCI_PARADOWN:
- MovePositionTo(pdoc->ParaDown(currentPos));
+ ParaUpOrDown(1);
break;
case SCI_PARADOWNEXTEND:
- MovePositionTo(pdoc->ParaDown(currentPos), selStream);
+ ParaUpOrDown(1, selStream);
break;
case SCI_LINESCROLLDOWN:
ScrollTo(topLine + 1);
CursorUpOrDown(-1, selRectangle);
break;
case SCI_PARAUP:
- MovePositionTo(pdoc->ParaUp(currentPos));
+ ParaUpOrDown(-1);
break;
case SCI_PARAUPEXTEND:
- MovePositionTo(pdoc->ParaUp(currentPos), selStream);
+ ParaUpOrDown(-1, selStream);
break;
case SCI_LINESCROLLUP:
ScrollTo(topLine - 1);
break;
case SCI_DELETEBACK:
DelCharBack(true);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_DELETEBACKNOTLINE:
DelCharBack(false);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_TAB:
Indent(true);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_BACKTAB:
Indent(false);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_NEWLINE:
LineTranspose();
break;
case SCI_LINEDUPLICATE:
- LineDuplicate();
+ Duplicate(true);
+ break;
+ case SCI_SELECTIONDUPLICATE:
+ Duplicate(false);
break;
case SCI_LOWERCASE:
ChangeCaseOfSelection(false);
NotifyHotSpotClicked(newPos, shift, ctrl, alt);
}
if (!shift) {
- inDragDrop = PointInSelection(pt);
+ inDragDrop = PointInSelection(pt) && !SelectionEmpty();
}
if (inDragDrop) {
SetMouseCapture(false);
SetEmptySelection(newPos);
}
selType = alt ? selRectangle : selStream;
- xStartSelect = xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
selectionType = selChar;
originalAnchorPos = currentPos;
+ SetRectangularRange();
}
}
}
}
}
// Display regular (drag) cursor over selection
- if (PointInSelection(pt)) {
+ if (PointInSelection(pt) && !SelectionEmpty()) {
DisplayCursor(Window::cursorArrow);
} else if (PointIsHotspot(pt)) {
DisplayCursor(Window::cursorHand);
}
void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
- //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture());
+ //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture());
if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) {
DisplayCursor(Window::cursorReverseArrow);
SetSelection(newPos);
}
}
- // Now we rely on the current pos to compute rectangular selection
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
+ SetRectangularRange();
lastClickTime = curTime;
lastClick = pt;
lastXChosen = pt.x;
if (timer.ticksToWait <= 0) {
caret.on = !caret.on;
timer.ticksToWait = caret.period;
- InvalidateCaret();
+ if (caret.active) {
+ InvalidateCaret();
+ }
}
}
if ((dwellDelay < SC_TIME_FOREVER) &&
}
}
-static bool IsIn(int a, int minimum, int maximum) {
- return (a >= minimum) && (a <= maximum);
+bool Editor::PaintContains(PRectangle rc) {
+ return rcPaint.Contains(rc);
}
-static bool IsOverlap(int mina, int maxa, int minb, int maxb) {
- return
- IsIn(mina, minb, maxb) ||
- IsIn(maxa, minb, maxb) ||
- IsIn(minb, mina, maxa) ||
- IsIn(maxb, mina, maxa);
+bool Editor::PaintContainsMargin() {
+ PRectangle rcSelMargin = GetClientRectangle();
+ rcSelMargin.right = vs.fixedColumnWidth;
+ return PaintContains(rcSelMargin);
}
void Editor::CheckForChangeOutsidePaint(Range r) {
if (!r.Valid())
return;
+ PRectangle rcRange = RectangleFromRange(r.start, r.end);
PRectangle rcText = GetTextRectangle();
- // Determine number of lines displayed including a possible partially displayed last line
- int linesDisplayed = (rcText.bottom - rcText.top - 1) / vs.lineHeight + 1;
- int bottomLine = topLine + linesDisplayed - 1;
-
- int lineRangeStart = cs.DisplayFromDoc(pdoc->LineFromPosition(r.start));
- int lineRangeEnd = cs.DisplayFromDoc(pdoc->LineFromPosition(r.end));
- if (!IsOverlap(topLine, bottomLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("No overlap (%d-%d) with window(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, topLine, bottomLine);
- return;
+ if (rcRange.top < rcText.top) {
+ rcRange.top = rcText.top;
}
-
- // Assert rcPaint contained within or equal to rcText
- if (rcPaint.top > rcText.top) {
- // does range intersect rcText.top .. rcPaint.top
- int paintTopLine = ((rcPaint.top - rcText.top - 1) / vs.lineHeight) + topLine;
- // paintTopLine is the top line of the paint rectangle or the line just above if that line is completely inside the paint rectangle
- if (IsOverlap(topLine, paintTopLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, topLine, paintTopLine);
- AbandonPaint();
- return;
- }
+ if (rcRange.bottom > rcText.bottom) {
+ rcRange.bottom = rcText.bottom;
}
- if (rcPaint.bottom < rcText.bottom) {
- // does range intersect rcPaint.bottom .. rcText.bottom
- int paintBottomLine = ((rcPaint.bottom - rcText.top - 1) / vs.lineHeight + 1) + topLine;
- // paintTopLine is the bottom line of the paint rectangle or the line just below if that line is completely inside the paint rectangle
- if (IsOverlap(paintBottomLine, bottomLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, paintBottomLine, bottomLine);
- AbandonPaint();
- return;
- }
+
+ if (!PaintContains(rcRange)) {
+ AbandonPaint();
}
}
}
-char BraceOpposite(char ch) {
- switch (ch) {
- case '(':
- return ')';
- case ')':
- return '(';
- case '[':
- return ']';
- case ']':
- return '[';
- case '{':
- return '}';
- case '}':
- return '{';
- case '<':
- return '>';
- case '>':
- return '<';
- default:
- return '\0';
- }
-}
-
-// TODO: should be able to extend styled region to find matching brace
-// TODO: may need to make DBCS safe
-// so should be moved into Document
-int Editor::BraceMatch(int position, int /*maxReStyle*/) {
- char chBrace = pdoc->CharAt(position);
- char chSeek = BraceOpposite(chBrace);
- if (chSeek == '\0')
- return - 1;
- char styBrace = static_cast<char>(
- pdoc->StyleAt(position) & pdoc->stylingBitsMask);
- int direction = -1;
- if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
- direction = 1;
- int depth = 1;
- position = position + direction;
- while ((position >= 0) && (position < pdoc->Length())) {
- char chAtPos = pdoc->CharAt(position);
- char styAtPos = static_cast<char>(pdoc->StyleAt(position) & pdoc->stylingBitsMask);
- if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) {
- if (chAtPos == chBrace)
- depth++;
- if (chAtPos == chSeek)
- depth--;
- if (depth == 0)
- return position;
- }
- position = position + direction;
- }
- return - 1;
-}
-
void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) {
if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) {
if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) {
NeedWrapping();
pdoc->AddWatcher(this, 0);
- Redraw();
SetScrollBars();
+ Redraw();
}
/**
return 0;
}
+int Editor::WrapCount(int line) {
+ AutoSurface surface(this);
+ AutoLineLayout ll(llc, RetrieveLineLayout(line));
+
+ if (surface && ll) {
+ LayoutLine(line, surface, vs, ll, wrapWidth);
+ return ll->lines;
+ } else {
+ return 1;
+ }
+}
+
static bool ValidMargin(unsigned long wParam) {
return wParam < ViewStyle::margins;
}
case SCI_PASTE:
Paste();
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
break;
case SCI_CANUNDO:
- return pdoc->CanUndo() ? 1 : 0;
+ return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0;
case SCI_EMPTYUNDOBUFFER:
pdoc->DeleteUndoHistory();
}
case SCI_CANREDO:
- return pdoc->CanRedo() ? 1 : 0;
+ return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0;
case SCI_MARKERLINEFROMHANDLE:
return pdoc->LineFromHandle(wParam);
if (lParam == 0) {
return 1 + lineEnd - lineStart;
}
+ PLATFORM_ASSERT(wParam > 0);
char *ptr = CharPtrFromSPtr(lParam);
unsigned int iPlace = 0;
for (unsigned int iChar = lineStart; iChar < lineEnd && iPlace < wParam - 1; iChar++) {
return pdoc->ExtendWordSelect(wParam, 1, lParam != 0);
case SCI_SETWRAPMODE:
- wrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone;
+ switch(wParam){
+ case SC_WRAP_WORD:
+ wrapState = eWrapWord;
+ break;
+ case SC_WRAP_CHAR:
+ wrapState = eWrapChar;
+ break;
+ default:
+ wrapState = eWrapNone;
+ break;
+ }
xOffset = 0;
InvalidateStyleRedraw();
ReconfigureScrollBars();
case SCI_GETENDATLASTLINE:
return endAtLastLine;
+ case SCI_SETCARETSTICKY:
+ PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
+ if (caretSticky != (wParam != 0)) {
+ caretSticky = wParam != 0;
+ }
+ break;
+
+ case SCI_GETCARETSTICKY:
+ return caretSticky;
+
+ case SCI_TOGGLECARETSTICKY:
+ caretSticky = !caretSticky;
+ break;
+
case SCI_GETCOLUMN:
return pdoc->GetColumn(wParam);
int markerID = pdoc->AddMark(wParam, lParam);
return markerID;
}
+ case SCI_MARKERADDSET:
+ if (lParam != 0)
+ pdoc->AddMarkSet(wParam, lParam);
+ break;
case SCI_MARKERDELETE:
pdoc->DeleteMark(wParam, lParam);
case SCI_DOCLINEFROMVISIBLE:
return cs.DocFromDisplay(wParam);
+ case SCI_WRAPCOUNT:
+ return WrapCount(wParam);
+
case SCI_SETFOLDLEVEL: {
int prev = pdoc->SetLevel(wParam, lParam);
if (prev != lParam)
case SCI_LINEENDRECTEXTEND:
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
+ case SCI_SELECTIONDUPLICATE:
return KeyCommand(iMessage);
case SCI_BRACEHIGHLIGHT:
case SCI_BRACEMATCH:
// wParam is position of char to find brace for,
// lParam is maximum amount of text to restyle to find it
- return BraceMatch(wParam, lParam);
+ return pdoc->BraceMatch(wParam, lParam);
case SCI_GETVIEWEOL:
return vs.viewEOL;
InvalidateStyleRedraw();
break;
+ case SCI_SETPASTECONVERTENDINGS:
+ convertPastes = wParam != 0;
+ break;
+
+ case SCI_GETPASTECONVERTENDINGS:
+ return convertPastes ? 1 : 0;
+
default:
return DefWndProc(iMessage, wParam, lParam);
}
int edgeColumn;
char *chars;
unsigned char *styles;
+ int styleBitsSet;
char *indicators;
int *positions;
char bracePreviousStyles[2];
LineLayout **cache;
bool allInvalidated;
int styleClock;
+ int useCount;
void Allocate(int length_);
void AllocateForLevel(int linesOnScreen, int linesInDoc);
public:
int scrollWidth;
bool verticalScrollBarVisible;
bool endAtLastLine;
+ bool caretSticky;
Surface *pixmapLine;
Surface *pixmapSelMargin;
int hsEnd;
// Wrapping support
- enum { eWrapNone, eWrapWord } wrapState;
+ enum { eWrapNone, eWrapWord, eWrapChar } wrapState;
bool backgroundWrapEnabled;
int wrapWidth;
int docLineLastWrapped;
int wrapVisualStartIndent;
int actualWrapVisualStartIndent;
+ bool convertPastes;
+
Document *pdoc;
Editor();
bool AbandonPaint();
void RedrawRect(PRectangle rc);
void Redraw();
- void RedrawSelMargin();
+ void RedrawSelMargin(int line=-1);
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
bool SelectionEmpty();
int SelectionStart();
int SelectionEnd();
+ void SetRectangularRange();
void InvalidateSelection(int currentPos_, int anchor_);
void SetSelection(int currentPos_, int anchor_);
void SetSelection(int currentPos_);
void PageMove(int direction, selTypes sel=noSel, bool stuttered = false);
void ChangeCaseOfSelection(bool makeUpperCase);
void LineTranspose();
- void LineDuplicate();
+ void Duplicate(bool forLine);
virtual void CancelModes();
void NewLine();
void CursorUpOrDown(int direction, selTypes sel=noSel);
+ void ParaUpOrDown(int direction, selTypes sel=noSel);
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
+ virtual bool PaintContains(PRectangle rc);
+ bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
- int BraceMatch(int position, int maxReStyle);
void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
void SetDocPointer(Document *document);
void GetHotSpotRange(int& hsStart, int& hsEnd);
int CodePage() const;
+ int WrapCount(int line);
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},
{'T', SCI_CTRL, SCI_LINETRANSPOSE},
- {'D', SCI_CTRL, SCI_LINEDUPLICATE},
+ {'D', SCI_CTRL, SCI_SELECTIONDUPLICATE},
{'U', SCI_CTRL, SCI_LOWERCASE},
{'U', SCI_CSHIFT, SCI_UPPERCASE},
{0,0,0},
const LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
-LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
- const char *languageName_, LexerFunction fnFolder_,
- const char * const wordListDescriptions_[]) :
+LexerModule::LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_,
+ LexerFunction fnFolder_,
+ const char * const wordListDescriptions_[],
+ int styleBits_) :
language(language_),
fnLexer(fnLexer_),
fnFolder(fnFolder_),
wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
languageName(languageName_) {
next = base;
base = this;
}
}
-const char * LexerModule::GetWordListDescription(int index) const {
+const char *LexerModule::GetWordListDescription(int index) const {
static const char *emptyStr = "";
PLATFORM_ASSERT(index < GetNumWordLists());
}
}
+int LexerModule::GetStyleBitsNeeded() const {
+ return styleBits;
+}
+
const LexerModule *LexerModule::Find(int language) {
const LexerModule *lm = base;
while (lm) {
//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
LINK_LEXER(lmAda);
+ LINK_LEXER(lmAns1);
LINK_LEXER(lmAPDL);
LINK_LEXER(lmAsm);
- LINK_LEXER(lmAsn1);
+ LINK_LEXER(lmASP);
LINK_LEXER(lmAU3);
LINK_LEXER(lmAVE);
LINK_LEXER(lmBaan);
LINK_LEXER(lmBash);
+ LINK_LEXER(lmBatch);
+ LINK_LEXER(lmBlitzBasic);
LINK_LEXER(lmBullant);
+ LINK_LEXER(lmCaml);
LINK_LEXER(lmClw);
LINK_LEXER(lmClwNoCase);
LINK_LEXER(lmConf);
LINK_LEXER(lmCPP);
LINK_LEXER(lmCPPNoCase);
- LINK_LEXER(lmTCL);
- LINK_LEXER(lmNncrontab);
+ LINK_LEXER(lmCsound);
LINK_LEXER(lmCss);
+ LINK_LEXER(lmDiff);
LINK_LEXER(lmEiffel);
LINK_LEXER(lmEiffelkw);
LINK_LEXER(lmErlang);
+ LINK_LEXER(lmErrorList);
LINK_LEXER(lmESCRIPT);
+ LINK_LEXER(lmF77);
+ LINK_LEXER(lmFlagShip);
LINK_LEXER(lmForth);
LINK_LEXER(lmFortran);
- LINK_LEXER(lmF77);
+ LINK_LEXER(lmFreeBasic);
LINK_LEXER(lmGui4Cli);
+ LINK_LEXER(lmHaskell);
LINK_LEXER(lmHTML);
- LINK_LEXER(lmXML);
- LINK_LEXER(lmASP);
- LINK_LEXER(lmPHP);
LINK_LEXER(lmKix);
+ LINK_LEXER(lmLatex);
LINK_LEXER(lmLISP);
+ LINK_LEXER(lmLot);
LINK_LEXER(lmLout);
LINK_LEXER(lmLua);
+ LINK_LEXER(lmMake);
LINK_LEXER(lmMatlab);
- LINK_LEXER(lmOctave);
LINK_LEXER(lmMETAPOST);
LINK_LEXER(lmMMIXAL);
- LINK_LEXER(lmLot);
LINK_LEXER(lmMSSQL);
+ LINK_LEXER(lmNncrontab);
LINK_LEXER(lmNsis);
- LINK_LEXER(lmBatch);
- LINK_LEXER(lmDiff);
- LINK_LEXER(lmProps);
- LINK_LEXER(lmMake);
- LINK_LEXER(lmErrorList);
- LINK_LEXER(lmLatex);
LINK_LEXER(lmNull);
+ LINK_LEXER(lmOctave);
LINK_LEXER(lmPascal);
LINK_LEXER(lmPB);
LINK_LEXER(lmPerl);
+ LINK_LEXER(lmPHP);
+ LINK_LEXER(lmPHPSCRIPT);
LINK_LEXER(lmPOV);
+ LINK_LEXER(lmProps);
LINK_LEXER(lmPS);
+ LINK_LEXER(lmPureBasic);
LINK_LEXER(lmPython);
+ LINK_LEXER(lmREBOL);
LINK_LEXER(lmRuby);
LINK_LEXER(lmScriptol);
+ LINK_LEXER(lmSmalltalk);
LINK_LEXER(lmSpecman);
LINK_LEXER(lmSQL);
+ LINK_LEXER(lmTADS3);
+ LINK_LEXER(lmTCL);
LINK_LEXER(lmTeX);
LINK_LEXER(lmVB);
LINK_LEXER(lmVBScript);
LINK_LEXER(lmVerilog);
LINK_LEXER(lmVHDL);
+ LINK_LEXER(lmXML);
LINK_LEXER(lmYAML);
//--Autogenerated -- end of automatically generated section
// Added fold.compact support set with fold.compact=1
// Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
// it will now only happen when fold.comment=2.
-//
+// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
+// Typed Characters now show as "default" till they match any table.
+// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
+// Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
+// Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
+// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
+// Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator.
+// Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account
+// - Added folding support for With...EndWith
+// - Added support for a DOT in variable names
+// - Fixed Underscore in CommentBlock
+// May 23, 2005 - Fixed the SentKey lexing in case of a missing }
+// Aug 11, 2005 - Fixed possible bug with s_save length > 100.
+// Aug 23, 2005 - Added Switch/endswitch support to the folding logic.
+//
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Scintilla source code edit control
static inline bool IsAWordStart(const int ch)
{
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$');
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
}
static inline bool IsAOperator(char ch) {
// split the portion of the sendkey in the part before and after the spaces
while ( ( (cTemp = szLine[nPos]) != '\0'))
{
- if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
+ // skip leading Ctrl/Shift/ALt state
+ if ((cTemp == '#' || cTemp == '!' || cTemp == '^') && (szLine[nPos+1] == '{') )
+ {
+ }
+ else if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
{
nFlag = 1;
// Add } to the end of the first bit for table lookup later.
} // GetSendKey()
+//
+// Routine to check the last "none comment" character on a line to see if its a continuation
+//
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
+{
+ int nsPos = styler.LineStart(szLine);
+ int nePos = styler.LineStart(szLine+1) - 2;
+ //int stylech = styler.StyleAt(nsPos);
+ while (nsPos < nePos)
+ {
+ //stylech = styler.StyleAt(nePos);
+ int stylech = styler.StyleAt(nsPos);
+ if (!(stylech == SCE_AU3_COMMENT)) {
+ char ch = styler.SafeGetCharAt(nePos);
+ if (!isspacechar(ch)) {
+ if (ch == '_')
+ return true;
+ else
+ return false;
+ }
+ }
+ nePos--; // skip to next char
+ } // End While
+ return false;
+} // IsContinuationLine()
+
+//
+// syntax highlighting logic
static void ColouriseAU3Doc(unsigned int startPos,
int length, int initStyle,
WordList *keywordlists[],
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ // find the first previous line without continuation character at the end
+ int lineCurrent = styler.GetLine(startPos);
+ int s_startPos = startPos;
+ // When not inside a Block comment: find First line without _
+ if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
+ (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent); // get start position
+ initStyle = 0; // reset the start style to 0
+ }
+ }
+ // Set the new length to include it from the start and set the start position
+ length = length + s_startPos - startPos; // correct the total length to process
styler.StartAt(startPos);
-
+
StyleContext sc(startPos, length, initStyle, styler);
char si; // string indicator "=1 '=2
- si=0;
+ char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
+ char ci; // comment indicator 0=not linecomment(;)
+ char s_save[100];
+ si=0;
+ ni=0;
+ ci=0;
//$$$
for (; sc.More(); sc.Forward()) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
+ // **********************************************
+ // save the total current word for eof processing
+ if (IsAWordChar(sc.ch) || 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';
+ }
+ }
+ // **********************************************
+ //
switch (sc.state)
{
case SCE_AU3_COMMENTBLOCK:
{
- if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0)))
- {
+ //Reset at line end
+ if (sc.atLineEnd) {
+ ci=0;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ //skip rest of line when a ; is encountered
+ if (sc.chPrev == ';') {
+ ci=2;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ // skip rest of the line
+ if (ci==2)
+ break;
+ // check when first character is detected on the line
+ if (ci==0) {
+ if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
+ ci=1;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ break;
+ }
+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
- {sc.SetState(SCE_AU3_COMMENT);} // set to comment line for the rest of the line
+ sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line
else
- {sc.SetState(SCE_AU3_COMMENTBLOCK);}
+ ci=2; // line doesn't begin with #CE so skip the rest of the line
}
break;
}
}
case SCE_AU3_OPERATOR:
{
- sc.SetState(SCE_AU3_DEFAULT);
+ // check if its a COMobject
+ if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_AU3_COMOBJ);
+ }
+ else {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
break;
}
case SCE_AU3_SPECIAL:
{
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
+ if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
break;
}
case SCE_AU3_KEYWORD:
sc.ChangeState(SCE_AU3_SPECIAL);
sc.SetState(SCE_AU3_SPECIAL);
}
+ else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
+ sc.ChangeState(SCE_AU3_EXPAND);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
else if (strcmp(s, "_") == 0) {
sc.ChangeState(SCE_AU3_OPERATOR);
sc.SetState(SCE_AU3_DEFAULT);
}
}
}
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_AU3_DEFAULT);}
break;
}
- case SCE_AU3_NUMBER:
+ case SCE_AU3_NUMBER:
{
- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
- break;
+ // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
+ //
+ // test for Hex notation
+ if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
+ {
+ ni = 2;
+ break;
+ }
+ // test for E notation
+ if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
+ {
+ ni = 3;
+ break;
+ }
+ // Allow Hex characters inside hex numeric strings
+ if ((ni == 2) &&
+ (sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
+ sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
+ {
+ break;
+ }
+ // test for 1 dec point only
+ if (sc.ch == '.')
+ {
+ if (ni==0)
+ {
+ ni=1;
+ }
+ else
+ {
+ ni=9;
+ }
+ break;
+ }
+ // end of numeric string ?
+ if (!(IsADigit(sc.ch)))
+ {
+ if (ni==9)
+ {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ }
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ case SCE_AU3_VARIABLE:
+ {
+ // Check if its a COMObject
+ if (sc.ch == '.' && !IsADigit(sc.chNext)) {
+ sc.SetState(SCE_AU3_OPERATOR);
+ }
+ else if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
}
- case SCE_AU3_VARIABLE:
- {
- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
- break;
+ case SCE_AU3_COMOBJ:
+ {
+ if (!(IsAWordChar(sc.ch))) {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
}
case SCE_AU3_STRING:
{
{
sc.ForwardSetState(SCE_AU3_DEFAULT);
}
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ if (sc.atLineEnd)
+ {
+ // at line end and not found a continuation char then reset to default
+ int lineCurrent = styler.GetLine(sc.currentPos);
+ if (!IsContinuationLine(lineCurrent,styler))
+ {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
// find Sendkeys in a STRING
if (sc.ch == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
// check if next portion is again a sendkey
if (sc.atLineEnd)
{
+ sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_DEFAULT);
si = 0; // reset string indicator
}
- if (sc.ch == '{' && sc.chPrev != '{') {sc.SetState(SCE_AU3_SENT);}
+ //if (sc.ch == '{' && sc.chPrev != '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
+ else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
else if (sc.ch == '\"') {
else if (sc.ch == '\'') {
sc.SetState(SCE_AU3_STRING);
si = 2; }
- else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_AU3_NUMBER);}
+ else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+ {
+ sc.SetState(SCE_AU3_NUMBER);
+ ni = 0;
+ }
else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
}
} //for (; sc.More(); sc.Forward())
- sc.Complete();
+
+ //*************************************
+ // Colourize the last word correctly
+ //*************************************
+ if (sc.state == SCE_AU3_KEYWORD)
+ {
+ if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
+ {
+ sc.ChangeState(SCE_AU3_COMMENTBLOCK);
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ else if (keywords.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_KEYWORD);
+ sc.SetState(SCE_AU3_KEYWORD);
+ }
+ else if (keywords2.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_FUNCTION);
+ sc.SetState(SCE_AU3_FUNCTION);
+ }
+ else if (keywords3.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_MACRO);
+ sc.SetState(SCE_AU3_MACRO);
+ }
+ else if (keywords5.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_PREPROCESSOR);
+ sc.SetState(SCE_AU3_PREPROCESSOR);
+ }
+ else if (keywords6.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_SPECIAL);
+ sc.SetState(SCE_AU3_SPECIAL);
+ }
+ else if (keywords7.InList(s_save) && sc.atLineEnd) {
+ sc.ChangeState(SCE_AU3_EXPAND);
+ sc.SetState(SCE_AU3_EXPAND);
+ }
+ else {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ if (sc.state == SCE_AU3_SENT)
+ {
+ // Send key string ended
+ if (sc.chPrev == '}' && sc.ch != '}')
+ {
+ // set color to SENDKEY when valid sendkey .. else set back to regular string
+ char sk[100];
+ // split {111 222} and return {111} and check if 222 is valid.
+ // if return code = 1 then invalid 222 so must be string
+ if (GetSendKey(s_save,sk))
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ // if single char between {?} then its ok as sendkey for a single character
+ else if (strlen(sk) == 3)
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ // if sendkey {111} is in table then ok as sendkey
+ else if (keywords4.InList(sk))
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ else
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ sc.SetState(SCE_AU3_STRING);
+ }
+ // check if next portion is again a sendkey
+ if (sc.atLineEnd)
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ //*************************************
+ sc.Complete();
}
//
} // GetStyleFirstWord()
-//
-// Routine to check the last "none comment" character on a line to see if its a continuation
-//
-static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
-{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine+1) - 2;
- //int stylech = styler.StyleAt(nsPos);
- while (nsPos < nePos)
- {
- //stylech = styler.StyleAt(nePos);
- int stylech = styler.StyleAt(nsPos);
- if (!(stylech == SCE_AU3_COMMENT)) {
- char ch = styler.SafeGetCharAt(nePos);
- if (!isspacechar(ch)) {
- if (ch == '_')
- return true;
- else
- return false;
- }
- }
- nePos--; // skip to next char
- } // End While
- return false;
-} // IsContinuationLine()
-
//
static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
// create new fold for these words
if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
- strcmp(szKeyword,"#region") == 0 ) {
+ strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
levelNext++;
}
- // create double Fold for select because Case will subtract one of the current level
- if (strcmp(szKeyword,"select") == 0) {
+ // create double Fold for select&switch because Case will subtract one of the current level
+ if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
levelNext++;
levelNext++;
}
// end the fold for these words before the current line
if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
- strcmp(szKeyword,"wend") == 0){
+ strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
levelNext--;
levelCurrent--;
}
levelCurrent--;
}
// end the double fold for this word before the current line
- if (strcmp(szKeyword,"endselect") == 0 ) {
+ if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
levelNext--;
levelNext--;
levelCurrent--;
"#autoit Sent keys",
"#autoit Pre-processors",
"#autoit Special",
+ "#autoit Expand",
0
};
LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
levelCurrent++;
}
- if ((strcmp(s, "end") == 0)) {
+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
+ // Normally "elseif" and "then" will be on the same line and will cancel
+ // each other out. // As implemented, this does not support fold.at.else.
levelCurrent--;
}
}
0, };
-LexerModule lmAsn1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
+LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
/** @file LexBash.cxx
** Lexer for Bash.
**/
-// Copyright 2004 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 2004-2005 by Neil Hodgson <neilh@scintilla.org>
// Adapted from LexPerl by Kein-Hong Man <mkh@pl.jaring.my> 2004
// The License.txt file describes the conditions under which this software may be distributed.
char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
HereDocCls() {
State = 0;
+ Quote = 0;
+ Quoted = false;
+ Indent = 0;
DelimiterLength = 0;
Delimiter = new char[HERE_DELIM_MAX];
Delimiter[0] = '\0';
HereDoc.Quoted = false;
HereDoc.DelimiterLength = 0;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- if (chNext == '\'') { // a quoted here-doc delimiter (' only)
+ if (chNext == '\'' || chNext == '\"') { // a quoted here-doc delimiter (' or ")
i++;
ch = chNext;
chNext = chNext2;
HereDoc.Indent = true;
HereDoc.State = 0;
} else if (isalpha(chNext) || chNext == '_' || chNext == '\\'
- || chNext == '-' || chNext == '+') {
+ || chNext == '-' || chNext == '+' || 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;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
}
} else { // an unquoted here-doc delimiter
- if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+') {
+ if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+' || ch == '!') {
HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
} else if (ch == '\\') {
styler.ColourTo(lengthDoc - 1, state);
}
+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 void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && (style == SCE_SH_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
+ // 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 (ch == '{') {
levelCurrent++;
--- /dev/null
+// Scintilla source code edit control
+/** @file LexBasic.cxx
+ ** Lexer for BlitzBasic and PureBasic.
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics
+// and derivatives. Once they diverge enough, might want to split it into multiple
+// lexers for more code clearity.
+//
+// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.
+
+// Folding only works for simple things like functions or types.
+
+// You may want to have a look at my ctags lexer as well, if you additionally to coloring
+// and folding need to extract things like label tags in your editor.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.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"
+
+/* Bits:
+ * 1 - whitespace
+ * 2 - operator
+ * 4 - identifier
+ * 8 - decimal digit
+ * 16 - hex digit
+ * 32 - bin digit
+ */
+static int character_classification[128] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
+ 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
+};
+
+static bool IsSpace(int c) {
+ return c < 128 && (character_classification[c] & 1);
+}
+
+static bool IsOperator(int c) {
+ return c < 128 && (character_classification[c] & 2);
+}
+
+static bool IsIdentifier(int c) {
+ return c < 128 && (character_classification[c] & 4);
+}
+
+static bool IsDigit(int c) {
+ return c < 128 && (character_classification[c] & 8);
+}
+
+static bool IsHexDigit(int c) {
+ return c < 128 && (character_classification[c] & 16);
+}
+
+static bool IsBinDigit(int c) {
+ return c < 128 && (character_classification[c] & 32);
+}
+
+static int LowerCase(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler, char comment_char) {
+ bool wasfirst = true, isfirst = true; // true if first token in a line
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ // Can't use sc.More() here else we miss the last character
+ for (; ; sc.Forward()) {
+ if (sc.state == SCE_B_IDENTIFIER) {
+ if (!IsIdentifier(sc.ch)) {
+ // Labels
+ if (wasfirst && sc.Match(':')) {
+ sc.ChangeState(SCE_B_LABEL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else {
+ char s[100];
+ int kstates[4] = {
+ SCE_B_KEYWORD,
+ SCE_B_KEYWORD2,
+ SCE_B_KEYWORD3,
+ SCE_B_KEYWORD4,
+ };
+ sc.GetCurrentLowered(s, sizeof(s));
+ for (int i = 0; i < 4; i++) {
+ if (keywordlists[i]->InList(s)) {
+ sc.ChangeState(kstates[i]);
+ }
+ }
+ // Types, must set them as operator else they will be
+ // matched as number/constant
+ if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||
+ sc.Match('#')) {
+ sc.SetState(SCE_B_OPERATOR);
+ } else {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+ }
+ } else if (sc.state == SCE_B_OPERATOR) {
+ if (!IsOperator(sc.ch) || sc.Match('#'))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_LABEL) {
+ if (!IsIdentifier(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_CONSTANT) {
+ if (!IsIdentifier(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_NUMBER) {
+ if (!IsDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_HEXNUMBER) {
+ if (!IsHexDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_BINNUMBER) {
+ if (!IsBinDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_STRING) {
+ if (sc.ch == '"') {
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_B_ERROR);
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+
+ if (sc.atLineStart)
+ isfirst = true;
+
+ if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
+ if (isfirst && sc.Match('.')) {
+ sc.SetState(SCE_B_LABEL);
+ } else if (isfirst && sc.Match('#')) {
+ wasfirst = isfirst;
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (sc.Match(comment_char)) {
+ sc.SetState(SCE_B_COMMENT);
+ } else if (sc.Match('"')) {
+ sc.SetState(SCE_B_STRING);
+ } else if (IsDigit(sc.ch)) {
+ sc.SetState(SCE_B_NUMBER);
+ } else if (sc.Match('$')) {
+ sc.SetState(SCE_B_HEXNUMBER);
+ } else if (sc.Match('%')) {
+ sc.SetState(SCE_B_BINNUMBER);
+ } else if (sc.Match('#')) {
+ sc.SetState(SCE_B_CONSTANT);
+ } else if (IsOperator(sc.ch)) {
+ sc.SetState(SCE_B_OPERATOR);
+ } else if (IsIdentifier(sc.ch)) {
+ wasfirst = isfirst;
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (!IsSpace(sc.ch)) {
+ sc.SetState(SCE_B_ERROR);
+ }
+ }
+
+ if (!IsSpace(sc.ch))
+ isfirst = false;
+
+ if (!sc.More())
+ break;
+ }
+ sc.Complete();
+}
+
+static int CheckBlitzFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckPureFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "procedure") ||
+ !strcmp(token, "enumeration") ||
+ !strcmp(token, "interface") ||
+ !strcmp(token, "structure")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "endprocedure") ||
+ !strcmp(token, "endenumeration") ||
+ !strcmp(token, "endinterface") ||
+ !strcmp(token, "endstructure")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckFreeFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "sub") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end sub") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+static void FoldBasicDoc(unsigned int startPos, int length,
+ Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
+ 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 = CheckFoldPoint(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++;
+ }
+ } 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;
+ }
+ }
+ }
+ 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;
+ }
+ }
+}
+
+static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
+}
+
+static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
+}
+
+static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
+}
+
+static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
+}
+
+static void FoldPureBasicDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
+}
+
+static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
+}
+
+static const char * const blitzbasicWordListDesc[] = {
+ "BlitzBasic Keywords",
+ "user1",
+ "user2",
+ "user3",
+ 0
+};
+
+static const char * const purebasicWordListDesc[] = {
+ "PureBasic Keywords",
+ "PureBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+static const char * const freebasicWordListDesc[] = {
+ "FreeBasic Keywords",
+ "FreeBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
+ FoldBlitzBasicDoc, blitzbasicWordListDesc);
+
+LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
+ FoldPureBasicDoc, purebasicWordListDesc);
+
+LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
+ FoldFreeBasicDoc, freebasicWordListDesc);
+
// Scintilla source code edit control
/** @file LexClw.cxx
** Lexer for Clarion.
+ ** 2004/12/17 Updated Lexer
**/
-// Copyright 2003 by Ron Schofield <ron@schofieldcomputer.com>
+// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
// 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 <ctype.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SciLexer.h"
-static char MakeUpperCase(char ch) {
- if (ch < 'a' || ch > 'z')
- return ch;
- else
- return static_cast<char>(ch - 'a' + 'A');
+// Is an end of line character
+inline bool IsEOL(const int ch) {
+
+ return(ch == '\n');
+}
+
+// Convert character to uppercase
+static char CharacterUpper(char chChar) {
+
+ if (chChar < 'a' || chChar > 'z') {
+ return(chChar);
+ }
+ else {
+ return(static_cast<char>(chChar - 'a' + 'A'));
+ }
}
-static void MakeUpperCaseString(char *s) {
- while (*s) {
- *s = MakeUpperCase(*s);
- s++;
+// Convert string to uppercase
+static void StringUpper(char *szString) {
+
+ while (*szString) {
+ *szString = CharacterUpper(*szString);
+ szString++;
}
}
// Is a label start character
inline bool IsALabelStart(const int iChar) {
+
return(isalpha(iChar) || iChar == '_');
}
// Is a label character
inline bool IsALabelCharacter(const int iChar) {
- return(isalnum(iChar) || iChar == '_' || iChar == ':');
+
+ return(isalnum(iChar) || iChar == '_' || iChar == ':');
}
-// Is the character is a ! and the the next character is not a !
-inline bool IsACommentStart(StyleContext &scDoc) {
- return(scDoc.ch == '!' && scDoc.chNext != '!');
+// Is the character is a ! and the the next character is not a !
+inline bool IsACommentStart(const int iChar) {
+
+ return(iChar == '!');
}
// Is the character a Clarion hex character (ABCDEF)
inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
+
// Case insensitive.
if (!bCaseSensitive) {
if (strchr("ABCDEFabcdef", iChar) != NULL) {
// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
+
// Case insensitive.
if (!bCaseSensitive) {
// If character is a numeric base character
// Set the correct numeric constant state
inline bool SetNumericConstantState(StyleContext &scDoc) {
+
int iPoints = 0; // Point counter
- char cNumericString[100]; // Numeric string buffer
+ char cNumericString[512]; // Numeric string buffer
// Buffer the current numberic string
scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
break;
default :
break;
- }
+ }
}
// If points found (can be more than one for improper formatted number
if (iPoints > 0) {
}
}
+// Get the next word in uppercase from the current position (keyword lookahead)
+inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
+
+ unsigned int iIndex = 0; // Buffer Index
+
+ // Loop through the remaining string from the current position
+ for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
+ // Get the character from the buffer using the offset
+ char cCharacter = styler[iOffset];
+ if (IsEOL(cCharacter)) {
+ break;
+ }
+ // If the character is alphabet character
+ if (isalpha(cCharacter)) {
+ // Add UPPERCASE character to the word buffer
+ cWord[iIndex++] = CharacterUpper(cCharacter);
+ }
+ }
+ // Add null termination
+ cWord[iIndex] = '\0';
+ // If no word was found
+ if (iIndex == 0) {
+ // Return failure
+ return(false);
+ }
+ // Else word was found
+ else {
+ // Return success
+ return(true);
+ }
+}
+
// Clarion Language Colouring Procedure
-static void ColouriseClwDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
+static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
+
+ int iParenthesesLevel = 0; // Parenthese Level
+ int iColumn1Label = false; // Label starts in Column 1
+
+ WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
+ WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
+ WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
+ WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
+ WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
+ WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
+ WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
+ WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
+ WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
- int iParenthesesLevel=0; // Parenthese Level
+ const char wlProcReservedKeywordList[] =
+ "PROCEDURE FUNCTION";
+ WordList wlProcReservedKeywords;
+ wlProcReservedKeywords.Set(wlProcReservedKeywordList);
- WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
- WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
- WordList &wlBuiltInProcsFuncs = *wlKeywords[2]; // Builtin Procedures and Functions
- WordList &wlStructsDataTypes = *wlKeywords[3]; // Structures and Data Types
- WordList &wlAttributes = *wlKeywords[4]; // Procedure Attributes
- WordList &wlStandardEquates = *wlKeywords[5]; // Standard Equates
- WordList &wlReservedWords = *wlKeywords[6]; // Clarion Reserved Keywords
+ const char wlCompilerKeywordList[] =
+ "COMPILE OMIT";
+ WordList wlCompilerKeywords;
+ wlCompilerKeywords.Set(wlCompilerKeywordList);
+
+ const char wlLegacyStatementsList[] =
+ "BOF EOF FUNCTION POINTER SHARE";
+ WordList wlLegacyStatements;
+ wlLegacyStatements.Set(wlLegacyStatementsList);
StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
if (!IsALabelCharacter(scDoc.ch)) {
// If the character is a . (dot syntax)
if (scDoc.ch == '.') {
+ // Turn off column 1 label flag as label now cannot be reserved work
+ iColumn1Label = false;
// Uncolour the . (dot) to default state, move forward one character,
// and change back to the label state.
scDoc.SetState(SCE_CLW_DEFAULT);
scDoc.Forward();
scDoc.SetState(SCE_CLW_LABEL);
}
- // Else terminate the label state
+ // Else check label
else {
- char cLabel[100]; // Label buffer
+ char cLabel[512]; // Label buffer
// Buffer the current label string
scDoc.GetCurrent(cLabel,sizeof(cLabel));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
- MakeUpperCaseString(cLabel);
+ StringUpper(cLabel);
}
- // If label string is in the Clarion reserved keyword list
- if (wlReservedWords.InList(cLabel)){
- // change to error state
+ // Else if UPPERCASE label string is in the Clarion compiler keyword list
+ if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
+ // change the label to error state
+ scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
+ }
+ // Else if UPPERCASE label string is in the Clarion reserved keyword list
+ else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
+ // change the label to error state
scDoc.ChangeState(SCE_CLW_ERROR);
}
+ // Else if UPPERCASE label string is
+ else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
+ char cWord[512]; // Word buffer
+ // Get the next word from the current position
+ if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
+ // If the next word is a procedure reserved word
+ if (wlProcReservedKeywords.InList(cWord)) {
+ // Change the label to error state
+ scDoc.ChangeState(SCE_CLW_ERROR);
+ }
+ }
+ }
// Else if label string is in the compiler directive keyword list
else if (wlCompilerDirectives.InList(cLabel)) {
// change the state to compiler directive state
else if (scDoc.state == SCE_CLW_KEYWORD) {
// If character is : (colon)
if (scDoc.ch == ':') {
- char cEquate[100]; // Equate buffer
+ char cEquate[512]; // Equate buffer
// Move forward to include : (colon) in buffer
scDoc.Forward();
// Buffer the equate string
scDoc.GetCurrent(cEquate,sizeof(cEquate));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
- MakeUpperCaseString(cEquate);
+ StringUpper(cEquate);
}
// If statement string is in the equate list
if (wlStandardEquates.InList(cEquate)) {
}
// If the character is not a valid label character
else if (!IsALabelCharacter(scDoc.ch)) {
- char cStatement[100]; // Statement buffer
+ char cStatement[512]; // Statement buffer
// Buffer the statement string
scDoc.GetCurrent(cStatement,sizeof(cStatement));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
- MakeUpperCaseString(cStatement);
+ StringUpper(cStatement);
}
// If statement string is in the Clarion keyword list
if (wlClarionKeywords.InList(cStatement)) {
- // Set to the Clarion keyword state
+ // Change the statement string to the Clarion keyword state
scDoc.ChangeState(SCE_CLW_KEYWORD);
}
// Else if statement string is in the compiler directive keyword list
else if (wlCompilerDirectives.InList(cStatement)) {
- // Set to the compiler directive state
+ // Change the statement string to the compiler directive state
scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
}
+ // Else if statement string is in the runtime expressions keyword list
+ else if (wlRuntimeExpressions.InList(cStatement)) {
+ // Change the statement string to the runtime expressions state
+ scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
+ }
// Else if statement string is in the builtin procedures and functions keyword list
else if (wlBuiltInProcsFuncs.InList(cStatement)) {
- // Set to the builtin procedures and functions state
+ // Change the statement string to the builtin procedures and functions state
scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
}
// Else if statement string is in the tructures and data types keyword list
else if (wlStructsDataTypes.InList(cStatement)) {
- // Set to the structures and data types state
+ // Change the statement string to the structures and data types state
scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
}
// Else if statement string is in the procedure attribute keyword list
else if (wlAttributes.InList(cStatement)) {
- // Set to the procedure attribute state
+ // Change the statement string to the procedure attribute state
scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
}
// Else if statement string is in the standard equate keyword list
else if (wlStandardEquates.InList(cStatement)) {
- // Set to the standard equate state
+ // Change the statement string to the standard equate state
scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
}
+ // Else if statement string is in the deprecated or legacy keyword list
+ else if (wlLegacyStatements.InList(cStatement)) {
+ // Change the statement string to the standard equate state
+ scDoc.ChangeState(SCE_CLW_DEPRECATED);
+ }
+ // Else the statement string doesn't match any work list
+ else {
+ // Change the statement string to the default state
+ scDoc.ChangeState(SCE_CLW_DEFAULT);
+ }
// Terminate the keyword state and set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
// Increment the parenthese level
iParenthesesLevel++;
}
- // Else if the character is a ) (close parenthese)
+ // Else if the character is a ) (close parenthese)
else if (scDoc.ch == ')') {
// If the parenthese level is set to zero
// parentheses matched
if (!iParenthesesLevel) {
scDoc.SetState(SCE_CLW_DEFAULT);
- }
+ }
// Else parenthese level is greater than zero
// still looking for matching parentheses
else {
|| IsAHexCharacter(scDoc.ch, bCaseSensitive)
|| scDoc.ch == '.'
|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
- // If the number was a real
+ // If the number was a real
if (SetNumericConstantState(scDoc)) {
// Colour the matched string to the real constant state
scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
// Beginning of Line Handling
if (scDoc.atLineStart) {
+ // Reset the column 1 label flag
+ iColumn1Label = false;
// If column 1 character is a label start character
if (IsALabelStart(scDoc.ch)) {
+ // Label character is found in column 1
+ // so set column 1 label flag and clear last column 1 label
+ iColumn1Label = true;
// Set the state to label
scDoc.SetState(SCE_CLW_LABEL);
}
// Set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
- // else if the start of a comment or is an * (asterisk)
- else if (IsACommentStart(scDoc) || scDoc.ch == '*' ) {
+ // else if comment start (!) or is an * (asterisk)
+ else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
}
}
// Default Handling
else {
- // If in default state
+ // If in default state
if (scDoc.state == SCE_CLW_DEFAULT) {
// If is a letter could be a possible statement
if (isalpha(scDoc.ch)) {
scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
}
// else if the start of a comment or a | (line continuation)
- else if (IsACommentStart(scDoc) || scDoc.ch == '|') {
+ else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
- }
+ }
// else if the character is a ' (single quote)
else if (scDoc.ch == '\'') {
- // If the character is also a ' (single quote)
+ // If the character is also a ' (single quote)
// Embedded Apostrophe
if (scDoc.chNext == '\'') {
// Move forward colouring it as default state
// move to the next character and then set the state to comment.
scDoc.ForwardSetState(SCE_CLW_STRING);
}
- }
- // else the character is an @ (apersand)
+ }
+ // else the character is an @ (ampersand)
else if (scDoc.ch == '@') {
// Case insensitive.
if (!bCaseSensitive) {
scDoc.SetState(SCE_CLW_PICTURE_STRING);
}
}
- }
+ }
}
}
}
}
// Clarion Language Case Sensitive Colouring Procedure
-static void ColouriseClwDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
- ColouriseClwDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
+static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+
+ ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
}
// Clarion Language Case Insensitive Colouring Procedure
-static void ColouriseClwDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
- ColouriseClwDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
+static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+
+ ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
+}
+
+// Fill Buffer
+
+static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
+
+ unsigned int uiPos = 0;
+
+ while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
+ szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
+ uiPos++;
+ }
+ szBuffer[uiPos] = '\0';
+}
+
+// Classify Clarion Fold Point
+
+static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
+
+ if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
+ if (strcmp(szString, "PROCEDURE") == 0) {
+ // iLevel = SC_FOLDLEVELBASE + 1;
+ }
+ else if (strcmp(szString, "MAP") == 0 ||
+ strcmp(szString,"ACCEPT") == 0 ||
+ strcmp(szString,"BEGIN") == 0 ||
+ strcmp(szString,"CASE") == 0 ||
+ strcmp(szString,"EXECUTE") == 0 ||
+ strcmp(szString,"IF") == 0 ||
+ strcmp(szString,"ITEMIZE") == 0 ||
+ strcmp(szString,"INTERFACE") == 0 ||
+ strcmp(szString,"JOIN") == 0 ||
+ strcmp(szString,"LOOP") == 0 ||
+ strcmp(szString,"MODULE") == 0 ||
+ strcmp(szString,"RECORD") == 0) {
+ iLevel++;
+ }
+ else if (strcmp(szString, "APPLICATION") == 0 ||
+ strcmp(szString, "CLASS") == 0 ||
+ strcmp(szString, "DETAIL") == 0 ||
+ strcmp(szString, "FILE") == 0 ||
+ strcmp(szString, "FOOTER") == 0 ||
+ strcmp(szString, "FORM") == 0 ||
+ strcmp(szString, "GROUP") == 0 ||
+ strcmp(szString, "HEADER") == 0 ||
+ strcmp(szString, "INTERFACE") == 0 ||
+ strcmp(szString, "MENU") == 0 ||
+ strcmp(szString, "MENUBAR") == 0 ||
+ strcmp(szString, "OLE") == 0 ||
+ strcmp(szString, "OPTION") == 0 ||
+ strcmp(szString, "QUEUE") == 0 ||
+ strcmp(szString, "REPORT") == 0 ||
+ strcmp(szString, "SHEET") == 0 ||
+ strcmp(szString, "TAB") == 0 ||
+ strcmp(szString, "TOOLBAR") == 0 ||
+ strcmp(szString, "VIEW") == 0 ||
+ strcmp(szString, "WINDOW") == 0) {
+ iLevel++;
+ }
+ else if (strcmp(szString, "END") == 0 ||
+ strcmp(szString, "UNTIL") == 0 ||
+ strcmp(szString, "WHILE") == 0) {
+ iLevel--;
+ }
+ }
+ return(iLevel);
}
// Clarion Language Folding Procedure
-#ifdef FOLDING_IMPLEMENTED
-static void FoldClwDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
+
+ unsigned int uiEndPos = uiStartPos + iLength;
+ int iLineCurrent = accStyler.GetLine(uiStartPos);
+ int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int iLevelCurrent = iLevelPrev;
+ char chNext = accStyler[uiStartPos];
+ int iStyle = iInitStyle;
+ int iStyleNext = accStyler.StyleAt(uiStartPos);
+ int iVisibleChars = 0;
+ int iLastStart = 0;
+
+ for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
+
+ char chChar = chNext;
+ chNext = accStyler.SafeGetCharAt(uiPos + 1);
+ int iStylePrev = iStyle;
+ iStyle = iStyleNext;
+ iStyleNext = accStyler.StyleAt(uiPos + 1);
+ bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
+
+ if (iStylePrev == SCE_CLW_DEFAULT) {
+ if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
+ // Store last word start point.
+ iLastStart = uiPos;
+ }
+ }
+
+ if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
+ if(iswordchar(chChar) && !iswordchar(chNext)) {
+ char chBuffer[100];
+ FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
+ iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
+ // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
+ // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
+ // iLevelPrev = SC_FOLDLEVELBASE;
+ // }
+ }
+ }
+
+ if (bEOL) {
+ int iLevel = iLevelPrev;
+ if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
+ iLevel |= SC_FOLDLEVELHEADERFLAG;
+ if (iLevel != accStyler.LevelAt(iLineCurrent)) {
+ accStyler.SetLevel(iLineCurrent,iLevel);
+ }
+ iLineCurrent++;
+ iLevelPrev = iLevelCurrent;
+ iVisibleChars = 0;
+ }
+
+ if (!isspacechar(chChar))
+ iVisibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags
+ // as they will be filled in later.
+ int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
}
-#endif
// Word List Descriptions
static const char * const rgWordListDescriptions[] = {
"Clarion Keywords",
"Compiler Directives",
"Built-in Procedures and Functions",
+ "Runtime Expressions",
"Structure and Data Types",
"Attributes",
"Standard Equates",
- "Reserved Words",
+ "Reserved Words (Labels)",
+ "Reserved Words (Procedure Labels)",
0,
};
// Case Sensitive Clarion Language Lexer
-LexerModule lmClw(SCLEX_CLW, ColouriseClwDocSensitive, "clw", NULL, rgWordListDescriptions);
+LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
// Case Insensitive Clarion Language Lexer
-LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClwDocInsensitive, "clwnocase", NULL, rgWordListDescriptions);
+LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);
// Scintilla source code edit control
/** @file LexCPP.cxx
- ** Lexer for C++, C, Java, and Javascript.
+ ** Lexer for C++, C, Java, and JavaScript.
**/
-// Copyright 1998-2002 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>
#define KEYWORD_BOXHEADER 1
#define KEYWORD_FOLDCONTRACTED 2
-static bool IsOKBeforeRE(const int ch) {
+static bool IsOKBeforeRE(int ch) {
return (ch == '(') || (ch == '=') || (ch == ',');
}
-static inline bool IsAWordChar(const int ch) {
+static inline bool IsAWordChar(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalpha(ch) || ch == '_');
}
-static inline bool IsADoxygenChar(const int ch) {
- return (islower(ch) || ch == '$' || ch == '@' ||
- ch == '\\' || ch == '&' || ch == '<' ||
- ch == '>' || ch == '#' || ch == '{' ||
- ch == '}' || ch == '[' || ch == ']');
+static inline bool IsADoxygenChar(int ch) {
+ return (ch < 0x80 && islower(ch)) || ch == '$' || ch == '@' ||
+ ch == '\\' || ch == '&' || ch == '<' ||
+ ch == '>' || ch == '#' || ch == '{' ||
+ ch == '}' || ch == '[' || ch == ']';
}
-static inline bool IsStateComment(const int state) {
- return ((state == SCE_C_COMMENT) ||
- (state == SCE_C_COMMENTLINE) ||
- (state == SCE_C_COMMENTDOC) ||
- (state == SCE_C_COMMENTDOCKEYWORD) ||
- (state == SCE_C_COMMENTDOCKEYWORDERROR));
-}
-
-static inline bool IsStateString(const int state) {
- return ((state == SCE_C_STRING) || (state == SCE_C_VERBATIM));
+static bool IsSpaceEquiv(int state) {
+ return (state <= SCE_C_COMMENTDOC) ||
+ // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
+ (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
+ (state == SCE_C_COMMENTDOCKEYWORDERROR);
}
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
- // Do not leak onto next line
- if (initStyle == SCE_C_STRINGEOL)
- initStyle = SCE_C_DEFAULT;
-
int chPrevNonWhite = ' ';
int visibleChars = 0;
bool lastWordWasUUID = false;
+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
+ bool continuationLine = false;
+
+ if (initStyle == SCE_C_PREPROCESSOR) {
+ // Set continuationLine if last character of previous line is '\'
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ int chBack = styler.SafeGetCharAt(startPos-1, 0);
+ int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
+ int lineEndChar = '!';
+ if (chBack2 == '\r' && chBack == '\n') {
+ lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
+ } else if (chBack == '\n' || chBack == '\r') {
+ lineEndChar = chBack2;
+ }
+ continuationLine = lineEndChar == '\\';
+ }
+ }
+
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (startPos > 0) {
+ int back = startPos;
+ while (--back && IsSpaceEquiv(styler.StyleAt(back)))
+ ;
+ if (styler.StyleAt(back) == SCE_C_OPERATOR) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ }
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
- if (sc.atLineStart && (sc.state == SCE_C_STRING)) {
- // Prevent SCE_C_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_C_STRING);
+ if (sc.atLineStart) {
+ if (sc.state == SCE_C_STRING) {
+ // Prevent SCE_C_STRINGEOL from leaking back to previous line which
+ // ends with a line continuation by locking in the state upto this position.
+ sc.SetState(SCE_C_STRING);
+ }
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ lastWordWasUUID = false;
}
// Handle line continuation generically.
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
+ continuationLine = true;
continue;
}
}
// Determine if the current state should terminate.
- if (sc.state == SCE_C_OPERATOR) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.state == SCE_C_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (keywords.InList(s)) {
- lastWordWasUUID = strcmp(s, "uuid") == 0;
- sc.ChangeState(SCE_C_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_C_WORD2);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_C_GLOBALCLASS);
- }
+ switch (sc.state) {
+ case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_PREPROCESSOR) {
- if (stylingWithinPreprocessor) {
- if (IsASpace(sc.ch)) {
+ break;
+ case SCE_C_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_C_DEFAULT);
}
- } else {
- if ((sc.ch == '\r') || (sc.ch == '\n') || (sc.Match('/', '*')) || (sc.Match('/', '/'))) {
+ break;
+ case SCE_C_IDENTIFIER:
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[1000];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (keywords.InList(s)) {
+ lastWordWasUUID = strcmp(s, "uuid") == 0;
+ sc.ChangeState(SCE_C_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_C_WORD2);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_C_GLOBALCLASS);
+ }
sc.SetState(SCE_C_DEFAULT);
}
- }
- } else if (sc.state == SCE_C_COMMENT) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_COMMENTDOC) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') {
- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
- }
- } else if (sc.state == SCE_C_COMMENTLINE || sc.state == SCE_C_COMMENTLINEDOC) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_C_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_C_COMMENTDOCKEYWORD) {
- if (sc.Match('*', '/')) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (!IsADoxygenChar(sc.ch)) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
+ break;
+ case SCE_C_PREPROCESSOR:
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (stylingWithinPreprocessor) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
} else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ if (sc.Match('/', '*') || sc.Match('/', '/')) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
}
- sc.SetState(SCE_C_COMMENTDOC);
- }
- } else if (sc.state == SCE_C_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ break;
+ case SCE_C_COMMENT:
+ if (sc.Match('*', '/')) {
sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT);
}
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
- sc.ForwardSetState(SCE_C_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_C_CHARACTER) {
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
- sc.ForwardSetState(SCE_C_DEFAULT);
- visibleChars = 0;
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ break;
+ case SCE_C_COMMENTDOC:
+ if (sc.Match('*', '/')) {
sc.Forward();
+ sc.ForwardSetState(SCE_C_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_C_COMMENTDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ }
}
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_REGEX) {
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == '/') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.ch == '\\') {
- // Gobble up the quoted character
- if (sc.chNext == '\\' || sc.chNext == '/') {
- sc.Forward();
+ break;
+ case SCE_C_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
}
- }
- } else if (sc.state == SCE_C_VERBATIM) {
- if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
+ break;
+ case SCE_C_COMMENTLINEDOC:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_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_C_COMMENTLINEDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_C_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
sc.Forward();
- } else {
sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (!IsADoxygenChar(sc.ch)) {
+ char s[100];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_C_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_C_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_C_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_REGEX:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '/') {
+ sc.Forward();
+ while ((sc.ch < 0x80) && islower(sc.ch))
+ sc.Forward(); // gobble regex flags
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '\\') {
+ // Gobble up the quoted character
+ if (sc.chNext == '\\' || sc.chNext == '/') {
+ sc.Forward();
+ }
+ }
+ break;
+ case SCE_C_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_VERBATIM:
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ }
+ break;
+ case SCE_C_UUID:
+ if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ sc.SetState(SCE_C_DEFAULT);
}
- }
- } else if (sc.state == SCE_C_UUID) {
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
- sc.SetState(SCE_C_DEFAULT);
- }
}
// Determine if a new state should be entered.
else
sc.SetState(SCE_C_COMMENTLINE);
} else if (sc.ch == '/' && IsOKBeforeRE(chPrevNonWhite)) {
- sc.SetState(SCE_C_REGEX);
+ sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
} else if (sc.ch == '\"') {
sc.SetState(SCE_C_STRING);
} else if (sc.ch == '\'') {
do {
sc.Forward();
} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.ch == '\r' || sc.ch == '\n') {
+ if (sc.atLineEnd) {
sc.SetState(SCE_C_DEFAULT);
}
} else if (isoperator(static_cast<char>(sc.ch))) {
}
}
- if (sc.atLineEnd) {
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- chPrevNonWhite = ' ';
- visibleChars = 0;
- lastWordWasUUID = false;
- }
- if (!IsASpace(sc.ch)) {
+ if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
chPrevNonWhite = sc.ch;
visibleChars++;
}
+ continuationLine = false;
}
sc.Complete();
}
static bool IsStreamCommentStyle(int style) {
return style == SCE_C_COMMENT ||
- style == SCE_C_COMMENTDOC ||
- style == SCE_C_COMMENTDOCKEYWORD ||
- style == SCE_C_COMMENTDOCKEYWORDERROR;
+ style == SCE_C_COMMENTDOC ||
+ style == SCE_C_COMMENTDOCKEYWORD ||
+ style == SCE_C_COMMENTDOCKEYWORDERROR;
}
// Store both the current line's fold level and the next lines in the
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)
+ 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)
+ sc.SetState(SCE_CSS_ATTRIBUTE);
+ break;
+ case ']':
+ if (lastState == SCE_CSS_ATTRIBUTE)
+ sc.SetState(SCE_CSS_TAG);
+ break;
case '{':
if (lastState == SCE_CSS_DIRECTIVE)
sc.SetState(SCE_CSS_DEFAULT);
sc.SetState(SCE_CSS_VALUE);
break;
case '.':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+ 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)
sc.SetState(SCE_CSS_CLASS);
break;
case '#':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+ 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)
sc.SetState(SCE_CSS_ID);
break;
case ',':
} else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
} else if (IsCssOperator(static_cast<char>(sc.ch))
+ && (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
&& (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
) {
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCaml.cxx
+ ** Lexer for Objective Caml.
+ **/
+// Copyright 2005 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.
+ 20050205 Quick compiler standards/"cleanliness" adjustment.
+ 20050206 Added cast for IsLeadByte().
+ 20050209 Changes to "external" build support.
+ 20050306 Fix for 1st-char-in-doc "corner" case.
+ 20050502 Fix for [harmless] one-past-the-end coloring.
+ 20050515 Refined numeric token recognition logic.
+ 20051125 Added 2nd "optional" keywords class.
+ 20051129 Support "magic" (read-only) comments for RCaml.
+ 20051204 Swtich to using StyleContext infrastructure.
+*/
+
+#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"
+
+// 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 */
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
+};
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+/*
+ (actually seems to work!)
+*/
+#include "WindowAccessor.h"
+#include "ExternalLexer.h"
+
+#if PLAT_WIN
+#include <windows.h>
+#endif
+
+static void ColouriseCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static void FoldCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static void InternalLexOrFold(int lexOrFold, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props);
+
+static const char* LexerName = "caml";
+
+#ifdef TRACE
+void Platform::DebugPrintf(const char *format, ...) {
+ char buffer[2000];
+ va_list pArguments;
+ va_start(pArguments, format);
+ vsprintf(buffer,format,pArguments);
+ va_end(pArguments);
+ Platform::DebugDisplay(buffer);
+}
+#else
+void Platform::DebugPrintf(const char *, ...) {
+}
+#endif
+
+bool Platform::IsDBCSLeadByte(int codePage, char ch) {
+ return ::IsDBCSLeadByteEx(codePage, ch) != 0;
+}
+
+long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
+ return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam);
+}
+
+long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) {
+ return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam,
+ reinterpret_cast<LPARAM>(lParam));
+}
+
+void EXT_LEXER_DECL Fold(unsigned int lexer, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ lexer;
+ // build expected data structures and do the Fold
+ InternalLexOrFold(1, startPos, length, initStyle, words, window, props);
+
+}
+
+int EXT_LEXER_DECL GetLexerCount()
+{
+ return 1; // just us [Objective] Caml lexers here!
+}
+
+void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ Index;
+ // return as much of our lexer name as will fit (what's up with Index?)
+ if (buflength > 0) {
+ buflength--;
+ int n = strlen(LexerName);
+ if (n > buflength)
+ n = buflength;
+ memcpy(name, LexerName, n), name[n] = '\0';
+ }
+}
+
+void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ lexer;
+ // build expected data structures and do the Lex
+ InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
+}
+
+static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // create and initialize a WindowAccessor (including contained PropSet)
+ PropSet ps;
+ ps.SetMultiple(props);
+ WindowAccessor wa(window, ps);
+ // create and initialize WordList(s)
+ int nWL = 0;
+ for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed
+ WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs
+ int i = 0;
+ for (; i < nWL; i++) {
+ wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION)
+ wl[i]->Set(words[i]);
+ }
+ wl[i] = 0;
+ // call our "internal" folder/lexer (... then do Flush!)
+ if (foldOrLex)
+ FoldCamlDoc(startPos, length, initStyle, wl, wa);
+ else
+ ColouriseCamlDoc(startPos, length, initStyle, wl, wa);
+ wa.Flush();
+ // clean up before leaving
+ for (i = nWL - 1; i >= 0; i--)
+ delete wl[i];
+ delete [] wl;
+}
+
+static
+#endif /* BUILD_AS_EXTERNAL_LEXER */
+
+void ColouriseCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ // 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 int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
+
+ // foreach char in range...
+ while (sc.More()) {
+ // set up [per-char] state info
+ int state2 = -1; // (ASSUME no state change)
+ int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
+ bool advance = true; // (ASSUME scanner "eats" 1 char)
+
+ // step state machine
+ switch (sc.state & 0x0f) {
+ case SCE_CAML_DEFAULT:
+ chToken = sc.currentPos; // save [possible] token start (JIC)
+ // it's wide open; what do we have?
+ if (iscamlf(sc.ch))
+ state2 = SCE_CAML_IDENTIFIER;
+ else if (sc.Match('`') && iscamlf(sc.chNext))
+ state2 = SCE_CAML_TAGNAME;
+ else if (sc.Match('#') && isdigit(sc.chNext))
+ state2 = SCE_CAML_LINENUM;
+ else if (isdigit(sc.ch)) {
+ 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?) */
+ state2 = SCE_CAML_CHAR, chLit = 0;
+ 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_OPERATOR;
+ break;
+
+ case SCE_CAML_IDENTIFIER:
+ // [try to] interpret as [additional] identifier char
+ if (!(iscaml(sc.ch) || sc.Match('\''))) {
+ const int n = sc.currentPos - chToken;
+ if (n < 24) {
+ // length is believable as keyword, [re-]construct token
+ char t[24];
+ for (int i = -n; i < 0; i++)
+ t[n + i] = static_cast<char>(sc.GetRelative(i));
+ t[n] = '\0';
+ // special-case "_" token as KEYWORD
+ if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD);
+ else if (keywords2.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD2);
+ else if (keywords3.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD3);
+ }
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ }
+ break;
+
+ case SCE_CAML_TAGNAME:
+ // [try to] interpret as [additional] tagname char
+ if (!(iscaml(sc.ch) || sc.Match('\'')))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;
+
+ /*case SCE_CAML_KEYWORD:
+ case SCE_CAML_KEYWORD2:
+ case SCE_CAML_KEYWORD3:
+ // [try to] interpret as [additional] keyword char
+ if (!iscaml(ch))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;*/
+
+ case SCE_CAML_LINENUM:
+ // [try to] interpret as [additional] linenum directive char
+ if (!isdigit(sc.ch))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ 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 */) {
+ // check for INCLUSIVE termination
+ if (o && strchr(")]};,", sc.ch)) {
+ if ((sc.Match(')') && sc.chPrev == '(')
+ || (sc.Match(']') && sc.chPrev == '['))
+ // special-case "()" and "[]" tokens as KEYWORDS
+ sc.ChangeState(SCE_CAML_KEYWORD);
+ chColor++;
+ } else
+ advance = false;
+ state2 = SCE_CAML_DEFAULT;
+ }
+ break;
+ }
+
+ 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))
+ break;
+ // how about an integer suffix?
+ if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
+ && (iscamld(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))
+ break;
+ // with an exponent? (I)
+ if ((sc.Match('e') || sc.Match('E'))
+ && (iscamld(sc.chPrev) || sc.chPrev == '.'))
+ break;
+ // with an exponent? (II)
+ if ((sc.Match('+') || sc.Match('-'))
+ && (sc.chPrev == 'e' || sc.chPrev == 'E'))
+ break;
+ }
+ // it looks like we have run out of number
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ 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)
+ // 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;
+
+ 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++;
+ break;
+
+ case SCE_CAML_COMMENT:
+ case SCE_CAML_COMMENT1:
+ case SCE_CAML_COMMENT2:
+ case SCE_CAML_COMMENT3:
+ // 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++;
+ // [try to] interpret as [additional] comment char
+ else if (sc.Match(')') && sc.chPrev == '*') {
+ if (nesting)
+ state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
+ else
+ state2 = SCE_CAML_DEFAULT;
+ chColor++;
+ // enable "magic" (read-only) comment AS REQUIRED
+ } else if (useMagic && sc.currentPos - chToken == 4
+ && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
+ sc.state |= 0x10; // (switch to read-only comment style)
+ break;
+ }
+
+ // 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
+ if (advance)
+ sc.Forward();
+ }
+
+ // do any required terminal char coloring (JIC)
+ sc.Complete();
+}
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+static
+#endif /* BUILD_AS_EXTERNAL_LEXER */
+void FoldCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ startPos || length || initStyle || keywordlists[0] || styler.Length();
+}
+
+static const char * const camlWordListDesc[] = {
+ "Keywords", // primary Objective Caml keywords
+ "Keywords2", // "optional" keywords (typically from Pervasives)
+ "Keywords3", // "optional" keywords (typically typenames)
+ 0
+};
+
+#ifndef BUILD_AS_EXTERNAL_LEXER
+LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc);
+#endif /* BUILD_AS_EXTERNAL_LEXER */
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCsound.cxx
+ ** Lexer for Csound (Orchestra & Score)
+ ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
+ **/
+// 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 <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+ ch == '_' || ch == '?');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
+ ch == '%' || ch == '@' || ch == '$' || ch == '?');
+}
+
+static inline bool IsCsoundOperator(char ch) {
+ if (isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
+ ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
+ ch == '%' || ch == ':')
+ return true;
+ return false;
+}
+
+static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &opcode = *keywordlists[0];
+ WordList &headerStmt = *keywordlists[1];
+ WordList &otherKeyword = *keywordlists[2];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_CSOUND_STRINGEOL)
+ initStyle = SCE_CSOUND_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ 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;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_CSOUND_OPERATOR) {
+ if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }else if (sc.state == SCE_CSOUND_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ } else if (sc.state == SCE_CSOUND_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+
+ if (opcode.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_OPCODE);
+ } else if (headerStmt.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_HEADERSTMT);
+ } else if (otherKeyword.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_USERKEYWORD);
+ } else if (s[0] == 'p') {
+ sc.ChangeState(SCE_CSOUND_PARAM);
+ } else if (s[0] == 'a') {
+ sc.ChangeState(SCE_CSOUND_ARATE_VAR);
+ } else if (s[0] == 'k') {
+ sc.ChangeState(SCE_CSOUND_KRATE_VAR);
+ } else if (s[0] == 'i') { // covers both i-rate variables and i-statements
+ sc.ChangeState(SCE_CSOUND_IRATE_VAR);
+ } else if (s[0] == 'g') {
+ sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
+ }
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_CSOUND_COMMENT ) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+ else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
+ (sc.state == SCE_CSOUND_KRATE_VAR) ||
+ (sc.state == SCE_CSOUND_IRATE_VAR)) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_CSOUND_DEFAULT) {
+ if (sc.ch == ';'){
+ sc.SetState(SCE_CSOUND_COMMENT);
+ } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+ sc.SetState(SCE_CSOUND_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_CSOUND_IDENTIFIER);
+ } else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_CSOUND_OPERATOR);
+ } else if (sc.ch == 'p') {
+ sc.SetState(SCE_CSOUND_PARAM);
+ } else if (sc.ch == 'a') {
+ sc.SetState(SCE_CSOUND_ARATE_VAR);
+ } else if (sc.ch == 'k') {
+ sc.SetState(SCE_CSOUND_KRATE_VAR);
+ } else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
+ sc.SetState(SCE_CSOUND_IRATE_VAR);
+ } else if (sc.ch == 'g') {
+ sc.SetState(SCE_CSOUND_GLOBAL_VAR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int stylePrev = 0;
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; 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 ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
+ char s[20];
+ unsigned int j = 0;
+ while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
+ s[j] = styler[i + j];
+ j++;
+ }
+ s[j] = '\0';
+
+ if (strcmp(s, "instr") == 0)
+ levelCurrent++;
+ if (strcmp(s, "endin") == 0)
+ levelCurrent--;
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ stylePrev = style;
+ }
+ // 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 csoundWordListDesc[] = {
+ "Opcodes",
+ "Header Statements",
+ "User keywords",
+ 0
+};
+
+LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
--- /dev/null
+// Scintilla source code edit control
+/** @file LexFlagShip.cxx
+ ** Lexer for FlagShip
+ ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
+ **/
+// Copyright 2005 by Randy Butler
+// 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 <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static bool IsFlagShipComment(Accessor &styler, int pos, int len) {
+ return len>0 && styler[pos]=='\'';
+}
+
+static inline bool IsTypeCharacter(int ch) {
+ return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
+}
+
+// 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 ||
+ (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsADateCharacter(const int ch) {
+ return (ch < 0x80) &&
+ (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
+}
+
+
+static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ //bool FSScriptSyntax = true;
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ styler.StartAt(startPos);
+
+ int visibleChars = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_FS_OPERATOR) {
+ sc.SetState(SCE_FS_DEFAULT);
+ } else if (sc.state == SCE_FS_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD4);
+ }// Else, it is really an identifier...
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_STRING) {
+ // VB doubles quotes to preserve them, so just end this string
+ // state now as a following quote will start again
+ if (sc.ch == '\"') {
+ if (tolower(sc.chNext) == 'c') {
+ sc.Forward();
+ }
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_FS_STRINGEOL);
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_COMMENT) {
+ if (sc.Match('*', '/')) { // new code
+ sc.Forward();
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ //if (sc.atLineEnd) { // old code
+ // sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_COMMENTLINE) { //new code
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_FS_DEFAULT);
+ visibleChars = 0;
+ }
+ } else if (sc.state == SCE_FS_PREPROCESSOR) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_DATE) {
+ if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_FS_DEFAULT) {
+ if (sc.Match('/', '*')) { // New code
+ sc.SetState(SCE_FS_COMMENT);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ //if (sc.ch == '\'') { // Old code
+ // sc.SetState(SCE_FS_COMMENT); // old code
+ } else if (sc.Match('/', '/')) { // New code
+ sc.SetState(SCE_FS_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_FS_STRING);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_FS_PREPROCESSOR);
+ } else if (sc.ch == '#') {
+ int n = 1;
+ int chSeek = ' ';
+ while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
+ chSeek = sc.GetRelative(n);
+ n++;
+ }
+ if (IsADigit(chSeek)) {
+ sc.SetState(SCE_FS_DATE);
+ } else {
+ sc.SetState(SCE_FS_OPERATOR);
+ }
+ } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
+ sc.SetState(SCE_FS_NUMBER);
+ } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
+ sc.SetState(SCE_FS_NUMBER);
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_FS_NUMBER);
+ } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
+ sc.SetState(SCE_FS_IDENTIFIER);
+ } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
+ sc.SetState(SCE_FS_OPERATOR);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldFlagShipDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+
+ int endPos = startPos + length;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsFlagShipComment);
+ char chNext = styler[startPos];
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsFlagShipComment);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ // Only non whitespace lines can be headers
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
+ // Line after is blank so check the next - maybe should continue further?
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsFlagShipComment);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+
+static const char * const FSWordListDesc[] = {
+ "Keywords",
+ "functions",
+ "user2",
+ "user3",
+ 0
+};
+
+LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
+
+
+
int style = initStyle;
/***************************************/
int lastStart = 0;
- char prevWord[32] = "", Label[6] = "";
+ char prevWord[32] = "";
+ char Label[6] = "";
// Variables for do label folding.
- static int doLabels[100], posLabel=-1;
+ static int doLabels[100];
+ static int posLabel=-1;
/***************************************/
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
if (!noforward) sc.Forward();
}
- styler.ColourTo(sc.currentPos, sc.state);
+ sc.Complete();
}
// Main folding function called by Scintilla - (based on props (.ini) files function)
/** @file LexHTML.cxx
** Lexer for HTML.
**/
-// Copyright 1998-2003 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>
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
-static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
+static inline int MakeLowerCase(int ch) {
+ if (ch < 'A' || ch > 'Z')
+ return ch;
+ else
+ return ch - 'A' + 'a';
+}
+
+static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
+ size_t i = 0;
+ for (; (i < end - start + 1) && (i < len-1); i++) {
+ s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
}
s[i] = '\0';
+}
+
+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));
//Platform::DebugPrintf("Scripting indicator [%s]\n", s);
if (strstr(s, "src")) // External script
return eScriptNone;
static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) {
int iResult = 0;
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (0 == strncmp(s, "php", 3)) {
iResult = 3;
}
if (wordIsNumber) {
chAttr = SCE_H_NUMBER;
} else {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s))
chAttr = SCE_H_ATTRIBUTE;
}
for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
char ch = styler[cPos];
if ((ch != '<') && (ch != '/')) {
- s[i++] = caseSensitive ? ch : static_cast<char>(tolower(ch));
+ s[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch));
}
}
if (wordIsNumber)
chAttr = SCE_HB_NUMBER;
else {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s)) {
chAttr = SCE_HB_WORD;
if (strcmp(s, "rem") == 0)
if (wordIsNumber)
chAttr = SCE_HPHP_NUMBER;
else {
- char s[100 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 100; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s))
chAttr = SCE_HPHP_WORD;
}
return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
}
+static bool IsScriptCommentState(const int state) {
+ return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT ||
+ state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
+}
+
static bool isLineEnd(char ch) {
return ch == '\r' || ch == '\n';
}
static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
int j;
+ while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
+ i++;
phpStringDelimiter[0] = '\n';
for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
if (j - i < phpStringDelimiterSize - 2)
char chPrev = ' ';
char ch = ' ';
char chPrevNonWhite = ' ';
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (scriptLanguage == eScriptJS && startPos > 0) {
+ int back = startPos;
+ int style = 0;
+ while (--back) {
+ style = styler.StyleAt(back);
+ if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)
+ // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
+ break;
+ }
+ if (style == SCE_HJ_SYMBOLS) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ }
+
styler.StartSegment(startPos);
const int lengthDoc = startPos + length;
for (int i = startPos; i < lengthDoc; i++) {
const char chPrev2 = chPrev;
chPrev = ch;
- if (ch != ' ' && ch != '\t')
+ if (!isspacechar(ch) && state != SCE_HJ_COMMENT &&
+ state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
chPrevNonWhite = ch;
ch = styler[i];
char chNext = styler.SafeGetCharAt(i + 1);
case SCE_H_SINGLESTRING:
case SCE_HJ_COMMENT:
case SCE_HJ_COMMENTDOC:
- // SCE_HJ_COMMENTLINE removed as this is a common thing done to hide
- // the end of script marker from some JS interpreters.
- //case SCE_HJ_COMMENTLINE:
+ //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
+ // the end of script marker from some JS interpreters.
case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX:
case SCE_HP_TRIPLEDOUBLE:
break;
default :
+ // check if the closing tag is a script tag
+ if (state == SCE_HJ_COMMENTLINE) {
+ char tag[7]; // room for the <script> tag
+ char chr; // current char
+ int j=0;
+ chr = styler.SafeGetCharAt(i+2);
+ while (j < 6 && !isspacechar(chr)) {
+ tag[j++] = static_cast<char>(MakeLowerCase(chr));
+ chr = styler.SafeGetCharAt(i+2+j);
+ }
+ tag[j] = '\0';
+ if (strcmp(tag, "script") != 0) break;
+ }
// closing tag of the script (it's a closing HTML tag anyway)
styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_TAGUNKNOWN;
!isPHPStringState(state) &&
(state != SCE_HPHP_COMMENT) &&
(ch == '<') &&
- (chNext == '?')) {
+ (chNext == '?') &&
+ !IsScriptCommentState(state) ) {
scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment() + 2, i + 10, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
- // fold whole script
- if (foldHTMLPreprocessor){
+ // Fold whole script, but not if the XML first tag (all XML-like tags in this case)
+ if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent++;
- if (scriptLanguage == eScriptXML)
- levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
}
// should be better
ch = styler.SafeGetCharAt(i);
}
// handle the start of ASP pre-processor = Non-HTML
- else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%')) {
+ else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
/////////////////////////////////////
// handle the start of SGML language (DTD)
else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
- (chPrev == '<') &&
- (ch == '!') &&
- (StateToPrint != SCE_H_CDATA) && (!IsCommentState(StateToPrint))) {
+ (chPrev == '<') &&
+ (ch == '!') &&
+ (StateToPrint != SCE_H_CDATA) &&
+ (!IsCommentState(StateToPrint)) &&
+ (!IsScriptCommentState(StateToPrint)) ) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
state = SCE_H_COMMENT; // wait for a pending command
- }
- else if (isWordCdata(i + 1, i + 7, styler)) {
+ styler.ColourTo(i + 2, SCE_H_COMMENT);
+ i += 2; // follow styling after the --
+ } else if (isWordCdata(i + 1, i + 7, styler)) {
state = SCE_H_CDATA;
} else {
styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
|| (inScriptType == eNonHtmlScriptPreProc)) && (
((scriptLanguage == eScriptPHP) && (ch == '?') && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT)) ||
((scriptLanguage != eScriptNone) && !isStringState(state) &&
- (ch == '%'))
+ ((ch == '%') || (ch == '?')))
) && (chNext == '>')) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
if (state == SCE_H_ASPAT) {
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
- scriptLanguage = eScriptNone;
- // unfold all scripting languages
- if (foldHTMLPreprocessor)
+ // Unfold all scripting languages, except for XML tag
+ if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
+ }
+ scriptLanguage = eScriptNone;
continue;
}
/////////////////////////////////////
if (ch == '/' && chPrev == '*') {
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
+ ch = ' ';
}
break;
case SCE_HJ_COMMENTLINE:
if (ch == '\r' || ch == '\n') {
styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));
state = SCE_HJ_DEFAULT;
+ ch = ' ';
}
break;
case SCE_HJ_DOUBLESTRING:
break;
case SCE_HJ_REGEX:
if (ch == '\r' || ch == '\n' || ch == '/') {
+ if (ch == '/') {
+ while (isascii(chNext) && islower(chNext)) { // gobble regex flags
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ }
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
} else if (ch == '\\') {
}
break;
case SCE_HPHP_NUMBER:
- if (!IsADigit(ch) && ch != '.' && ch != 'e' && ch != 'E' && (ch != '-' || (chPrev != 'e' && chPrev != 'E'))) {
+ // recognize bases 8,10 or 16 integers OR floating-point numbers
+ if (!IsADigit(ch)
+ && strchr(".xXabcdefABCDEF", ch) == NULL
+ && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) {
styler.ColourTo(i - 1, SCE_HPHP_NUMBER);
if (isoperator(ch))
state = SCE_HPHP_OPERATOR;
sc.Complete();
}
+static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ if(startPos == 0) initStyle = SCE_HPHP_DEFAULT;
+ ColouriseHyperTextDoc(startPos,length,initStyle,keywordlists,styler);
+}
+
static const char * const htmlWordListDesc[] = {
"HTML elements and attributes",
"JavaScript keywords",
0,
};
-LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc);
-LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc);
-LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc);
-LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc);
+static const char * const phpscriptWordListDesc[] = {
+ "", //Unused
+ "", //Unused
+ "", //Unused
+ "", //Unused
+ "PHP keywords",
+ "", //Unused
+ 0,
+};
+
+LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc, 7);
+LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc, 7);
+// SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
+LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 7);
+LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 7);
+LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 7);
--- /dev/null
+/******************************************************************
+ * LexHaskell.cxx
+ *
+ * A haskell lexer for the scintilla code control.
+ * Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
+ * External lexer stuff inspired from the caml external lexer.
+ *
+ * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
+ *
+ *
+ * TODO:
+ * * Implement a folder :)
+ * * Nice Character-lexing (stuff inside '\''), LexPython has
+ * this.
+ *
+ *
+ *****************************************************************/
+
+#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 BUILD_AS_EXTERNAL_LEXER
+
+#include "ExternalLexer.h"
+#include "WindowAccessor.h"
+
+#define BUILD_EXTERNAL_LEXER 0
+
+#endif
+
+// Max level of nested comments
+#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
+
+
+enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
+
+static inline bool IsNewline(const int ch) {
+ return (ch == '\n' || ch == '\r');
+}
+
+static inline bool IsWhitespace(const int ch) {
+ return ( ch == ' '
+ || ch == '\t'
+ || IsNewline(ch) );
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
+}
+
+static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+
+ int kwLast = kwOther;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ // Check for state end
+ // Operator
+ if (sc.state == SCE_HA_OPERATOR) {
+ kwLast = kwOther;
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ // String
+ else if (sc.state == SCE_HA_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Char
+ else if (sc.state == SCE_HA_CHARACTER) {
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Number
+ else if (sc.state == SCE_HA_NUMBER) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Types, constructors, etc.
+ else if (sc.state == SCE_HA_CAPITAL) {
+ if (!IsAWordChar(sc.ch) || sc.ch == '.') {
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Identifier
+ else if (sc.state == SCE_HA_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ int style = SCE_HA_IDENTIFIER;
+ if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
+ style = SCE_HA_IMPORT;
+ } else if (keywords.InList(s)) {
+ style = SCE_HA_KEYWORD;
+ } else if (kwLast == kwData) {
+ style = SCE_HA_DATA;
+ } else if (kwLast == kwClass) {
+ style = SCE_HA_CLASS;
+ } else if (kwLast == kwModule) {
+ style = SCE_HA_MODULE;
+ } else if (isupper(s[0])) {
+ style = SCE_HA_CAPITAL;
+ }
+ sc.ChangeState(style);
+ sc.SetState(SCE_HA_DEFAULT);
+ if (style == SCE_HA_KEYWORD) {
+ if (0 == strcmp(s, "class"))
+ kwLast = kwClass;
+ else if (0 == strcmp(s, "data"))
+ kwLast = kwData;
+ else if (0 == strcmp(s, "instance"))
+ kwLast = kwInstance;
+ else if (0 == strcmp(s, "import"))
+ kwLast = kwImport;
+ else if (0 == strcmp(s, "module"))
+ kwLast = kwModule;
+ else
+ kwLast = kwOther;
+ } else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
+ style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
+ style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
+ kwLast = kwOther;
+ }
+ }
+ }
+ // Comments
+ // Oneliner
+ else if (sc.state == SCE_HA_COMMENTLINE) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ // Nested
+ else if (sc.state >= SCE_HA_COMMENTBLOCK) {
+ if (sc.Match("{-")) {
+ if (sc.state < SCE_HA_COMMENTMAX)
+ sc.SetState(sc.state + 1);
+ }
+ else if (sc.Match("-}")) {
+ sc.Forward();
+ if (sc.state == SCE_HA_COMMENTBLOCK)
+ sc.ForwardSetState(SCE_HA_DEFAULT);
+ else
+ sc.ForwardSetState(sc.state - 1);
+ }
+ }
+ // New state?
+ if (sc.state == SCE_HA_DEFAULT) {
+ // Digit
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_HA_NUMBER);
+ }
+ // Comment line
+ else if (sc.Match("--")) {
+ sc.SetState(SCE_HA_COMMENTLINE);
+ // Comment block
+ }
+ else if (sc.Match("{-")) {
+ sc.SetState(SCE_HA_COMMENTBLOCK);
+ }
+ // String
+ else if (sc.Match('\"')) {
+ sc.SetState(SCE_HA_STRING);
+ }
+ // Character
+ else if (sc.Match('\'') && IsWhitespace(sc.GetRelative(-1)) ) {
+ sc.SetState(SCE_HA_CHARACTER);
+ }
+ // Stringstart
+ else if (sc.Match('\"')) {
+ sc.SetState(SCE_HA_STRING);
+ }
+ // Operator
+ else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_HA_OPERATOR);
+ }
+ // Keyword
+ else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HA_IDENTIFIER);
+ }
+
+ }
+ }
+ sc.Complete();
+}
+
+// External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
+// Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
+#ifdef BUILD_EXTERNAL_LEXER
+static const char* LexerName = "haskell";
+
+void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
+ char *words[], WindowID window, char *props)
+{
+ PropSet ps;
+ ps.SetMultiple(props);
+ WindowAccessor wa(window, ps);
+
+ int nWL = 0;
+ for (; words[nWL]; nWL++) ;
+ WordList** wl = new WordList* [nWL + 1];
+ int i = 0;
+ for (; i<nWL; i++)
+ {
+ wl[i] = new WordList();
+ wl[i]->Set(words[i]);
+ }
+ wl[i] = 0;
+
+ ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
+ wa.Flush();
+ for (i=nWL-1;i>=0;i--)
+ delete wl[i];
+ delete [] wl;
+}
+
+void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
+ char *words[], WindowID window, char *props)
+{
+
+}
+
+int EXT_LEXER_DECL GetLexerCount()
+{
+ return 1;
+}
+
+void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
+{
+ if (buflength > 0) {
+ buflength--;
+ int n = strlen(LexerName);
+ if (n > buflength)
+ n = buflength;
+ memcpy(name, LexerName, n), name[n] = '\0';
+ }
+}
+#endif
+
+LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
+
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
+#include "StyleContext.h"
+#define SCE_LISP_CHARACTER 29
+#define SCE_LISP_MACRO 30
+#define SCE_LISP_MACRO_DISPATCH 31
static inline bool isLispoperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
- if (ch == '\'' || ch == '(' || ch == ')' )
+ if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' )
return true;
return false;
}
}
-static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
PLATFORM_ASSERT(end >= start);
char s[100];
unsigned int i;
else {
if (keywords.InList(s)) {
chAttr = SCE_LISP_KEYWORD;
+ } else if (keywords_kw.InList(s)) {
+ chAttr = SCE_LISP_KEYWORD_KW;
+ } else if ((s[0] == '*' && s[i-1] == '*') ||
+ (s[0] == '+' && s[i-1] == '+')) {
+ chAttr = SCE_LISP_SPECIAL;
}
}
styler.ColourTo(end, chAttr);
Accessor &styler) {
WordList &keywords = *keywordlists[0];
+ WordList &keywords_kw = *keywordlists[1];
styler.StartAt(startPos);
- int state = initStyle;
+ int state = initStyle, radix = -1;
char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length;
styler.StartSegment(startPos);
}
if (state == SCE_LISP_DEFAULT) {
- if (isLispwordstart(ch)) {
+ if (ch == '#') {
+ styler.ColourTo(i - 1, state);
+ radix = -1;
+ state = SCE_LISP_MACRO_DISPATCH;
+ } else if (isLispwordstart(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_IDENTIFIER;
}
else if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
}
else if (ch == '\"') {
styler.ColourTo(i - 1, state);
state = SCE_LISP_STRING;
}
- } else if (state == SCE_LISP_IDENTIFIER) {
+ } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
if (!isLispwordstart(ch)) {
- classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler);
+ if (state == SCE_LISP_IDENTIFIER) {
+ classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
+ } else {
+ styler.ColourTo(i - 1, state);
+ }
state = SCE_LISP_DEFAULT;
} /*else*/
if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
+ }
+ } else if (state == SCE_LISP_MACRO_DISPATCH) {
+ if (!isdigit(ch)) {
+ if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
+ state = SCE_LISP_DEFAULT;
+ } else {
+ switch (ch) {
+ case '|': state = SCE_LISP_MULTI_COMMENT; break;
+ case 'o':
+ case 'O': radix = 8; state = SCE_LISP_MACRO; break;
+ case 'x':
+ case 'X': radix = 16; state = SCE_LISP_MACRO; break;
+ case 'b':
+ case 'B': radix = 2; state = SCE_LISP_MACRO; break;
+ case '\\': state = SCE_LISP_CHARACTER; break;
+ case ':':
+ case '-':
+ case '+': state = SCE_LISP_MACRO; break;
+ case '\'': if (isLispwordstart(chNext)) {
+ state = SCE_LISP_SPECIAL;
+ } else {
+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ state = SCE_LISP_DEFAULT;
+ }
+ break;
+ default: if (isLispoperator(ch)) {
+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ }
+ state = SCE_LISP_DEFAULT;
+ break;
+ }
+ }
+ }
+ } else if (state == SCE_LISP_MACRO) {
+ if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
+ state = SCE_LISP_SPECIAL;
+ } else {
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_CHARACTER) {
+ if (isLispoperator(ch)) {
+ styler.ColourTo(i, SCE_LISP_SPECIAL);
+ state = SCE_LISP_DEFAULT;
+ } else if (isLispwordstart(ch)) {
+ styler.ColourTo(i, SCE_LISP_SPECIAL);
+ state = SCE_LISP_SPECIAL;
+ } else {
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_SPECIAL) {
+ if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_DEFAULT;
+ }
+ if (isLispoperator(ch) || ch=='\'') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
}
-
} else {
if (state == SCE_LISP_COMMENT) {
if (atEOL) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_DEFAULT;
}
+ } else if (state == SCE_LISP_MULTI_COMMENT) {
+ if (ch == '|' && chNext == '#') {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ styler.ColourTo(i, state);
+ state = SCE_LISP_DEFAULT;
+ }
} else if (state == SCE_LISP_STRING) {
if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
}
static const char * const lispWordListDesc[] = {
+ "Functions and special operators",
"Keywords",
0
};
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SciLexer.h"
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+ return ch >= 0x80 ||
+ (isalnum(ch) || ch == '.' || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordStart(int ch) {
+ return ch >= 0x80 ||
+ (isalpha(ch) || ch == '_');
}
-static inline bool IsANumberChar(const int 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) &&
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.
+static int LongDelimCheck(StyleContext &sc) {
+ int sep = 1;
+ while (sc.GetRelative(sep) == '=' && sep < 0xFF)
+ sep++;
+ if (sc.GetRelative(sep) == sc.ch)
+ return sep;
+ return 0;
+}
+
static void ColouriseLuaDoc(
unsigned int startPos,
int length,
WordList &keywords8 = *keywordlists[7];
int currentLine = styler.GetLine(startPos);
- // Initialize the literal string [[ ... ]] nesting level, if we are inside such a string.
- int literalStringLevel = 0;
- if (initStyle == SCE_LUA_LITERALSTRING) {
- literalStringLevel = styler.GetLineState(currentLine - 1);
- }
- // Initialize the block comment --[[ ... ]] nesting level, if we are inside such a comment
- int blockCommentLevel = 0;
- if (initStyle == SCE_LUA_COMMENT) {
- blockCommentLevel = styler.GetLineState(currentLine - 1);
+ // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
+ // if we are inside such a string. Block comment was introduced in Lua 5.0,
+ // blocks with separators [=[ ... ]=] in Lua 5.1.
+ int nestLevel = 0;
+ int sepCount = 0;
+ if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
+ int lineState = styler.GetLineState(currentLine - 1);
+ nestLevel = lineState >> 8;
+ sepCount = lineState & 0xFF;
}
// Do not leak onto next line
- if (initStyle == SCE_LUA_STRINGEOL) {
+ if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
initStyle = SCE_LUA_DEFAULT;
}
currentLine = styler.GetLine(sc.currentPos);
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
- // Inside a literal string, we set the line state
- styler.SetLineState(currentLine, literalStringLevel);
- break;
- case SCE_LUA_COMMENT: // Block comment
- // Inside a block comment, we set the line state
- styler.SetLineState(currentLine, blockCommentLevel);
+ case SCE_LUA_COMMENT:
+ // Inside a literal string or block comment, we set the line state
+ styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
break;
default:
// Reset the line state
}
sc.SetState(SCE_LUA_DEFAULT);
}
- } else if (sc.state == SCE_LUA_COMMENTLINE ) {
+ } else if (sc.state == SCE_LUA_COMMENTLINE || sc.state == SCE_LUA_PREPROCESSOR) {
if (sc.atLineEnd) {
- sc.SetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_PREPROCESSOR ) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_LUA_DEFAULT);
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
if (sc.ch == '\\') {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
- } else if (sc.state == SCE_LUA_LITERALSTRING) {
- if (sc.Match('[', '[')) {
- literalStringLevel++;
- sc.Forward();
- sc.SetState(SCE_LUA_LITERALSTRING);
- } else if (sc.Match(']', ']') && literalStringLevel > 0) {
- literalStringLevel--;
- sc.Forward();
- if (literalStringLevel == 0) {
- sc.ForwardSetState(SCE_LUA_DEFAULT);
+ } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) {
+ if (sc.ch == '[') {
+ int sep = LongDelimCheck(sc);
+ if (sep == 1 && sepCount == 1) { // [[-only allowed to nest
+ nestLevel++;
+ sc.Forward();
}
- }
- } else if (sc.state == SCE_LUA_COMMENT) { // Lua 5.0's block comment
- if (sc.Match('[', '[')) {
- blockCommentLevel++;
- sc.Forward();
- } else if (sc.Match(']', ']') && blockCommentLevel > 0) {
- blockCommentLevel--;
- sc.Forward();
- if (blockCommentLevel == 0) {
+ } else if (sc.ch == ']') {
+ int sep = LongDelimCheck(sc);
+ if (sep == 1 && sepCount == 1) { // un-nest with ]]-only
+ nestLevel--;
+ sc.Forward();
+ if (nestLevel == 0) {
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sep > 1 && sep == sepCount) { // ]=]-style delim
+ sc.Forward(sep);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
}
sc.SetState(SCE_LUA_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_LUA_IDENTIFIER);
- } else if (sc.Match('\"')) {
+ } else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
- } else if (sc.Match('\'')) {
+ } else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
- } else if (sc.Match('[', '[')) {
- literalStringLevel = 1;
- sc.SetState(SCE_LUA_LITERALSTRING);
- sc.Forward();
- } else if (sc.Match("--[[")) { // Lua 5.0's block comment
- blockCommentLevel = 1;
- sc.SetState(SCE_LUA_COMMENT);
- sc.Forward(3);
+ } else if (sc.ch == '[') {
+ sepCount = LongDelimCheck(sc);
+ if (sepCount == 0) {
+ sc.SetState(SCE_LUA_OPERATOR);
+ } else {
+ nestLevel = 1;
+ sc.SetState(SCE_LUA_LITERALSTRING);
+ sc.Forward(sepCount);
+ }
} else if (sc.Match('-', '-')) {
sc.SetState(SCE_LUA_COMMENTLINE);
- sc.Forward();
+ if (sc.Match("--[")) {
+ sc.Forward(2);
+ sepCount = LongDelimCheck(sc);
+ if (sepCount > 0) {
+ nestLevel = 1;
+ sc.ChangeState(SCE_LUA_COMMENT);
+ sc.Forward(sepCount);
+ }
+ } else {
+ sc.Forward();
+ }
} 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))) {
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_LUA_WORD) {
- if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e') {
+ if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
for (unsigned int j = 0; j < 8; j++) {
if (!iswordchar(styler[i + j])) {
break;
s[j + 1] = '\0';
}
- if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0)) {
+ if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) {
levelCurrent++;
}
- if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) {
levelCurrent--;
}
}
} else if (ch == '}' || ch == ')') {
levelCurrent--;
}
+ } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
}
if (atEOL) {
"Basic functions",
"String, (table) & math functions",
"(coroutines), I/O & system facilities",
- "XXX",
- "XXX",
+ "user1",
+ "user2",
+ "user3",
+ "user4",
0
};
/** @file LexMSSQL.cxx
** Lexer for MSSQL.
**/
-// Copyright 1998-2002 by Filip Yaghob <fy@eg.cz>
+// By Filip Yaghob <fyaghob@gmail.com>
#include <stdlib.h>
#define KW_MSSQL_STORED_PROCEDURES 5
#define KW_MSSQL_OPERATORS 6
-//~ val SCE_MSSQL_DEFAULT=0
-//~ val SCE_MSSQL_COMMENT=1
-//~ val SCE_MSSQL_LINE_COMMENT=2
-//~ val SCE_MSSQL_NUMBER=3
-//~ val SCE_MSSQL_STRING=4
-//~ val SCE_MSSQL_OPERATOR=5
-//~ val SCE_MSSQL_IDENTIFIER=6
-//~ val SCE_MSSQL_VARIABLE=7
-//~ val SCE_MSSQL_COLUMN_NAME=8
-//~ val SCE_MSSQL_STATEMENT=9
-//~ val SCE_MSSQL_DATATYPE=10
-//~ val SCE_MSSQL_SYSTABLE=11
-//~ val SCE_MSSQL_GLOBAL_VARIABLE=12
-//~ val SCE_MSSQL_FUNCTION=13
-//~ val SCE_MSSQL_STORED_PROCEDURE=14
-//~ val SCE_MSSQL_DEFAULT_PREF_DATATYPE 15
-//~ val SCE_MSSQL_COLUMN_NAME_2 16
-
static bool isMSSQLOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
bool fold = styler.GetPropertyInt("fold") != 0;
int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0;
-/*
- WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
- WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
- WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
- WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
- WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
- char s[100];
- int iixx = 0;
- s[0] = 's'; s[1] = 'e'; s[2] = 'l'; s[3] = 'e'; s[4] = 'c'; s[5] = 't'; s[6] = 0;
- if (kwStatements.InList(s))
- iixx = 1;
- s[0] = 's'; s[1] = 'e'; s[2] = 'r'; s[3] = 'v'; s[4] = 'e'; s[5] = 'r'; s[6] = 'n'; s[7] = 'a'; s[8] = 'm'; s[9] = 'e'; s[10] = 0;
- if (kwGlobalVariables.InList(s))
- iixx += 2;
-*/
int state = initStyle;
int prevState = initStyle;
char chPrev = ' ';
styler.ColourTo(lengthDoc - 1, state);
}
+static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
+ char s[10];
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ // Comment folding
+ if (foldComment) {
+ if (!inComment && (style == SCE_MSSQL_COMMENT))
+ levelCurrent++;
+ else if (inComment && (style != SCE_MSSQL_COMMENT))
+ levelCurrent--;
+ inComment = (style == SCE_MSSQL_COMMENT);
+ }
+ if (style == SCE_MSSQL_STATEMENT) {
+ // Folding between begin and end
+ if (ch == 'b' || ch == 'e') {
+ for (unsigned int j = 0; j < 5; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = styler[i + j];
+ s[j + 1] = '\0';
+ }
+ if (strcmp(s, "begin") == 0) {
+ levelCurrent++;
+ }
+ if (strcmp(s, "end") == 0) {
+ levelCurrent--;
+ }
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
static const char * const sqlWordListDesc[] = {
"Statements",
"Data Types",
0,
};
-LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", 0, sqlWordListDesc);
+LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
// 0 no keyword highlighting
- // 1 metapost keyword highlighting
- // 2+ metafun keyword highlighting
+ // 1 metapost keyword hightlighting
+ // 2+ metafun keyword hightlighting
int extraInterface = 0 ;
/** @file LexNsis.cxx
** Lexer for NSIS
**/
-// Copyright 2003, 2004 by Angelo Mandato <angelo [at] spaceblue [dot] com>
-// Last Updated: 02/22/2004
+// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
+// Last Updated: 03/13/2005
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#define SCE_NSIS_MACRODEF 12
#define SCE_NSIS_STRINGVAR 13
#define SCE_NSIS_NUMBER 14
+// ADDED for Scintilla v1.63
+#define SCE_NSIS_SECTIONGROUP 15
+#define SCE_NSIS_PAGEEX 16
+#define SCE_NSIS_FUNCTIONDEF 17
+#define SCE_NSIS_COMMENTBOX 18
*/
static bool isNsisNumber(char ch)
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
+static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
+{
+ int nNextLine = -1;
+ for( unsigned int i = start; i < end; i++ )
+ {
+ char cNext = styler.SafeGetCharAt( i );
+ if( cNext == '\n' )
+ {
+ nNextLine = i+1;
+ break;
+ }
+ }
+
+ if( nNextLine == -1 ) // We never foudn the next line...
+ return false;
+
+ for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
+ {
+ char cNext = styler.SafeGetCharAt( firstChar );
+ if( cNext == ' ' )
+ continue;
+ if( cNext == '\t' )
+ continue;
+ if( cNext == '!' )
+ {
+ if( styler.Match(firstChar, "!else") )
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
static int NsisCmp( char *s1, char *s2, bool bIgnoreCase )
{
if( bIgnoreCase )
return strcmp( s1, s2 );
}
-static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler )
+static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
{
+ int style = styler.StyleAt(end);
+
// If the word is too long, it is not what we are looking for
- if( end - start > 13 )
+ if( end - start > 20 )
return foldlevel;
- // Check the style at this point, if it is not valid, then return zero
- if( styler.StyleAt(end) != SCE_NSIS_FUNCTION && styler.StyleAt(end) != SCE_NSIS_SECTIONDEF &&
- styler.StyleAt(end) != SCE_NSIS_SUBSECTIONDEF && styler.StyleAt(end) != SCE_NSIS_IFDEFINEDEF &&
- styler.StyleAt(end) != SCE_NSIS_MACRODEF )
- return foldlevel;
+ if( foldUtilityCmd )
+ {
+ // Check the style at this point, if it is not valid, then return zero
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
+ style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
+ return foldlevel;
+ }
+ else
+ {
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
+ return foldlevel;
+ }
int newFoldlevel = foldlevel;
bool bIgnoreCase = false;
if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
bIgnoreCase = true;
- char s[15]; // The key word we are looking for has atmost 13 characters
- for (unsigned int i = 0; i < end - start + 1 && i < 14; i++)
+ char s[20]; // The key word we are looking for has atmost 13 characters
+ for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
{
s[i] = static_cast<char>( styler[ start + i ] );
s[i + 1] = '\0';
newFoldlevel++;
else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
newFoldlevel--;
+ else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
+ newFoldlevel++;
}
else
{
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 )
+ if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
newFoldlevel++;
- else if( NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 )
+ else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
newFoldlevel--;
}
-
+
return newFoldlevel;
}
if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
return SCE_NSIS_IFDEFINEDEF;
+ if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
+ return SCE_NSIS_IFDEFINEDEF;
+
+ if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
+ return SCE_NSIS_SECTIONGROUP;
+
if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
return SCE_NSIS_SECTIONDEF;
if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
return SCE_NSIS_SUBSECTIONDEF;
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
- return SCE_NSIS_FUNCTION;
+ if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
+ return SCE_NSIS_PAGEEX;
+
+ if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
+ return SCE_NSIS_FUNCTIONDEF;
if ( Functions.InList(s) )
return SCE_NSIS_FUNCTION;
bool bHasSimpleNsisNumber = true;
for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
{
- if( s[j] == '\0' || s[j] == '\r' || s[j] == '\n' )
- break;
-
if( !isNsisNumber( s[j] ) )
{
bHasSimpleNsisNumber = false;
static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_NSIS_DEFAULT;
+ if( startPos > 0 )
+ state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
+
styler.StartAt( startPos );
styler.GetLine( startPos );
break;
}
+
+ if( cCurrChar == '/' && cNextChar == '*' )
+ {
+ styler.ColourTo(i-1,state);
+ state = SCE_NSIS_COMMENTBOX;
+ break;
+ }
+
break;
case SCE_NSIS_COMMENT:
if( cNextChar == '\n' || cNextChar == '\r' )
{
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
+ // Special case:
+ if( cCurrChar == '\\' )
+ {
+ styler.ColourTo(i-2,state);
+ styler.ColourTo(i,SCE_NSIS_DEFAULT);
+ }
+ else
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
}
break;
case SCE_NSIS_STRINGDQ:
- if( cCurrChar == '"' || cNextChar == '\r' || cNextChar == '\n' )
+ case SCE_NSIS_STRINGLQ:
+ case SCE_NSIS_STRINGRQ:
+
+ if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
+ break; // Ignore the next character, even if it is a quote of some sort
+
+ if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
{
- styler.ColourTo(i,SCE_NSIS_STRINGDQ);
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
- break;
- case SCE_NSIS_STRINGLQ:
- if( cCurrChar == '`' || cNextChar == '\r' || cNextChar == '\n' )
- {
- styler.ColourTo(i,SCE_NSIS_STRINGLQ);
+
+ if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
+ {
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
- break;
- case SCE_NSIS_STRINGRQ:
- if( cCurrChar == '\'' || cNextChar == '\r' || cNextChar == '\n' )
+
+ if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
{
- styler.ColourTo(i,SCE_NSIS_STRINGRQ);
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
+
+ if( cNextChar == '\r' || cNextChar == '\n' )
+ {
+ int nCurLine = styler.GetLine(i+1);
+ int nBack = i;
+ // We need to check if the previous line has a \ in it...
+ bool bNextLine = false;
+
+ while( nBack > 0 )
+ {
+ if( styler.GetLine(nBack) != nCurLine )
+ break;
+
+ char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
+
+ if( cTemp == '\\' )
+ {
+ bNextLine = true;
+ break;
+ }
+ if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
+ break;
+
+ nBack--;
+ }
+
+ if( bNextLine )
+ {
+ styler.ColourTo(i+1,state);
+ }
+ if( bNextLine == false )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ }
break;
+
case SCE_NSIS_FUNCTION:
// NSIS KeyWord:
state = SCE_NSIS_DEFAULT;
else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
{
- state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
+ state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
styler.ColourTo( i, state);
state = SCE_NSIS_DEFAULT;
}
}
}
break;
+ case SCE_NSIS_COMMENTBOX:
+
+ if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ break;
}
- if( state == SCE_NSIS_COMMENT )
+ if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
{
styler.ColourTo(i,state);
}
bVarInString = false;
bIngoreNextDollarSign = true;
}
- else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
+ else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
{
+ styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
bVarInString = false;
- bIngoreNextDollarSign = true;
+ bIngoreNextDollarSign = false;
}
// Covers "$INSTDIR and user vars like $MYVAR"
}
// Colourise remaining document
- switch( state )
- {
- case SCE_NSIS_COMMENT:
- case SCE_NSIS_STRINGDQ:
- case SCE_NSIS_STRINGLQ:
- case SCE_NSIS_STRINGRQ:
- case SCE_NSIS_VARIABLE:
- case SCE_NSIS_STRINGVAR:
- styler.ColourTo(nLengthDoc-1,state); break;
-
- default:
- styler.ColourTo(nLengthDoc-1,SCE_NSIS_DEFAULT); break;
- }
+ styler.ColourTo(nLengthDoc-1,state);
}
static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
if( styler.GetPropertyInt("fold") == 0 )
return;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
+ bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
+ bool blockComment = false;
+
int lineCurrent = styler.GetLine(startPos);
unsigned int safeStartPos = styler.LineStart( lineCurrent );
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
+ int style = styler.StyleAt(safeStartPos);
+ if( style == SCE_NSIS_COMMENTBOX )
+ {
+ if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
+ levelNext++;
+ blockComment = true;
+ }
for (unsigned int i = safeStartPos; i < startPos + length; i++)
{
char chCurr = styler.SafeGetCharAt(i);
+ style = styler.StyleAt(i);
+ if( blockComment && style != SCE_NSIS_COMMENTBOX )
+ {
+ levelNext--;
+ blockComment = false;
+ }
+ else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
+ {
+ levelNext++;
+ blockComment = true;
+ }
- if( bArg1 ) //&& chCurr != '\n' )
+ if( bArg1 && !blockComment)
{
if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
+ {
nWordStart = i;
- else if( !isNsisLetter(chCurr) && nWordStart > -1 )
+ }
+ else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
{
- int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler );
- if( newLevel != levelNext )
+ int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
+
+ if( newLevel == levelNext )
+ {
+ if( foldAtElse && foldUtilityCmd )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+ }
+ else
levelNext = newLevel;
bArg1 = false;
}
if( chCurr == '\n' )
{
+ if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+
// If we are on a new line...
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext)
+ if (levelUse < levelNext )
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
+
static inline bool AtEOL(Accessor &styler, unsigned int i) {
return (styler[i] == '\n') ||
- ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
+ ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
+}
+
+// Tests for BATCH Operators
+static bool IsBOperator(char ch) {
+ return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
+ (ch == '|') || (ch == '?') || (ch == '*');
+}
+
+// Tests for BATCH Separators
+static bool IsBSeparator(char ch) {
+ return (ch == ':') || (ch == '\\') || (ch == '.') || (ch == ';') ||
+ (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
}
static void ColouriseBatchLine(
WordList &keywords,
Accessor &styler) {
- unsigned int i = 0;
- unsigned int state = SCE_BAT_DEFAULT;
+ 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
+ unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
+ bool forFound = false; // No Local Variable without FOR statement
+ // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
+ // Toggling Regular Keyword Checking off improves readability
+ // Other Regular Keywords and External Commands / Programs might also benefit from toggling
+ // Need a more robust algorithm to properly toggle Regular Keyword Checking
+ bool continueProcessing = true; // Used to toggle Regular Keyword Checking
+ // Special Keywords are those that allow certain characters without whitespace after the command
+ // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
+ // Special Keyword Buffer used to determine if the first n characters is a Keyword
+ char sKeywordBuffer[10]; // Special Keyword Buffer
+ bool sKeywordFound; // Exit Special Keyword for-loop if found
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip initial spaces
- i++;
- }
- if (lineBuffer[i] == '@') { // Hide command (ECHO OFF)
- styler.ColourTo(startLine + i, SCE_BAT_HIDE);
- i++;
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip next spaces
- i++;
- }
+ // Skip initial spaces
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
}
- if (lineBuffer[i] == ':') {
- // Label
- if (lineBuffer[i + 1] == ':') {
- // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ // Set External Command / Program Location
+ cmdLoc = offset;
+
+ // Check for Fake Label (Comment) or Real Label - return if found
+ if (lineBuffer[offset] == ':') {
+ if (lineBuffer[offset + 1] == ':') {
+ // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
styler.ColourTo(endPos, SCE_BAT_COMMENT);
- } else { // Real label
+ } else {
+ // Colorize Real Label
styler.ColourTo(endPos, SCE_BAT_LABEL);
}
- } else {
- // Check if initial word is a keyword
- char wordBuffer[21];
- unsigned int wbl = 0, offset = i;
- // Copy word in buffer
- for (; offset < lengthLine && wbl < 20 &&
+ return;
+ // Check for Drive Change (Drive Change is internal command) - return if found
+ } else if ((isalpha(lineBuffer[offset])) &&
+ (lineBuffer[offset + 1] == ':') &&
+ ((isspacechar(lineBuffer[offset + 2])) ||
+ (((lineBuffer[offset + 2] == '\\')) &&
+ (isspacechar(lineBuffer[offset + 3]))))) {
+ // Colorize Regular Keyword
+ styler.ColourTo(endPos, SCE_BAT_WORD);
+ return;
+ }
+
+ // Check for Hide Command (@ECHO OFF/ON)
+ 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 (!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 (!isspacechar(lineBuffer[offset])) {
+ cmdLoc = offset;
+ }
+ }
+ }
+ // Skip next spaces
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+
+ // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
+ while (offset < lengthLine) {
+ if (offset > startLine) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Copy word from Line Buffer into Word Buffer
+ wbl = 0;
+ for (; offset < lengthLine && wbl < 80 &&
!isspacechar(lineBuffer[offset]); wbl++, offset++) {
wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
}
wordBuffer[wbl] = '\0';
- // Check if it is a comment
+ wbo = 0;
+
+ // Check for Comment - return if found
if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
styler.ColourTo(endPos, SCE_BAT_COMMENT);
- return ;
+ return;
}
- // Check if it is in the list
- if (keywords.InList(wordBuffer)) {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword
- } else {
- // Search end of word (can be a long path)
- while (offset < lengthLine &&
- !isspacechar(lineBuffer[offset])) {
- offset++;
+ // Check for Separator
+ if (IsBSeparator(wordBuffer[0])) {
+ // Check for External Command / Program
+ if ((cmdLoc == offset - wbl) &&
+ ((wordBuffer[0] == ':') ||
+ (wordBuffer[0] == '\\') ||
+ (wordBuffer[0] == '.'))) {
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize External Command / Program
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ } else {
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Check for Regular Keyword in list
+ } else if ((keywords.InList(wordBuffer)) &&
+ (continueProcessing)) {
+ // Local Variables do not exist if no FOR statement
+ if (CompareCaseInsensitive(wordBuffer, "for") == 0) {
+ forFound = true;
+ }
+ // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
+ if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "set") == 0)) {
+ continueProcessing = false;
+ }
+ // Identify External Command / Program Location for ERRORLEVEL, and EXIST
+ if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip comparison
+ while ((cmdLoc < lengthLine) &&
+ (!isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
+ } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "do") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ }
+ // Colorize Regular keyword
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
+ // No need to Reset Offset
+ // Check for Special Keyword in list, External Command / Program, or Default Text
+ } else if ((wordBuffer[0] != '%') &&
+ (!IsBOperator(wordBuffer[0])) &&
+ (continueProcessing)) {
+ // Check for Special Keyword
+ // Affected Commands are in Length range 2-6
+ // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
+ sKeywordFound = false;
+ for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
+ wbo = 0;
+ // Copy Keyword Length from Word Buffer into Special Keyword Buffer
+ for (; wbo < keywordLength; wbo++) {
+ sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
+ }
+ sKeywordBuffer[wbo] = '\0';
+ // Check for Special Keyword in list
+ if ((keywords.InList(sKeywordBuffer)) &&
+ ((IsBOperator(wordBuffer[wbo])) ||
+ (IsBSeparator(wordBuffer[wbo])))) {
+ sKeywordFound = true;
+ // ECHO requires no further Regular Keyword Checking
+ if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
+ continueProcessing = false;
+ }
+ // Colorize Special Keyword as Regular Keyword
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
}
- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program
}
- // Remainder of the line: colourise the variables.
-
- while (offset < lengthLine) {
- if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
- styler.ColourTo(startLine + offset - 1, state);
- if (Is0To9(lineBuffer[offset + 1])) {
- styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
- offset += 2;
- } else if (lineBuffer[offset + 1] == '%' &&
- !isspacechar(lineBuffer[offset + 2])) {
- // Should be safe, as there is CRLF at the end of the line...
- styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER);
- offset += 3;
+ // Check for External Command / Program or Default Text
+ if (!sKeywordFound) {
+ wbo = 0;
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Reset External Command / Program Location
+ cmdLoc = offset - (wbl - wbo);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ // CHOICE requires no further Regular Keyword Checking
+ if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
+ continueProcessing = false;
+ }
+ // Check for START (and its switches) - What follows is External Command \ Program
+ if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Reset External Command / Program Location if command switch detected
+ if (lineBuffer[cmdLoc] == '/') {
+ // Skip command switch
+ while ((cmdLoc < lengthLine) &&
+ (!isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ }
+ }
+ // Colorize External command / program
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ // No need to Reset Offset
+ // Check for Default Text
} else {
- state = SCE_BAT_IDENTIFIER;
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ }
+ // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
+ } 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++;
+ }
+ // Check for Argument (%n)
+ if ((Is0To9(wordBuffer[1])) &&
+ (wordBuffer[wbo] != '%')) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - 2);
+ }
+ // Colorize Argument
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ // Check for Environment Variable (%x...%)
+ } else if ((wordBuffer[1] != '%') &&
+ (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 Local Variable (%%a)
+ } else if ((forFound) &&
+ (wordBuffer[1] == '%') &&
+ (wordBuffer[2] != '%') &&
+ (!IsBOperator(wordBuffer[2])) &&
+ (!IsBSeparator(wordBuffer[2]))) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - 3);
+ }
+ // Colorize Local Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 3);
+ }
+ // Check for Operator
+ } else if (IsBOperator(wordBuffer[0])) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+ // Check for Comparison Operator
+ if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
+ // Identify External Command / Program Location for IF
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Colorize Comparison Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ // Check for Pipe Operator
+ } else if (wordBuffer[0] == '|') {
+ // Reset External Command / Program Location
+ cmdLoc = offset - wbl + 1;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
}
- } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') {
- styler.ColourTo(startLine + offset, state);
- state = SCE_BAT_DEFAULT;
- } else if (state == SCE_BAT_DEFAULT &&
- (lineBuffer[offset] == '*' ||
- lineBuffer[offset] == '?' ||
- lineBuffer[offset] == '=' ||
- lineBuffer[offset] == '<' ||
- lineBuffer[offset] == '>' ||
- lineBuffer[offset] == '|')) {
- styler.ColourTo(startLine + offset - 1, state);
- styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR);
+ // Colorize Pipe Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Check for Other Operator
+ } else {
+ // Check for > Operator
+ if (wordBuffer[0] == '>') {
+ // Turn Keyword and External Command / Program checking back on
+ continueProcessing = true;
+ }
+ // Colorize Other Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ }
+ // Check for Default Text
+ } else {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
}
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ // Skip next spaces - nothing happens if Offset was Reset
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
offset++;
}
- // if (endPos > startLine + offset - 1) {
- styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed
- // }
}
-
+ // Colorize Default Text for remainder of line - currently not lexed
+ styler.ColourTo(endPos, SCE_BAT_DEFAULT);
}
-// ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
-// IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
-// FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
-// ToDo: %n (parameters), %EnvironmentVariable% colourising
-// ToDo: Colourise = > >> < | "
static void ColouriseBatchDoc(
unsigned int startPos,
int nextLevel = prevLevel;
if (prevLevel & SC_FOLDLEVELHEADERFLAG)
nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
-
+
int lineType = styler.StyleAt(curLineStart);
if (lineType == SCE_DIFF_COMMAND)
nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
} else if (lineType == SCE_DIFF_POSITION)
nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG;
-
+
if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
styler.SetLevel(curLine, nextLevel);
prevLevel = nextLevel;
-
+
curLineStart = styler.LineStart(++curLine);
} while (static_cast<int>(startPos) + length > curLineStart);
}
lineCurrent++;
visibleChars = 0;
- headerPoint=false;
+ headerPoint = false;
}
if (!isspacechar(ch))
visibleChars++;
}
}
-static bool strstart(char *haystack, char *needle) {
+static bool strstart(const char *haystack, const char *needle) {
return strncmp(haystack, needle, strlen(needle)) == 0;
}
-static void ColouriseErrorListLine(
- char *lineBuffer,
- unsigned int lengthLine,
- // unsigned int startLine,
- unsigned int endPos,
- Accessor &styler) {
- const int unRecognized = 99;
+static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine) {
if (lineBuffer[0] == '>') {
// Command or return status
- styler.ColourTo(endPos, SCE_ERR_CMD);
+ return SCE_ERR_CMD;
} else if (lineBuffer[0] == '<') {
// Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
- styler.ColourTo(endPos, SCE_ERR_DEFAULT);
+ return SCE_ERR_DEFAULT;
} else if (lineBuffer[0] == '!') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_CHANGED);
+ return SCE_ERR_DIFF_CHANGED;
} else if (lineBuffer[0] == '+') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_ADDITION);
- } else if (lineBuffer[0] == '-' && lineBuffer[1] == '-' && lineBuffer[2] == '-') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_MESSAGE);
+ if (strstart(lineBuffer, "+++ ")) {
+ return SCE_ERR_DIFF_MESSAGE;
+ } else {
+ return SCE_ERR_DIFF_ADDITION;
+ }
} else if (lineBuffer[0] == '-') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION);
+ if (strstart(lineBuffer, "--- ")) {
+ return SCE_ERR_DIFF_MESSAGE;
+ } else {
+ return SCE_ERR_DIFF_DELETION;
+ }
} else if (strstart(lineBuffer, "cf90-")) {
// Absoft Pro Fortran 90/95 v8.2 error and/or warning message
- styler.ColourTo(endPos, SCE_ERR_ABSF);
+ return SCE_ERR_ABSF;
} else if (strstart(lineBuffer, "fortcom:")) {
// Intel Fortran Compiler v8.0 error/warning message
- styler.ColourTo(endPos, SCE_ERR_IFORT);
+ return SCE_ERR_IFORT;
} else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
- styler.ColourTo(endPos, SCE_ERR_PYTHON);
+ return SCE_ERR_PYTHON;
} else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
- styler.ColourTo(endPos, SCE_ERR_PHP);
+ return SCE_ERR_PHP;
} else if ((strstart(lineBuffer, "Error ") ||
- strstart(lineBuffer, "Warning ")) &&
- strstr(lineBuffer, " at (") &&
- strstr(lineBuffer, ") : ") &&
- (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
+ strstart(lineBuffer, "Warning ")) &&
+ strstr(lineBuffer, " at (") &&
+ strstr(lineBuffer, ") : ") &&
+ (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
// Intel Fortran Compiler error/warning message
- styler.ColourTo(endPos, SCE_ERR_IFC);
+ return SCE_ERR_IFC;
} else if (strstart(lineBuffer, "Error ")) {
// Borland error message
- styler.ColourTo(endPos, SCE_ERR_BORLAND);
+ return SCE_ERR_BORLAND;
} else if (strstart(lineBuffer, "Warning ")) {
// Borland warning message
- styler.ColourTo(endPos, SCE_ERR_BORLAND);
+ return SCE_ERR_BORLAND;
} else if (strstr(lineBuffer, "at line " ) &&
(strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, "file ") &&
(strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
// Lua 4 error message
- styler.ColourTo(endPos, SCE_ERR_LUA);
+ return SCE_ERR_LUA;
} else if (strstr(lineBuffer, " at " ) &&
(strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, " line ") &&
(strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
- (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
+ (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
// perl error message
- styler.ColourTo(endPos, SCE_ERR_PERL);
+ return SCE_ERR_PERL;
} else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
- strstr(lineBuffer, ":line ")) {
+ strstr(lineBuffer, ":line ")) {
// A .NET traceback
- styler.ColourTo(endPos, SCE_ERR_NET);
+ return SCE_ERR_NET;
} else if (strstart(lineBuffer, "Line ") &&
- strstr(lineBuffer, ", file ")) {
+ strstr(lineBuffer, ", file ")) {
// Essential Lahey Fortran error message
- styler.ColourTo(endPos, SCE_ERR_ELF);
+ return SCE_ERR_ELF;
} else if (strstart(lineBuffer, "line ") &&
- strstr(lineBuffer, " column ")) {
+ strstr(lineBuffer, " column ")) {
// HTML tidy style: line 42 column 1
- styler.ColourTo(endPos, SCE_ERR_TIDY);
+ return SCE_ERR_TIDY;
} else if (strstart(lineBuffer, "\tat ") &&
- strstr(lineBuffer, "(") &&
- strstr(lineBuffer, ".java:")) {
+ strstr(lineBuffer, "(") &&
+ strstr(lineBuffer, ".java:")) {
// Java stack back trace
- styler.ColourTo(endPos, SCE_ERR_JAVA_STACK);
+ return SCE_ERR_JAVA_STACK;
} else {
- // Look for GCC <filename>:<line>:message
- // Look for Microsoft <filename>(line) :message
- // Look for Microsoft <filename>(line,pos)message
- // Look for CTags \tmessage
- // Look for Lua 5 traceback \t<filename>:<line>:message
+ // Look for one of the following formats:
+ // GCC: <filename>:<line>:<message>
+ // Microsoft: <filename>(<line>) :<message>
+ // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal
+ // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal
+ // Microsoft: <filename>(<line>,<column>)<message>
+ // CTags: \t<message>
+ // Lua 5 traceback: \t<filename>:<line>:<message>
bool initialTab = (lineBuffer[0] == '\t');
- int state = 0;
+ enum { stInitial,
+ stGccStart, stGccDigit, stGcc,
+ stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
+ stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
+ stUnrecognized
+ } state = stInitial;
for (unsigned int i = 0; i < lengthLine; i++) {
char ch = lineBuffer[i];
char chNext = ' ';
- if ((i+1) < lengthLine)
- chNext = lineBuffer[i+1];
- if (state == 0) {
+ if ((i + 1) < lengthLine)
+ chNext = lineBuffer[i + 1];
+ if (state == stInitial) {
if (ch == ':') {
// May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
if ((chNext != '\\') && (chNext != '/')) {
// This check is not completely accurate as may be on
// GTK+ with a file name that includes ':'.
- state = 1;
+ state = stGccStart;
}
} else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
// May be Microsoft
// Check against '0' often removes phone numbers
- state = 10;
+ state = stMsStart;
} else if ((ch == '\t') && (!initialTab)) {
// May be CTags
- state = 20;
+ state = stCtagsStart;
}
- } else if (state == 1) {
- state = Is1To9(ch) ? 2 : unRecognized;
- } else if (state == 2) {
+ } else if (state == stGccStart) { // <filename>:
+ state = Is1To9(ch) ? stGccDigit : stUnrecognized;
+ } else if (state == stGccDigit) { // <filename>:<line>
if (ch == ':') {
- state = 3; // :9.*: is GCC
+ state = stGcc; // :9.*: is GCC
break;
} else if (!Is0To9(ch)) {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 10) {
- state = Is0To9(ch) ? 11 : unRecognized;
- } else if (state == 11) {
+ } else if (state == stMsStart) { // <filename>(
+ state = Is0To9(ch) ? stMsDigit : stUnrecognized;
+ } else if (state == stMsDigit) { // <filename>(<line>
if (ch == ',') {
- state = 14;
+ state = stMsDigitComma;
} else if (ch == ')') {
- state = 12;
+ state = stMsBracket;
} else if ((ch != ' ') && !Is0To9(ch)) {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 12) {
+ } else if (state == stMsBracket) { // <filename>(<line>)
if ((ch == ' ') && (chNext == ':')) {
- state = 13;
+ state = stMsVc;
+ } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {
+ // Possibly Delphi.. don't test against chNext as it's one of the strings below.
+ char word[512];
+ unsigned int j, chPos;
+ unsigned numstep;
+ chPos = 0;
+ if (ch == ' ')
+ numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
+ else
+ numstep = 2; // otherwise add 2.
+ for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
+ word[chPos++] = lineBuffer[j];
+ word[chPos] = 0;
+ if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
+ !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") ||
+ !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) {
+ state = stMsVc;
+ } else
+ state = stUnrecognized;
} else {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 14) {
+ } else if (state == stMsDigitComma) { // <filename>(<line>,
if (ch == ')') {
- state = 15;
+ state = stMsDotNet;
break;
} else if ((ch != ' ') && !Is0To9(ch)) {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 20) {
- if ((lineBuffer[i-1] == '\t') &&
- ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) {
- state = 24;
+ } else if (state == stCtagsStart) {
+ if ((lineBuffer[i - 1] == '\t') &&
+ ((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) {
+ state = stCtags;
break;
- } else if ((ch == '/') && (lineBuffer[i+1] == '^')) {
- state = 21;
+ } else if ((ch == '/') && (lineBuffer[i + 1] == '^')) {
+ state = stCtagsStartString;
}
- } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) {
- state = 22;
+ } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) {
+ state = stCtagsStringDollar;
break;
}
}
- if (state == 3) {
- styler.ColourTo(endPos, SCE_ERR_GCC);
- } else if ((state == 13) || (state == 14) || (state == 15)) {
- styler.ColourTo(endPos, SCE_ERR_MS);
- } else if ((state == 22) || (state == 24)) {
- styler.ColourTo(endPos, SCE_ERR_CTAG);
+ if (state == stGcc) {
+ return SCE_ERR_GCC;
+ } else if ((state == stMsVc) || (state == stMsDotNet)) {
+ return SCE_ERR_MS;
+ } else if ((state == stCtagsStringDollar) || (state == stCtags)) {
+ return SCE_ERR_CTAG;
} else {
- styler.ColourTo(endPos, SCE_ERR_DEFAULT);
+ return SCE_ERR_DEFAULT;
}
}
}
+static void ColouriseErrorListLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int endPos,
+ Accessor &styler) {
+ styler.ColourTo(endPos, RecogniseErrorListLine(lineBuffer, lengthLine));
+}
+
static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[1024];
+ char lineBuffer[10000];
styler.StartAt(startPos);
styler.StartSegment(startPos);
unsigned int linePos = 0;
** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language).
** Written by Philippe Lhoste but this is mostly a derivative of LexCPP...
**/
-// Copyright 1998-2003 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.
// Some points that distinguish from a simple C lexer:
#include "Scintilla.h"
#include "SciLexer.h"
-static inline bool IsAWordChar(const int ch) {
+static inline bool IsAWordChar(int ch) {
return ch < 0x80 && (isalnum(ch) || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
+static inline bool IsAWordStart(int ch) {
return ch < 0x80 && isalpha(ch);
}
-static inline bool IsANumberChar(const int 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) &&
}
// Do not leak onto next line
- if (initStyle == SCE_POV_STRINGEOL) {
+ if (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) {
initStyle = SCE_POV_DEFAULT;
}
- StyleContext sc(startPos, length, initStyle, styler);
short stringLen = 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
}
} else if (sc.state == SCE_POV_DIRECTIVE) {
if (!IsAWordChar(sc.ch)) {
- char s[100], *p;
+ char s[100];
+ char *p;
sc.GetCurrent(s, sizeof(s));
p = s;
// Skip # and whitespace between # and directive word
}
} else if (sc.state == SCE_POV_COMMENTLINE) {
if (sc.atLineEnd) {
- sc.SetState(SCE_POV_DEFAULT);
+ sc.ForwardSetState(SCE_POV_DEFAULT);
}
} else if (sc.state == SCE_POV_STRING) {
if (sc.ch == '\\') {
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
/** @file LexPerl.cxx
** Lexer for subset of Perl.
**/
-// Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my> 2003-2004
-// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2005 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 <stdlib.h>
#include "Scintilla.h"
#include "SciLexer.h"
-#define PERLNUM_DECIMAL 1
-#define PERLNUM_NON_DEC 2
-#define PERLNUM_FLOAT 3
-#define PERLNUM_VECTOR 4
-#define PERLNUM_V_VECTOR 5
+#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
+
+#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
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
return false;
}
-static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+static bool isPerlKeyword(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_PL_IDENTIFIER;
- if (keywords.InList(s))
- chAttr = SCE_PL_WORD;
- styler.ColourTo(end, chAttr);
- return chAttr;
+ 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';
+ return keywords.InList(s);
}
static inline bool isEndVar(char ch) {
}
static inline char actualNumStyle(int numberStyle) {
- switch (numberStyle) {
- case PERLNUM_VECTOR:
- case PERLNUM_V_VECTOR:
- return SCE_PL_STRING;
- case PERLNUM_DECIMAL:
- case PERLNUM_NON_DEC:
- case PERLNUM_FLOAT:
- default:
- return SCE_PL_NUMBER;
- }
+ 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 bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
HereDocCls() {
State = 0;
+ Quote = 0;
+ Quoted = false;
DelimiterLength = 0;
Delimiter = new char[HERE_DELIM_MAX];
Delimiter[0] = '\0';
|| state == SCE_PL_CHARACTER
|| state == SCE_PL_NUMBER
|| state == SCE_PL_IDENTIFIER
+ || state == SCE_PL_ERROR
) {
while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) {
startPos--;
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;
+ }
+
styler.StartAt(startPos);
char chPrev = styler.SafeGetCharAt(startPos - 1);
if (startPos == 0)
if (isdigit(ch) || (isdigit(chNext) &&
(ch == '.' || ch == 'v'))) {
state = SCE_PL_NUMBER;
+ backflag = BACK_NONE;
numState = PERLNUM_DECIMAL;
dotCount = 0;
if (ch == '0') { // hex,bin,octal
- if (chNext == 'x' || chNext == 'b' || isdigit(chNext)) {
- numState = PERLNUM_NON_DEC;
- }
+ if (chNext == 'x') {
+ numState = PERLNUM_HEX;
+ } else if (chNext == 'b') {
+ numState = PERLNUM_BINARY;
+ } else if (isdigit(chNext)) {
+ numState = PERLNUM_OCTAL;
+ }
+ if (numState != PERLNUM_DECIMAL) {
+ i++;
+ ch = chNext;
+ chNext = chNext2;
+ }
} else if (ch == 'v') { // vector
numState = PERLNUM_V_VECTOR;
}
} else if (iswordstart(ch)) {
- if (chPrev == '>' && styler.SafeGetCharAt(i - 2) == '-') {
- state = SCE_PL_IDENTIFIER; // part of "->" expr
- if ((!iswordchar(chNext) && chNext != '\'')
- || (chNext == '.' && chNext2 == '.')) {
- // We need that if length of word == 1!
- styler.ColourTo(i, SCE_PL_IDENTIFIER);
- state = SCE_PL_DEFAULT;
- }
- } else if (ch == 's' && !isNonQuote(chNext)) {
+ // 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;
Quote.New(2);
} else if (ch == 'm' && !isNonQuote(chNext)) {
} else if (ch == 't' && chNext == 'r' && !isNonQuote(chNext2)) {
state = SCE_PL_REGSUBST;
Quote.New(2);
- i++;
- chNext = chNext2;
+ 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;
- i++;
- chNext = chNext2;
Quote.New(1);
+ kw++;
} else if (ch == 'x' && (chNext == '=' || // repetition
- (chNext != '_' && !isalnum(chNext)) ||
- (isdigit(chPrev) && isdigit(chNext)))) {
- styler.ColourTo(i, SCE_PL_OPERATOR);
- } else {
- state = SCE_PL_WORD;
- if ((!iswordchar(chNext) && chNext != '\'')
- || (chNext == '.' && chNext2 == '.')) {
- // We need that if length of word == 1!
- // This test is copied from the SCE_PL_WORD handler.
- classifyWordPerl(styler.GetStartSegment(), i, keywords, styler);
- state = SCE_PL_DEFAULT;
- }
- }
+ (chNext != '_' && !isalnum(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 == '&')
+ // &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 ((!iswordchar(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 {
+ styler.ColourTo(i, SCE_PL_WORD);
+ state = SCE_PL_DEFAULT;
+ backflag = BACK_KEYWORD;
+ backPos = i;
+ }
+ ch = styler.SafeGetCharAt(i);
+ chNext = styler.SafeGetCharAt(i + 1);
+ // a repetition operator 'x'
+ } else if (state == SCE_PL_OPERATOR) {
+ styler.ColourTo(i, SCE_PL_OPERATOR);
+ state = SCE_PL_DEFAULT;
+ // 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
Quote.New(1);
Quote.Open(ch);
}
+ 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);
chNext = chNext2;
}
}
+ backflag = BACK_NONE;
} else if (ch == '@') {
if (isalpha(chNext) || chNext == '#' || chNext == '$'
- || chNext == '_' || chNext == '+') {
+ || chNext == '_' || chNext == '+' || chNext == '-') {
state = SCE_PL_ARRAY;
} else if (chNext != '{' && chNext != '[') {
styler.ColourTo(i, SCE_PL_ARRAY);
- i++;
- ch = ' ';
} else {
styler.ColourTo(i, SCE_PL_ARRAY);
}
+ backflag = BACK_NONE;
} else if (ch == '%') {
- if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') {
+ if (isalpha(chNext) || chNext == '#' || chNext == '$'
+ || chNext == '_' || chNext == '!' || chNext == '^') {
state = SCE_PL_HASH;
+ i++;
+ ch = chNext;
+ chNext = chNext2;
} else if (chNext == '{') {
styler.ColourTo(i, SCE_PL_HASH);
} else {
styler.ColourTo(i, SCE_PL_OPERATOR);
}
+ backflag = BACK_NONE;
} else if (ch == '*') {
- if (isalpha(chNext) || chNext == '_' || chNext == '{') {
+ char strch[2];
+ strch[0] = chNext;
+ strch[1] = '\0';
+ if (isalpha(chNext) || chNext == '_' ||
+ NULL != strstr("^/|,\\\";#%^:?<>)[]", strch)) {
state = SCE_PL_SYMBOLTABLE;
+ i++;
+ ch = chNext;
+ chNext = chNext2;
+ } else if (chNext == '{') {
+ styler.ColourTo(i, SCE_PL_SYMBOLTABLE);
} else {
if (chNext == '*') { // exponentiation
i++;
}
styler.ColourTo(i, SCE_PL_OPERATOR);
}
- } else if (ch == '/') {
+ backflag = BACK_NONE;
+ } else if (ch == '/' || (ch == '<' && chNext == '<')) {
// 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.
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;
char bkch;
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--;
bk--;
}
break;
+ case SCE_PL_SCALAR: // for $var<< case
+ hereDocScalar = true;
+ break;
// other styles uses the default, preferRE=false
case SCE_PL_WORD:
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;
}
}
- if (preferRE) {
- state = SCE_PL_REGEX;
- Quote.New(1);
- Quote.Open(ch);
- } else {
- styler.ColourTo(i, SCE_PL_OPERATOR);
- }
- } else if (ch == '<' && chNext == '<') {
- state = SCE_PL_HERE_DELIM;
- HereDoc.State = 0;
+ 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;
+ styler.ColourTo(i, SCE_PL_OPERATOR);
+ }
+ } else { // handle regexp
+ if (preferRE) {
+ state = SCE_PL_REGEX;
+ Quote.New(1);
+ Quote.Open(ch);
+ } else { // / operator
+ styler.ColourTo(i, SCE_PL_OPERATOR);
+ }
+ }
+ backflag = BACK_NONE;
} else if (ch == '<') {
// looks forward for matching > on same line
unsigned int fw = i + 1;
while (fw < lengthDoc) {
char fwch = styler.SafeGetCharAt(fw);
- if (isEOLChar(fwch) || isspacechar(fwch))
+ if (fwch == ' ') {
+ if (styler.SafeGetCharAt(fw-1) != '\\' ||
+ styler.SafeGetCharAt(fw-2) != '\\')
+ break;
+ } else if (isEOLChar(fwch) || isspacechar(fwch)) {
break;
- else if (fwch == '>') {
+ } else if (fwch == '>') {
if ((fw - i) == 2 && // '<=>' case
styler.SafeGetCharAt(fw-1) == '=') {
styler.ColourTo(fw, SCE_PL_OPERATOR);
fw++;
}
styler.ColourTo(i, SCE_PL_OPERATOR);
+ backflag = BACK_NONE;
} 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
i++;
ch = chNext;
chNext = chNext2;
+ backflag = BACK_NONE;
} else if (isPerlOperator(ch)) {
if (ch == '.' && chNext == '.') { // .. and ...
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
styler.ColourTo(i, SCE_PL_OPERATOR);
+ backflag = BACK_OPERATOR;
+ backPos = i;
} else {
// keep colouring defaults to make restart easier
styler.ColourTo(i, SCE_PL_DEFAULT);
if (chNext == '.') {
// double dot is always an operator
goto numAtEnd;
- } else if (numState == PERLNUM_NON_DEC || numState == PERLNUM_FLOAT) {
+ } else if (numState <= PERLNUM_FLOAT) {
// non-decimal number or float exponent, consume next dot
styler.ColourTo(i - 1, SCE_PL_NUMBER);
styler.ColourTo(i, SCE_PL_OPERATOR);
if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
if (isalpha(ch)) {
if (dotCount == 0) { // change to word
- state = SCE_PL_WORD;
+ state = SCE_PL_IDENTIFIER;
} else { // vector then word
goto numAtEnd;
}
if (!isdigit(ch)) { // float then word
goto numAtEnd;
}
- } else {// (numState == PERLNUM_NON_DEC)
- // allow alphanum for bin,hex,oct for now
- }
+ } 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:
state = SCE_PL_DEFAULT;
goto restartLexer;
}
- } else if (state == SCE_PL_WORD) {
- if ((!iswordchar(chNext) && chNext != '\'')
- || chNext == '.') {
- // ".." is always an operator if preceded by a SCE_PL_WORD.
- // "." never used in Perl variable names
- // Archaic Perl has quotes inside names
- if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")
- || isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__")) {
- styler.ColourTo(i, SCE_PL_DATASECTION);
- state = SCE_PL_DATASECTION;
- } else {
- classifyWordPerl(styler.GetStartSegment(), i, keywords, styler);
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- }
} else if (state == SCE_PL_IDENTIFIER) {
- if ((!iswordchar(chNext) && chNext != '\'')
- || chNext == '.') {
+ if (!iswordstart(chNext) && chNext != '\'') {
styler.ColourTo(i, SCE_PL_IDENTIFIER);
state = SCE_PL_DEFAULT;
ch = ' ';
// 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
+ if (chNext == '\'' || chNext == '"' || chNext == '`') {
+ // a quoted here-doc delimiter
i++;
ch = chNext;
chNext = chNext2;
HereDoc.Quoted = true;
- } else if (isalpha(chNext) || chNext == '_') {
- // an unquoted here-doc delimiter, no special handling
} else if (isspacechar(chNext) || isdigit(chNext) || chNext == '\\'
- || chNext == '=' || 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;
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
}
} 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);
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) {
- if (ch == '=' && isEOLChar(chPrev)) {
- 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;
+ } 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;
+ }
+ }
}
}
} else if (state == SCE_PL_SCALAR // variable names
chNext = chNext2;
}
else if (isEndVar(ch)) {
- if ((state == SCE_PL_SCALAR || state == SCE_PL_ARRAY)
- && i == (styler.GetStartSegment() + 1)) {
+ if (i == (styler.GetStartSegment() + 1)) {
// Special variable: $(, $_ etc.
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
styler.ColourTo(lengthDoc - 1, state);
}
+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];
+ int style = styler.StyleAt(i);
+ if (ch == '#' && style == SCE_PL_COMMENTLINE)
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ // Custom folding of POD and packages
+ bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+ bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelPrev = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
int styleNext = styler.StyleAt(startPos);
+ // Used at end of line to determine if the line was a package definition
+ bool isPackageLine = false;
+ bool isPodHeading = false;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && (style == SCE_PL_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
+ bool atLineStart = isEOLChar(chPrev) || 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 (ch == '{') {
levelCurrent++;
levelCurrent--;
}
}
+ // Custom POD folding
+ if (foldPOD && atLineStart) {
+ int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
+ if (style == SCE_PL_POD) {
+ if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
+ levelCurrent++;
+ else if (styler.Match(i, "=cut"))
+ levelCurrent--;
+ 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"))
+ 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;
+ }
+ }
+ // Custom package folding
+ if (foldPackage && atLineStart) {
+ if (style == SCE_PL_WORD && styler.Match(i, "package")) {
+ isPackageLine = true;
+ }
+ }
+
if (atEOL) {
int lev = levelPrev;
+ if (isPodHeading) {
+ lev = levelPrev - 1;
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ isPodHeading = false;
+ }
+ // Check if line was a package declaration
+ // because packages need "special" treatment
+ if (isPackageLine) {
+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ levelCurrent = SC_FOLDLEVELBASE + 1;
+ isPackageLine = false;
+ }
+ lev |= levelCurrent << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
}
if (!isspacechar(ch))
visibleChars++;
+ chPrev = ch;
}
// 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;
}
WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
+ } else if (keywords2.InList(s)) {
+ style = SCE_P_WORD2;
}
sc.ChangeState(style);
sc.SetState(SCE_P_DEFAULT);
kwLast = kwImport;
else
kwLast = kwOther;
- } else if (style == SCE_P_CLASSNAME) {
- kwLast = kwOther;
- } else if (style == SCE_P_DEFNAME) {
+ } else {
kwLast = kwOther;
}
}
if (sc.ch == '\r' || sc.ch == '\n') {
sc.SetState(SCE_P_DEFAULT);
}
+ } else if (sc.state == SCE_P_DECORATOR) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_P_DEFAULT);
+ }
} else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
if (sc.ch == '\\') {
if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
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))) {
unsigned int nextIndex = 0;
sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
static const char * const pythonWordListDesc[] = {
"Keywords",
+ "Highlighted identifiers",
0
};
--- /dev/null
+// Scintilla source code edit control
+/** @file LexRebol.cxx
+ ** Lexer for REBOL.
+ ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste
+ **
+ ** History:
+ ** 2005-04-07 First release.
+ ** 2005-04-10 Closing parens and brackets go now in default style
+ ** String and comment nesting should be more safe
+ **/
+// Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm>
+// 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 "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+
+static inline bool IsAWordChar(const int ch) {
+ return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
+}
+
+static inline bool IsAWordStart(const int ch, const int ch2) {
+ return ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) ||
+ (isalpha(ch) || ch == '?' || ch == '!' || ch == '\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
+}
+
+static inline bool IsAnOperator(const int ch, const int ch2, const int ch3) {
+ // One char operators
+ if (IsASpaceOrTab(ch2)) {
+ return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?';
+ }
+
+ // Two char operators
+ if (IsASpaceOrTab(ch3)) {
+ return (ch == '*' && ch2 == '*') ||
+ (ch == '/' && ch2 == '/') ||
+ (ch == '<' && (ch2 == '=' || ch2 == '>')) ||
+ (ch == '>' && ch2 == '=') ||
+ (ch == '=' && (ch2 == '=' || ch2 == '?')) ||
+ (ch == '?' && ch2 == '?');
+ }
+
+ return false;
+}
+
+static inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) {
+ return (ch == '#' && ch2 == '{') ||
+ (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) ||
+ (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' );
+}
+
+
+static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+
+ int currentLine = styler.GetLine(startPos);
+ // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string.
+ int stringLevel = 0;
+ if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) {
+ stringLevel = styler.GetLineState(currentLine - 1);
+ }
+
+ bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK;
+ int dotCount = 0;
+
+ // Do not leak onto next line
+ if (initStyle == SCE_REBOL_COMMENTLINE) {
+ initStyle = SCE_REBOL_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ if (startPos == 0) {
+ sc.SetState(SCE_REBOL_PREFACE);
+ }
+ for (; sc.More(); sc.Forward()) {
+
+ //--- What to do at line end ?
+ if (sc.atLineEnd) {
+ // Can be either inside a {} string or simply at eol
+ if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK &&
+ sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE)
+ sc.SetState(SCE_REBOL_DEFAULT);
+
+ // Update the line state, so it can be seen by next line
+ currentLine = styler.GetLine(sc.currentPos);
+ switch (sc.state) {
+ case SCE_REBOL_BRACEDSTRING:
+ case SCE_REBOL_COMMENTBLOCK:
+ // Inside a braced string, we set the line state
+ styler.SetLineState(currentLine, stringLevel);
+ break;
+ default:
+ // Reset the line state
+ styler.SetLineState(currentLine, 0);
+ break;
+ }
+
+ // continue with next char
+ continue;
+ }
+
+ //--- What to do on white-space ?
+ if (IsASpaceOrTab(sc.ch))
+ {
+ // Return to default if any of these states
+ if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER ||
+ sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR ||
+ sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE ||
+ sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME ||
+ sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE ||
+ sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Specialize state ?
+ // URL, Email look like identifier
+ if (sc.state == SCE_REBOL_IDENTIFIER)
+ {
+ if (sc.ch == ':' && !IsASpace(sc.chNext)) {
+ sc.ChangeState(SCE_REBOL_URL);
+ } else if (sc.ch == '@') {
+ sc.ChangeState(SCE_REBOL_EMAIL);
+ } else if (sc.ch == '$') {
+ sc.ChangeState(SCE_REBOL_MONEY);
+ }
+ }
+ // Words look like identifiers
+ if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) {
+ // Keywords ?
+ if (!IsAWordChar(sc.ch) || sc.Match('/')) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ blockComment = strcmp(s, "comment") == 0;
+ if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD8);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD7);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD6);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD5);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD4);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD3);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD2);
+ } else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD);
+ }
+ // Keep same style if there are refinements
+ if (!sc.Match('/')) {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+ // special numbers
+ } else if (sc.state == SCE_REBOL_NUMBER) {
+ switch (sc.ch) {
+ case 'x': sc.ChangeState(SCE_REBOL_PAIR);
+ break;
+ case ':': sc.ChangeState(SCE_REBOL_TIME);
+ break;
+ case '-':
+ case '/': sc.ChangeState(SCE_REBOL_DATE);
+ break;
+ case '.': if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE);
+ break;
+ }
+ }
+
+ //--- Determine if the current state should terminate
+ if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) {
+ if (sc.ch == '^' && sc.chNext == '\"') {
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) {
+ if (sc.ch == '}') {
+ if (--stringLevel == 0) {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.ch == '{') {
+ stringLevel++;
+ }
+ } else if (sc.state == SCE_REBOL_BINARY) {
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_TAG) {
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_PREFACE) {
+ if (sc.MatchIgnoreCase("rebol"))
+ {
+ int i;
+ for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++);
+ if (sc.GetRelative(i) == '[')
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Parens and bracket changes to default style when the current is a number
+ if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE ||
+ sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL ||
+ sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) {
+ if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Determine if a new state should be entered.
+ if (sc.state == SCE_REBOL_DEFAULT) {
+ if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) {
+ sc.SetState(SCE_REBOL_OPERATOR);
+ } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) {
+ sc.SetState(SCE_REBOL_BINARY);
+ } else if (IsAWordStart(sc.ch, sc.chNext)) {
+ sc.SetState(SCE_REBOL_IDENTIFIER);
+ } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') {
+ dotCount = 0;
+ sc.SetState(SCE_REBOL_NUMBER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_REBOL_QUOTEDSTRING);
+ } else if (sc.ch == '{') {
+ sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING);
+ ++stringLevel;
+ } else if (sc.ch == ';') {
+ sc.SetState(SCE_REBOL_COMMENTLINE);
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_REBOL_MONEY);
+ } else if (sc.ch == '%') {
+ sc.SetState(SCE_REBOL_FILE);
+ } else if (sc.ch == '<') {
+ sc.SetState(SCE_REBOL_TAG);
+ } else if (sc.ch == '#' && sc.chNext == '"') {
+ sc.SetState(SCE_REBOL_CHARACTER);
+ sc.Forward();
+ } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) {
+ sc.SetState(SCE_REBOL_ISSUE);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+
+static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; 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_REBOL_DEFAULT) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const rebolWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, "rebol", FoldRebolDoc, rebolWordListDesc);
+
#include "Scintilla.h"
#include "SciLexer.h"
-static void ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+//XXX Identical to Perl, put in common area
+static inline bool isEOLChar(char ch) {
+ return (ch == '\r') || (ch == '\n');
+}
+
+#define isSafeASCII(ch) ((unsigned int)(ch) <= 127)
+// This one's redundant, but makes for more readable code
+#define isHighBitChar(ch) ((unsigned int)(ch) > 127)
+
+static inline bool isSafeAlpha(char ch) {
+ return (isSafeASCII(ch) && isalpha(ch)) || ch == '_';
+}
+
+static inline bool isSafeAlnum(char ch) {
+ return (isSafeASCII(ch) && isalnum(ch)) || ch == '_';
+}
+
+static inline bool isSafeAlnumOrHigh(char ch) {
+ return isHighBitChar(ch) || isalnum(ch) || ch == '_';
+}
+
+static inline bool isSafeDigit(char ch) {
+ return isSafeASCII(ch) && isdigit(ch);
+}
+
+static inline bool isSafeWordcharOrHigh(char ch) {
+ return isHighBitChar(ch) || iswordchar(ch);
+}
+
+static bool inline iswhitespace(char ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+#define MAX_KEYWORD_LENGTH 200
+
+#define STYLE_MASK 63
+#define actual_style(style) (style & STYLE_MASK)
+
+static bool followsDot(unsigned int pos, Accessor &styler) {
+ styler.Flush();
+ for (; pos >= 1; --pos) {
+ int style = actual_style(styler.StyleAt(pos));
+ char ch;
+ switch (style) {
+ case SCE_RB_DEFAULT:
+ ch = styler[pos];
+ if (ch == ' ' || ch == '\t') {
+ //continue
+ } else {
+ return false;
+ }
+ break;
+
+ case SCE_RB_OPERATOR:
+ return styler[pos] == '.';
+
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+// Forward declarations
+static bool keywordIsAmbiguous(const char *prevWord);
+static bool keywordDoStartsLoop(int pos,
+ Accessor &styler);
+static bool keywordIsModifier(const char *word,
+ int pos,
+ Accessor &styler);
+
+static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100];
- bool wordIsNumber = isdigit(styler[start]) != 0;
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
+ unsigned int i, j;
+ unsigned int lim = end - start + 1; // num chars to copy
+ if (lim >= MAX_KEYWORD_LENGTH) {
+ lim = MAX_KEYWORD_LENGTH - 1;
+ }
+ for (i = start, j = 0; j < lim; i++, j++) {
+ s[j] = styler[i];
}
- char chAttr = SCE_P_IDENTIFIER;
+ s[j] = '\0';
+ int chAttr;
if (0 == strcmp(prevWord, "class"))
- chAttr = SCE_P_CLASSNAME;
+ chAttr = SCE_RB_CLASSNAME;
else if (0 == strcmp(prevWord, "module"))
- chAttr = SCE_P_CLASSNAME;
+ chAttr = SCE_RB_MODULE_NAME;
else if (0 == strcmp(prevWord, "def"))
- chAttr = SCE_P_DEFNAME;
- else if (wordIsNumber)
- chAttr = SCE_P_NUMBER;
- else if (keywords.InList(s))
- chAttr = SCE_P_WORD;
- // make sure that dot-qualifiers inside the word are lexed correct
- else for (unsigned int i = 0; i < end - start + 1; i++) {
- if (styler[start + i] == '.') {
- styler.ColourTo(start + i - 1, chAttr);
- styler.ColourTo(start + i, SCE_P_OPERATOR);
+ chAttr = SCE_RB_DEFNAME;
+ else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
+ if (keywordIsAmbiguous(s)
+ && keywordIsModifier(s, start, styler)) {
+
+ // Demoted keywords are colored as keywords,
+ // but do not affect changes in indentation.
+ //
+ // Consider the word 'if':
+ // 1. <<if test ...>> : normal
+ // 2. <<stmt if test>> : demoted
+ // 3. <<lhs = if ...>> : normal: start a new indent level
+ // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
+
+ chAttr = SCE_RB_WORD_DEMOTED;
+ } else {
+ chAttr = SCE_RB_WORD;
+ }
+ } else
+ chAttr = SCE_RB_IDENTIFIER;
+ styler.ColourTo(end, chAttr);
+ if (chAttr == SCE_RB_WORD) {
+ strcpy(prevWord, s);
+ } else {
+ prevWord[0] = 0;
+ }
+ return chAttr;
+}
+
+
+//XXX Identical to Perl, put in common area
+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++;
}
- styler.ColourTo(end, chAttr);
- strcpy(prevWord, s);
+ return true;
}
-static bool IsRbComment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]=='#';
+// Do Ruby better -- find the end of the line, work back,
+// and then check for leading white space
+
+// Precondition: the here-doc target can be indented
+static bool lookingAtHereDocDelim(Accessor &styler,
+ int pos,
+ int lengthDoc,
+ const char *HereDocDelim)
+{
+ if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {
+ return false;
+ }
+ while (--pos > 0) {
+ char ch = styler[pos];
+ if (isEOLChar(ch)) {
+ return true;
+ } else if (ch != ' ' && ch != '\t') {
+ return false;
+ }
+ }
+ return false;
}
-static bool IsRbStringStart(char ch, char chNext, char chNext2) {
- if (ch == '\'' || ch == '"')
- return true;
- if (ch == 'u' || ch == 'U') {
- if (chNext == '"' || chNext == '\'')
- return true;
- if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
- return true;
- }
- if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\''))
- return true;
+//XXX Identical to Perl, put in common area
+static char opposite(char ch) {
+ if (ch == '(')
+ return ')';
+ if (ch == '[')
+ return ']';
+ if (ch == '{')
+ return '}';
+ if (ch == '<')
+ return '>';
+ return ch;
+}
+
+// Null transitions when we see we've reached the end
+// and need to relex the curr char.
- return false;
+static void redo_char(int &i, char &ch, char &chNext, char &chNext2,
+ int &state) {
+ i--;
+ chNext2 = chNext;
+ chNext = ch;
+ state = SCE_RB_DEFAULT;
}
-static bool IsRbWordStart(char ch, char chNext, char chNext2) {
- return (iswordchar(ch) && !IsRbStringStart(ch, chNext, chNext2));
+static void advance_char(int &i, char &ch, char &chNext, char &chNext2) {
+ i++;
+ ch = chNext;
+ chNext = 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 GetRbStringState(Accessor &styler, int i, int *nextIndex) {
- char ch = styler.SafeGetCharAt(i);
- char chNext = styler.SafeGetCharAt(i + 1);
+// precondition: startPos points to one after the EOL char
+static bool currLineContainsHereDelims(int& startPos,
+ Accessor &styler) {
+ if (startPos <= 1)
+ return false;
- // Advance beyond r, u, or ur prefix, 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') {
- if (chNext == 'r' || chNext == 'R')
- i += 2;
- else
- i += 1;
- ch = styler.SafeGetCharAt(i);
- chNext = styler.SafeGetCharAt(i + 1);
- }
+ int pos;
+ for (pos = startPos - 1; pos > 0; pos--) {
+ char ch = styler.SafeGetCharAt(pos);
+ if (isEOLChar(ch)) {
+ // Leave the pointers where they are -- there are no
+ // here doc delims on the current line, even if
+ // the EOL isn't default style
+
+ return false;
+ } else {
+ styler.Flush();
+ if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {
+ break;
+ }
+ }
+ }
+ if (pos == 0) {
+ return false;
+ }
+ // Update the pointers so we don't have to re-analyze the string
+ startPos = pos;
+ return true;
+}
- if (ch != '"' && ch != '\'') {
- *nextIndex = i + 1;
- return SCE_P_DEFAULT;
- }
- if (i>0 && styler.SafeGetCharAt(i-1) == '$') {
- *nextIndex = i + 1;
- return SCE_P_DEFAULT;
- }
+static bool isEmptyLine(int pos,
+ Accessor &styler) {
+ int spaceFlags = 0;
+ int lineCurrent = styler.GetLine(pos);
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+ return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;
+}
- if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {
- *nextIndex = i + 3;
+static bool RE_CanFollowKeyword(const char *keyword) {
+ if (!strcmp(keyword, "and")
+ || !strcmp(keyword, "begin")
+ || !strcmp(keyword, "break")
+ || !strcmp(keyword, "case")
+ || !strcmp(keyword, "do")
+ || !strcmp(keyword, "else")
+ || !strcmp(keyword, "elsif")
+ || !strcmp(keyword, "if")
+ || !strcmp(keyword, "next")
+ || !strcmp(keyword, "return")
+ || !strcmp(keyword, "when")
+ || !strcmp(keyword, "unless")
+ || !strcmp(keyword, "until")
+ || !strcmp(keyword, "not")
+ || !strcmp(keyword, "or")) {
+ return true;
+ }
+ return false;
+}
- if (ch == '"')
- return SCE_P_TRIPLEDOUBLE;
- else
- return SCE_P_TRIPLE;
- } else {
- *nextIndex = i + 1;
+// Look at chars up to but not including endPos
+// Don't look at styles in case we're looking forward
- if (ch == '"')
- return SCE_P_STRING;
- else
- return SCE_P_CHARACTER;
- }
+static int skipWhitespace(int startPos,
+ int endPos,
+ Accessor &styler) {
+ for (int i = startPos; i < endPos; i++) {
+ if (!iswhitespace(styler[i])) {
+ return i;
+ }
+ }
+ return endPos;
+}
+
+// This routine looks for false positives like
+// undef foo, <<
+// There aren't too many.
+//
+// iPrev points to the start of <<
+
+static bool sureThisIsHeredoc(int iPrev,
+ Accessor &styler,
+ char *prevWord) {
+
+ // Not so fast, since Ruby's so dynamic. Check the context
+ // to make sure we're OK.
+ int prevStyle;
+ int lineStart = styler.GetLine(iPrev);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+
+ // Find the first word after some whitespace
+ int firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler);
+ if (firstWordPosn >= iPrev) {
+ // Have something like {^ <<}
+ //XXX Look at the first previous non-comment non-white line
+ // to establish the context. Not too likely though.
+ return true;
+ } else {
+ switch (prevStyle = styler.StyleAt(firstWordPosn)) {
+ case SCE_RB_WORD:
+ case SCE_RB_WORD_DEMOTED:
+ case SCE_RB_IDENTIFIER:
+ break;
+ default:
+ return true;
+ }
+ }
+ int firstWordEndPosn = firstWordPosn;
+ char *dst = prevWord;
+ for (;;) {
+ if (firstWordEndPosn >= iPrev ||
+ styler.StyleAt(firstWordEndPosn) != prevStyle) {
+ *dst = 0;
+ break;
+ }
+ *dst++ = styler[firstWordEndPosn];
+ firstWordEndPosn += 1;
+ }
+ //XXX Write a style-aware thing to regex scintilla buffer objects
+ if (!strcmp(prevWord, "undef")
+ || !strcmp(prevWord, "def")
+ || !strcmp(prevWord, "alias")) {
+ // These keywords are what we were looking for
+ return false;
+ }
+ return true;
+}
+
+// Routine that saves us from allocating a buffer for the here-doc target
+// targetEndPos points one past the end of the current target
+static bool haveTargetMatch(int currPos,
+ int lengthDoc,
+ int targetStartPos,
+ int targetEndPos,
+ Accessor &styler) {
+ if (lengthDoc - currPos < targetEndPos - targetStartPos) {
+ return false;
+ }
+ int i, j;
+ for (i = targetStartPos, j = currPos;
+ i < targetEndPos && j < lengthDoc;
+ i++, j++) {
+ if (styler[i] != styler[j]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// We need a check because the form
+// [identifier] <<[target]
+// is ambiguous. The Ruby lexer/parser resolves it by
+// looking to see if [identifier] names a variable or a
+// function. If it's the first, it's the start of a here-doc.
+// If it's a var, it's an operator. This lexer doesn't
+// maintain a symbol table, so it looks ahead to see what's
+// going on, in cases where we have
+// ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target]
+//
+// If there's no occurrence of [target] on a line, assume we don't.
+
+// return true == yes, we have no heredocs
+
+static bool sureThisIsNotHeredoc(int lt2StartPos,
+ Accessor &styler) {
+ int prevStyle;
+ // Use full document, not just part we're styling
+ int lengthDoc = styler.Length();
+ int lineStart = styler.GetLine(lt2StartPos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ const bool definitely_not_a_here_doc = true;
+ const bool looks_like_a_here_doc = false;
+
+ // Find the first word after some whitespace
+ int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);
+ if (firstWordPosn >= lt2StartPos) {
+ return definitely_not_a_here_doc;
+ }
+ prevStyle = styler.StyleAt(firstWordPosn);
+ // If we have '<<' following a keyword, it's not a heredoc
+ if (prevStyle != SCE_RB_IDENTIFIER) {
+ return definitely_not_a_here_doc;
+ }
+ int newStyle = prevStyle;
+ // Some compilers incorrectly warn about uninit newStyle
+ for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
+ // Inner loop looks at the name
+ for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
+ newStyle = styler.StyleAt(firstWordPosn);
+ if (newStyle != prevStyle) {
+ break;
+ }
+ }
+ // Do we have '::' or '.'?
+ if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) {
+ char ch = styler[firstWordPosn];
+ if (ch == '.') {
+ // yes
+ } else if (ch == ':') {
+ if (styler.StyleAt(++firstWordPosn) != SCE_RB_OPERATOR) {
+ return definitely_not_a_here_doc;
+ } else if (styler[firstWordPosn] != ':') {
+ return definitely_not_a_here_doc;
+ }
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ // Skip next batch of white-space
+ firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);
+ if (firstWordPosn != lt2StartPos) {
+ // Have [[^ws[identifier]ws[*something_else*]ws<<
+ return definitely_not_a_here_doc;
+ }
+ // OK, now 'j' will point to the current spot moving ahead
+ int j = firstWordPosn + 1;
+ if (styler.StyleAt(j) != SCE_RB_OPERATOR || styler[j] != '<') {
+ // This shouldn't happen
+ return definitely_not_a_here_doc;
+ }
+ int nextLineStartPosn = styler.LineStart(lineStart + 1);
+ if (nextLineStartPosn >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ }
+ j = skipWhitespace(j + 1, nextLineStartPosn, styler);
+ if (j >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ }
+ bool allow_indent;
+ int target_start, target_end;
+ // From this point on no more styling, since we're looking ahead
+ if (styler[j] == '-') {
+ allow_indent = true;
+ j++;
+ } else {
+ allow_indent = false;
+ }
+
+ // Allow for quoted targets.
+ char target_quote = 0;
+ switch (styler[j]) {
+ case '\'':
+ case '"':
+ case '`':
+ target_quote = styler[j];
+ j += 1;
+ }
+
+ if (isSafeAlnum(styler[j])) {
+ // Init target_end because some compilers think it won't
+ // be initialized by the time it's used
+ target_start = target_end = j;
+ j++;
+ } else {
+ return definitely_not_a_here_doc;
+ }
+ for (; j < lengthDoc; j++) {
+ if (!isSafeAlnum(styler[j])) {
+ if (target_quote && styler[j] != target_quote) {
+ // unquoted end
+ return definitely_not_a_here_doc;
+ }
+
+ // And for now make sure that it's a newline
+ // don't handle arbitrary expressions yet
+
+ target_end = j;
+ if (target_quote) {
+ // Now we can move to the character after the string delimiter.
+ j += 1;
+ }
+ j = skipWhitespace(j, lengthDoc, styler);
+ if (j >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ } else {
+ char ch = styler[j];
+ if (ch == '#' || isEOLChar(ch)) {
+ // This is OK, so break and continue;
+ break;
+ } else {
+ return definitely_not_a_here_doc;
+ }
+ }
+ }
+ }
+
+ // Just look at the start of each line
+ int last_line = styler.GetLine(lengthDoc - 1);
+ // But don't go too far
+ if (last_line > lineStart + 50) {
+ last_line = lineStart + 50;
+ }
+ for (int line_num = lineStart + 1; line_num <= last_line; line_num++) {
+ if (allow_indent) {
+ j = skipWhitespace(styler.LineStart(line_num), lengthDoc, styler);
+ } else {
+ j = styler.LineStart(line_num);
+ }
+ // target_end is one past the end
+ if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) {
+ // We got it
+ return looks_like_a_here_doc;
+ }
+ }
+ return definitely_not_a_here_doc;
+}
+
+//todo: if we aren't looking at a stdio character,
+// move to the start of the first line that is not in a
+// multi-line construct
+
+static void synchronizeDocStart(unsigned int& startPos,
+ int &length,
+ int &initStyle,
+ Accessor &styler,
+ bool skipWhiteSpace=false) {
+
+ styler.Flush();
+ int style = actual_style(styler.StyleAt(startPos));
+ switch (style) {
+ case SCE_RB_STDIN:
+ case SCE_RB_STDOUT:
+ case SCE_RB_STDERR:
+ // Don't do anything else with these.
+ return;
+ }
+
+ int pos = startPos;
+ // Quick way to characterize each line
+ int lineStart;
+ for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {
+ // Now look at the style before the previous line's EOL
+ pos = styler.LineStart(lineStart) - 1;
+ if (pos <= 10) {
+ lineStart = 0;
+ break;
+ }
+ char ch = styler.SafeGetCharAt(pos);
+ char chPrev = styler.SafeGetCharAt(pos - 1);
+ if (ch == '\n' && chPrev == '\r') {
+ pos--;
+ }
+ if (styler.SafeGetCharAt(pos - 1) == '\\') {
+ // Continuation line -- keep going
+ } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {
+ // Part of multi-line construct -- keep going
+ } else if (currLineContainsHereDelims(pos, styler)) {
+ // Keep going, with pos and length now pointing
+ // at the end of the here-doc delimiter
+ } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {
+ // Keep going
+ } else {
+ break;
+ }
+ }
+ pos = styler.LineStart(lineStart);
+ length += (startPos - pos);
+ startPos = pos;
+ initStyle = SCE_RB_DEFAULT;
}
static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
- int lengthDoc = startPos + length;
+ // Lexer for Ruby 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];
- // Backtrack to previous line in case need to fix its tab whinging
- if (startPos > 0) {
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0) {
- startPos = styler.LineStart(lineCurrent-1);
- if (startPos == 0)
- initStyle = SCE_P_DEFAULT;
- else
- initStyle = styler.StyleAt(startPos-1);
+ class HereDocCls {
+ public:
+ int State;
+ // States
+ // 0: '<<' encountered
+ // 1: collect the delimiter
+ // 1b: text between the end of the delimiter and the EOL
+ // 2: here doc text (lines after the delimiter)
+ char Quote; // the char after '<<'
+ bool Quoted; // true if Quote in ('\'','"','`')
+ int DelimiterLength; // strlen(Delimiter)
+ char Delimiter[256]; // the Delimiter, limit of 256: from Perl
+ bool CanBeIndented;
+ HereDocCls() {
+ State = 0;
+ DelimiterLength = 0;
+ Delimiter[0] = '\0';
+ CanBeIndented = false;
}
- }
+ };
+ HereDocCls HereDoc;
- // Ruby uses a different mask because bad indentation is marked by oring with 32
- styler.StartAt(startPos, 127);
+ class QuoteCls {
+ public:
+ int Count;
+ char Up;
+ char Down;
+ QuoteCls() {
+ this->New();
+ }
+ void New() {
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ }
+ void Open(char u) {
+ Count++;
+ Up = u;
+ Down = opposite(Up);
+ }
+ };
+ QuoteCls Quote;
- WordList &keywords = *keywordlists[0];
+ int numDots = 0; // For numbers --
+ // Don't start lexing in the middle of a num
+
+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
+ false);
- int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
- char prevWord[200];
+ bool preferRE = true;
+ int state = initStyle;
+ int lengthDoc = startPos + length;
+
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
prevWord[0] = '\0';
if (length == 0)
- return ;
+ return;
- int state = initStyle & 31;
-
- int nextIndex = 0;
- char chPrev = ' ';
- char chPrev2 = ' ';
- char chNext = styler[startPos];
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
+ char chNext = styler.SafeGetCharAt(startPos);
+ // Ruby uses a different mask because bad indentation is marked by oring with 32
+ styler.StartAt(startPos, 127);
styler.StartSegment(startPos);
- bool atStartLine = true;
- int spaceFlags = 0;
- for (int i = startPos; i < lengthDoc; i++) {
-
- if (atStartLine) {
- char chBad = static_cast<char>(64);
- char chGood = static_cast<char>(0);
- char chFlags = chGood;
- if (whingeLevel == 1) {
- chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
- } else if (whingeLevel == 2) {
- chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
- } else if (whingeLevel == 3) {
- chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
- } else if (whingeLevel == 4) {
- chFlags = (spaceFlags & wsTab) ? chBad : chGood;
- }
- styler.SetFlags(chFlags, static_cast<char>(state));
- atStartLine = false;
- }
+ static int q_states[] = {SCE_RB_STRING_Q,
+ SCE_RB_STRING_QQ,
+ SCE_RB_STRING_QR,
+ SCE_RB_STRING_QW,
+ SCE_RB_STRING_QW,
+ SCE_RB_STRING_QX};
+ static const char* q_chars = "qQrwWx";
+
+ for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
char chNext2 = styler.SafeGetCharAt(i + 2);
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
- if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {
- // Perform colourisation of white space and triple quoted strings at end of each line to allow
- // tab marking to work inside white space and triple quoted strings
- styler.ColourTo(i, state);
- }
- atStartLine = true;
- }
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
+ if (styler.IsLeadByte(ch)) {
+ chNext = chNext2;
chPrev = ' ';
- chPrev2 = ' ';
i += 1;
continue;
}
+
+ // skip on DOS/Windows
+ //No, don't, because some things will get tagged on,
+ // so we won't recognize keywords, for example
+#if 0
+ if (ch == '\r' && chNext == '\n') {
+ continue;
+ }
+#endif
+
+ if (HereDoc.State == 1 && isEOLChar(ch)) {
+ // Begin of here-doc (the line after the here-doc delimiter):
+ HereDoc.State = 2;
+ styler.ColourTo(i-1, state);
+ // Don't check for a missing quote, just jump into
+ // the here-doc state
+ state = SCE_RB_HERE_Q;
+ }
- if (state == SCE_P_STRINGEOL) {
- if (ch != '\r' && ch != '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_P_DEFAULT;
- }
- }
- if (state == SCE_P_DEFAULT) {
- if (IsRbWordStart(ch, chNext, chNext2)) {
- styler.ColourTo(i - 1, state);
- state = SCE_P_WORD;
+ // Regular transitions
+ if (state == SCE_RB_DEFAULT) {
+ if (isSafeDigit(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_NUMBER;
+ numDots = 0;
+ } else if (isHighBitChar(ch) || iswordstart(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_WORD;
} else if (ch == '#') {
styler.ColourTo(i - 1, state);
- state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
- } else if (ch == '=' && chNext == 'b') {
+ state = SCE_RB_COMMENTLINE;
+ } else if (ch == '=') {
// =begin indicates the start of a comment (doc) block
- if(styler.SafeGetCharAt(i + 2) == 'e' && styler.SafeGetCharAt(i + 3) == 'g' && styler.SafeGetCharAt(i + 4) == 'i' && styler.SafeGetCharAt(i + 5) == 'n') {
+ 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))) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_POD;
+ } else {
styler.ColourTo(i - 1, state);
- state = SCE_P_TRIPLEDOUBLE; //SCE_C_COMMENT;
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ preferRE = true;
}
- } else if (IsRbStringStart(ch, chNext, chNext2)) {
+ } else if (ch == '"') {
styler.ColourTo(i - 1, state);
- state = GetRbStringState(styler, i, &nextIndex);
- if (nextIndex != i + 1) {
- i = nextIndex - 1;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (isoperator(ch)) {
+ state = SCE_RB_STRING;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_CHARACTER;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '`') {
styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_P_OPERATOR);
- }
- } else if (state == SCE_P_WORD) {
- if (!iswordchar(ch)) {
- ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
- state = SCE_P_DEFAULT;
- if (ch == '#') {
- state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
- } else if (IsRbStringStart(ch, chNext, chNext2)) {
- styler.ColourTo(i - 1, state);
- state = GetRbStringState(styler, i, &nextIndex);
- if (nextIndex != i + 1) {
- i = nextIndex - 1;
- ch = ' ';
- chPrev = ' ';
+ state = SCE_RB_BACKTICKS;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '@') {
+ // Instance or class var
+ styler.ColourTo(i - 1, state);
+ if (chNext == '@') {
+ state = SCE_RB_CLASS_VAR;
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ state = SCE_RB_INSTANCE_VAR;
+ }
+ } else if (ch == '$') {
+ // Check for a builtin global
+ styler.ColourTo(i - 1, state);
+ // Recognize it bit by bit
+ state = SCE_RB_GLOBAL;
+ } else if (ch == '/' && preferRE) {
+ // Ambigous operator
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_REGEX;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '<' && chNext == '<' && chNext2 != '=') {
+
+ // Recognise the '<<' symbol - either a here document or a binary op
+ styler.ColourTo(i - 1, state);
+ i++;
+ chNext = chNext2;
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+
+ if (! (strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) {
+ // It's definitely not a here-doc,
+ // based on Ruby's lexer/parser in the
+ // heredoc_identifier routine.
+ // Nothing else to do.
+ } else if (preferRE) {
+ if (sureThisIsHeredoc(i - 1, styler, prevWord)) {
+ state = SCE_RB_HERE_DELIM;
+ HereDoc.State = 0;
+ }
+ // else leave it in default state
+ } else {
+ if (sureThisIsNotHeredoc(i - 1, styler)) {
+ // leave state as default
+ // We don't have all the heuristics Perl has for indications
+ // of a here-doc, because '<<' is overloadable and used
+ // for so many other classes.
+ } else {
+ state = SCE_RB_HERE_DELIM;
+ HereDoc.State = 0;
+ }
+ }
+ preferRE = (state != SCE_RB_HERE_DELIM);
+ } else if (ch == ':') {
+ styler.ColourTo(i - 1, state);
+ if (chNext == ':') {
+ // Mark "::" as an operator, not symbol start
+ styler.ColourTo(i + 1, SCE_RB_OPERATOR);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else if (isSafeWordcharOrHigh(chNext)) {
+ state = SCE_RB_SYMBOL;
+ } else if (strchr("[*!~+-*/%=<>&^|", chNext)) {
+ // Do the operator analysis in-line, looking ahead
+ // Based on the table in pickaxe 2nd ed., page 339
+ bool doColoring = true;
+ switch (chNext) {
+ case '[':
+ if (chNext2 == ']' ) {
+ char ch_tmp = styler.SafeGetCharAt(i + 3);
+ if (ch_tmp == '=') {
+ i += 3;
+ ch = ch_tmp;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ i += 2;
+ ch = chNext2;
+ chNext = ch_tmp;
+ }
+ } else {
+ doColoring = false;
+ }
+ break;
+
+ case '*':
+ if (chNext2 == '*') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ case '!':
+ if (chNext2 == '=' || chNext2 == '~') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ case '<':
+ if (chNext2 == '<') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext2 == '=') {
+ char ch_tmp = styler.SafeGetCharAt(i + 3);
+ if (ch_tmp == '>') { // <=> operator
+ i += 3;
+ ch = ch_tmp;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ i += 2;
+ ch = chNext2;
+ chNext = ch_tmp;
+ }
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ default:
+ // Simple one-character operators
+ advance_char(i, ch, chNext, chNext2);
+ break;
+ }
+ if (doColoring) {
+ styler.ColourTo(i, SCE_RB_SYMBOL);
+ state = SCE_RB_DEFAULT;
+ }
+ } else if (!preferRE) {
+ // Don't color symbol strings (yet)
+ // Just color the ":" and color rest as string
+ styler.ColourTo(i, SCE_RB_SYMBOL);
+ state = SCE_RB_DEFAULT;
+ } else {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ state = SCE_RB_DEFAULT;
+ preferRE = true;
+ }
+ } else if (ch == '%') {
+ styler.ColourTo(i - 1, state);
+ bool have_string = false;
+ if (strchr(q_chars, chNext) && !isSafeWordcharOrHigh(chNext2)) {
+ Quote.New();
+ const char *hit = strchr(q_chars, chNext);
+ if (hit != NULL) {
+ state = q_states[hit - q_chars];
+ Quote.Open(chNext2);
+ i += 2;
+ ch = chNext2;
chNext = styler.SafeGetCharAt(i + 1);
+ have_string = true;
+ }
+ } else if (!isSafeWordcharOrHigh(chNext)) {
+ // Ruby doesn't allow high bit chars here,
+ // but the editor host might
+ state = SCE_RB_STRING_QQ;
+ Quote.Open(chNext);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ have_string = true;
+ }
+ if (!have_string) {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ // stay in default
+ preferRE = true;
+ }
+ } else if (isoperator(ch) || ch == '.') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ // If we're ending an expression or block,
+ // assume it ends an object, and the ambivalent
+ // constructs are binary operators
+ //
+ // So if we don't have one of these chars,
+ // we aren't ending an object exp'n, and ops
+ // like : << / are unary operators.
+
+ preferRE = (strchr(")}].", ch) == NULL);
+ // Stay in default state
+ } else if (isEOLChar(ch)) {
+ // Make sure it's a true line-end, with no backslash
+ if ((ch == '\r' || (ch == '\n' && chPrev != '\r'))
+ && chPrev != '\\') {
+ // Assume we've hit the end of the statement.
+ preferRE = true;
+ }
+ }
+ } else if (state == SCE_RB_WORD) {
+ if (ch == '.' || !isSafeWordcharOrHigh(ch)) {
+ // Words include x? in all contexts,
+ // and <letters>= after either 'def' or a dot
+ // Move along until a complete word is on our left
+
+ // Default accessor treats '.' as word-chars,
+ // but we don't for now.
+
+ if (ch == '='
+ && isSafeWordcharOrHigh(chPrev)
+ && (chNext == '('
+ || strchr(" \t\n\r", chNext) != NULL)
+ && (!strcmp(prevWord, "def")
+ || followsDot(styler.GetStartSegment(), styler))) {
+ // <name>= is a name only when being def'd -- Get it the next time
+ // This means that <name>=<name> is always lexed as
+ // <name>, (op, =), <name>
+ } else if ((ch == '?' || ch == '!')
+ && isSafeWordcharOrHigh(chPrev)
+ && !isSafeWordcharOrHigh(chNext)) {
+ // <name>? is a name -- Get it the next time
+ // But <name>?<name> is always lexed as
+ // <name>, (op, ?), <name>
+ // Same with <name>! to indicate a method that
+ // modifies its target
+ } else if (isEOLChar(ch)
+ && isMatch(styler, lengthDoc, i - 7, "__END__")) {
+ styler.ColourTo(i, SCE_RB_DATASECTION);
+ state = SCE_RB_DATASECTION;
+ // No need to handle this state -- we'll just move to the end
+ preferRE = false;
+ } else {
+ int wordStartPos = styler.GetStartSegment();
+ int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord);
+ switch (word_style) {
+ case SCE_RB_WORD:
+ preferRE = RE_CanFollowKeyword(prevWord);
+ break;
+
+ case SCE_RB_WORD_DEMOTED:
+ preferRE = true;
+ break;
+
+ case SCE_RB_IDENTIFIER:
+ if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
+ preferRE = true;
+ } else if (isEOLChar(ch)) {
+ preferRE = true;
+ } else {
+ preferRE = false;
+ }
+ break;
+ default:
+ preferRE = false;
+ }
+ if (ch == '.') {
+ // We might be redefining an operator-method
+ preferRE = false;
+ }
+ // And if it's the first
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ }
+ }
+ } else if (state == SCE_RB_NUMBER) {
+ if (isSafeAlnumOrHigh(ch) || ch == '_') {
+ // Keep going
+ } else if (ch == '.' && ++numDots == 1) {
+ // Keep going
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_COMMENTLINE) {
+ if (isEOLChar(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ // Use whatever setting we had going into the comment
+ }
+ } else if (state == SCE_RB_HERE_DELIM) {
+ // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
+ // Slightly different: if we find an immediate '-',
+ // the target can appear indented.
+
+ if (HereDoc.State == 0) { // '<<' encountered
+ HereDoc.State = 1;
+ HereDoc.DelimiterLength = 0;
+ if (ch == '-') {
+ HereDoc.CanBeIndented = true;
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ HereDoc.CanBeIndented = false;
+ }
+ if (isEOLChar(ch)) {
+ // Bail out of doing a here doc if there's no target
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else {
+ HereDoc.Quote = ch;
+
+ if (ch == '\'' || ch == '"' || ch == '`') {
+ HereDoc.Quoted = true;
+ HereDoc.Delimiter[0] = '\0';
+ } else {
+ HereDoc.Quoted = false;
+ HereDoc.Delimiter[0] = ch;
+ HereDoc.Delimiter[1] = '\0';
+ HereDoc.DelimiterLength = 1;
+ }
+ }
+ } else if (HereDoc.State == 1) { // collect the delimiter
+ if (isEOLChar(ch)) {
+ // End the quote now, and go back for more
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ i--;
+ chNext = ch;
+ chNext2 = chNext;
+ preferRE = false;
+ } else if (HereDoc.Quoted) {
+ if (ch == HereDoc.Quote) { // closing quote => end of delimiter
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else {
+ if (ch == '\\' && !isEOLChar(chNext)) {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ }
+ } else { // an unquoted here-doc delimiter
+ if (isSafeAlnumOrHigh(ch) || ch == '_') {
+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state);
+ preferRE = false;
}
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_P_OPERATOR);
- }
- }
- } else {
- if (state == SCE_P_COMMENTLINE || state == SCE_P_COMMENTBLOCK) {
- if (ch == '\r' || ch == '\n') {
+ }
+ if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {
styler.ColourTo(i - 1, state);
- state = SCE_P_DEFAULT;
- }
- } else if (state == SCE_P_STRING) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourTo(i - 1, state);
- state = SCE_P_STRINGEOL;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
+ state = SCE_RB_ERROR;
+ preferRE = false;
}
- } else if (state == SCE_P_CHARACTER) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourTo(i - 1, state);
- state = SCE_P_STRINGEOL;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
+ }
+ } else if (state == SCE_RB_HERE_Q) {
+ // Not needed: HereDoc.State == 2
+ // Indentable here docs: look backwards
+ // Non-indentable: look forwards, like in Perl
+ //
+ // Why: so we can quickly resolve things like <<-" abc"
+
+ if (!HereDoc.CanBeIndented) {
+ if (isEOLChar(chPrev)
+ && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
+ styler.ColourTo(i - 1, state);
+ i += HereDoc.DelimiterLength - 1;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (isEOLChar(chNext)) {
+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
+ state = SCE_RB_DEFAULT;
+ HereDoc.State = 0;
+ preferRE = false;
+ }
+ // Otherwise we skipped through the here doc faster.
+ }
+ } else if (isEOLChar(chNext)
+ && lookingAtHereDocDelim(styler,
+ i - HereDoc.DelimiterLength + 1,
+ lengthDoc,
+ HereDoc.Delimiter)) {
+ styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state);
+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ HereDoc.State = 0;
+ }
+ } else if (state == SCE_RB_CLASS_VAR
+ || state == SCE_RB_INSTANCE_VAR
+ || state == SCE_RB_SYMBOL) {
+ if (!isSafeWordcharOrHigh(ch)) {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_GLOBAL) {
+ if (!isSafeWordcharOrHigh(ch)) {
+ // handle special globals here as well
+ if (chPrev == '$') {
+ if (ch == '-') {
+ // Include the next char, like $-a
+ advance_char(i, ch, chNext, chNext2);
+ }
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ }
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_POD) {
+ // PODs end with ^=end\s, -- any whitespace can follow =end
+ if (strchr(" \t\n\r", ch) != NULL
+ && i > 5
+ && isEOLChar(styler[i - 5])
+ && isMatch(styler, lengthDoc, i - 4, "=end")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {
+ if (ch == '\\' && Quote.Up != '\\') {
+ // Skip one
+ advance_char(i, ch, chNext, chNext2);
+ } else if (ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ // Include the options
+ while (isSafeAlpha(chNext)) {
+ i++;
ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
- }
- } else if (state == SCE_P_TRIPLE) {
- if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
- }
- } else if (state == SCE_P_TRIPLEDOUBLE) {
- // =end terminates the comment block
- if (ch == 'd' && chPrev == 'n' && chPrev2 == 'e') {
- if (styler.SafeGetCharAt(i - 3) == '=') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
- }
- }
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (ch == Quote.Up) {
+ // Only if close quoter != open quoter
+ Quote.Count++;
+
+ } else if (ch == '#' ) {
+ //todo: distinguish comments from pound chars
+ // for now, handle as comment
+ styler.ColourTo(i - 1, state);
+ bool inEscape = false;
+ while (++i < lengthDoc) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\\') {
+ inEscape = true;
+ } else if (isEOLChar(ch)) {
+ // Comment inside a regex
+ styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);
+ break;
+ } else if (inEscape) {
+ inEscape = false; // don't look at char
+ } else if (ch == Quote.Down) {
+ // Have the regular handler deal with this
+ // to get trailing modifiers.
+ i--;
+ ch = styler[i];
+ break;
+ }
+ }
+ chNext = styler.SafeGetCharAt(i + 1);
+ chNext2 = styler.SafeGetCharAt(i + 2);
+ }
+ // Quotes of all kinds...
+ } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
+ state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
+ state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
+ state == SCE_RB_BACKTICKS) {
+ if (!Quote.Down && !isspacechar(ch)) {
+ Quote.Open(ch);
+ } else if (ch == '\\' && Quote.Up != '\\') {
+ //Riddle me this: Is it safe to skip *every* escaped char?
+ advance_char(i, ch, chNext, chNext2);
+ } else if (ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (ch == Quote.Up) {
+ Quote.Count++;
+ }
+ }
+
+ if (state == SCE_RB_ERROR) {
+ break;
+ }
+ chPrev = ch;
+ }
+ if (state == SCE_RB_WORD) {
+ // We've ended on a word, possibly at EOF, and need to
+ // classify it.
+ (void) ClassifyWordRb(styler.GetStartSegment(), lengthDoc - 1, keywords, styler, prevWord);
+ } else {
+ styler.ColourTo(lengthDoc - 1, state);
+ }
+}
+
+// Helper functions for folding, disambiguation keywords
+// Assert that there are no high-bit chars
+
+static void getPrevWord(int pos,
+ char *prevWord,
+ Accessor &styler,
+ int word_state)
+{
+ int i;
+ styler.Flush();
+ for (i = pos - 1; i > 0; i--) {
+ if (actual_style(styler.StyleAt(i)) != word_state) {
+ i++;
+ break;
+ }
+ }
+ if (i < pos - MAX_KEYWORD_LENGTH) // overflow
+ i = pos - MAX_KEYWORD_LENGTH;
+ char *dst = prevWord;
+ for (; i <= pos; i++) {
+ *dst++ = styler[i];
+ }
+ *dst = 0;
+}
+
+static bool keywordIsAmbiguous(const char *prevWord)
+{
+ // Order from most likely used to least likely
+ // Lots of ways to do a loop in Ruby besides 'while/until'
+ if (!strcmp(prevWord, "if")
+ || !strcmp(prevWord, "do")
+ || !strcmp(prevWord, "while")
+ || !strcmp(prevWord, "unless")
+ || !strcmp(prevWord, "until")) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Demote keywords in the following conditions:
+// if, while, unless, until modify a statement
+// do after a while or until, as a noise word (like then after if)
+
+static bool keywordIsModifier(const char *word,
+ int pos,
+ Accessor &styler)
+{
+ if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
+ return keywordDoStartsLoop(pos, styler);
+ }
+ char ch;
+ int style = SCE_RB_DEFAULT;
+ int lineStart = styler.GetLine(pos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ while (--pos >= lineStartPosn) {
+ style = actual_style(styler.StyleAt(pos));
+ if (style == SCE_RB_DEFAULT) {
+ if (iswhitespace(ch = styler[pos])) {
+ //continue
+ } else if (ch == '\r' || ch == '\n') {
+ // Scintilla's LineStart() and GetLine() routines aren't
+ // platform-independent, so if we have text prepared with
+ // a different system we can't rely on it.
+ return false;
}
+ } else {
+ break;
}
- chPrev2 = chPrev;
- chPrev = ch;
- }
- if (state == SCE_P_WORD) {
- ClassifyWordRb(styler.GetStartSegment(), lengthDoc-1, keywords, styler, prevWord);
- } else {
- styler.ColourTo(lengthDoc-1, state);
- }
+ }
+ if (pos < lineStartPosn) {
+ return false; //XXX not quite right if the prev line is a continuation
+ }
+ // First things where the action is unambiguous
+ switch (style) {
+ case SCE_RB_DEFAULT:
+ case SCE_RB_COMMENTLINE:
+ case SCE_RB_POD:
+ case SCE_RB_CLASSNAME:
+ case SCE_RB_DEFNAME:
+ case SCE_RB_MODULE_NAME:
+ return false;
+ case SCE_RB_OPERATOR:
+ break;
+ case SCE_RB_WORD:
+ // Watch out for uses of 'else if'
+ //XXX: Make a list of other keywords where 'if' isn't a modifier
+ // and can appear legitimately
+ // Formulate this to avoid warnings from most compilers
+ if (strcmp(word, "if") == 0) {
+ char prevWord[MAX_KEYWORD_LENGTH + 1];
+ getPrevWord(pos, prevWord, styler, SCE_RB_WORD);
+ return strcmp(prevWord, "else") != 0;
+ }
+ return true;
+ default:
+ return true;
+ }
+ // Assume that if the keyword follows an operator,
+ // usually it's a block assignment, like
+ // a << if x then y else z
+
+ ch = styler[pos];
+ switch (ch) {
+ case ')':
+ case ']':
+ case '}':
+ return true;
+ default:
+ return false;
+ }
}
-static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- int lengthDoc = startPos + length;
+#define WHILE_BACKWARDS "elihw"
+#define UNTIL_BACKWARDS "litnu"
+
+// Nothing fancy -- look to see if we follow a while/until somewhere
+// on the current line
+
+static bool keywordDoStartsLoop(int pos,
+ Accessor &styler)
+{
+ char ch;
+ int style;
+ int lineStart = styler.GetLine(pos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ while (--pos >= lineStartPosn) {
+ style = actual_style(styler.StyleAt(pos));
+ if (style == SCE_RB_DEFAULT) {
+ if ((ch = styler[pos]) == '\r' || ch == '\n') {
+ // Scintilla's LineStart() and GetLine() routines aren't
+ // platform-independent, so if we have text prepared with
+ // a different system we can't rely on it.
+ return false;
+ }
+ } else if (style == SCE_RB_WORD) {
+ // Check for while or until, but write the word in backwards
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ char *dst = prevWord;
+ int wordLen = 0;
+ int start_word;
+ for (start_word = pos;
+ start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD;
+ start_word--) {
+ if (++wordLen < MAX_KEYWORD_LENGTH) {
+ *dst++ = styler[start_word];
+ }
+ }
+ *dst = 0;
+ // Did we see our keyword?
+ if (!strcmp(prevWord, WHILE_BACKWARDS)
+ || !strcmp(prevWord, UNTIL_BACKWARDS)) {
+ return true;
+ }
+ // We can move pos to the beginning of the keyword, and then
+ // accept another decrement, as we can never have two contiguous
+ // keywords:
+ // word1 word2
+ // ^
+ // <- move to start_word
+ // ^
+ // <- loop decrement
+ // ^ # pointing to end of word1 is fine
+ pos = start_word;
+ }
+ }
+ return false;
+}
+
+/*
+ * Folding Ruby
+ *
+ * The language is quite complex to analyze without a full parse.
+ * For example, this line shouldn't affect fold level:
+ *
+ * print "hello" if feeling_friendly?
+ *
+ * Neither should this:
+ *
+ * print "hello" \
+ * if feeling_friendly?
+ *
+ *
+ * But this should:
+ *
+ * if feeling_friendly? #++
+ * print "hello" \
+ * print "goodbye"
+ * end #--
+ *
+ * So we cheat, by actually looking at the existing indentation
+ * levels for each line, and just echoing it back. Like Python.
+ * Then if we get better at it, we'll take braces into consideration,
+ * which always affect folding levels.
+
+ * How the keywords should work:
+ * No effect:
+ * __FILE__ __LINE__ BEGIN END alias and
+ * defined? false in nil not or self super then
+ * true undef
+
+ * Always increment:
+ * begin class def do for module when {
+ *
+ * Always decrement:
+ * end }
+ *
+ * Increment if these start a statement
+ * if unless until while -- do nothing if they're modifiers
- // Backtrack to previous line in case need to fix its fold status
+ * These end a block if there's no modifier, but don't bother
+ * break next redo retry return yield
+ *
+ * These temporarily de-indent, but re-indent
+ * case else elsif ensure rescue
+ *
+ * This means that the folder reflects indentation rather
+ * than setting it. The language-service updates indentation
+ * when users type return and finishes entering de-denters.
+ *
+ * Later offer to fold POD, here-docs, strings, and blocks of comments
+ */
+
+static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
+ false);
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- if (startPos == 0)
- initStyle = SCE_P_DEFAULT;
- else
- initStyle = styler.StyleAt(startPos-1);
- }
- }
- int state = initStyle & 31;
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsRbComment);
- if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
- indentCurrent |= SC_FOLDLEVELWHITEFLAG;
+ int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)
+ & SC_FOLDLEVELNUMBERMASK
+ & ~SC_FOLDLEVELBASE);
+ int levelCurrent = levelPrev;
char chNext = styler[startPos];
- for (int i = startPos; i < lengthDoc; i++) {
+ int styleNext = styler.StyleAt(startPos);
+ int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1);
+ bool buffer_ends_with_eol = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
- int style = styler.StyleAt(i) & 31;
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsRbComment);
- if ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE))
- indentNext |= SC_FOLDLEVELWHITEFLAG;
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsRbComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_RB_COMMENTLINE) {
+ if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
+ if (chNext == '{') {
+ levelCurrent++;
+ } else if (chNext == '}') {
+ levelCurrent--;
}
+ }
+ } else if (style == SCE_RB_OPERATOR) {
+ if (strchr("[{(", ch)) {
+ levelCurrent++;
+ } else if (strchr(")}]", ch)) {
+ // Don't decrement below 0
+ if (levelCurrent > 0)
+ levelCurrent--;
}
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
+ } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {
+ // Look at the keyword on the left and decide what to do
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ prevWord[0] = 0;
+ getPrevWord(i, prevWord, styler, SCE_RB_WORD);
+ if (!strcmp(prevWord, "end")) {
+ // Don't decrement below 0
+ if (levelCurrent > 0)
+ levelCurrent--;
+ } else if ( !strcmp(prevWord, "if")
+ || !strcmp(prevWord, "def")
+ || !strcmp(prevWord, "class")
+ || !strcmp(prevWord, "module")
+ || !strcmp(prevWord, "begin")
+ || !strcmp(prevWord, "case")
+ || !strcmp(prevWord, "do")
+ || !strcmp(prevWord, "while")
+ || !strcmp(prevWord, "unless")
+ || !strcmp(prevWord, "until")
+ || !strcmp(prevWord, "for")
+ ) {
+ levelCurrent++;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);
lineCurrent++;
- }
- }
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ buffer_ends_with_eol = true;
+ } else if (!isspacechar(ch)) {
+ visibleChars++;
+ buffer_ends_with_eol = false;
+ }
+ }
+ // 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) {
+ lineCurrent++;
+ int new_lev = levelCurrent;
+ if (visibleChars == 0 && foldCompact)
+ new_lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ new_lev |= SC_FOLDLEVELHEADERFLAG;
+ levelCurrent = new_lev;
+ }
+ styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE);
}
static const char * const rubyWordListDesc[] = {
// Scintilla source code edit control
/** @file LexSQL.cxx
- ** Lexer for SQL.
+ ** Lexer for SQL, including PL/SQL and SQL*Plus.
**/
-// Copyright 1998-2002 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 "PropSet.h"
#include "Accessor.h"
+#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
-static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- s[i + 1] = '\0';
- }
- char chAttr = SCE_C_IDENTIFIER;
- if (wordIsNumber)
- chAttr = SCE_C_NUMBER;
- else {
- if (keywords.InList(s))
- chAttr = SCE_C_WORD;
- }
- styler.ColourTo(end, chAttr);
+static 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 void ColouriseSQLDoc(unsigned int startPos, int length,
- int initStyle, WordList *keywordlists[], Accessor &styler) {
+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 == '+');
+}
- WordList &keywords = *keywordlists[0];
- styler.StartAt(startPos);
+static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords1 = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &kw_pldoc = *keywordlists[2];
+ WordList &kw_sqlplus = *keywordlists[3];
+ WordList &kw_user1 = *keywordlists[4];
+ WordList &kw_user2 = *keywordlists[5];
+ WordList &kw_user3 = *keywordlists[6];
+ WordList &kw_user4 = *keywordlists[7];
+
+ StyleContext sc(startPos, length, initStyle, styler);
- bool fold = styler.GetPropertyInt("fold") != 0;
bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+ bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
+ bool fold = styler.GetPropertyInt("fold") != 0;
int lineCurrent = styler.GetLine(startPos);
- int spaceFlags = 0;
-
- int state = initStyle;
- char chPrev = ' ';
- char chNext = styler[startPos];
- styler.StartSegment(startPos);
- unsigned int lengthDoc = startPos + length;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ for (; sc.More(); sc.Forward()) {
+ // Fold based on indentation
+ if (sc.atLineStart) {
+ int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
- int lev = indentCurrent;
+ int level = indentCurrent;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
+ level |= SC_FOLDLEVELHEADERFLAG;
}
}
if (fold) {
- styler.SetLevel(lineCurrent, lev);
+ styler.SetLevel(lineCurrent, level);
}
}
- 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_SQL_OPERATOR:
+ sc.SetState(SCE_SQL_DEFAULT);
+ break;
+ case SCE_SQL_NUMBER:
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_IDENTIFIER:
+ if (!IsAWordChar(sc.ch)) {
+ int nextState = SCE_SQL_DEFAULT;
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords1.InList(s)) {
+ sc.ChangeState(SCE_SQL_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_SQL_WORD2);
+ } else if (kw_sqlplus.InListAbbreviated(s, '~')) {
+ sc.ChangeState(SCE_SQL_SQLPLUS);
+ if (strncmp(s, "rem", 3) == 0) {
+ nextState = SCE_SQL_SQLPLUS_COMMENT;
+ } else if (strncmp(s, "pro", 3) == 0) {
+ nextState = SCE_SQL_SQLPLUS_PROMPT;
+ }
+ } else if (kw_user1.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER1);
+ } else if (kw_user2.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER2);
+ } else if (kw_user3.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER3);
+ } else if (kw_user4.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER4);
+ }
+ sc.SetState(nextState);
+ }
+ break;
+ case SCE_SQL_QUOTEDIDENTIFIER:
+ if (sc.ch == 0x60) {
+ if (sc.chNext == 0x60) {
+ sc.Forward(); // Ignore it
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SQL_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // 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_SQL_COMMENTDOC;
+ sc.SetState(SCE_SQL_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_SQL_COMMENTLINE:
+ case SCE_SQL_COMMENTLINEDOC:
+ case SCE_SQL_SQLPLUS_COMMENT:
+ case SCE_SQL_SQLPLUS_PROMPT:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ } else if (!IsADoxygenChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {
+ sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_SQL_CHARACTER:
+ if (sqlBackslashEscapes && sc.ch == '\\') {
+ sc.Forward();
+ } else if (sc.ch == '\'') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SQL_STRING:
+ if (sc.ch == '\\') {
+ // Escape sequence
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
}
- if (state == SCE_C_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_C_WORD;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_COMMENTLINE;
- } else if (ch == '#') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_COMMENTLINEDOC;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_CHARACTER;
- } else if (ch == '"') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_STRING;
- } else if (isoperator(ch)) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_C_OPERATOR);
- }
- } else if (state == SCE_C_WORD) {
- if (!iswordchar(ch)) {
- classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler);
- state = SCE_C_DEFAULT;
- if (ch == '/' && chNext == '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '#') {
- state = SCE_C_COMMENTLINEDOC;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (ch == '"') {
- state = SCE_C_STRING;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_C_OPERATOR);
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_SQL_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_SQL_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_SQL_IDENTIFIER);
+ } else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
+ sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
+ sc.SetState(SCE_SQL_COMMENTDOC);
+ } else {
+ sc.SetState(SCE_SQL_COMMENT);
}
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('-', '-')) {
+ // MySQL requires a space or control char after --
+ // http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
+ // Perhaps we should enforce that with proper property:
+//~ } else if (sc.Match("-- ")) {
+ sc.SetState(SCE_SQL_COMMENTLINE);
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_SQL_COMMENTLINEDOC);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_SQL_CHARACTER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_SQL_STRING);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_SQL_OPERATOR);
}
- } else {
- if (state == SCE_C_COMMENT) {
- if (ch == '/' && chPrev == '*') {
- if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
- (styler.GetStartSegment() == startPos)))) {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- }
+ }
+ }
+ sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_SQL_COMMENT ||
+ style == SCE_SQL_COMMENTDOC ||
+ style == SCE_SQL_COMMENTDOCKEYWORD ||
+ style == SCE_SQL_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.
+static void FoldSQLDoc(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;
+ 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) & SC_FOLDLEVELNUMBERMASK;
+ }
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ bool endFound = false;
+ 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 (foldComment && (style == SCE_SQL_COMMENTLINE)) {
+ // MySQL needs -- comments to be followed by space or control char
+ if ((ch == '-') && (chNext == '-')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ char chNext3 = styler.SafeGetCharAt(i + 3);
+ if (chNext2 == '{' || chNext3 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}' || chNext3 == '}') {
+ levelNext--;
}
- } else if (state == SCE_C_COMMENTLINE || state == SCE_C_COMMENTLINEDOC) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_DEFAULT;
+ }
+ }
+ if (style == SCE_SQL_OPERATOR) {
+ if (ch == '(') {
+ levelNext++;
+ } else if (ch == ')') {
+ levelNext--;
+ }
+ }
+ // If new keyword (cannot trigger on elseif or nullif, does less tests)
+ if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
+ const int MAX_KW_LEN = 6; // Maximum length of folding keywords
+ char s[MAX_KW_LEN + 2];
+ unsigned int j = 0;
+ for (; j < MAX_KW_LEN + 1; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
}
- } else if (state == SCE_C_CHARACTER) {
- if (sqlBackslashEscapes && ch == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- } else if (ch == '\'') {
- if (chNext == '\'') {
- i++;
- } else {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- i++;
- }
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
+ s[j] = static_cast<char>(tolower(styler[i + j]));
+ }
+ if (j == MAX_KW_LEN + 1) {
+ // Keyword too long, don't test it
+ s[0] = '\0';
+ } else {
+ s[j] = '\0';
+ }
+ if (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0) {
+ if (endFound) {
+ // ignore
+ endFound = false;
+ } else {
+ levelNext++;
}
- } else if (state == SCE_C_STRING) {
- if (ch == '"') {
- if (chNext == '"') {
- i++;
- } else {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- i++;
- }
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
+ } 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) {
+ endFound = true;
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE) {
+ levelNext = SC_FOLDLEVELBASE;
}
}
- if (state == SCE_C_DEFAULT) { // One of the above succeeded
- if (ch == '/' && chNext == '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '#') {
- state = SCE_C_COMMENTLINEDOC;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (ch == '"') {
- state = SCE_C_STRING;
- } else if (iswordstart(ch)) {
- state = SCE_C_WORD;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_C_OPERATOR);
- }
+ }
+ if (atEOL) {
+ int level = levelCurrent;
+ if (visibleChars == 0 && foldCompact) {
+ // Empty line
+ level |= SC_FOLDLEVELWHITEFLAG;
}
+ if (visibleChars > 0 && levelNext > levelCurrent) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (level != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, level);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+ endFound = false;
+ }
+ if (!isspacechar(ch)) {
+ visibleChars++;
}
- chPrev = ch;
}
- styler.ColourTo(lengthDoc - 1, state);
}
static const char * const sqlWordListDesc[] = {
"Keywords",
+ "Database Objects",
+ "PLDoc",
+ "SQL*Plus",
+ "User Keywords 1",
+ "User Keywords 2",
+ "User Keywords 3",
+ "User Keywords 4",
0
};
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
+LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", FoldSQLDoc, sqlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSmalltalk.cxx
+ ** Lexer for Smalltalk language.
+ ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com
+ **/
+// 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 "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+/*
+| lexTable classificationBlock charClasses |
+charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
+lexTable := ByteArray new: 128.
+classificationBlock := [ :charClass :chars |
+ | flag |
+ flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
+ chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
+
+classificationBlock
+ value: #DecDigit value: '0123456789';
+ value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ value: #Special value: '()[]{};.^:';
+ value: #BinSel value: '~@%&*-+=|\/,<>?!';
+ value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
+
+((String new: 500) streamContents: [ :stream |
+ stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
+ lexTable keysAndValuesDo: [ :index :value |
+ ((index - 1) rem: 16) == 0 ifTrue: [
+ stream crLf; tab]
+ ifFalse: [
+ stream space].
+ stream print: value.
+ index ~= 256 ifTrue: [
+ stream nextPut: $,]].
+ stream crLf; nextPutAll: '};'; crLf.
+
+ charClasses keysAndValuesDo: [ :index :name |
+ stream
+ crLf;
+ nextPutAll: (
+ ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
+ expandMacrosWith: name with: (1 bitShift: (index - 1)))
+ ]]) edit
+*/
+
+// autogenerated {{{{
+
+static int ClassificationTable[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16,
+ 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2,
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0,
+};
+
+static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}
+static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}
+static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}
+static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}
+static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}
+// autogenerated }}}}
+
+static inline bool isAlphaNumeric(int ch) {
+ return isDecDigit(ch) || isLetter(ch);
+}
+
+static inline bool isDigitOfRadix(int ch, int radix)
+{
+ if (isDecDigit(ch))
+ return (ch - '0') < radix;
+ else if (!isUpper(ch))
+ return false;
+ else
+ return (ch - 'A' + 10) < radix;
+}
+
+static inline void skipComment(StyleContext& sc)
+{
+ while (sc.More() && sc.ch != '\"')
+ sc.Forward();
+}
+
+static inline void skipString(StyleContext& sc)
+{
+ while (sc.More()) {
+ if (sc.ch == '\'') {
+ if (sc.chNext != '\'')
+ return;
+ sc.Forward();
+ }
+ sc.Forward();
+ }
+}
+
+static void handleHash(StyleContext& sc)
+{
+ if (isSpecial(sc.chNext)) {
+ sc.SetState(SCE_ST_SPECIAL);
+ return;
+ }
+
+ sc.SetState(SCE_ST_SYMBOL);
+ sc.Forward();
+ if (sc.ch == '\'') {
+ sc.Forward();
+ skipString(sc);
+ }
+ else {
+ if (isLetter(sc.ch)) {
+ while (isAlphaNumeric(sc.chNext) || sc.chNext == ':')
+ sc.Forward();
+ }
+ else if (isBinSel(sc.ch)) {
+ while (isBinSel(sc.chNext))
+ sc.Forward();
+ }
+ }
+}
+
+static inline void handleSpecial(StyleContext& sc)
+{
+ if (sc.ch == ':' && sc.chNext == '=') {
+ sc.SetState(SCE_ST_ASSIGN);
+ sc.Forward();
+ }
+ else {
+ if (sc.ch == '^')
+ sc.SetState(SCE_ST_RETURN);
+ else
+ sc.SetState(SCE_ST_SPECIAL);
+ }
+}
+
+static inline void skipInt(StyleContext& sc, int radix)
+{
+ while (isDigitOfRadix(sc.chNext, radix))
+ sc.Forward();
+}
+
+static void handleNumeric(StyleContext& sc)
+{
+ char num[256];
+ int nl;
+ int radix;
+
+ sc.SetState(SCE_ST_NUMBER);
+ num[0] = static_cast<char>(sc.ch);
+ nl = 1;
+ while (isDecDigit(sc.chNext)) {
+ num[nl++] = static_cast<char>(sc.chNext);
+ sc.Forward();
+ if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check
+ break;
+ }
+ if (sc.chNext == 'r') {
+ num[nl] = 0;
+ if (num[0] == '-')
+ radix = atoi(num + 1);
+ else
+ radix = atoi(num);
+ sc.Forward();
+ if (sc.chNext == '-')
+ sc.Forward();
+ skipInt(sc, radix);
+ }
+ else
+ radix = 10;
+ if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix))
+ return;
+ sc.Forward();
+ skipInt(sc, radix);
+ if (sc.chNext == 's') {
+ // ScaledDecimal
+ sc.Forward();
+ while (isDecDigit(sc.chNext))
+ sc.Forward();
+ return;
+ }
+ else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q')
+ return;
+ sc.Forward();
+ if (sc.chNext == '+' || sc.chNext == '-')
+ sc.Forward();
+ skipInt(sc, radix);
+}
+
+static inline void handleBinSel(StyleContext& sc)
+{
+ sc.SetState(SCE_ST_BINARY);
+ while (isBinSel(sc.chNext))
+ sc.Forward();
+}
+
+static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
+{
+ char ident[256];
+ int il;
+ int state;
+ bool doubleColonPresent;
+
+ sc.SetState(SCE_ST_DEFAULT);
+
+ ident[0] = static_cast<char>(sc.ch);
+ il = 1;
+ while (isAlphaNumeric(sc.chNext)) {
+ ident[il++] = static_cast<char>(sc.chNext);
+ sc.Forward();
+ if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check
+ break;
+ }
+
+ if (sc.chNext == ':') {
+ doubleColonPresent = true;
+ ident[il++] = ':';
+ sc.Forward();
+ }
+ else
+ doubleColonPresent = false;
+ ident[il] = 0;
+
+ if (specialSelectorList->InList(ident))
+ state = SCE_ST_SPEC_SEL;
+ else if (doubleColonPresent)
+ state = SCE_ST_KWSEND;
+ else if (isUpper(ident[0]))
+ state = SCE_ST_GLOBAL;
+ else {
+ if (!strcmp(ident, "self"))
+ state = SCE_ST_SELF;
+ else if (!strcmp(ident, "super"))
+ state = SCE_ST_SUPER;
+ else if (!strcmp(ident, "nil"))
+ state = SCE_ST_NIL;
+ else if (!strcmp(ident, "true") || !strcmp(ident, "false"))
+ state = SCE_ST_BOOL;
+ else
+ state = SCE_ST_DEFAULT;
+ }
+
+ sc.ChangeState(state);
+}
+
+static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *wordLists[], Accessor &styler)
+{
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ if (initStyle == SCE_ST_COMMENT) {
+ skipComment(sc);
+ if (sc.More())
+ sc.Forward();
+ }
+ else if (initStyle == SCE_ST_STRING) {
+ skipString(sc);
+ if (sc.More())
+ sc.Forward();
+ }
+
+ for (; sc.More(); sc.Forward()) {
+ int ch;
+
+ ch = sc.ch;
+ if (ch == '\"') {
+ sc.SetState(SCE_ST_COMMENT);
+ sc.Forward();
+ skipComment(sc);
+ }
+ else if (ch == '\'') {
+ sc.SetState(SCE_ST_STRING);
+ sc.Forward();
+ skipString(sc);
+ }
+ else if (ch == '#')
+ handleHash(sc);
+ else if (ch == '$') {
+ sc.SetState(SCE_ST_CHARACTER);
+ sc.Forward();
+ }
+ else if (isSpecial(ch))
+ handleSpecial(sc);
+ else if (isDecDigit(ch))
+ handleNumeric(sc);
+ else if (isLetter(ch))
+ handleLetter(sc, wordLists[0]);
+ else if (isBinSel(ch)) {
+ if (ch == '-' && isDecDigit(sc.chNext))
+ handleNumeric(sc);
+ else
+ handleBinSel(sc);
+ }
+ else
+ sc.SetState(SCE_ST_DEFAULT);
+ }
+ sc.Complete();
+}
+
+static const char* const smalltalkWordListDesc[] = {
+ "Special selectors",
+ 0
+};
+
+LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexTADS3.cxx
+ ** Lexer for TADS3.
+ **/
+/* Copyright 2005 by Michael Cartmell
+ * Parts copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+ * In particular FoldTADS3Doc is derived from FoldCppDoc
+ * The License.txt file describes the conditions under which this software may
+ * be distributed.
+ */
+
+/*
+ * TADS3 is a language designed by Michael J. Roberts for the writing of text
+ * based games. TADS comes from Text Adventure Development System. It has good
+ * support for the processing and outputting of formatted text and much of a
+ * TADS program listing consists of strings.
+ *
+ * TADS has two types of strings, those enclosed in single quotes (') and those
+ * enclosed in double quotes ("). These strings have different symantics and
+ * can be given different highlighting if desired.
+ *
+ * There can be embedded within both types of strings html tags
+ * ( <tag key=value> ), library directives ( <.directive> ), and message
+ * parameters ( {The doctor's/his} ).
+ *
+ * Double quoted strings can also contain interpolated expressions
+ * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions
+ * may themselves contain single or double quoted strings, although the double
+ * quoted strings may not contain interpolated expressions.
+ *
+ * These embedded constructs influence the output and formatting and are an
+ * important part of a program and require highlighting.
+ *
+ * LINKS
+ * http://www.tads.org/
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static const int T3_SINGLE_QUOTE = 1;
+static const int T3_INT_EXPRESSION = 2;
+
+static inline bool IsEOL(const int ch, const int chNext) {
+ return (ch == '\r' && chNext != '\n') || (ch == '\n');
+}
+
+static inline bool IsASpaceOrTab(const int ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+static inline bool IsATADS3Operator(const int ch) {
+ return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
+ || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
+ || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'
+ || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'
+ || ch == '@' || ch == '&' || ch == '~';
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return isalnum(ch) || ch == '_' || ch == '.';
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return isalpha(ch) || ch == '_';
+}
+
+static inline bool IsAHexDigit(const int ch) {
+ int lch = tolower(ch);
+ return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c'
+ || lch == 'd' || lch == 'e' || lch == 'f';
+}
+
+static inline bool IsAnHTMLChar(int ch) {
+ return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';
+}
+
+static inline bool IsADirectiveChar(int ch) {
+ return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/';
+}
+
+static inline bool IsANumberStart(StyleContext &sc) {
+ return isdigit(sc.ch)
+ || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext));
+}
+
+inline static void ColouriseTADS3Operator(StyleContext &sc) {
+ int initState = sc.state;
+ sc.SetState(SCE_T3_OPERATOR);
+ sc.ForwardSetState(initState);
+}
+
+static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = sc.ch;
+ if (endState == SCE_T3_HTML_STRING) {
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '"';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ chQuote = '\'';
+ } else {
+ endState = SCE_T3_D_STRING;
+ chQuote = '\'';
+ }
+ } else {
+ sc.SetState(SCE_T3_HTML_STRING);
+ sc.Forward();
+ }
+ int chString = chQuote == '"'? '\'': '"';
+
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.ch == chString) {
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))
+ || sc.Match('\\', static_cast<char>(chString))) {
+ sc.Forward(2);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3HTMLTagStart(StyleContext &sc) {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.Forward();
+ if (sc.ch == '/') {
+ sc.Forward();
+ }
+ while (IsAnHTMLChar(sc.ch)) {
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = '"';
+ int chString = '\'';
+ switch (endState) {
+ case SCE_T3_S_STRING:
+ ColouriseTADS3HTMLTagStart(sc);
+ sc.SetState(SCE_T3_HTML_DEFAULT);
+ chQuote = '\'';
+ chString = '"';
+ break;
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ ColouriseTADS3HTMLTagStart(sc);
+ sc.SetState(SCE_T3_HTML_DEFAULT);
+ break;
+ case SCE_T3_HTML_DEFAULT:
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ chString = '"';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ } else {
+ endState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.Match('/', '>')) {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.ch == '>') {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.ch == chString) {
+ ColouriseTADSHTMLString(sc, lineState);
+ } else if (sc.ch == '=') {
+ ColouriseTADS3Operator(sc);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3Keyword(StyleContext &sc,
+ WordList *keywordlists[], unsigned int endPos) {
+ char s[250];
+ WordList &keywords = *keywordlists[0];
+ WordList &userwords1 = *keywordlists[1];
+ WordList &userwords2 = *keywordlists[2];
+ WordList &userwords3 = *keywordlists[3];
+ int initState = sc.state;
+ sc.SetState(SCE_T3_IDENTIFIER);
+ while (sc.More() && (IsAWordChar(sc.ch))) {
+ sc.Forward();
+ }
+ sc.GetCurrent(s, sizeof(s));
+ if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
+ // have to find if "in" is next
+ int n = 1;
+ while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))
+ n++;
+ if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {
+ sc.Forward(n+2);
+ sc.ChangeState(SCE_T3_KEYWORD);
+ }
+ } else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_T3_KEYWORD);
+ } else if (userwords3.InList(s)) {
+ sc.ChangeState(SCE_T3_USER3);
+ } else if (userwords2.InList(s)) {
+ sc.ChangeState(SCE_T3_USER2);
+ } else if (userwords1.InList(s)) {
+ sc.ChangeState(SCE_T3_USER1);
+ }
+ sc.SetState(initState);
+}
+
+static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = '"';
+ switch (endState) {
+ case SCE_T3_S_STRING:
+ sc.SetState(SCE_T3_MSG_PARAM);
+ sc.Forward();
+ chQuote = '\'';
+ break;
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ sc.SetState(SCE_T3_MSG_PARAM);
+ sc.Forward();
+ break;
+ case SCE_T3_MSG_PARAM:
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ } else {
+ endState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+ while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == '\\') {
+ sc.Forward();
+ }
+ sc.Forward();
+ }
+ if (sc.ch == chQuote) {
+ sc.SetState(endState);
+ } else {
+ sc.ForwardSetState(endState);
+ }
+}
+
+static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {
+ int initState = sc.state;
+ int chQuote = '"';
+ switch (initState) {
+ case SCE_T3_S_STRING:
+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
+ sc.Forward(2);
+ chQuote = '\'';
+ break;
+ case SCE_T3_D_STRING:
+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
+ sc.Forward(2);
+ break;
+ case SCE_T3_LIB_DIRECTIVE:
+ if (lineState&T3_SINGLE_QUOTE) {
+ initState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ } else {
+ initState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+ while (sc.More() && IsADirectiveChar(sc.ch)) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ sc.Forward();
+ };
+ if (sc.ch == '>' || !sc.More()) {
+ sc.ForwardSetState(initState);
+ } else if (sc.ch == chQuote) {
+ sc.SetState(initState);
+ } else {
+ sc.ChangeState(initState);
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3String(StyleContext &sc, int &lineState) {
+ int chQuote = sc.ch;
+ int endState = sc.state;
+ switch (sc.state) {
+ case SCE_T3_DEFAULT:
+ case SCE_T3_X_DEFAULT:
+ if (chQuote == '"') {
+ if (sc.state == SCE_T3_DEFAULT) {
+ sc.SetState(SCE_T3_D_STRING);
+ } else {
+ sc.SetState(SCE_T3_X_STRING);
+ }
+ lineState &= ~T3_SINGLE_QUOTE;
+ } else {
+ sc.SetState(SCE_T3_S_STRING);
+ lineState |= T3_SINGLE_QUOTE;
+ }
+ sc.Forward();
+ break;
+ case SCE_T3_S_STRING:
+ chQuote = '\'';
+ endState = lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;
+ break;
+ case SCE_T3_D_STRING:
+ chQuote = '"';
+ endState = SCE_T3_DEFAULT;
+ break;
+ case SCE_T3_X_STRING:
+ chQuote = '"';
+ endState = SCE_T3_X_DEFAULT;
+ break;
+ }
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
+ lineState |= T3_INT_EXPRESSION;
+ sc.SetState(SCE_T3_X_DEFAULT);
+ sc.Forward(2);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))) {
+ sc.Forward(2);
+ } else if (sc.ch == '{') {
+ ColouriseTADS3MsgParam(sc, lineState);
+ } else if (sc.Match('<', '.')) {
+ ColouriseTADS3LibDirective(sc, lineState);
+ } else if (sc.ch == '<') {
+ ColouriseTADS3HTMLTag(sc, lineState);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3Comment(StyleContext &sc, int endState) {
+ sc.SetState(SCE_T3_BLOCK_COMMENT);
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.Match('*', '/')) {
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ sc.Forward();
+ }
+}
+
+static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
+ sc.SetState(initState);
+ while (sc.More()) {
+ if (sc.ch == '\\') {
+ sc.Forward();
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ }
+ if (IsEOL(sc.ch, sc.chNext)) {
+ sc.SetState(endState);
+ return;
+ }
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3Number(StyleContext &sc) {
+ int endState = sc.state;
+ bool inHexNumber = false;
+ bool seenE = false;
+ bool seenDot = sc.ch == '.';
+ sc.SetState(SCE_T3_NUMBER);
+ if (sc.More()) {
+ sc.Forward();
+ }
+ if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {
+ inHexNumber = true;
+ sc.Forward();
+ }
+ while (sc.More()) {
+ if (inHexNumber) {
+ if (!IsAHexDigit(sc.ch)) {
+ break;
+ }
+ } else if (!isdigit(sc.ch)) {
+ if (!seenE && tolower(sc.ch) == 'e') {
+ seenE = true;
+ seenDot = true;
+ if (sc.chNext == '+' || sc.chNext == '-') {
+ sc.Forward();
+ }
+ } else if (!seenDot && sc.ch == '.') {
+ seenDot = true;
+ } else {
+ break;
+ }
+ }
+ sc.Forward();
+ }
+ sc.SetState(endState);
+}
+
+static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ int visibleChars = 0;
+ int bracketLevel = 0;
+ int lineState = 0;
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ lineState = styler.GetLineState(lineCurrent-1);
+ }
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ while (sc.More()) {
+
+ if (IsEOL(sc.ch, sc.chNext)) {
+ styler.SetLineState(lineCurrent, lineState);
+ lineCurrent++;
+ visibleChars = 0;
+ sc.Forward();
+ if (sc.ch == '\n') {
+ sc.Forward();
+ }
+ }
+
+ switch(sc.state) {
+ case SCE_T3_PREPROCESSOR:
+ case SCE_T3_LINE_COMMENT:
+ ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
+ break;
+ case SCE_T3_S_STRING:
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ break;
+ case SCE_T3_MSG_PARAM:
+ ColouriseTADS3MsgParam(sc, lineState);
+ break;
+ case SCE_T3_LIB_DIRECTIVE:
+ ColouriseTADS3LibDirective(sc, lineState);
+ break;
+ case SCE_T3_HTML_DEFAULT:
+ ColouriseTADS3HTMLTag(sc, lineState);
+ break;
+ case SCE_T3_HTML_STRING:
+ ColouriseTADSHTMLString(sc, lineState);
+ break;
+ case SCE_T3_BLOCK_COMMENT:
+ ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
+ break;
+ case SCE_T3_DEFAULT:
+ case SCE_T3_X_DEFAULT:
+ if (IsASpaceOrTab(sc.ch)) {
+ sc.Forward();
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
+ } else if (sc.Match('/', '*')) {
+ ColouriseTADS3Comment(sc, sc.state);
+ visibleChars++;
+ } else if (sc.Match('/', '/')) {
+ ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
+ } else if (sc.ch == '"') {
+ bracketLevel = 0;
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ } else if (sc.ch == '\'') {
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
+ && sc.Match('>', '>')) {
+ sc.Forward(2);
+ sc.SetState(SCE_T3_D_STRING);
+ lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION);
+ } else if (IsATADS3Operator(sc.ch)) {
+ if (sc.state == SCE_T3_X_DEFAULT) {
+ if (sc.ch == '(') {
+ bracketLevel++;
+ } else if (sc.ch == ')') {
+ bracketLevel--;
+ }
+ }
+ ColouriseTADS3Operator(sc);
+ visibleChars++;
+ } else if (IsANumberStart(sc)) {
+ ColouriseTADS3Number(sc);
+ visibleChars++;
+ } else if (IsAWordStart(sc.ch)) {
+ ColouriseTADS3Keyword(sc, keywordlists, endPos);
+ visibleChars++;
+ } else if (sc.Match("...")) {
+ sc.SetState(SCE_T3_IDENTIFIER);
+ sc.Forward(3);
+ sc.SetState(SCE_T3_DEFAULT);
+ } else {
+ sc.Forward();
+ visibleChars++;
+ }
+ break;
+ default:
+ sc.SetState(SCE_T3_DEFAULT);
+ sc.Forward();
+ }
+ }
+ sc.Complete();
+}
+
+/*
+ TADS3 has two styles of top level block (TLB). Eg
+
+ // default style
+ silverKey : Key 'small silver key' 'small silver key'
+ "A small key glints in the sunlight. "
+ ;
+
+ and
+
+ silverKey : Key {
+ 'small silver key'
+ 'small silver key'
+ "A small key glints in the sunlight. "
+ }
+
+ Some constructs mandate one or the other, but usually the author has may choose
+ either.
+
+ T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
+ seen and is also used to match the closing ';' of the default style.
+
+ T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
+ what characters may be seen without incrementing the block level. The general
+ pattern is identifier <punc> identifier, acceptable punctuation characters
+ are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
+ characters are syntactically correct, eg parentheses match. A ')' always
+ signifies the start of a block. We just need to check if it is followed by a
+ '{', in which case we let the brace handling code handle the folding level.
+
+ expectingIdentifier == false && expectingIdentifier == false
+ Before the start of a TLB.
+
+ expectingIdentifier == true && expectingIdentifier == true
+ Currently in an identifier. Will accept identifier or punctuation.
+
+ expectingIdentifier == true && expectingIdentifier == false
+ Just seen a punctuation character & now waiting for an identifier to start.
+
+ expectingIdentifier == false && expectingIdentifier == truee
+ We were in an identifier and have seen space. Now waiting to see a punctuation
+ character
+
+ Space, comments & preprocessor directives are always acceptable and are
+ equivalent.
+*/
+
+static const int T3_SEENSTART = 1 << 12;
+static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
+static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
+
+static inline bool IsStringTransition(int s1, int s2) {
+ return s1 != s2
+ && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
+ || s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)
+ && s2 != SCE_T3_LIB_DIRECTIVE
+ && s2 != SCE_T3_MSG_PARAM
+ && s2 != SCE_T3_HTML_TAG
+ && s2 != SCE_T3_HTML_STRING;
+}
+
+static inline bool IsATADS3Punctuation(const int ch) {
+ return ch == ':' || ch == ',' || ch == '(' || ch == ')';
+}
+
+static inline bool IsAnIdentifier(const int style) {
+ return style == SCE_T3_IDENTIFIER
+ || style == SCE_T3_USER1
+ || style == SCE_T3_USER2
+ || style == SCE_T3_USER3;
+}
+
+static inline bool IsSpaceEquivalent(const int ch, const int style) {
+ return isspace(ch)
+ || style == SCE_T3_BLOCK_COMMENT
+ || style == SCE_T3_LINE_COMMENT
+ || style == SCE_T3_PREPROCESSOR;
+}
+
+static char peekAhead(unsigned int startPos, unsigned int endPos,
+ Accessor &styler) {
+ for (unsigned int i = startPos; i < endPos; i++) {
+ int style = styler.StyleAt(i);
+ char ch = styler[i];
+ if (!IsSpaceEquivalent(ch, style)) {
+ if (IsAnIdentifier(style)) {
+ return 'a';
+ }
+ if (IsATADS3Punctuation(ch)) {
+ return ':';
+ }
+ if (ch == '{') {
+ return '{';
+ }
+ return '*';
+ }
+ }
+ return ' ';
+}
+
+static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int seenStart = levelCurrent & T3_SEENSTART;
+ int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;
+ int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;
+ levelCurrent &= SC_FOLDLEVELNUMBERMASK;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char ch = chNext;
+ int stylePrev = style;
+ bool redo = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ if (redo) {
+ redo = false;
+ i--;
+ } else {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ }
+ bool atEOL = IsEOL(ch, chNext);
+
+ if (levelNext == SC_FOLDLEVELBASE) {
+ if (IsSpaceEquivalent(ch, style)) {
+ if (expectingPunctuation) {
+ expectingIdentifier = 0;
+ }
+ if (style == SCE_T3_BLOCK_COMMENT) {
+ levelNext++;
+ }
+ } else if (ch == '{') {
+ levelNext++;
+ seenStart = 0;
+ } else if (ch == '\'' || ch == '"' || ch == '[') {
+ levelNext++;
+ if (seenStart) {
+ redo = true;
+ }
+ } else if (ch == ';') {
+ seenStart = 0;
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ } else if (expectingIdentifier && expectingPunctuation) {
+ if (IsATADS3Punctuation(ch)) {
+ if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
+ levelNext++;
+ } else {
+ expectingPunctuation = 0;
+ }
+ } else if (!IsAnIdentifier(style)) {
+ levelNext++;
+ }
+ } else if (expectingIdentifier && !expectingPunctuation) {
+ if (!IsAnIdentifier(style)) {
+ levelNext++;
+ } else {
+ expectingPunctuation = T3_EXPECTINGPUNCTUATION;
+ }
+ } else if (!expectingIdentifier && expectingPunctuation) {
+ if (!IsATADS3Punctuation(ch)) {
+ levelNext++;
+ } else {
+ if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
+ levelNext++;
+ } else {
+ expectingIdentifier = T3_EXPECTINGIDENTIFIER;
+ expectingPunctuation = 0;
+ }
+ }
+ } else if (!expectingIdentifier && !expectingPunctuation) {
+ if (IsAnIdentifier(style)) {
+ seenStart = T3_SEENSTART;
+ expectingIdentifier = T3_EXPECTINGIDENTIFIER;
+ expectingPunctuation = T3_EXPECTINGPUNCTUATION;
+ }
+ }
+
+ if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ }
+
+ } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart
+ && ch == ';' && style == SCE_T3_OPERATOR ) {
+ levelNext--;
+ seenStart = 0;
+ } else if (style == SCE_T3_BLOCK_COMMENT) {
+ if (stylePrev != SCE_T3_BLOCK_COMMENT) {
+ levelNext++;
+ } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ } else if (ch == '\'' || ch == '"') {
+ if (IsStringTransition(style, stylePrev)) {
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (IsStringTransition(style, styleNext)) {
+ levelNext--;
+ }
+ } else if (style == SCE_T3_OPERATOR) {
+ if (ch == '{' || ch == '[') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}' || ch == ']') {
+ levelNext--;
+ }
+ }
+
+ if (atEOL) {
+ if (seenStart && levelNext == SC_FOLDLEVELBASE) {
+ switch (peekAhead(i+1, endPos, styler)) {
+ case ' ':
+ case '{':
+ break;
+ case '*':
+ levelNext++;
+ break;
+ case 'a':
+ if (expectingPunctuation) {
+ levelNext++;
+ }
+ break;
+ case ':':
+ if (expectingIdentifier) {
+ levelNext++;
+ }
+ break;
+ }
+ if (levelNext != SC_FOLDLEVELBASE) {
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ }
+ }
+ int lev = levelMinCurrent | (levelNext | expectingIdentifier
+ | expectingPunctuation | seenStart) << 16;
+ if (levelMinCurrent < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ }
+ }
+}
+
+static const char * const tads3WordList[] = {
+ "TADS3 Keywords",
+ "User defined 1",
+ "User defined 2",
+ "User defined 3",
+ 0
+};
+
+LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList);
// Hooks into the system:
static const char * const texWordListDesc[] = {
- "TeX, eTeX, pdfTeX, Omega"
+ "TeX, eTeX, pdfTeX, Omega",
"ConTeXt Dutch",
"ConTeXt English",
"ConTeXt German",
/** @file LexVB.cxx
** Lexer for Visual Basic and VBScript.
**/
-// Copyright 1998-2003 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 "Scintilla.h"
#include "SciLexer.h"
+// Internal state, highlighted as number
+#define SCE_B_FILENUMBER SCE_B_DEFAULT+100
+
+
static bool IsVBComment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]=='\'';
+ return len > 0 && styler[pos] == '\'';
}
static inline bool IsTypeCharacter(int ch) {
static inline bool IsAWordStart(int ch) {
return ch >= 0x80 ||
- (isalnum(ch) || ch == '_');
+ (isalpha(ch) || ch == '_');
}
-static inline bool IsADateCharacter(const int 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) &&
- (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
}
static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
styler.StartAt(startPos);
int visibleChars = 0;
+ int fileNbDigits = 0;
+
+ // Do not leak onto next line
+ if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
+ initStyle = SCE_B_DEFAULT;
+ }
StyleContext sc(startPos, length, initStyle, styler);
}
}
} else if (sc.state == SCE_B_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ // Also accepts A-F for hex. numbers
+ if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
sc.SetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_STRING) {
}
} else if (sc.state == SCE_B_COMMENT) {
if (sc.atLineEnd) {
- sc.SetState(SCE_B_DEFAULT);
+ sc.ForwardSetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_PREPROCESSOR) {
if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_FILENUMBER) {
+ if (IsADigit(sc.ch)) {
+ fileNbDigits++;
+ if (fileNbDigits > 3) {
+ sc.ChangeState(SCE_B_DATE);
+ }
+ } else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
+ // Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
+ // Too bad if date is format #27, Oct, 2003# or something like that...
+ // Use regular number state
+ sc.ChangeState(SCE_B_NUMBER);
sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.ch == '#') {
+ sc.ChangeState(SCE_B_DATE);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else {
+ sc.ChangeState(SCE_B_DATE);
+ }
+ if (sc.state != SCE_B_FILENUMBER) {
+ fileNbDigits = 0;
}
} else if (sc.state == SCE_B_DATE) {
- if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_B_STRINGEOL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else if (sc.ch == '#') {
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
// Preprocessor commands are alone on their line
sc.SetState(SCE_B_PREPROCESSOR);
} else if (sc.ch == '#') {
- int n = 1;
- int chSeek = ' ';
- while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
- chSeek = sc.GetRelative(n);
- n++;
- }
- if (IsADigit(chSeek)) {
- sc.SetState(SCE_B_DATE);
- } else {
- sc.SetState(SCE_B_OPERATOR);
- }
+ // It can be a date literal, ending with #, or a file number, from 1 to 511
+ // The date literal depends on the locale, so anything can go between #'s.
+ // Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
+ // So we set the FILENUMBER state, and switch to DATE if it isn't a file number
+ sc.SetState(SCE_B_FILENUMBER);
} else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
+ // Hexadecimal number
sc.SetState(SCE_B_NUMBER);
+ sc.Forward();
} else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
+ // Octal number
sc.SetState(SCE_B_NUMBER);
+ sc.Forward();
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_B_NUMBER);
} else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
sc.SetState(SCE_B_IDENTIFIER);
- } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
+ } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division
sc.SetState(SCE_B_OPERATOR);
}
}
surface->LineTo(right - 5, centreY + 5);
right += 4;
}
- } else { // SC_MARK_SHORTARROW
+ } else if (markType == SC_MARK_SHORTARROW) {
Point pts[] = {
Point(centreX, centreY + dimOn2),
Point(centreX + dimOn2, centreY),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
fore.allocated, back.allocated);
+ } else { // SC_MARK_FULLRECT
+ surface->FillRectangle(rcWhole, back.allocated);
}
}
// End SString functions
+bool PropSet::caseSensitiveFilenames = false;
+
PropSet::PropSet() {
superPS = 0;
for (int root = 0; root < hashRoots; root++)
VarChain(const char*var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
bool contains(const char *testVar) const {
- return (var && (0 == strcmp(var, testVar)))
+ return (var && (0 == strcmp(var, testVar)))
|| (link && link->contains(testVar));
}
return true;
}
-static bool IsSuffixCaseInsensitive(const char *target, const char *suffix) {
+static bool IsSuffix(const char *target, const char *suffix, bool caseSensitive) {
size_t lentarget = strlen(target);
size_t lensuffix = strlen(suffix);
if (lensuffix > lentarget)
return false;
+ if (caseSensitive) {
+ for (int i = static_cast<int>(lensuffix) - 1; i >= 0; i--) {
+ if (target[i + lentarget - lensuffix] != suffix[i])
+ return false;
+ }
+ } else {
for (int i = static_cast<int>(lensuffix) - 1; i >= 0; i--) {
if (MakeUpperCase(target[i + lentarget - lensuffix]) !=
MakeUpperCase(suffix[i]))
return false;
}
+ }
return true;
}
char delchr = *del;
*del = '\0';
if (*keyfile == '*') {
- if (IsSuffixCaseInsensitive(filename, keyfile + 1)) {
+ if (IsSuffix(filename, keyfile + 1, caseSensitiveFilenames)) {
*del = delchr;
delete []keyptr;
return p->val;
list = 0;
len = 0;
sorted = false;
+ sortedNoCase = false;
}
void WordList::Set(const char *s) {
list = StringDup(s);
sorted = false;
+ sortedNoCase = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
wordsNoCase = new char * [len + 1];
memcpy(wordsNoCase, words, (len + 1) * sizeof (*words));
void WordList::SetFromAllocated() {
sorted = false;
+ sortedNoCase = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
wordsNoCase = new char * [len + 1];
memcpy(wordsNoCase, words, (len + 1) * sizeof (*words));
return CompareCaseInsensitive(*(char**)(a1), *(char**)(a2));
}
-static void SortWordList(char **words, char **wordsNoCase, unsigned int len) {
+static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
cmpString);
+}
+
+static void SortWordListNoCase(char **wordsNoCase, unsigned int len) {
qsort(reinterpret_cast<void*>(wordsNoCase), len, sizeof(*wordsNoCase),
cmpStringNoCase);
}
return false;
if (!sorted) {
sorted = true;
- SortWordList(words, wordsNoCase, len);
+ 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--) {
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;
+}
+
/**
* Returns an element (complete) of the wordlist array which has
* the same beginning as the passed string.
if (0 == words)
return NULL;
- if (!sorted) {
- sorted = true;
- SortWordList(words, wordsNoCase, len);
- }
if (ignoreCase) {
+ if (!sortedNoCase) {
+ sortedNoCase = true;
+ SortWordListNoCase(wordsNoCase, len);
+ }
while (start <= end) { // binary searching loop
pivot = (start + end) >> 1;
word = wordsNoCase[pivot];
while (end < len-1 && !CompareNCaseInsensitive(wordStart, wordsNoCase[end+1], searchLen)) {
end++;
}
-
+
// Finds first word in a series of equal words
for (pivot = start; pivot <= end; pivot++) {
word = wordsNoCase[pivot];
end = pivot - 1;
}
} else { // preserve the letter case
+ if (!sorted) {
+ sorted = true;
+ SortWordList(words, len);
+ }
while (start <= end) { // binary searching loop
pivot = (start + end) >> 1;
word = words[pivot];
while (end < len-1 && !strncmp(wordStart, words[end+1], searchLen)) {
end++;
}
-
+
// Finds first word in a series of equal words
pivot = start;
while (pivot <= end) {
if (0 == words)
return NULL;
- if (!sorted) {
- sorted = true;
- SortWordList(words, wordsNoCase, len);
- }
if (ignoreCase) {
+ if (!sortedNoCase) {
+ sortedNoCase = true;
+ SortWordListNoCase(wordsNoCase, len);
+ }
while (start <= end) { // Binary searching loop
pivot = (start + end) / 2;
cond = CompareNCaseInsensitive(wordStart, wordsNoCase[pivot], searchLen);
}
}
} else { // Preserve the letter case
+ if (!sorted) {
+ sorted = true;
+ SortWordList(words, len);
+ }
while (start <= end) { // Binary searching loop
pivot = (start + end) / 2;
cond = strncmp(wordStart, words[pivot], searchLen);
class CharacterIndexer {
public:
virtual char CharAt(int index)=0;
+ virtual ~CharacterIndexer() {
+ }
};
class RESearch {
ScintillaBase::ScintillaBase() {
displayPopupMenu = true;
listType = 0;
+ maxListWidth = 0;
#ifdef SCI_LEXER
lexLanguage = SCLEX_CONTAINER;
+ performingStyle = false;
lexCurrent = 0;
for (int wl = 0;wl < numWordLists;wl++)
keyWordLists[wl] = new WordList;
return;
}
}
- ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode());
+ ac.Start(wMain, idAutoComplete, currentPos, LocationFromPosition(currentPos),
+ lenEntered, vs.lineHeight, IsUnicodeMode());
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom);
ac.lb->SetPositionRelative(rcac, wMain);
ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
- ac.lb->SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth);
+ unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
+ ac.lb->SetAverageCharWidth(aveCharWidth);
ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
ac.SetList(list);
PRectangle rcList = ac.lb->GetDesiredRect();
int heightAlloced = rcList.bottom - rcList.top;
widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left);
+ if (maxListWidth != 0)
+ widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
// Make an allowance for large strings in list
rcList.left = pt.x - ac.lb->CaretFromEdge();
rcList.right = rcList.left + widthLB;
}
rcList.bottom = rcList.top + heightAlloced;
ac.lb->SetPositionRelative(rcList, wMain);
- ac.Show();
+ ac.Show(true);
if (lenEntered != 0) {
AutoCompleteMoveToCurrentWord();
}
selected[0] = '\0';
if (item != -1) {
ac.lb->GetValue(item, selected, sizeof(selected));
+ } else {
+ ac.Cancel();
+ return;
}
- ac.Cancel();
- if (item == -1)
+
+ ac.Show(false);
+
+ listSelected = selected;
+ SCNotification scn = {0};
+ scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
+ scn.message = 0;
+ scn.wParam = listType;
+ scn.listType = listType;
+ Position firstPos = ac.posStart - ac.startLen;
+ scn.lParam = firstPos;
+ scn.text = listSelected.c_str();
+ NotifyParent(scn);
+
+ if (!ac.Active())
return;
+ ac.Cancel();
- if (listType > 0) {
- userListSelected = selected;
- SCNotification scn;
- scn.nmhdr.code = SCN_USERLISTSELECTION;
- scn.message = 0;
- scn.wParam = listType;
- scn.listType = listType;
- scn.lParam = 0;
- scn.text = userListSelected.c_str();
- NotifyParent(scn);
+ if (listType > 0)
return;
- }
- Position firstPos = ac.posStart - ac.startLen;
Position endPos = currentPos;
if (ac.dropRestOfWord)
endPos = pdoc->ExtendWordSelect(endPos, 1, true);
}
void ScintillaBase::CallTipClick() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_CALLTIPCLICK;
scn.position = ct.clickPlace;
NotifyParent(scn);
}
void ScintillaBase::Colourise(int start, int end) {
- int lengthDoc = pdoc->Length();
- if (end == -1)
- end = lengthDoc;
- int len = end - start;
-
- PLATFORM_ASSERT(len >= 0);
- PLATFORM_ASSERT(start + len <= lengthDoc);
-
- //WindowAccessor styler(wMain.GetID(), props);
- DocumentAccessor styler(pdoc, props, wMain.GetID());
-
- int styleStart = 0;
- if (start > 0)
- styleStart = styler.StyleAt(start - 1);
- styler.SetCodePage(pdoc->dbcsCodePage);
-
- if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
- lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- if (styler.GetPropertyInt("fold")) {
- lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
+ if (!performingStyle) {
+ // Protect against reentrance, which may occur, for example, when
+ // fold points are discovered while performing styling and the folding
+ // code looks for child lines which may trigger styling.
+ performingStyle = true;
+
+ int lengthDoc = pdoc->Length();
+ if (end == -1)
+ end = lengthDoc;
+ int len = end - start;
+
+ PLATFORM_ASSERT(len >= 0);
+ PLATFORM_ASSERT(start + len <= lengthDoc);
+
+ //WindowAccessor styler(wMain.GetID(), props);
+ DocumentAccessor styler(pdoc, props, wMain.GetID());
+
+ int styleStart = 0;
+ if (start > 0)
+ styleStart = styler.StyleAt(start - 1);
+ styler.SetCodePage(pdoc->dbcsCodePage);
+
+ if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
+ lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
styler.Flush();
+ if (styler.GetPropertyInt("fold")) {
+ lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
+ styler.Flush();
+ }
}
+
+ performingStyle = false;
}
}
#endif
case SCI_AUTOCGETDROPRESTOFWORD:
return ac.dropRestOfWord;
+ case SCI_AUTOCSETMAXHEIGHT:
+ ac.lb->SetVisibleRows(wParam);
+ break;
+
+ case SCI_AUTOCGETMAXHEIGHT:
+ return ac.lb->GetVisibleRows();
+
+ case SCI_AUTOCSETMAXWIDTH:
+ maxListWidth = wParam;
+ break;
+
+ case SCI_AUTOCGETMAXWIDTH:
+ return maxListWidth;
+
case SCI_REGISTERIMAGE:
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break;
return lexLanguage;
case SCI_COLOURISE:
- Colourise(wParam, lParam);
+ if (lexLanguage == SCLEX_CONTAINER) {
+ pdoc->ModifiedAt(wParam);
+ NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
+ } else {
+ Colourise(wParam, lParam);
+ }
Redraw();
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_GETPROPERTYEXPANDED: {
+ SString val = props.GetExpanded(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_GETPROPERTYINT:
+ return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
+
case SCI_SETKEYWORDS:
if (wParam < numWordLists) {
keyWordLists[wParam]->Clear();
SetLexerLanguage(reinterpret_cast<const char *>(lParam));
break;
+ case SCI_GETSTYLEBITSNEEDED:
+ return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
#endif
default:
CallTip ct;
int listType; ///< 0 is an autocomplete list
- SString userListSelected; ///< Receives listbox selected string
+ SString listSelected; ///< Receives listbox selected string
+ int maxListWidth; /// Maximum width of list, in average character widths
+
+ bool performingStyle; ///< Prevent reentrance
#ifdef SCI_LEXER
int lexLanguage;
currentPos(startPos),
atLineStart(true),
atLineEnd(false),
- state(initStyle),
+ state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
ch(0),
chNext(0) {
return currentPos - styler.GetStartSegment();
}
int GetRelative(int n) {
- return styler.SafeGetCharAt(currentPos+n);
+ return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
}
bool Match(char ch0) {
return ch == ch0;
return false;
s++;
for (int n=2; *s; n++) {
- if (*s != tolower((styler.SafeGetCharAt(currentPos+n))))
+ if (*s !=
+ tolower(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
return false;
s++;
}
height = atoi(line0);
line0 = NextField(line0);
nColours = atoi(line0);
+ line0 = NextField(line0);
+ if (atoi(line0) != 1) {
+ // Only one char per pixel is supported
+ return;
+ }
codes = new char[nColours];
colours = new ColourPair[nColours];
for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) {
set[i]->Init(textForm);
+ set[i]->CopyDesiredColours();
return;
}
}
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_AUTOCOMP_SELECTION )
}
+// Add a set of markers to a line.
+void wxStyledTextCtrl::MarkerAddSet(int line, int set) {
+ SendMsg(2466, line, set);
+}
+
// Set a margin to be either numeric or symbolic.
void wxStyledTextCtrl::SetMarginType(int margin, int marginType) {
SendMsg(2240, margin, marginType);
SendMsg(2286, separatorCharacter, 0);
}
+// Set the maximum width, in characters, of auto-completion and user lists.
+// Set to 0 to autosize to fit longest item, which is the default.
+void wxStyledTextCtrl::AutoCompSetMaxWidth(int characterCount) {
+ SendMsg(2208, characterCount, 0);
+}
+
+// Get the maximum width, in characters, of auto-completion and user lists.
+int wxStyledTextCtrl::AutoCompGetMaxWidth() {
+ return SendMsg(2209, 0, 0);
+}
+
+// Set the maximum height, in rows, of auto-completion and user lists.
+// The default is 5 rows.
+void wxStyledTextCtrl::AutoCompSetMaxHeight(int rowCount) {
+ SendMsg(2210, rowCount, 0);
+}
+
+// Set the maximum height, in rows, of auto-completion and user lists.
+int wxStyledTextCtrl::AutoCompGetMaxHeight() {
+ return SendMsg(2211, 0, 0);
+}
+
// Set the number of spaces used for one level of indentation.
void wxStyledTextCtrl::SetIndent(int indentSize) {
SendMsg(2122, indentSize, 0);
return SendMsg(2221, lineDisplay, 0);
}
+// The number of display lines needed to wrap a document line
+int wxStyledTextCtrl::WrapCount(int line) {
+ return SendMsg(2235, line, 0);
+}
+
// Set the fold level of a line.
// This encodes an integer level along with flags indicating whether the
// line is a header and whether it is effectively white space.
// Retrieve whether the maximum scroll position has the last
// line at the bottom of the view.
-int wxStyledTextCtrl::GetEndAtLastLine() {
- return SendMsg(2278, 0, 0);
+bool wxStyledTextCtrl::GetEndAtLastLine() {
+ return SendMsg(2278, 0, 0) != 0;
}
// Retrieve the height of a particular line of text in pixels.
SendMsg(2446, bytes, 0);
}
-// Find the position of a column on a line taking into account tabs and
+// Find the position of a column on a line taking into account tabs and
// multi-byte characters. If beyond end of line, return line end position.
int wxStyledTextCtrl::FindColumn(int line, int column) {
return SendMsg(2456, line, column);
}
+// Can the caret preferred x position only be changed by explicit movement commands?
+bool wxStyledTextCtrl::GetCaretSticky() {
+ return SendMsg(2457, 0, 0) != 0;
+}
+
+// Stop the caret preferred x position changing when the user types.
+void wxStyledTextCtrl::SetCaretSticky(bool useCaretStickyBehaviour) {
+ SendMsg(2458, useCaretStickyBehaviour, 0);
+}
+
+// Switch between sticky and non-sticky: meant to be bound to a key.
+void wxStyledTextCtrl::ToggleCaretSticky() {
+ SendMsg(2459, 0, 0);
+}
+
+// Enable/Disable convert-on-paste for line endings
+void wxStyledTextCtrl::SetPasteConvertEndings(bool convert) {
+ SendMsg(2467, convert, 0);
+}
+
+// Get convert-on-paste setting
+bool wxStyledTextCtrl::GetPasteConvertEndings() {
+ return SendMsg(2468, 0, 0) != 0;
+}
+
+// Duplicate the selection. If selection empty duplicate the line containing the caret.
+void wxStyledTextCtrl::SelectionDuplicate() {
+ SendMsg(2469, 0, 0);
+}
+
// Start notifying the container of all key presses and commands.
void wxStyledTextCtrl::StartRecord() {
SendMsg(3001, 0, 0);
SendMsg(4006, 0, (long)(const char*)wx2stc(language));
}
+// Retrieve a 'property' value previously set with SetProperty.
+wxString wxStyledTextCtrl::GetProperty(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTY, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(4008, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);
+}
+
+// Retrieve a 'property' value previously set with SetProperty,
+// with '$()' variable replacement on returned buffer.
+wxString wxStyledTextCtrl::GetPropertyExpanded(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTYEXPANDED, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(4009, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);
+}
+
+// Retrieve a 'property' value previously set with SetProperty,
+// interpreted as an int AFTER any '$()' variable replacement.
+int wxStyledTextCtrl::GetPropertyInt(const wxString& key) {
+ return SendMsg(4010, (long)(const char*)wx2stc(key), 0);
+}
+
+// Retrieve the number of bits the current lexer needs for styling.
+int wxStyledTextCtrl::GetStyleBitsNeeded() {
+ return SendMsg(4011, 0, 0);
+}
+
// END of generated section
//----------------------------------------------------------------------
case wxSTC_CHARSET_THAI:
encoding = wxFONTENCODING_ISO8859_11;
break;
+
+ case wxSTC_CHARSET_CYRILLIC:
+ encoding = wxFONTENCODING_ISO8859_5;
+ break;
+
+ case wxSTC_CHARSET_8859_15:
+ encoding = wxFONTENCODING_ISO8859_15;;
+ break;
}
// We just have Scintilla track the wxFontEncoding for us. It gets used
evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
break;
+ case SCN_AUTOCSELECTION:
+ evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION);
+ break;
+
default:
return;
}
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_AUTOCOMP_SELECTION )
case wxSTC_CHARSET_THAI:
encoding = wxFONTENCODING_ISO8859_11;
break;
+
+ case wxSTC_CHARSET_CYRILLIC:
+ encoding = wxFONTENCODING_ISO8859_5;
+ break;
+
+ case wxSTC_CHARSET_8859_15:
+ encoding = wxFONTENCODING_ISO8859_15;;
+ break;
}
// We just have Scintilla track the wxFontEncoding for us. It gets used
evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
break;
+ case SCN_AUTOCSELECTION:
+ evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION);
+ break;
+
default:
return;
}
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_CLICK, 1673)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_DCLICK, 1674)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_CALLTIP_CLICK, 1675)
+ DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_SELECTION, 1676)
END_DECLARE_EVENT_TYPES()
#else
enum {
wxEVT_STC_ZOOM,
wxEVT_STC_HOTSPOT_CLICK,
wxEVT_STC_HOTSPOT_DCLICK,
- wxEVT_STC_CALLTIP_CLICK
+ wxEVT_STC_CALLTIP_CLICK,
+ wxEVT_STC_AUTOCOMP_SELECTION
};
#endif
#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
-
+#define EVT_STC_AUTOCOMP_SELECTION(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_SELECTION id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#endif
//----------------------------------------------------------------------
#ifndef SWIG
#if wxUSE_UNICODE
-wxString stc2wx(const char* str);
-wxString stc2wx(const char* str, size_t len);
-const wxWX2MBbuf wx2stc(const wxString& str);
+WXDLLIMPEXP_STC wxString stc2wx(const char* str);
+WXDLLIMPEXP_STC wxString stc2wx(const char* str, size_t len);
+WXDLLIMPEXP_STC const wxWX2MBbuf wx2stc(const wxString& str);
#else // not UNICODE
#define wxSTC_MARK_DOTDOTDOT 23
#define wxSTC_MARK_ARROWS 24
#define wxSTC_MARK_PIXMAP 25
+#define wxSTC_MARK_FULLRECT 26
#define wxSTC_MARK_CHARACTER 10000
// Markers used for outlining column.
#define wxSTC_CHARSET_MAC 77
#define wxSTC_CHARSET_OEM 255
#define wxSTC_CHARSET_RUSSIAN 204
+#define wxSTC_CHARSET_CYRILLIC 1251
#define wxSTC_CHARSET_SHIFTJIS 128
#define wxSTC_CHARSET_SYMBOL 2
#define wxSTC_CHARSET_TURKISH 162
#define wxSTC_CHARSET_ARABIC 178
#define wxSTC_CHARSET_VIETNAMESE 163
#define wxSTC_CHARSET_THAI 222
+#define wxSTC_CHARSET_8859_15 1000
#define wxSTC_CASE_MIXED 0
#define wxSTC_CASE_UPPER 1
#define wxSTC_CASE_LOWER 2
#define wxSTC_TIME_FOREVER 10000000
#define wxSTC_WRAP_NONE 0
#define wxSTC_WRAP_WORD 1
+#define wxSTC_WRAP_CHAR 2
#define wxSTC_WRAPVISUALFLAG_NONE 0x0000
#define wxSTC_WRAPVISUALFLAG_END 0x0001
#define wxSTC_WRAPVISUALFLAG_START 0x0002
#define wxSTC_PERFORMED_USER 0x10
#define wxSTC_PERFORMED_UNDO 0x20
#define wxSTC_PERFORMED_REDO 0x40
+#define wxSTC_MULTISTEPUNDOREDO 0x80
#define wxSTC_LASTSTEPINUNDOREDO 0x100
#define wxSTC_MOD_CHANGEMARKER 0x200
#define wxSTC_MOD_BEFOREINSERT 0x400
#define wxSTC_MOD_BEFOREDELETE 0x800
-#define wxSTC_MODEVENTMASKALL 0xF77
+#define wxSTC_MULTILINEUNDOREDO 0x1000
+#define wxSTC_MODEVENTMASKALL 0x1FFF
// Symbolic key codes and modifier flags.
// ASCII and other printable characters below 256.
#define wxSTC_KEY_ADD 310
#define wxSTC_KEY_SUBTRACT 311
#define wxSTC_KEY_DIVIDE 312
+#define wxSTC_SCMOD_NORM 0
#define wxSTC_SCMOD_SHIFT 1
#define wxSTC_SCMOD_CTRL 2
#define wxSTC_SCMOD_ALT 4
#define wxSTC_LEX_NNCRONTAB 26
#define wxSTC_LEX_BULLANT 27
#define wxSTC_LEX_VBSCRIPT 28
-#define wxSTC_LEX_ASP 29
-#define wxSTC_LEX_PHP 30
#define wxSTC_LEX_BAAN 31
#define wxSTC_LEX_MATLAB 32
#define wxSTC_LEX_SCRIPTOL 33
#define wxSTC_LEX_BASH 62
#define wxSTC_LEX_ASN1 63
#define wxSTC_LEX_VHDL 64
+#define wxSTC_LEX_CAML 65
+#define wxSTC_LEX_BLITZBASIC 66
+#define wxSTC_LEX_PUREBASIC 67
+#define wxSTC_LEX_HASKELL 68
+#define wxSTC_LEX_PHPSCRIPT 69
+#define wxSTC_LEX_TADS3 70
+#define wxSTC_LEX_REBOL 71
+#define wxSTC_LEX_SMALLTALK 72
+#define wxSTC_LEX_FLAGSHIP 73
+#define wxSTC_LEX_CSOUND 74
+#define wxSTC_LEX_FREEBASIC 75
// When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
// value assigned in sequence from SCLEX_AUTOMATIC+1.
#define wxSTC_P_IDENTIFIER 11
#define wxSTC_P_COMMENTBLOCK 12
#define wxSTC_P_STRINGEOL 13
+#define wxSTC_P_WORD2 14
+#define wxSTC_P_DECORATOR 15
// Lexical states for SCLEX_CPP
#define wxSTC_C_DEFAULT 0
#define wxSTC_PL_ARRAY 13
#define wxSTC_PL_HASH 14
#define wxSTC_PL_SYMBOLTABLE 15
+#define wxSTC_PL_VARIABLE_INDEXER 16
#define wxSTC_PL_REGEX 17
#define wxSTC_PL_REGSUBST 18
#define wxSTC_PL_LONGQUOTE 19
#define wxSTC_PL_STRING_QX 28
#define wxSTC_PL_STRING_QR 29
#define wxSTC_PL_STRING_QW 30
+#define wxSTC_PL_POD_VERB 31
+
+// Lexical states for SCLEX_RUBY
+#define wxSTC_RB_DEFAULT 0
+#define wxSTC_RB_ERROR 1
+#define wxSTC_RB_COMMENTLINE 2
+#define wxSTC_RB_POD 3
+#define wxSTC_RB_NUMBER 4
+#define wxSTC_RB_WORD 5
+#define wxSTC_RB_STRING 6
+#define wxSTC_RB_CHARACTER 7
+#define wxSTC_RB_CLASSNAME 8
+#define wxSTC_RB_DEFNAME 9
+#define wxSTC_RB_OPERATOR 10
+#define wxSTC_RB_IDENTIFIER 11
+#define wxSTC_RB_REGEX 12
+#define wxSTC_RB_GLOBAL 13
+#define wxSTC_RB_SYMBOL 14
+#define wxSTC_RB_MODULE_NAME 15
+#define wxSTC_RB_INSTANCE_VAR 16
+#define wxSTC_RB_CLASS_VAR 17
+#define wxSTC_RB_BACKTICKS 18
+#define wxSTC_RB_DATASECTION 19
+#define wxSTC_RB_HERE_DELIM 20
+#define wxSTC_RB_HERE_Q 21
+#define wxSTC_RB_HERE_QQ 22
+#define wxSTC_RB_HERE_QX 23
+#define wxSTC_RB_STRING_Q 24
+#define wxSTC_RB_STRING_QQ 25
+#define wxSTC_RB_STRING_QX 26
+#define wxSTC_RB_STRING_QR 27
+#define wxSTC_RB_STRING_QW 28
+#define wxSTC_RB_WORD_DEMOTED 29
+#define wxSTC_RB_STDIN 30
+#define wxSTC_RB_STDOUT 31
+#define wxSTC_RB_STDERR 40
+#define wxSTC_RB_UPPER_BOUND 41
// Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC
#define wxSTC_B_DEFAULT 0
#define wxSTC_B_KEYWORD4 12
#define wxSTC_B_CONSTANT 13
#define wxSTC_B_ASM 14
+#define wxSTC_B_LABEL 15
+#define wxSTC_B_ERROR 16
+#define wxSTC_B_HEXNUMBER 17
+#define wxSTC_B_BINNUMBER 18
// Lexical states for SCLEX_PROPERTIES
#define wxSTC_PROPS_DEFAULT 0
#define wxSTC_LISP_COMMENT 1
#define wxSTC_LISP_NUMBER 2
#define wxSTC_LISP_KEYWORD 3
+#define wxSTC_LISP_KEYWORD_KW 4
+#define wxSTC_LISP_SYMBOL 5
#define wxSTC_LISP_STRING 6
#define wxSTC_LISP_STRINGEOL 8
#define wxSTC_LISP_IDENTIFIER 9
#define wxSTC_LISP_OPERATOR 10
+#define wxSTC_LISP_SPECIAL 11
+#define wxSTC_LISP_MULTI_COMMENT 12
// Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW
#define wxSTC_EIFFEL_DEFAULT 0
#define wxSTC_CSS_DOUBLESTRING 13
#define wxSTC_CSS_SINGLESTRING 14
#define wxSTC_CSS_IDENTIFIER2 15
+#define wxSTC_CSS_ATTRIBUTE 16
// Lexical states for SCLEX_POV
#define wxSTC_POV_DEFAULT 0
#define wxSTC_NSIS_MACRODEF 12
#define wxSTC_NSIS_STRINGVAR 13
#define wxSTC_NSIS_NUMBER 14
+#define wxSTC_NSIS_SECTIONGROUP 15
+#define wxSTC_NSIS_PAGEEX 16
+#define wxSTC_NSIS_FUNCTIONDEF 17
+#define wxSTC_NSIS_COMMENTBOX 18
// Lexical states for SCLEX_MMIXAL
#define wxSTC_MMIXAL_LEADWS 0
#define wxSTC_CLW_PICTURE_STRING 7
#define wxSTC_CLW_KEYWORD 8
#define wxSTC_CLW_COMPILER_DIRECTIVE 9
-#define wxSTC_CLW_BUILTIN_PROCEDURES_FUNCTION 10
-#define wxSTC_CLW_STRUCTURE_DATA_TYPE 11
-#define wxSTC_CLW_ATTRIBUTE 12
-#define wxSTC_CLW_STANDARD_EQUATE 13
-#define wxSTC_CLW_ERROR 14
+#define wxSTC_CLW_RUNTIME_EXPRESSIONS 10
+#define wxSTC_CLW_BUILTIN_PROCEDURES_FUNCTION 11
+#define wxSTC_CLW_STRUCTURE_DATA_TYPE 12
+#define wxSTC_CLW_ATTRIBUTE 13
+#define wxSTC_CLW_STANDARD_EQUATE 14
+#define wxSTC_CLW_ERROR 15
+#define wxSTC_CLW_DEPRECATED 16
// Lexical states for SCLEX_LOT
#define wxSTC_LOT_DEFAULT 0
#define wxSTC_AU3_SENT 10
#define wxSTC_AU3_PREPROCESSOR 11
#define wxSTC_AU3_SPECIAL 12
+#define wxSTC_AU3_EXPAND 13
+#define wxSTC_AU3_COMOBJ 14
// Lexical states for SCLEX_APDL
#define wxSTC_APDL_DEFAULT 0
#define wxSTC_VHDL_STDTYPE 13
#define wxSTC_VHDL_USERWORD 14
+// Lexical states for SCLEX_CAML
+#define wxSTC_CAML_DEFAULT 0
+#define wxSTC_CAML_IDENTIFIER 1
+#define wxSTC_CAML_TAGNAME 2
+#define wxSTC_CAML_KEYWORD 3
+#define wxSTC_CAML_KEYWORD2 4
+#define wxSTC_CAML_KEYWORD3 5
+#define wxSTC_CAML_LINENUM 6
+#define wxSTC_CAML_OPERATOR 7
+#define wxSTC_CAML_NUMBER 8
+#define wxSTC_CAML_CHAR 9
+#define wxSTC_CAML_STRING 11
+#define wxSTC_CAML_COMMENT 12
+#define wxSTC_CAML_COMMENT1 13
+#define wxSTC_CAML_COMMENT2 14
+#define wxSTC_CAML_COMMENT3 15
+
+// Lexical states for SCLEX_HASKELL
+#define wxSTC_HA_DEFAULT 0
+#define wxSTC_HA_IDENTIFIER 1
+#define wxSTC_HA_KEYWORD 2
+#define wxSTC_HA_NUMBER 3
+#define wxSTC_HA_STRING 4
+#define wxSTC_HA_CHARACTER 5
+#define wxSTC_HA_CLASS 6
+#define wxSTC_HA_MODULE 7
+#define wxSTC_HA_CAPITAL 8
+#define wxSTC_HA_DATA 9
+#define wxSTC_HA_IMPORT 10
+#define wxSTC_HA_OPERATOR 11
+#define wxSTC_HA_INSTANCE 12
+#define wxSTC_HA_COMMENTLINE 13
+#define wxSTC_HA_COMMENTBLOCK 14
+#define wxSTC_HA_COMMENTBLOCK2 15
+#define wxSTC_HA_COMMENTBLOCK3 16
+
+// Lexical states of SCLEX_TADS3
+#define wxSTC_T3_DEFAULT 0
+#define wxSTC_T3_X_DEFAULT 1
+#define wxSTC_T3_PREPROCESSOR 2
+#define wxSTC_T3_BLOCK_COMMENT 3
+#define wxSTC_T3_LINE_COMMENT 4
+#define wxSTC_T3_OPERATOR 5
+#define wxSTC_T3_KEYWORD 6
+#define wxSTC_T3_NUMBER 7
+#define wxSTC_T3_IDENTIFIER 8
+#define wxSTC_T3_S_STRING 9
+#define wxSTC_T3_D_STRING 10
+#define wxSTC_T3_X_STRING 11
+#define wxSTC_T3_LIB_DIRECTIVE 12
+#define wxSTC_T3_MSG_PARAM 13
+#define wxSTC_T3_HTML_TAG 14
+#define wxSTC_T3_HTML_DEFAULT 15
+#define wxSTC_T3_HTML_STRING 16
+#define wxSTC_T3_USER1 17
+#define wxSTC_T3_USER2 18
+#define wxSTC_T3_USER3 19
+
+// Lexical states for SCLEX_REBOL
+#define wxSTC_REBOL_DEFAULT 0
+#define wxSTC_REBOL_COMMENTLINE 1
+#define wxSTC_REBOL_COMMENTBLOCK 2
+#define wxSTC_REBOL_PREFACE 3
+#define wxSTC_REBOL_OPERATOR 4
+#define wxSTC_REBOL_CHARACTER 5
+#define wxSTC_REBOL_QUOTEDSTRING 6
+#define wxSTC_REBOL_BRACEDSTRING 7
+#define wxSTC_REBOL_NUMBER 8
+#define wxSTC_REBOL_PAIR 9
+#define wxSTC_REBOL_TUPLE 10
+#define wxSTC_REBOL_BINARY 11
+#define wxSTC_REBOL_MONEY 12
+#define wxSTC_REBOL_ISSUE 13
+#define wxSTC_REBOL_TAG 14
+#define wxSTC_REBOL_FILE 15
+#define wxSTC_REBOL_EMAIL 16
+#define wxSTC_REBOL_URL 17
+#define wxSTC_REBOL_DATE 18
+#define wxSTC_REBOL_TIME 19
+#define wxSTC_REBOL_IDENTIFIER 20
+#define wxSTC_REBOL_WORD 21
+#define wxSTC_REBOL_WORD2 22
+#define wxSTC_REBOL_WORD3 23
+#define wxSTC_REBOL_WORD4 24
+#define wxSTC_REBOL_WORD5 25
+#define wxSTC_REBOL_WORD6 26
+#define wxSTC_REBOL_WORD7 27
+#define wxSTC_REBOL_WORD8 28
+
+// Lexical states for SCLEX_SQL
+#define wxSTC_SQL_DEFAULT 0
+#define wxSTC_SQL_COMMENT 1
+#define wxSTC_SQL_COMMENTLINE 2
+#define wxSTC_SQL_COMMENTDOC 3
+#define wxSTC_SQL_NUMBER 4
+#define wxSTC_SQL_WORD 5
+#define wxSTC_SQL_STRING 6
+#define wxSTC_SQL_CHARACTER 7
+#define wxSTC_SQL_SQLPLUS 8
+#define wxSTC_SQL_SQLPLUS_PROMPT 9
+#define wxSTC_SQL_OPERATOR 10
+#define wxSTC_SQL_IDENTIFIER 11
+#define wxSTC_SQL_SQLPLUS_COMMENT 13
+#define wxSTC_SQL_COMMENTLINEDOC 15
+#define wxSTC_SQL_WORD2 16
+#define wxSTC_SQL_COMMENTDOCKEYWORD 17
+#define wxSTC_SQL_COMMENTDOCKEYWORDERROR 18
+#define wxSTC_SQL_USER1 19
+#define wxSTC_SQL_USER2 20
+#define wxSTC_SQL_USER3 21
+#define wxSTC_SQL_USER4 22
+#define wxSTC_SQL_QUOTEDIDENTIFIER 23
+
+// Lexical states for SCLEX_SMALLTALK
+#define wxSTC_ST_DEFAULT 0
+#define wxSTC_ST_STRING 1
+#define wxSTC_ST_NUMBER 2
+#define wxSTC_ST_COMMENT 3
+#define wxSTC_ST_SYMBOL 4
+#define wxSTC_ST_BINARY 5
+#define wxSTC_ST_BOOL 6
+#define wxSTC_ST_SELF 7
+#define wxSTC_ST_SUPER 8
+#define wxSTC_ST_NIL 9
+#define wxSTC_ST_GLOBAL 10
+#define wxSTC_ST_RETURN 11
+#define wxSTC_ST_SPECIAL 12
+#define wxSTC_ST_KWSEND 13
+#define wxSTC_ST_ASSIGN 14
+#define wxSTC_ST_CHARACTER 15
+#define wxSTC_ST_SPEC_SEL 16
+
+// Lexical states for SCLEX_FLAGSHIP (clipper)
+#define wxSTC_FS_DEFAULT 0
+#define wxSTC_FS_COMMENT 1
+#define wxSTC_FS_COMMENTLINE 2
+#define wxSTC_FS_COMMENTDOC 3
+#define wxSTC_FS_COMMENTLINEDOC 4
+#define wxSTC_FS_COMMENTDOCKEYWORD 5
+#define wxSTC_FS_COMMENTDOCKEYWORDERROR 6
+#define wxSTC_FS_KEYWORD 7
+#define wxSTC_FS_KEYWORD2 8
+#define wxSTC_FS_KEYWORD3 9
+#define wxSTC_FS_KEYWORD4 10
+#define wxSTC_FS_NUMBER 11
+#define wxSTC_FS_STRING 12
+#define wxSTC_FS_PREPROCESSOR 13
+#define wxSTC_FS_OPERATOR 14
+#define wxSTC_FS_IDENTIFIER 15
+#define wxSTC_FS_DATE 16
+#define wxSTC_FS_STRINGEOL 17
+#define wxSTC_FS_CONSTANT 18
+#define wxSTC_FS_ASM 19
+#define wxSTC_FS_LABEL 20
+#define wxSTC_FS_ERROR 21
+#define wxSTC_FS_HEXNUMBER 22
+#define wxSTC_FS_BINNUMBER 23
+
+// Lexical states for SCLEX_CSOUND
+#define wxSTC_CSOUND_DEFAULT 0
+#define wxSTC_CSOUND_COMMENT 1
+#define wxSTC_CSOUND_NUMBER 2
+#define wxSTC_CSOUND_OPERATOR 3
+#define wxSTC_CSOUND_INSTR 4
+#define wxSTC_CSOUND_IDENTIFIER 5
+#define wxSTC_CSOUND_OPCODE 6
+#define wxSTC_CSOUND_HEADERSTMT 7
+#define wxSTC_CSOUND_USERKEYWORD 8
+#define wxSTC_CSOUND_COMMENTBLOCK 9
+#define wxSTC_CSOUND_PARAM 10
+#define wxSTC_CSOUND_ARATE_VAR 11
+#define wxSTC_CSOUND_KRATE_VAR 12
+#define wxSTC_CSOUND_IRATE_VAR 13
+#define wxSTC_CSOUND_GLOBAL_VAR 14
+#define wxSTC_CSOUND_STRINGEOL 15
+
//-----------------------------------------
// Commands that can be bound to keystrokes
// Define a marker from a bitmap
void MarkerDefineBitmap(int markerNumber, const wxBitmap& bmp);
+ // Add a set of markers to a line.
+ void MarkerAddSet(int line, int set);
+
// Set a margin to be either numeric or symbolic.
void SetMarginType(int margin, int marginType);
// Default is '?' but can be changed if items contain '?'.
void AutoCompSetTypeSeparator(int separatorCharacter);
+ // Set the maximum width, in characters, of auto-completion and user lists.
+ // Set to 0 to autosize to fit longest item, which is the default.
+ void AutoCompSetMaxWidth(int characterCount);
+
+ // Get the maximum width, in characters, of auto-completion and user lists.
+ int AutoCompGetMaxWidth();
+
+ // Set the maximum height, in rows, of auto-completion and user lists.
+ // The default is 5 rows.
+ void AutoCompSetMaxHeight(int rowCount);
+
+ // Set the maximum height, in rows, of auto-completion and user lists.
+ int AutoCompGetMaxHeight();
+
// Set the number of spaces used for one level of indentation.
void SetIndent(int indentSize);
// Find the document line of a display line taking hidden lines into account.
int DocLineFromVisible(int lineDisplay);
+ // The number of display lines needed to wrap a document line
+ int WrapCount(int line);
+
// Set the fold level of a line.
// This encodes an integer level along with flags indicating whether the
// line is a header and whether it is effectively white space.
// Retrieve whether the maximum scroll position has the last
// line at the bottom of the view.
- int GetEndAtLastLine();
+ bool GetEndAtLastLine();
// Retrieve the height of a particular line of text in pixels.
int TextHeight(int line);
// Enlarge the document to a particular size of text bytes.
void Allocate(int bytes);
- // Find the position of a column on a line taking into account tabs and
+ // Find the position of a column on a line taking into account tabs and
// multi-byte characters. If beyond end of line, return line end position.
int FindColumn(int line, int column);
+ // Can the caret preferred x position only be changed by explicit movement commands?
+ bool GetCaretSticky();
+
+ // Stop the caret preferred x position changing when the user types.
+ void SetCaretSticky(bool useCaretStickyBehaviour);
+
+ // Switch between sticky and non-sticky: meant to be bound to a key.
+ void ToggleCaretSticky();
+
+ // Enable/Disable convert-on-paste for line endings
+ void SetPasteConvertEndings(bool convert);
+
+ // Get convert-on-paste setting
+ bool GetPasteConvertEndings();
+
+ // Duplicate the selection. If selection empty duplicate the line containing the caret.
+ void SelectionDuplicate();
+
// Start notifying the container of all key presses and commands.
void StartRecord();
// Set the lexing language of the document based on string name.
void SetLexerLanguage(const wxString& language);
+ // Retrieve a 'property' value previously set with SetProperty.
+ wxString GetProperty(const wxString& key);
+
+ // Retrieve a 'property' value previously set with SetProperty,
+ // with '$()' variable replacement on returned buffer.
+ wxString GetPropertyExpanded(const wxString& key);
+
+ // Retrieve a 'property' value previously set with SetProperty,
+ // interpreted as an int AFTER any '$()' variable replacement.
+ int GetPropertyInt(const wxString& key);
+
+ // Retrieve the number of bits the current lexer needs for styling.
+ int GetStyleBitsNeeded();
+
// END of generated section
//----------------------------------------------------------------------
// Others...
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_CLICK, 1673)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_DCLICK, 1674)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_CALLTIP_CLICK, 1675)
+ DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_SELECTION, 1676)
END_DECLARE_EVENT_TYPES()
#else
enum {
wxEVT_STC_ZOOM,
wxEVT_STC_HOTSPOT_CLICK,
wxEVT_STC_HOTSPOT_DCLICK,
- wxEVT_STC_CALLTIP_CLICK
+ wxEVT_STC_CALLTIP_CLICK,
+ wxEVT_STC_AUTOCOMP_SELECTION
};
#endif
#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
-
+#define EVT_STC_AUTOCOMP_SELECTION(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_SELECTION id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#endif
//----------------------------------------------------------------------
stcdll_LexAsn1.o \
stcdll_LexBaan.o \
stcdll_LexBash.o \
+ stcdll_LexBasic.o \
stcdll_LexBullant.o \
stcdll_LexCLW.o \
stcdll_LexCPP.o \
stcdll_LexCSS.o \
+ stcdll_LexCaml.o \
+ stcdll_LexCsound.o \
stcdll_LexConf.o \
stcdll_LexCrontab.o \
stcdll_LexEScript.o \
stcdll_LexEiffel.o \
stcdll_LexErlang.o \
+ stcdll_LexFlagship.o \
stcdll_LexForth.o \
stcdll_LexFortran.o \
stcdll_LexGui4Cli.o \
stcdll_LexHTML.o \
+ stcdll_LexHaskell.o \
stcdll_LexKix.o \
stcdll_LexLisp.o \
stcdll_LexLout.o \
stcdll_LexPascal.o \
stcdll_LexPerl.o \
stcdll_LexPython.o \
+ stcdll_LexRebol.o \
stcdll_LexRuby.o \
stcdll_LexSQL.o \
+ stcdll_LexSmalltalk.o \
+ stcdll_LexTADS3.o \
stcdll_LexScriptol.o \
stcdll_LexSpecman.o \
stcdll_LexTeX.o \
stclib_LexAsn1.o \
stclib_LexBaan.o \
stclib_LexBash.o \
+ stclib_LexBasic.o \
stclib_LexBullant.o \
stclib_LexCLW.o \
stclib_LexCPP.o \
stclib_LexCSS.o \
+ stclib_LexCaml.o \
+ stclib_LexCsound.o \
stclib_LexConf.o \
stclib_LexCrontab.o \
stclib_LexEScript.o \
stclib_LexEiffel.o \
stclib_LexErlang.o \
+ stclib_LexFlagship.o \
stclib_LexForth.o \
stclib_LexFortran.o \
stclib_LexGui4Cli.o \
stclib_LexHTML.o \
+ stclib_LexHaskell.o \
stclib_LexKix.o \
stclib_LexLisp.o \
stclib_LexLout.o \
stclib_LexPascal.o \
stclib_LexPerl.o \
stclib_LexPython.o \
+ stclib_LexRebol.o \
stclib_LexRuby.o \
stclib_LexSQL.o \
+ stclib_LexSmalltalk.o \
+ stclib_LexTADS3.o \
stclib_LexScriptol.o \
stclib_LexSpecman.o \
stclib_LexTeX.o \
stcdll_LexBash.o: $(srcdir)/scintilla/src/LexBash.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexBash.cxx
+stcdll_LexBasic.o: $(srcdir)/scintilla/src/LexBasic.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexBasic.cxx
+
stcdll_LexBullant.o: $(srcdir)/scintilla/src/LexBullant.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexBullant.cxx
stcdll_LexCSS.o: $(srcdir)/scintilla/src/LexCSS.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexCSS.cxx
+stcdll_LexCaml.o: $(srcdir)/scintilla/src/LexCaml.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexCaml.cxx
+
+stcdll_LexCsound.o: $(srcdir)/scintilla/src/LexCsound.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexCsound.cxx
+
stcdll_LexConf.o: $(srcdir)/scintilla/src/LexConf.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexConf.cxx
stcdll_LexErlang.o: $(srcdir)/scintilla/src/LexErlang.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexErlang.cxx
+stcdll_LexFlagship.o: $(srcdir)/scintilla/src/LexFlagship.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexFlagship.cxx
+
stcdll_LexForth.o: $(srcdir)/scintilla/src/LexForth.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexForth.cxx
stcdll_LexHTML.o: $(srcdir)/scintilla/src/LexHTML.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexHTML.cxx
+stcdll_LexHaskell.o: $(srcdir)/scintilla/src/LexHaskell.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexHaskell.cxx
+
stcdll_LexKix.o: $(srcdir)/scintilla/src/LexKix.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexKix.cxx
stcdll_LexPython.o: $(srcdir)/scintilla/src/LexPython.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexPython.cxx
+stcdll_LexRebol.o: $(srcdir)/scintilla/src/LexRebol.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexRebol.cxx
+
stcdll_LexRuby.o: $(srcdir)/scintilla/src/LexRuby.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexRuby.cxx
stcdll_LexSQL.o: $(srcdir)/scintilla/src/LexSQL.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexSQL.cxx
+stcdll_LexSmalltalk.o: $(srcdir)/scintilla/src/LexSmalltalk.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexSmalltalk.cxx
+
+stcdll_LexTADS3.o: $(srcdir)/scintilla/src/LexTADS3.cxx
+ $(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexTADS3.cxx
+
stcdll_LexScriptol.o: $(srcdir)/scintilla/src/LexScriptol.cxx
$(CXXC) -c -o $@ $(STCDLL_CXXFLAGS) $(srcdir)/scintilla/src/LexScriptol.cxx
stclib_LexBash.o: $(srcdir)/scintilla/src/LexBash.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexBash.cxx
+stclib_LexBasic.o: $(srcdir)/scintilla/src/LexBasic.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexBasic.cxx
+
stclib_LexBullant.o: $(srcdir)/scintilla/src/LexBullant.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexBullant.cxx
stclib_LexCSS.o: $(srcdir)/scintilla/src/LexCSS.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexCSS.cxx
+stclib_LexCaml.o: $(srcdir)/scintilla/src/LexCaml.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexCaml.cxx
+
+stclib_LexCsound.o: $(srcdir)/scintilla/src/LexCsound.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexCsound.cxx
+
stclib_LexConf.o: $(srcdir)/scintilla/src/LexConf.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexConf.cxx
stclib_LexErlang.o: $(srcdir)/scintilla/src/LexErlang.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexErlang.cxx
+stclib_LexFlagship.o: $(srcdir)/scintilla/src/LexFlagship.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexFlagship.cxx
+
stclib_LexForth.o: $(srcdir)/scintilla/src/LexForth.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexForth.cxx
stclib_LexHTML.o: $(srcdir)/scintilla/src/LexHTML.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexHTML.cxx
+stclib_LexHaskell.o: $(srcdir)/scintilla/src/LexHaskell.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexHaskell.cxx
+
stclib_LexKix.o: $(srcdir)/scintilla/src/LexKix.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexKix.cxx
stclib_LexPython.o: $(srcdir)/scintilla/src/LexPython.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexPython.cxx
+stclib_LexRebol.o: $(srcdir)/scintilla/src/LexRebol.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexRebol.cxx
+
stclib_LexRuby.o: $(srcdir)/scintilla/src/LexRuby.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexRuby.cxx
stclib_LexSQL.o: $(srcdir)/scintilla/src/LexSQL.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexSQL.cxx
+stclib_LexSmalltalk.o: $(srcdir)/scintilla/src/LexSmalltalk.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexSmalltalk.cxx
+
+stclib_LexTADS3.o: $(srcdir)/scintilla/src/LexTADS3.cxx
+ $(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexTADS3.cxx
+
stclib_LexScriptol.o: $(srcdir)/scintilla/src/LexScriptol.cxx
$(CXXC) -c -o $@ $(STCLIB_CXXFLAGS) $(srcdir)/scintilla/src/LexScriptol.cxx
#include "wx/mstream.h"
#include "wx/image.h"
#include "wx/imaglist.h"
+#include "wx/tokenzr.h"
#include "Platform.h"
#include "PlatWX.h"
CallBackAction doubleClickAction;
void* doubleClickActionData;
public:
- wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
+ wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point location) :
wxPopupWindow(parent, wxBORDER_NONE)
{
SetBackgroundColour(*wxBLACK); // for our simple border
CallBackAction doubleClickAction;
void* doubleClickActionData;
public:
- wxSTCListBoxWin(wxWindow* parent, wxWindowID id) :
- wxWindow(parent, id, wxDefaultPosition, wxSize(0,0), wxSIMPLE_BORDER )
+ wxSTCListBoxWin(wxWindow* parent, wxWindowID id, Point location) :
+ wxWindow(parent, id, wxPoint(location.x, location.y), wxSize(0,0), wxSIMPLE_BORDER )
{
lv = new wxSTCListBox(this, id, wxDefaultPosition, wxDefaultSize,
int desiredVisibleRows;
int aveCharWidth;
int maxStrWidth;
+ Point location; // Caret location at which the list is opened
wxImageList* imgList;
wxArrayInt* imgTypeMap;
~ListBoxImpl();
virtual void SetFont(Font &font);
- virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_);
+ virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_);
virtual void SetAverageCharWidth(int width);
virtual void SetVisibleRows(int rows);
+ virtual int GetVisibleRows() const;
virtual PRectangle GetDesiredRect();
virtual int CaretFromEdge();
virtual void Clear();
virtual void Append(char *s, int type = -1);
+ void Append(const wxString& text, int type);
virtual int Length();
virtual void Select(int n);
virtual int GetSelection();
virtual void RegisterImage(int type, const char *xpm_data);
virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(CallBackAction, void *);
-
+ virtual void SetList(const char* list, char separator, char typesep);
};
}
-void ListBoxImpl::Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_) {
+void ListBoxImpl::Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_) {
+ location = location_;
lineHeight = lineHeight_;
unicodeMode = unicodeMode_;
maxStrWidth = 0;
- id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID);
+ id = new wxSTCListBoxWin(GETWIN(parent.GetID()), ctrlID, location);
if (imgList != NULL)
GETLB(id)->SetImageList(imgList, wxIMAGE_LIST_SMALL);
}
}
+int ListBoxImpl::GetVisibleRows() const {
+ return desiredVisibleRows;
+}
+
PRectangle ListBoxImpl::GetDesiredRect() {
// wxListCtrl doesn't have a DoGetBestSize, so instead we kept track of
// the max size in Append and calculate it here...
- int maxw = maxStrWidth;
+ int maxw = maxStrWidth * aveCharWidth;
int maxh ;
// give it a default if there are no lines, and/or add a bit more
void ListBoxImpl::Append(char *s, int type) {
- wxString text = stc2wx(s);
+ Append(stc2wx(s), type);
+}
+
+void ListBoxImpl::Append(const wxString& text, int type) {
long count = GETLB(id)->GetItemCount();
long itemID = GETLB(id)->InsertItem(count, wxEmptyString);
GETLB(id)->SetItem(itemID, 1, text);
- int itemWidth = 0;
- GETLB(id)->GetTextExtent(text, &itemWidth, NULL);
- maxStrWidth = wxMax(maxStrWidth, itemWidth);
+ maxStrWidth = wxMax(maxStrWidth, text.Length());
if (type != -1) {
wxCHECK_RET(imgTypeMap, wxT("Unexpected NULL imgTypeMap"));
long idx = imgTypeMap->Item(type);
}
}
+void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
+ GETLB(id)->Freeze();
+ Clear();
+ wxStringTokenizer tkzr(stc2wx(list), (wxChar)separator);
+ while ( tkzr.HasMoreTokens() ) {
+ wxString token = tkzr.GetNextToken();
+ long type = -1;
+ int pos = token.Find(typesep);
+ if (pos != -1) {
+ token.Mid(pos+1).ToLong(&type);
+ token.Truncate(pos);
+ }
+ Append(token, (int)type);
+ }
+ GETLB(id)->Thaw();
+}
+
int ListBoxImpl::Length() {
return GETLB(id)->GetItemCount();
}
-
ListBox::ListBox() {
}
'AutoCGetTypeSeparator' : ('AutoCompGetTypeSeparator', 0, 0, 0),
'AutoCSetTypeSeparator' : ('AutoCompSetTypeSeparator', 0, 0, 0),
'AutoCGetCurrent' : ('AutoCompGetCurrent', 0, 0, 0),
-
+ 'AutoCSetMaxWidth' : ('AutoCompSetMaxWidth', 0, 0, 0),
+ 'AutoCGetMaxWidth' : ('AutoCompGetMaxWidth', 0, 0, 0),
+ 'AutoCSetMaxHeight' : ('AutoCompSetMaxHeight', 0, 0, 0),
+ 'AutoCGetMaxHeight' : ('AutoCompGetMaxHeight', 0, 0, 0),
+ 'AutoCGetMaxHeight' : ('AutoCompGetMaxHeight', 0, 0, 0),
+
'RegisterImage' :
(0,
'''void %s(int type, const wxBitmap& bmp);''',
'TargetAsUTF8' : ( None, 0, 0, 0),
'SetLengthForEncode' : ( None, 0, 0, 0),
'EncodedFromUTF8' : ( None, 0, 0, 0),
-
+
+
+ 'GetProperty' :
+ (0,
+ 'wxString %s(const wxString& key);',
+
+ '''wxString %s(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTY, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(%s, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);''',
+ ("Retrieve a 'property' value previously set with SetProperty.",)),
+
+ 'GetPropertyExpanded' :
+ (0,
+ 'wxString %s(const wxString& key);',
+
+ '''wxString %s(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTYEXPANDED, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(%s, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);''',
+ ("Retrieve a 'property' value previously set with SetProperty,",
+ "with '$()' variable replacement on returned buffer.")),
+
+ 'GetPropertyInt' : (0, 0, 0,
+ ("Retrieve a 'property' value previously set with SetProperty,",
+ "interpreted as an int AFTER any '$()' variable replacement.")),
+
'GetDocPointer' :
(0,
distribution. All other code needed to implement Scintilla on top of
wxWindows is located in the directory above this one.
-The current version of the Scintilla code is 1.62
+The current version of the Scintilla code is 1.67
LexerFunction fnLexer;
LexerFunction fnFolder;
const char * const * wordListDescriptions;
+ int styleBits;
static const LexerModule *base;
static int nextLanguage;
public:
const char *languageName;
- LexerModule(int language_, LexerFunction fnLexer_,
- const char *languageName_=0, LexerFunction fnFolder_=0,
- const char * const wordListDescriptions_[] = NULL);
+ LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_=0,
+ LexerFunction fnFolder_=0,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=5);
+ virtual ~LexerModule() {
+ }
int GetLanguage() const { return language; }
// -1 is returned if no WordList information is available
int GetNumWordLists() const;
const char *GetWordListDescription(int index) const;
+ int GetStyleBitsNeeded() const;
+
virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
static ListBox *Allocate();
virtual void SetFont(Font &font)=0;
- virtual void Create(Window &parent, int ctrlID, int lineHeight_, bool unicodeMode_)=0;
+ virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0;
virtual void SetAverageCharWidth(int width)=0;
virtual void SetVisibleRows(int rows)=0;
+ virtual int GetVisibleRows() const=0;
virtual PRectangle GetDesiredRect()=0;
virtual int CaretFromEdge()=0;
virtual void Clear()=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
+ virtual void SetList(const char* list, char separator, char typesep)=0;
};
/**
Property *props[hashRoots];
Property *enumnext;
int enumhash;
+ static bool caseSensitiveFilenames;
static unsigned int HashString(const char *s, size_t len) {
unsigned int ret = 0;
while (len--) {
char *ToString(); // Caller must delete[] the return value
bool GetFirst(char **key, char **val);
bool GetNext(char **key, char **val);
+ static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) {
+ caseSensitiveFilenames = caseSensitiveFilenames_;
+ }
private:
- // copy-value semantics not implemented
+ // copy-value semantics not implemented
PropSet(const PropSet ©);
void operator=(const PropSet &assign);
};
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
bool sorted;
+ bool sortedNoCase;
int starts[256];
WordList(bool onlyLineEnds_ = false) :
- words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), sorted(false) {}
+ words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
+ sorted(false), sortedNoCase(false) {}
~WordList() { Clear(); }
operator bool() { return len ? true : false; }
char *operator[](int ind) { return words[ind]; }
char *Allocate(int size);
void SetFromAllocated();
bool InList(const char *s);
+ bool InListAbbreviated(const char *s, const char marker);
const char *GetNearestWord(const char *wordStart, int searchLen,
bool ignoreCase = false, SString wordCharacters="", int wordIndex = -1);
char *GetNearestWords(const char *wordStart, int searchLen,
bool operator!=(const char *sOther) const {
return !operator==(sOther);
}
- bool contains(char ch) {
+ bool contains(char ch) const {
return (s && *s) ? strchr(s, ch) != 0 : false;
}
void setsizegrowth(lenpos_t sizeGrowth_) {
bool startswith(const char *prefix);
bool endswith(const char *suffix);
int search(const char *sFind, lenpos_t start=0) const;
- bool contains(const char *sFind) {
+ bool contains(const char *sFind) const {
return search(sFind) >= 0;
}
int substitute(char chFind, char chReplace);
#define SCLEX_NNCRONTAB 26
#define SCLEX_BULLANT 27
#define SCLEX_VBSCRIPT 28
-#define SCLEX_ASP 29
-#define SCLEX_PHP 30
#define SCLEX_BAAN 31
#define SCLEX_MATLAB 32
#define SCLEX_SCRIPTOL 33
#define SCLEX_BASH 62
#define SCLEX_ASN1 63
#define SCLEX_VHDL 64
+#define SCLEX_CAML 65
+#define SCLEX_BLITZBASIC 66
+#define SCLEX_PUREBASIC 67
+#define SCLEX_HASKELL 68
+#define SCLEX_PHPSCRIPT 69
+#define SCLEX_TADS3 70
+#define SCLEX_REBOL 71
+#define SCLEX_SMALLTALK 72
+#define SCLEX_FLAGSHIP 73
+#define SCLEX_CSOUND 74
+#define SCLEX_FREEBASIC 75
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
#define SCE_P_IDENTIFIER 11
#define SCE_P_COMMENTBLOCK 12
#define SCE_P_STRINGEOL 13
+#define SCE_P_WORD2 14
+#define SCE_P_DECORATOR 15
#define SCE_C_DEFAULT 0
#define SCE_C_COMMENT 1
#define SCE_C_COMMENTLINE 2
#define SCE_PL_ARRAY 13
#define SCE_PL_HASH 14
#define SCE_PL_SYMBOLTABLE 15
+#define SCE_PL_VARIABLE_INDEXER 16
#define SCE_PL_REGEX 17
#define SCE_PL_REGSUBST 18
#define SCE_PL_LONGQUOTE 19
#define SCE_PL_STRING_QX 28
#define SCE_PL_STRING_QR 29
#define SCE_PL_STRING_QW 30
+#define SCE_PL_POD_VERB 31
+#define SCE_RB_DEFAULT 0
+#define SCE_RB_ERROR 1
+#define SCE_RB_COMMENTLINE 2
+#define SCE_RB_POD 3
+#define SCE_RB_NUMBER 4
+#define SCE_RB_WORD 5
+#define SCE_RB_STRING 6
+#define SCE_RB_CHARACTER 7
+#define SCE_RB_CLASSNAME 8
+#define SCE_RB_DEFNAME 9
+#define SCE_RB_OPERATOR 10
+#define SCE_RB_IDENTIFIER 11
+#define SCE_RB_REGEX 12
+#define SCE_RB_GLOBAL 13
+#define SCE_RB_SYMBOL 14
+#define SCE_RB_MODULE_NAME 15
+#define SCE_RB_INSTANCE_VAR 16
+#define SCE_RB_CLASS_VAR 17
+#define SCE_RB_BACKTICKS 18
+#define SCE_RB_DATASECTION 19
+#define SCE_RB_HERE_DELIM 20
+#define SCE_RB_HERE_Q 21
+#define SCE_RB_HERE_QQ 22
+#define SCE_RB_HERE_QX 23
+#define SCE_RB_STRING_Q 24
+#define SCE_RB_STRING_QQ 25
+#define SCE_RB_STRING_QX 26
+#define SCE_RB_STRING_QR 27
+#define SCE_RB_STRING_QW 28
+#define SCE_RB_WORD_DEMOTED 29
+#define SCE_RB_STDIN 30
+#define SCE_RB_STDOUT 31
+#define SCE_RB_STDERR 40
+#define SCE_RB_UPPER_BOUND 41
#define SCE_B_DEFAULT 0
#define SCE_B_COMMENT 1
#define SCE_B_NUMBER 2
#define SCE_B_KEYWORD4 12
#define SCE_B_CONSTANT 13
#define SCE_B_ASM 14
+#define SCE_B_LABEL 15
+#define SCE_B_ERROR 16
+#define SCE_B_HEXNUMBER 17
+#define SCE_B_BINNUMBER 18
#define SCE_PROPS_DEFAULT 0
#define SCE_PROPS_COMMENT 1
#define SCE_PROPS_SECTION 2
#define SCE_LISP_COMMENT 1
#define SCE_LISP_NUMBER 2
#define SCE_LISP_KEYWORD 3
+#define SCE_LISP_KEYWORD_KW 4
+#define SCE_LISP_SYMBOL 5
#define SCE_LISP_STRING 6
#define SCE_LISP_STRINGEOL 8
#define SCE_LISP_IDENTIFIER 9
#define SCE_LISP_OPERATOR 10
+#define SCE_LISP_SPECIAL 11
+#define SCE_LISP_MULTI_COMMENT 12
#define SCE_EIFFEL_DEFAULT 0
#define SCE_EIFFEL_COMMENTLINE 1
#define SCE_EIFFEL_NUMBER 2
#define SCE_CSS_DOUBLESTRING 13
#define SCE_CSS_SINGLESTRING 14
#define SCE_CSS_IDENTIFIER2 15
+#define SCE_CSS_ATTRIBUTE 16
#define SCE_POV_DEFAULT 0
#define SCE_POV_COMMENT 1
#define SCE_POV_COMMENTLINE 2
#define SCE_NSIS_MACRODEF 12
#define SCE_NSIS_STRINGVAR 13
#define SCE_NSIS_NUMBER 14
+#define SCE_NSIS_SECTIONGROUP 15
+#define SCE_NSIS_PAGEEX 16
+#define SCE_NSIS_FUNCTIONDEF 17
+#define SCE_NSIS_COMMENTBOX 18
#define SCE_MMIXAL_LEADWS 0
#define SCE_MMIXAL_COMMENT 1
#define SCE_MMIXAL_LABEL 2
#define SCE_CLW_PICTURE_STRING 7
#define SCE_CLW_KEYWORD 8
#define SCE_CLW_COMPILER_DIRECTIVE 9
-#define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 10
-#define SCE_CLW_STRUCTURE_DATA_TYPE 11
-#define SCE_CLW_ATTRIBUTE 12
-#define SCE_CLW_STANDARD_EQUATE 13
-#define SCE_CLW_ERROR 14
+#define SCE_CLW_RUNTIME_EXPRESSIONS 10
+#define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 11
+#define SCE_CLW_STRUCTURE_DATA_TYPE 12
+#define SCE_CLW_ATTRIBUTE 13
+#define SCE_CLW_STANDARD_EQUATE 14
+#define SCE_CLW_ERROR 15
+#define SCE_CLW_DEPRECATED 16
#define SCE_LOT_DEFAULT 0
#define SCE_LOT_HEADER 1
#define SCE_LOT_BREAK 2
#define SCE_AU3_SENT 10
#define SCE_AU3_PREPROCESSOR 11
#define SCE_AU3_SPECIAL 12
+#define SCE_AU3_EXPAND 13
+#define SCE_AU3_COMOBJ 14
#define SCE_APDL_DEFAULT 0
#define SCE_APDL_COMMENT 1
#define SCE_APDL_COMMENTBLOCK 2
#define SCE_VHDL_STDPACKAGE 12
#define SCE_VHDL_STDTYPE 13
#define SCE_VHDL_USERWORD 14
+#define SCE_CAML_DEFAULT 0
+#define SCE_CAML_IDENTIFIER 1
+#define SCE_CAML_TAGNAME 2
+#define SCE_CAML_KEYWORD 3
+#define SCE_CAML_KEYWORD2 4
+#define SCE_CAML_KEYWORD3 5
+#define SCE_CAML_LINENUM 6
+#define SCE_CAML_OPERATOR 7
+#define SCE_CAML_NUMBER 8
+#define SCE_CAML_CHAR 9
+#define SCE_CAML_STRING 11
+#define SCE_CAML_COMMENT 12
+#define SCE_CAML_COMMENT1 13
+#define SCE_CAML_COMMENT2 14
+#define SCE_CAML_COMMENT3 15
+#define SCE_HA_DEFAULT 0
+#define SCE_HA_IDENTIFIER 1
+#define SCE_HA_KEYWORD 2
+#define SCE_HA_NUMBER 3
+#define SCE_HA_STRING 4
+#define SCE_HA_CHARACTER 5
+#define SCE_HA_CLASS 6
+#define SCE_HA_MODULE 7
+#define SCE_HA_CAPITAL 8
+#define SCE_HA_DATA 9
+#define SCE_HA_IMPORT 10
+#define SCE_HA_OPERATOR 11
+#define SCE_HA_INSTANCE 12
+#define SCE_HA_COMMENTLINE 13
+#define SCE_HA_COMMENTBLOCK 14
+#define SCE_HA_COMMENTBLOCK2 15
+#define SCE_HA_COMMENTBLOCK3 16
+#define SCE_T3_DEFAULT 0
+#define SCE_T3_X_DEFAULT 1
+#define SCE_T3_PREPROCESSOR 2
+#define SCE_T3_BLOCK_COMMENT 3
+#define SCE_T3_LINE_COMMENT 4
+#define SCE_T3_OPERATOR 5
+#define SCE_T3_KEYWORD 6
+#define SCE_T3_NUMBER 7
+#define SCE_T3_IDENTIFIER 8
+#define SCE_T3_S_STRING 9
+#define SCE_T3_D_STRING 10
+#define SCE_T3_X_STRING 11
+#define SCE_T3_LIB_DIRECTIVE 12
+#define SCE_T3_MSG_PARAM 13
+#define SCE_T3_HTML_TAG 14
+#define SCE_T3_HTML_DEFAULT 15
+#define SCE_T3_HTML_STRING 16
+#define SCE_T3_USER1 17
+#define SCE_T3_USER2 18
+#define SCE_T3_USER3 19
+#define SCE_REBOL_DEFAULT 0
+#define SCE_REBOL_COMMENTLINE 1
+#define SCE_REBOL_COMMENTBLOCK 2
+#define SCE_REBOL_PREFACE 3
+#define SCE_REBOL_OPERATOR 4
+#define SCE_REBOL_CHARACTER 5
+#define SCE_REBOL_QUOTEDSTRING 6
+#define SCE_REBOL_BRACEDSTRING 7
+#define SCE_REBOL_NUMBER 8
+#define SCE_REBOL_PAIR 9
+#define SCE_REBOL_TUPLE 10
+#define SCE_REBOL_BINARY 11
+#define SCE_REBOL_MONEY 12
+#define SCE_REBOL_ISSUE 13
+#define SCE_REBOL_TAG 14
+#define SCE_REBOL_FILE 15
+#define SCE_REBOL_EMAIL 16
+#define SCE_REBOL_URL 17
+#define SCE_REBOL_DATE 18
+#define SCE_REBOL_TIME 19
+#define SCE_REBOL_IDENTIFIER 20
+#define SCE_REBOL_WORD 21
+#define SCE_REBOL_WORD2 22
+#define SCE_REBOL_WORD3 23
+#define SCE_REBOL_WORD4 24
+#define SCE_REBOL_WORD5 25
+#define SCE_REBOL_WORD6 26
+#define SCE_REBOL_WORD7 27
+#define SCE_REBOL_WORD8 28
+#define SCE_SQL_DEFAULT 0
+#define SCE_SQL_COMMENT 1
+#define SCE_SQL_COMMENTLINE 2
+#define SCE_SQL_COMMENTDOC 3
+#define SCE_SQL_NUMBER 4
+#define SCE_SQL_WORD 5
+#define SCE_SQL_STRING 6
+#define SCE_SQL_CHARACTER 7
+#define SCE_SQL_SQLPLUS 8
+#define SCE_SQL_SQLPLUS_PROMPT 9
+#define SCE_SQL_OPERATOR 10
+#define SCE_SQL_IDENTIFIER 11
+#define SCE_SQL_SQLPLUS_COMMENT 13
+#define SCE_SQL_COMMENTLINEDOC 15
+#define SCE_SQL_WORD2 16
+#define SCE_SQL_COMMENTDOCKEYWORD 17
+#define SCE_SQL_COMMENTDOCKEYWORDERROR 18
+#define SCE_SQL_USER1 19
+#define SCE_SQL_USER2 20
+#define SCE_SQL_USER3 21
+#define SCE_SQL_USER4 22
+#define SCE_SQL_QUOTEDIDENTIFIER 23
+#define SCE_ST_DEFAULT 0
+#define SCE_ST_STRING 1
+#define SCE_ST_NUMBER 2
+#define SCE_ST_COMMENT 3
+#define SCE_ST_SYMBOL 4
+#define SCE_ST_BINARY 5
+#define SCE_ST_BOOL 6
+#define SCE_ST_SELF 7
+#define SCE_ST_SUPER 8
+#define SCE_ST_NIL 9
+#define SCE_ST_GLOBAL 10
+#define SCE_ST_RETURN 11
+#define SCE_ST_SPECIAL 12
+#define SCE_ST_KWSEND 13
+#define SCE_ST_ASSIGN 14
+#define SCE_ST_CHARACTER 15
+#define SCE_ST_SPEC_SEL 16
+#define SCE_FS_DEFAULT 0
+#define SCE_FS_COMMENT 1
+#define SCE_FS_COMMENTLINE 2
+#define SCE_FS_COMMENTDOC 3
+#define SCE_FS_COMMENTLINEDOC 4
+#define SCE_FS_COMMENTDOCKEYWORD 5
+#define SCE_FS_COMMENTDOCKEYWORDERROR 6
+#define SCE_FS_KEYWORD 7
+#define SCE_FS_KEYWORD2 8
+#define SCE_FS_KEYWORD3 9
+#define SCE_FS_KEYWORD4 10
+#define SCE_FS_NUMBER 11
+#define SCE_FS_STRING 12
+#define SCE_FS_PREPROCESSOR 13
+#define SCE_FS_OPERATOR 14
+#define SCE_FS_IDENTIFIER 15
+#define SCE_FS_DATE 16
+#define SCE_FS_STRINGEOL 17
+#define SCE_FS_CONSTANT 18
+#define SCE_FS_ASM 19
+#define SCE_FS_LABEL 20
+#define SCE_FS_ERROR 21
+#define SCE_FS_HEXNUMBER 22
+#define SCE_FS_BINNUMBER 23
+#define SCE_CSOUND_DEFAULT 0
+#define SCE_CSOUND_COMMENT 1
+#define SCE_CSOUND_NUMBER 2
+#define SCE_CSOUND_OPERATOR 3
+#define SCE_CSOUND_INSTR 4
+#define SCE_CSOUND_IDENTIFIER 5
+#define SCE_CSOUND_OPCODE 6
+#define SCE_CSOUND_HEADERSTMT 7
+#define SCE_CSOUND_USERKEYWORD 8
+#define SCE_CSOUND_COMMENTBLOCK 9
+#define SCE_CSOUND_PARAM 10
+#define SCE_CSOUND_ARATE_VAR 11
+#define SCE_CSOUND_KRATE_VAR 12
+#define SCE_CSOUND_IRATE_VAR 13
+#define SCE_CSOUND_GLOBAL_VAR 14
+#define SCE_CSOUND_STRINGEOL 15
+#define SCLEX_ASP 29
+#define SCLEX_PHP 30
//--Autogenerated -- end of section automatically generated from Scintilla.iface
#endif
#ifndef SCINTILLA_H
#define SCINTILLA_H
-#ifdef PLAT_WIN
+#if LCCWIN
+typedef BOOL bool;
+#endif
+
#if PLAT_WIN
// Return false on failure:
bool Scintilla_RegisterClasses(void *hInstance);
bool Scintilla_ReleaseResources();
#endif
-#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 _MSC_VER
#if _MSC_VER >= 1300
#include <BaseTsd.h>
#endif
-#endif
#ifdef MAXULONG_PTR
typedef ULONG_PTR uptr_t;
typedef LONG_PTR sptr_t;
#define SC_MARK_DOTDOTDOT 23
#define SC_MARK_ARROWS 24
#define SC_MARK_PIXMAP 25
+#define SC_MARK_FULLRECT 26
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
#define SCI_MARKERNEXT 2047
#define SCI_MARKERPREVIOUS 2048
#define SCI_MARKERDEFINEPIXMAP 2049
+#define SCI_MARKERADDSET 2466
#define SC_MARGIN_SYMBOL 0
#define SC_MARGIN_NUMBER 1
#define SCI_SETMARGINTYPEN 2240
#define SC_CHARSET_MAC 77
#define SC_CHARSET_OEM 255
#define SC_CHARSET_RUSSIAN 204
+#define SC_CHARSET_CYRILLIC 1251
#define SC_CHARSET_SHIFTJIS 128
#define SC_CHARSET_SYMBOL 2
#define SC_CHARSET_TURKISH 162
#define SC_CHARSET_ARABIC 178
#define SC_CHARSET_VIETNAMESE 163
#define SC_CHARSET_THAI 222
+#define SC_CHARSET_8859_15 1000
#define SCI_STYLECLEARALL 2050
#define SCI_STYLESETFORE 2051
#define SCI_STYLESETBACK 2052
#define SCI_CLEARREGISTEREDIMAGES 2408
#define SCI_AUTOCGETTYPESEPARATOR 2285
#define SCI_AUTOCSETTYPESEPARATOR 2286
+#define SCI_AUTOCSETMAXWIDTH 2208
+#define SCI_AUTOCGETMAXWIDTH 2209
+#define SCI_AUTOCSETMAXHEIGHT 2210
+#define SCI_AUTOCGETMAXHEIGHT 2211
#define SCI_SETINDENT 2122
#define SCI_GETINDENT 2123
#define SCI_SETUSETABS 2124
#define SCI_CALLTIPSETFOREHLT 2207
#define SCI_VISIBLEFROMDOCLINE 2220
#define SCI_DOCLINEFROMVISIBLE 2221
+#define SCI_WRAPCOUNT 2235
#define SC_FOLDLEVELBASE 0x400
#define SC_FOLDLEVELWHITEFLAG 0x1000
#define SC_FOLDLEVELHEADERFLAG 0x2000
#define SCI_WORDENDPOSITION 2267
#define SC_WRAP_NONE 0
#define SC_WRAP_WORD 1
+#define SC_WRAP_CHAR 2
#define SCI_SETWRAPMODE 2268
#define SCI_GETWRAPMODE 2269
#define SC_WRAPVISUALFLAG_NONE 0x0000
#define SCI_SETLENGTHFORENCODE 2448
#define SCI_ENCODEDFROMUTF8 2449
#define SCI_FINDCOLUMN 2456
+#define SCI_GETCARETSTICKY 2457
+#define SCI_SETCARETSTICKY 2458
+#define SCI_TOGGLECARETSTICKY 2459
+#define SCI_SETPASTECONVERTENDINGS 2467
+#define SCI_GETPASTECONVERTENDINGS 2468
+#define SCI_SELECTIONDUPLICATE 2469
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
#define SCI_SETKEYWORDS 4005
#define SCI_SETLEXERLANGUAGE 4006
#define SCI_LOADLEXERLIBRARY 4007
+#define SCI_GETPROPERTY 4008
+#define SCI_GETPROPERTYEXPANDED 4009
+#define SCI_GETPROPERTYINT 4010
+#define SCI_GETSTYLEBITSNEEDED 4011
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
#define SC_PERFORMED_USER 0x10
#define SC_PERFORMED_UNDO 0x20
#define SC_PERFORMED_REDO 0x40
+#define SC_MULTISTEPUNDOREDO 0x80
#define SC_LASTSTEPINUNDOREDO 0x100
#define SC_MOD_CHANGEMARKER 0x200
#define SC_MOD_BEFOREINSERT 0x400
#define SC_MOD_BEFOREDELETE 0x800
-#define SC_MODEVENTMASKALL 0xF77
+#define SC_MULTILINEUNDOREDO 0x1000
+#define SC_MODEVENTMASKALL 0x1FFF
#define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256
#define SCK_ADD 310
#define SCK_SUBTRACT 311
#define SCK_DIVIDE 312
+#define SCMOD_NORM 0
#define SCMOD_SHIFT 1
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCN_HOTSPOTCLICK 2019
#define SCN_HOTSPOTDOUBLECLICK 2020
#define SCN_CALLTIPCLICK 2021
+#define SCN_AUTOCSELECTION 2022
//--Autogenerated -- end of section automatically generated from Scintilla.iface
// These structures are defined to be exactly the same shape as the Win32
#endif
struct NotifyHeader {
- // hwndFrom is really an environment specifc window handle or pointer
+ // 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.
- //WindowID hwndFrom;
void *hwndFrom;
- unsigned int idFrom;
+ uptr_t idFrom;
unsigned int code;
};
int ch; // SCN_CHARADDED, SCN_KEY
int modifiers; // SCN_KEY
int modificationType; // SCN_MODIFIED
- const char *text; // SCN_MODIFIED
+ const char *text; // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION
int length; // SCN_MODIFIED
int linesAdded; // SCN_MODIFIED
int message; // SCN_MACRORECORD
val SC_MARK_DOTDOTDOT=23
val SC_MARK_ARROWS=24
val SC_MARK_PIXMAP=25
+val SC_MARK_FULLRECT=26
val SC_MARK_CHARACTER=10000
# Define a marker from a pixmap.
fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
+# Add a set of markers to a line.
+fun void MarkerAddSet=2466(int line, int set)
+
enu MarginType=SC_MARGIN_
val SC_MARGIN_SYMBOL=0
val SC_MARGIN_NUMBER=1
val SC_CHARSET_MAC=77
val SC_CHARSET_OEM=255
val SC_CHARSET_RUSSIAN=204
+val SC_CHARSET_CYRILLIC=1251
val SC_CHARSET_SHIFTJIS=128
val SC_CHARSET_SYMBOL=2
val SC_CHARSET_TURKISH=162
val SC_CHARSET_ARABIC=178
val SC_CHARSET_VIETNAMESE=163
val SC_CHARSET_THAI=222
+val SC_CHARSET_8859_15=1000
# Clear all the styles and make equivalent to the global default style.
set void StyleClearAll=2050(,)
# Default is '?' but can be changed if items contain '?'.
set void AutoCSetTypeSeparator=2286(int separatorCharacter,)
+# Set the maximum width, in characters, of auto-completion and user lists.
+# Set to 0 to autosize to fit longest item, which is the default.
+set void AutoCSetMaxWidth=2208(int characterCount,)
+
+# Get the maximum width, in characters, of auto-completion and user lists.
+get int AutoCGetMaxWidth=2209(,)
+
+# Set the maximum height, in rows, of auto-completion and user lists.
+# The default is 5 rows.
+set void AutoCSetMaxHeight=2210(int rowCount,)
+
+# Set the maximum height, in rows, of auto-completion and user lists.
+get int AutoCGetMaxHeight=2211(,)
+
# Set the number of spaces used for one level of indentation.
set void SetIndent=2122(int indentSize,)
# Find the document line of a display line taking hidden lines into account.
fun int DocLineFromVisible=2221(int lineDisplay,)
+# The number of display lines needed to wrap a document line
+fun int WrapCount=2235(int line,)
+
enu FoldLevel=SC_FOLDLEVEL
val SC_FOLDLEVELBASE=0x400
val SC_FOLDLEVELWHITEFLAG=0x1000
enu Wrap=SC_WRAP_
val SC_WRAP_NONE=0
val SC_WRAP_WORD=1
+val SC_WRAP_CHAR=2
# Sets whether text is word wrapped.
set void SetWrapMode=2268(int mode,)
# Retrieve whether the maximum scroll position has the last
# line at the bottom of the view.
-get int GetEndAtLastLine=2278(,)
+get bool GetEndAtLastLine=2278(,)
# Retrieve the height of a particular line of text in pixels.
fun int TextHeight=2279(int line,)
fun int TargetAsUTF8=2447(, stringresult s)
# Set the length of the utf8 argument for calling EncodedFromUTF8.
-# Set to 0 and the string will be measured to the first nul.
+# Set to -1 and the string will be measured to the first nul.
fun void SetLengthForEncode=2448(int bytes,)
# Translates a UTF8 string into the document encoding.
# On error return 0.
fun int EncodedFromUTF8=2449(string utf8, stringresult encoded)
-# Find the position of a column on a line taking into account tabs and
+# Find the position of a column on a line taking into account tabs and
# multi-byte characters. If beyond end of line, return line end position.
fun int FindColumn=2456(int line, int column)
+# Can the caret preferred x position only be changed by explicit movement commands?
+get bool GetCaretSticky=2457(,)
+
+# Stop the caret preferred x position changing when the user types.
+set void SetCaretSticky=2458(bool useCaretStickyBehaviour,)
+
+# Switch between sticky and non-sticky: meant to be bound to a key.
+fun void ToggleCaretSticky=2459(,)
+
+# Enable/Disable convert-on-paste for line endings
+set void SetPasteConvertEndings=2467(bool convert,)
+
+# Get convert-on-paste setting
+get bool GetPasteConvertEndings=2468(,)
+
+# Duplicate the selection. If selection empty duplicate the line containing the caret.
+fun void SelectionDuplicate=2469(,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
# Load a lexer library (dll / so).
fun void LoadLexerLibrary=4007(, string path)
+# Retrieve a "property" value previously set with SetProperty.
+fun int GetProperty=4008(string key, stringresult buf)
+
+# Retrieve a "property" value previously set with SetProperty,
+# with "$()" variable replacement on returned buffer.
+fun int GetPropertyExpanded=4009(string key, stringresult buf)
+
+# Retrieve a "property" value previously set with SetProperty,
+# interpreted as an int AFTER any "$()" variable replacement.
+get int GetPropertyInt=4010(string key,)
+
+# Retrieve the number of bits the current lexer needs for styling.
+get int GetStyleBitsNeeded=4011(,)
+
# 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_PERFORMED_USER=0x10
val SC_PERFORMED_UNDO=0x20
val SC_PERFORMED_REDO=0x40
+val SC_MULTISTEPUNDOREDO=0x80
val SC_LASTSTEPINUNDOREDO=0x100
val SC_MOD_CHANGEMARKER=0x200
val SC_MOD_BEFOREINSERT=0x400
val SC_MOD_BEFOREDELETE=0x800
-val SC_MODEVENTMASKALL=0xF77
+val SC_MULTILINEUNDOREDO=0x1000
+val SC_MODEVENTMASKALL=0x1FFF
# For compatibility, these go through the COMMAND notification rather than NOTIFY
# and should have had exactly the same values as the EN_* constants.
val SCK_DIVIDE=312
enu KeyMod=SCMOD_
+val SCMOD_NORM=0
val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCLEX_NNCRONTAB=26
val SCLEX_BULLANT=27
val SCLEX_VBSCRIPT=28
-val SCLEX_ASP=29
-val SCLEX_PHP=30
val SCLEX_BAAN=31
val SCLEX_MATLAB=32
val SCLEX_SCRIPTOL=33
val SCLEX_BASH=62
val SCLEX_ASN1=63
val SCLEX_VHDL=64
+val SCLEX_CAML=65
+val SCLEX_BLITZBASIC=66
+val SCLEX_PUREBASIC=67
+val SCLEX_HASKELL=68
+val SCLEX_PHPSCRIPT=69
+val SCLEX_TADS3=70
+val SCLEX_REBOL=71
+val SCLEX_SMALLTALK=72
+val SCLEX_FLAGSHIP=73
+val SCLEX_CSOUND=74
+val SCLEX_FREEBASIC=75
# 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 Ruby=SCLEX_RUBY SCE_P_
val SCE_P_DEFAULT=0
val SCE_P_COMMENTLINE=1
val SCE_P_NUMBER=2
val SCE_P_IDENTIFIER=11
val SCE_P_COMMENTBLOCK=12
val SCE_P_STRINGEOL=13
+val SCE_P_WORD2=14
+val SCE_P_DECORATOR=15
# Lexical states for SCLEX_CPP
lex Cpp=SCLEX_CPP SCE_C_
-lex SQL=SCLEX_SQL SCE_C_
lex Pascal=SCLEX_PASCAL SCE_C_
lex TCL=SCLEX_TCL SCE_C_
lex BullAnt=SCLEX_BULLANT SCE_C_
val SCE_PL_ARRAY=13
val SCE_PL_HASH=14
val SCE_PL_SYMBOLTABLE=15
+val SCE_PL_VARIABLE_INDEXER=16
val SCE_PL_REGEX=17
val SCE_PL_REGSUBST=18
val SCE_PL_LONGQUOTE=19
val SCE_PL_STRING_QX=28
val SCE_PL_STRING_QR=29
val SCE_PL_STRING_QW=30
+val SCE_PL_POD_VERB=31
+# Lexical states for SCLEX_RUBY
+lex Ruby=SCLEX_RUBY SCE_RB_
+val SCE_RB_DEFAULT=0
+val SCE_RB_ERROR=1
+val SCE_RB_COMMENTLINE=2
+val SCE_RB_POD=3
+val SCE_RB_NUMBER=4
+val SCE_RB_WORD=5
+val SCE_RB_STRING=6
+val SCE_RB_CHARACTER=7
+val SCE_RB_CLASSNAME=8
+val SCE_RB_DEFNAME=9
+val SCE_RB_OPERATOR=10
+val SCE_RB_IDENTIFIER=11
+val SCE_RB_REGEX=12
+val SCE_RB_GLOBAL=13
+val SCE_RB_SYMBOL=14
+val SCE_RB_MODULE_NAME=15
+val SCE_RB_INSTANCE_VAR=16
+val SCE_RB_CLASS_VAR=17
+val SCE_RB_BACKTICKS=18
+val SCE_RB_DATASECTION=19
+val SCE_RB_HERE_DELIM=20
+val SCE_RB_HERE_Q=21
+val SCE_RB_HERE_QQ=22
+val SCE_RB_HERE_QX=23
+val SCE_RB_STRING_Q=24
+val SCE_RB_STRING_QQ=25
+val SCE_RB_STRING_QX=26
+val SCE_RB_STRING_QR=27
+val SCE_RB_STRING_QW=28
+val SCE_RB_WORD_DEMOTED=29
+val SCE_RB_STDIN=30
+val SCE_RB_STDOUT=31
+val SCE_RB_STDERR=40
+val SCE_RB_UPPER_BOUND=41
# Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC
lex VB=SCLEX_VB SCE_B_
lex VBScript=SCLEX_VBSCRIPT SCE_B_
val SCE_B_KEYWORD4=12
val SCE_B_CONSTANT=13
val SCE_B_ASM=14
+val SCE_B_LABEL=15
+val SCE_B_ERROR=16
+val SCE_B_HEXNUMBER=17
+val SCE_B_BINNUMBER=18
# Lexical states for SCLEX_PROPERTIES
lex Properties=SCLEX_PROPERTIES SCE_PROPS_
val SCE_PROPS_DEFAULT=0
val SCE_LISP_COMMENT=1
val SCE_LISP_NUMBER=2
val SCE_LISP_KEYWORD=3
+val SCE_LISP_KEYWORD_KW=4
+val SCE_LISP_SYMBOL=5
val SCE_LISP_STRING=6
val SCE_LISP_STRINGEOL=8
val SCE_LISP_IDENTIFIER=9
val SCE_LISP_OPERATOR=10
+val SCE_LISP_SPECIAL=11
+val SCE_LISP_MULTI_COMMENT=12
# Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW
lex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_
lex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_
val SCE_CSS_DOUBLESTRING=13
val SCE_CSS_SINGLESTRING=14
val SCE_CSS_IDENTIFIER2=15
+val SCE_CSS_ATTRIBUTE=16
# Lexical states for SCLEX_POV
lex POV=SCLEX_POV SCE_POV_
val SCE_POV_DEFAULT=0
val SCE_NSIS_MACRODEF=12
val SCE_NSIS_STRINGVAR=13
val SCE_NSIS_NUMBER=14
+val SCE_NSIS_SECTIONGROUP=15
+val SCE_NSIS_PAGEEX=16
+val SCE_NSIS_FUNCTIONDEF=17
+val SCE_NSIS_COMMENTBOX=18
# Lexical states for SCLEX_MMIXAL
lex MMIXAL=SCLEX_MMIXAL SCE_MMIXAL_
val SCE_MMIXAL_LEADWS=0
val SCE_CLW_PICTURE_STRING=7
val SCE_CLW_KEYWORD=8
val SCE_CLW_COMPILER_DIRECTIVE=9
-val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=10
-val SCE_CLW_STRUCTURE_DATA_TYPE=11
-val SCE_CLW_ATTRIBUTE=12
-val SCE_CLW_STANDARD_EQUATE=13
-val SCE_CLW_ERROR=14
+val SCE_CLW_RUNTIME_EXPRESSIONS=10
+val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=11
+val SCE_CLW_STRUCTURE_DATA_TYPE=12
+val SCE_CLW_ATTRIBUTE=13
+val SCE_CLW_STANDARD_EQUATE=14
+val SCE_CLW_ERROR=15
+val SCE_CLW_DEPRECATED=16
# Lexical states for SCLEX_LOT
lex LOT=SCLEX_LOT SCE_LOT_
val SCE_LOT_DEFAULT=0
val SCE_AU3_SENT=10
val SCE_AU3_PREPROCESSOR=11
val SCE_AU3_SPECIAL=12
+val SCE_AU3_EXPAND=13
+val SCE_AU3_COMOBJ=14
# Lexical states for SCLEX_APDL
lex APDL=SCLEX_APDL SCE_APDL_
val SCE_APDL_DEFAULT=0
val SCE_VHDL_STDPACKAGE=12
val SCE_VHDL_STDTYPE=13
val SCE_VHDL_USERWORD=14
+# Lexical states for SCLEX_CAML
+lex Caml=SCLEX_CAML SCE_CAML_
+val SCE_CAML_DEFAULT=0
+val SCE_CAML_IDENTIFIER=1
+val SCE_CAML_TAGNAME=2
+val SCE_CAML_KEYWORD=3
+val SCE_CAML_KEYWORD2=4
+val SCE_CAML_KEYWORD3=5
+val SCE_CAML_LINENUM=6
+val SCE_CAML_OPERATOR=7
+val SCE_CAML_NUMBER=8
+val SCE_CAML_CHAR=9
+val SCE_CAML_STRING=11
+val SCE_CAML_COMMENT=12
+val SCE_CAML_COMMENT1=13
+val SCE_CAML_COMMENT2=14
+val SCE_CAML_COMMENT3=15
+# Lexical states for SCLEX_HASKELL
+lex Haskell=SCLEX_HASKELL SCE_HA_
+val SCE_HA_DEFAULT=0
+val SCE_HA_IDENTIFIER=1
+val SCE_HA_KEYWORD=2
+val SCE_HA_NUMBER=3
+val SCE_HA_STRING=4
+val SCE_HA_CHARACTER=5
+val SCE_HA_CLASS=6
+val SCE_HA_MODULE=7
+val SCE_HA_CAPITAL=8
+val SCE_HA_DATA=9
+val SCE_HA_IMPORT=10
+val SCE_HA_OPERATOR=11
+val SCE_HA_INSTANCE=12
+val SCE_HA_COMMENTLINE=13
+val SCE_HA_COMMENTBLOCK=14
+val SCE_HA_COMMENTBLOCK2=15
+val SCE_HA_COMMENTBLOCK3=16
+# Lexical states of SCLEX_TADS3
+lex TADS3=SCLEX_TADS3 SCE_T3_
+val SCE_T3_DEFAULT=0
+val SCE_T3_X_DEFAULT=1
+val SCE_T3_PREPROCESSOR=2
+val SCE_T3_BLOCK_COMMENT=3
+val SCE_T3_LINE_COMMENT=4
+val SCE_T3_OPERATOR=5
+val SCE_T3_KEYWORD=6
+val SCE_T3_NUMBER=7
+val SCE_T3_IDENTIFIER=8
+val SCE_T3_S_STRING=9
+val SCE_T3_D_STRING=10
+val SCE_T3_X_STRING=11
+val SCE_T3_LIB_DIRECTIVE=12
+val SCE_T3_MSG_PARAM=13
+val SCE_T3_HTML_TAG=14
+val SCE_T3_HTML_DEFAULT=15
+val SCE_T3_HTML_STRING=16
+val SCE_T3_USER1=17
+val SCE_T3_USER2=18
+val SCE_T3_USER3=19
+# Lexical states for SCLEX_REBOL
+lex Rebol=SCLEX_REBOL SCE_REBOL_
+val SCE_REBOL_DEFAULT=0
+val SCE_REBOL_COMMENTLINE=1
+val SCE_REBOL_COMMENTBLOCK=2
+val SCE_REBOL_PREFACE=3
+val SCE_REBOL_OPERATOR=4
+val SCE_REBOL_CHARACTER=5
+val SCE_REBOL_QUOTEDSTRING=6
+val SCE_REBOL_BRACEDSTRING=7
+val SCE_REBOL_NUMBER=8
+val SCE_REBOL_PAIR=9
+val SCE_REBOL_TUPLE=10
+val SCE_REBOL_BINARY=11
+val SCE_REBOL_MONEY=12
+val SCE_REBOL_ISSUE=13
+val SCE_REBOL_TAG=14
+val SCE_REBOL_FILE=15
+val SCE_REBOL_EMAIL=16
+val SCE_REBOL_URL=17
+val SCE_REBOL_DATE=18
+val SCE_REBOL_TIME=19
+val SCE_REBOL_IDENTIFIER=20
+val SCE_REBOL_WORD=21
+val SCE_REBOL_WORD2=22
+val SCE_REBOL_WORD3=23
+val SCE_REBOL_WORD4=24
+val SCE_REBOL_WORD5=25
+val SCE_REBOL_WORD6=26
+val SCE_REBOL_WORD7=27
+val SCE_REBOL_WORD8=28
+# Lexical states for SCLEX_SQL
+lex SQL=SCLEX_SQL SCE_SQL_
+val SCE_SQL_DEFAULT=0
+val SCE_SQL_COMMENT=1
+val SCE_SQL_COMMENTLINE=2
+val SCE_SQL_COMMENTDOC=3
+val SCE_SQL_NUMBER=4
+val SCE_SQL_WORD=5
+val SCE_SQL_STRING=6
+val SCE_SQL_CHARACTER=7
+val SCE_SQL_SQLPLUS=8
+val SCE_SQL_SQLPLUS_PROMPT=9
+val SCE_SQL_OPERATOR=10
+val SCE_SQL_IDENTIFIER=11
+val SCE_SQL_SQLPLUS_COMMENT=13
+val SCE_SQL_COMMENTLINEDOC=15
+val SCE_SQL_WORD2=16
+val SCE_SQL_COMMENTDOCKEYWORD=17
+val SCE_SQL_COMMENTDOCKEYWORDERROR=18
+val SCE_SQL_USER1=19
+val SCE_SQL_USER2=20
+val SCE_SQL_USER3=21
+val SCE_SQL_USER4=22
+val SCE_SQL_QUOTEDIDENTIFIER=23
+# Lexical states for SCLEX_SMALLTALK
+lex Smalltalk=SCLEX_SMALLTALK SCE_ST_
+val SCE_ST_DEFAULT=0
+val SCE_ST_STRING=1
+val SCE_ST_NUMBER=2
+val SCE_ST_COMMENT=3
+val SCE_ST_SYMBOL=4
+val SCE_ST_BINARY=5
+val SCE_ST_BOOL=6
+val SCE_ST_SELF=7
+val SCE_ST_SUPER=8
+val SCE_ST_NIL=9
+val SCE_ST_GLOBAL=10
+val SCE_ST_RETURN=11
+val SCE_ST_SPECIAL=12
+val SCE_ST_KWSEND=13
+val SCE_ST_ASSIGN=14
+val SCE_ST_CHARACTER=15
+val SCE_ST_SPEC_SEL=16
+# Lexical states for SCLEX_FLAGSHIP (clipper)
+lex FlagShip=SCLEX_FLAGSHIP SCE_B_
+val SCE_FS_DEFAULT=0
+val SCE_FS_COMMENT=1
+val SCE_FS_COMMENTLINE=2
+val SCE_FS_COMMENTDOC=3
+val SCE_FS_COMMENTLINEDOC=4
+val SCE_FS_COMMENTDOCKEYWORD=5
+val SCE_FS_COMMENTDOCKEYWORDERROR=6
+val SCE_FS_KEYWORD=7
+val SCE_FS_KEYWORD2=8
+val SCE_FS_KEYWORD3=9
+val SCE_FS_KEYWORD4=10
+val SCE_FS_NUMBER=11
+val SCE_FS_STRING=12
+val SCE_FS_PREPROCESSOR=13
+val SCE_FS_OPERATOR=14
+val SCE_FS_IDENTIFIER=15
+val SCE_FS_DATE=16
+val SCE_FS_STRINGEOL=17
+val SCE_FS_CONSTANT=18
+val SCE_FS_ASM=19
+val SCE_FS_LABEL=20
+val SCE_FS_ERROR=21
+val SCE_FS_HEXNUMBER=22
+val SCE_FS_BINNUMBER=23
+# Lexical states for SCLEX_CSOUND
+lex Csound=SCLEX_CSOUND SCE_CSOUND_
+val SCE_CSOUND_DEFAULT=0
+val SCE_CSOUND_COMMENT=1
+val SCE_CSOUND_NUMBER=2
+val SCE_CSOUND_OPERATOR=3
+val SCE_CSOUND_INSTR=4
+val SCE_CSOUND_IDENTIFIER=5
+val SCE_CSOUND_OPCODE=6
+val SCE_CSOUND_HEADERSTMT=7
+val SCE_CSOUND_USERKEYWORD=8
+val SCE_CSOUND_COMMENTBLOCK=9
+val SCE_CSOUND_PARAM=10
+val SCE_CSOUND_ARATE_VAR=11
+val SCE_CSOUND_KRATE_VAR=12
+val SCE_CSOUND_IRATE_VAR=13
+val SCE_CSOUND_GLOBAL_VAR=14
+val SCE_CSOUND_STRINGEOL=15
# Events
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
+evt void AutoCSelection=2022(string text)
cat Deprecated
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
void (* notify) (ScintillaObject *ttt);
};
-guint scintilla_get_type (void);
+GtkType scintilla_get_type (void);
GtkWidget* scintilla_new (void);
-void scintilla_set_id (ScintillaObject *sci,int id);
+void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);
return active;
}
-void AutoComplete::Start(Window &parent, int ctrlID, int position,
- int startLen_, int lineHeight, bool unicodeMode) {
+void AutoComplete::Start(Window &parent, int ctrlID,
+ int position, Point location, int startLen_,
+ int lineHeight, bool unicodeMode) {
if (active) {
Cancel();
}
- lb->Create(parent, ctrlID, lineHeight, unicodeMode);
+ lb->Create(parent, ctrlID, location, lineHeight, unicodeMode);
lb->Clear();
active = true;
startLen = startLen_;
}
void AutoComplete::SetList(const char *list) {
- lb->Clear();
- char *words = new char[strlen(list) + 1];
- if (words) {
- strcpy(words, list);
- char *startword = words;
- char *numword = NULL;
- int i = 0;
- for (; words && words[i]; i++) {
- if (words[i] == separator) {
- words[i] = '\0';
- if (numword)
- *numword = '\0';
- lb->Append(startword, numword?atoi(numword + 1):-1);
- startword = words + i + 1;
- numword = NULL;
- } else if (words[i] == typesep) {
- numword = words + i;
- }
- }
- if (startword) {
- if (numword)
- *numword = '\0';
- lb->Append(startword, numword?atoi(numword + 1):-1);
- }
- delete []words;
- }
+ lb->SetList(list, separator, typesep);
}
-void AutoComplete::Show() {
- lb->Show();
- lb->Select(0);
+void AutoComplete::Show(bool show) {
+ lb->Show(show);
+ if (show)
+ lb->Select(0);
}
void AutoComplete::Cancel() {
if (lb->Created()) {
+ lb->Clear();
lb->Destroy();
active = false;
}
--pivot;
}
location = pivot;
+ if (ignoreCase) {
+ // Check for exact-case match
+ for (; pivot <= end; pivot++) {
+ lb->GetValue(pivot, item, maxItemLen);
+ if (!strncmp(word, item, lenWord)) {
+ location = pivot;
+ break;
+ }
+ if (CompareNCaseInsensitive(word, item, lenWord))
+ break;
+ }
+ }
} else if (cond < 0) {
end = pivot - 1;
} else if (cond > 0) {
char stopChars[256];
char fillUpChars[256];
char separator;
- char typesep; // Type separator
+ char typesep; // Type seperator
public:
bool ignoreCase;
bool Active();
/// Display the auto completion list positioned to be near a character position
- void Start(Window &parent, int ctrlID, int position,
+ void Start(Window &parent, int ctrlID, int position, Point location,
int startLen_, int lineHeight, bool unicodeMode);
/// The stop chars are characters which, when typed, cause the auto completion list to disappear
void SetSeparator(char separator_);
char GetSeparator();
- /// The typesep character is used for separating the word from the type
+ /// The typesep character is used for seperating the word from the type
void SetTypesep(char separator_);
char GetTypesep();
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
- void Show();
+ void Show(bool show);
void Cancel();
/// Move the current list element by delta, scrolling appropriately
inCallTipMode = false;
posStartCallTip = 0;
val = 0;
- xUp = -100;
- xDown = -100;
+ rectUp = PRectangle(0,0,0,0);
+ rectDown = PRectangle(0,0,0,0);
lineHeight = 1;
startHighlight = 0;
endHighlight = 0;
if (IsArrowCharacter(s[startSeg])) {
xEnd = x + widthArrow;
offsetMain = xEnd;
+ rcClient.left = x;
+ rcClient.right = xEnd;
if (draw) {
const int halfWidth = widthArrow / 2 - 3;
const int centreX = x + widthArrow / 2 - 1;
const int centreY = (rcClient.top + rcClient.bottom) / 2;
- rcClient.left = x;
- rcClient.right = xEnd;
surface->FillRectangle(rcClient, colourBG.allocated);
PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
surface->FillRectangle(rcClientInner, colourUnSel.allocated);
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
colourBG.allocated, colourBG.allocated);
}
- } else {
- if (s[startSeg] == '\001') {
- xUp = x+1;
- } else {
- xDown = x+1;
- }
+ }
+ if (s[startSeg] == '\001') {
+ rectUp = rcClient;
+ } else if (s[startSeg] == '\002') {
+ rectDown = rcClient;
}
} else {
xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
void CallTip::MouseClick(Point pt) {
clickPlace = 0;
- if (pt.y < lineHeight) {
- if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
- clickPlace = 1;
- } else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
- clickPlace = 2;
- }
- }
+ if (rectUp.Contains(pt))
+ clickPlace = 1;
+ if (rectDown.Contains(pt))
+ clickPlace = 2;
}
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
int numLines = 1;
const char *newline;
const char *look = val;
- xUp = -100;
- xDown = -100;
+ rectUp = PRectangle(0,0,0,0);
+ rectDown = PRectangle(0,0,0,0);
offsetMain = 5;
int width = PaintContents(surfaceMeasure, false) + 5;
while ((newline = strchr(look, '\n')) != NULL) {
int endHighlight;
char *val;
Font font;
- int xUp;
- int xDown;
+ PRectangle rectUp;
+ PRectangle rectDown;
int lineHeight;
int offsetMain;
// Private so CallTip objects can not be copied
linesData[i] = linesData[i + 1];
}
if (levels) {
- // Level information merges back onto previous line
- int posAbove = pos - 1;
- if (posAbove < 0)
- posAbove = 0;
- for (int j = posAbove; j < lines; j++) {
+ // Move up following lines but merge header flag from this line
+ // to line before to avoid a temporary disappearence causing expansion.
+ int firstHeader = levels[pos] & SC_FOLDLEVELHEADERFLAG;
+ for (int j = pos; j < lines; j++) {
levels[j] = levels[j + 1];
}
+ if (pos > 0)
+ levels[pos-1] |= firstHeader;
}
lines--;
}
} else if (currentAction == savePoint) {
currentAction++;
} else if ((at == insertAction) &&
- (position != (actPrevious.position + actPrevious.lenData*2))) {
+ (position != (actPrevious.position + actPrevious.lenData))) {
// Insertions must be immediately after to coalesce
currentAction++;
} else if (!actions[currentAction].mayCoalesce) {
currentAction++;
} else if (at == removeAction) {
if ((lengthData == 1) || (lengthData == 2)){
- if ((position + lengthData * 2) == actPrevious.position) {
+ if ((position + lengthData) == actPrevious.position) {
; // Backspace -> OK
} else if (position == actPrevious.position) {
; // Delete -> OK
for (int i = 0; i < insertLength / 2; i++) {
data[i] = s[i * 2];
}
- uh.AppendAction(insertAction, position, data, insertLength / 2);
+ uh.AppendAction(insertAction, position / 2, data, insertLength / 2);
}
BasicInsertString(position, s, insertLength);
return data;
}
-void CellBuffer::InsertCharStyle(int position, char ch, char style) {
- char s[2];
- s[0] = ch;
- s[1] = style;
- InsertString(position*2, s, 2);
-}
-
bool CellBuffer::SetStyleAt(int position, char style, char mask) {
style &= mask;
char curVal = ByteAt(position * 2 + 1);
const char *CellBuffer::DeleteChars(int position, int deleteLength) {
// InsertString and DeleteChars are the bottleneck though which all changes occur
+ PLATFORM_ASSERT(deleteLength > 0);
char *data = 0;
if (!readOnly) {
if (collectingUndo) {
for (int i = 0; i < deleteLength / 2; i++) {
data[i] = ByteAt(position + i * 2);
}
- uh.AppendAction(removeAction, position, data, deleteLength / 2);
+ uh.AppendAction(removeAction, position / 2, data, deleteLength / 2);
}
BasicDeleteChars(position, deleteLength);
//Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength);
if (insertLength == 0)
return ;
+ PLATFORM_ASSERT(insertLength > 0);
RoomFor(insertLength);
GapTo(position);
}
bool CellBuffer::CanUndo() {
- return (!readOnly) && (uh.CanUndo());
+ return uh.CanUndo();
}
int CellBuffer::StartUndo() {
void CellBuffer::PerformUndoStep() {
const Action &actionStep = uh.GetUndoStep();
if (actionStep.at == insertAction) {
- BasicDeleteChars(actionStep.position, actionStep.lenData*2);
+ BasicDeleteChars(actionStep.position*2, actionStep.lenData*2);
} else if (actionStep.at == removeAction) {
char *styledData = new char[actionStep.lenData * 2];
for (int i = 0; i < actionStep.lenData; i++) {
styledData[i*2] = actionStep.data[i];
styledData[i*2 + 1] = 0;
}
- BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
+ BasicInsertString(actionStep.position*2, styledData, actionStep.lenData*2);
delete []styledData;
}
uh.CompletedUndoStep();
}
bool CellBuffer::CanRedo() {
- return (!readOnly) && (uh.CanRedo());
+ return uh.CanRedo();
}
int CellBuffer::StartRedo() {
styledData[i*2] = actionStep.data[i];
styledData[i*2 + 1] = 0;
}
- BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
+ BasicInsertString(actionStep.position*2, styledData, actionStep.lenData*2);
delete []styledData;
} else if (actionStep.at == removeAction) {
- BasicDeleteChars(actionStep.position, actionStep.lenData*2);
+ BasicDeleteChars(actionStep.position*2, actionStep.lenData*2);
}
uh.CompletedRedoStep();
}
int LineStart(int line);
int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
const char *InsertString(int position, char *s, int insertLength);
- void InsertCharStyle(int position, char ch, char style);
/// Setting styles for positions outside the range of the buffer is safe and has no effect.
/// @return true if the style of a character is changed.
int Document::AddMark(int line, int markerNum) {
int prev = cb.AddMark(line, markerNum);
- DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0);
+ DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+ mh.line = line;
NotifyModified(mh);
return prev;
}
+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);
+ DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+ mh.line = line;
+ NotifyModified(mh);
+}
+
void Document::DeleteMark(int line, int markerNum) {
cb.DeleteMark(line, markerNum);
- DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0);
+ DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+ mh.line = line;
NotifyModified(mh);
}
void Document::DeleteMarkFromHandle(int markerHandle) {
cb.DeleteMarkFromHandle(markerHandle);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+ mh.line = -1;
NotifyModified(mh);
}
void Document::DeleteAllMarks(int markerNum) {
cb.DeleteAllMarks(markerNum);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+ mh.line = -1;
NotifyModified(mh);
}
return 1;
}
}
-#include <assert.h>
+
// Normalise a position so that it is not halfway through a two byte character.
// This can occur in two situations -
// When lines are terminated with \r\n pairs which should be treated as one character.
if (pos >= Length())
return Length();
- // assert pos > 0 && pos < Length()
+ // PLATFORM_ASSERT(pos > 0 && pos < Length());
if (checkLineEnd && IsCrLf(pos - 1)) {
if (moveDir > 0)
return pos + 1;
endStyled = pos;
}
+void Document::CheckReadOnly() {
+ if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
+ enteredReadOnlyCount++;
+ NotifyModifyAttempt();
+ enteredReadOnlyCount--;
+ }
+}
+
// Document only modified by gateways DeleteChars, InsertStyledString, Undo, Redo, and SetStyleAt.
// SetStyleAt does not change the persistent state of a document
return false;
if ((pos + len) > Length())
return false;
- if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
- enteredReadOnlyCount++;
- NotifyModifyAttempt();
- enteredReadOnlyCount--;
- }
+ CheckReadOnly();
if (enteredCount != 0) {
return false;
} else {
* Insert a styled string (char/style pairs) with a length.
*/
bool Document::InsertStyledString(int position, char *s, int insertLength) {
- if (cb.IsReadOnly() && enteredReadOnlyCount == 0) {
- enteredReadOnlyCount++;
- NotifyModifyAttempt();
- enteredReadOnlyCount--;
- }
+ CheckReadOnly();
if (enteredCount != 0) {
return false;
} else {
}
int Document::Undo() {
- int newPos = 0;
+ int newPos = -1;
+ CheckReadOnly();
if (enteredCount == 0) {
enteredCount++;
- bool startSavePoint = cb.IsSavePoint();
- int steps = cb.StartUndo();
- //Platform::DebugPrintf("Steps=%d\n", steps);
- for (int step = 0; step < steps; step++) {
- int prevLinesTotal = LinesTotal();
- const Action &action = cb.GetUndoStep();
- if (action.at == removeAction) {
- NotifyModified(DocModification(
- SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
- } else {
- NotifyModified(DocModification(
- SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
- }
- cb.PerformUndoStep();
- int cellPosition = action.position / 2;
- 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 {
- modFlags |= SC_MOD_DELETETEXT;
+ if (!cb.IsReadOnly()) {
+ bool startSavePoint = cb.IsSavePoint();
+ bool multiLine = false;
+ int steps = cb.StartUndo();
+ //Platform::DebugPrintf("Steps=%d\n", steps);
+ for (int step = 0; step < steps; step++) {
+ const int prevLinesTotal = LinesTotal();
+ const Action &action = cb.GetUndoStep();
+ if (action.at == removeAction) {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
+ } else {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
+ }
+ cb.PerformUndoStep();
+ int cellPosition = action.position;
+ 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 {
+ modFlags |= SC_MOD_DELETETEXT;
+ }
+ if (steps > 1)
+ modFlags |= SC_MULTISTEPUNDOREDO;
+ const int linesAdded = LinesTotal() - prevLinesTotal;
+ if (linesAdded != 0)
+ multiLine = true;
+ if (step == steps - 1) {
+ modFlags |= SC_LASTSTEPINUNDOREDO;
+ if (multiLine)
+ modFlags |= SC_MULTILINEUNDOREDO;
+ }
+ NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
+ linesAdded, action.data));
}
- if (step == steps - 1)
- modFlags |= SC_LASTSTEPINUNDOREDO;
- NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
- LinesTotal() - prevLinesTotal, action.data));
- }
- bool endSavePoint = cb.IsSavePoint();
- if (startSavePoint != endSavePoint)
- NotifySavePoint(endSavePoint);
+ bool endSavePoint = cb.IsSavePoint();
+ if (startSavePoint != endSavePoint)
+ NotifySavePoint(endSavePoint);
+ }
enteredCount--;
}
return newPos;
}
int Document::Redo() {
- int newPos = 0;
+ int newPos = -1;
+ CheckReadOnly();
if (enteredCount == 0) {
enteredCount++;
- bool startSavePoint = cb.IsSavePoint();
- int steps = cb.StartRedo();
- for (int step = 0; step < steps; step++) {
- int prevLinesTotal = LinesTotal();
- const Action &action = cb.GetRedoStep();
- if (action.at == insertAction) {
- NotifyModified(DocModification(
- SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
- } else {
- NotifyModified(DocModification(
- SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
- }
- cb.PerformRedoStep();
- ModifiedAt(action.position / 2);
- newPos = action.position / 2;
-
- int modFlags = SC_PERFORMED_REDO;
- if (action.at == insertAction) {
- newPos += action.lenData;
- modFlags |= SC_MOD_INSERTTEXT;
- } else {
- modFlags |= SC_MOD_DELETETEXT;
+ if (!cb.IsReadOnly()) {
+ bool startSavePoint = cb.IsSavePoint();
+ bool multiLine = false;
+ int steps = cb.StartRedo();
+ for (int step = 0; step < steps; step++) {
+ const int prevLinesTotal = LinesTotal();
+ const Action &action = cb.GetRedoStep();
+ if (action.at == insertAction) {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
+ } else {
+ NotifyModified(DocModification(
+ SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
+ }
+ cb.PerformRedoStep();
+ ModifiedAt(action.position);
+ newPos = action.position;
+
+ int modFlags = SC_PERFORMED_REDO;
+ if (action.at == insertAction) {
+ newPos += action.lenData;
+ modFlags |= SC_MOD_INSERTTEXT;
+ } else {
+ modFlags |= SC_MOD_DELETETEXT;
+ }
+ if (steps > 1)
+ modFlags |= SC_MULTISTEPUNDOREDO;
+ const int linesAdded = LinesTotal() - prevLinesTotal;
+ if (linesAdded != 0)
+ multiLine = true;
+ if (step == steps - 1) {
+ modFlags |= SC_LASTSTEPINUNDOREDO;
+ if (multiLine)
+ modFlags |= SC_MULTILINEUNDOREDO;
+ }
+ NotifyModified(
+ DocModification(modFlags, action.position, action.lenData,
+ linesAdded, action.data));
}
- if (step == steps - 1)
- modFlags |= SC_LASTSTEPINUNDOREDO;
- NotifyModified(
- DocModification(modFlags, action.position / 2, action.lenData,
- LinesTotal() - prevLinesTotal, action.data));
- }
- bool endSavePoint = cb.IsSavePoint();
- if (startSavePoint != endSavePoint)
- NotifySavePoint(endSavePoint);
+ bool endSavePoint = cb.IsSavePoint();
+ if (startSavePoint != endSavePoint)
+ NotifySavePoint(endSavePoint);
+ }
enteredCount--;
}
return newPos;
*/
bool Document::InsertString(int position, const char *s, size_t insertLength) {
bool changed = false;
- char *sWithStyle = new char[insertLength * 2];
- if (sWithStyle) {
- for (size_t i = 0; i < insertLength; i++) {
- sWithStyle[i*2] = s[i];
- sWithStyle[i*2 + 1] = 0;
+ if (insertLength > 0) {
+ char *sWithStyle = new char[insertLength * 2];
+ if (sWithStyle) {
+ for (size_t i = 0; i < insertLength; i++) {
+ sWithStyle[i*2] = s[i];
+ sWithStyle[i*2 + 1] = 0;
+ }
+ changed = InsertStyledString(position*2, sWithStyle,
+ static_cast<int>(insertLength*2));
+ delete []sWithStyle;
}
- changed = InsertStyledString(position*2, sWithStyle,
- static_cast<int>(insertLength*2));
- delete []sWithStyle;
}
return changed;
}
CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
+ BeginUndoAction();
DeleteChars(thisLineStart, indentPos - thisLineStart);
InsertString(thisLineStart, linebuf);
+ EndUndoAction();
}
}
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab
for (int line = lineBottom; line >= lineTop; line--) {
int indentOfLine = GetLineIndentation(line);
- if (forwards)
- SetLineIndentation(line, indentOfLine + IndentSize());
- else
+ if (forwards) {
+ if (LineStart(line) < LineEnd(line)) {
+ SetLineIndentation(line, indentOfLine + IndentSize());
+ }
+ } else {
SetLineIndentation(line, indentOfLine - IndentSize());
+ }
}
}
for (int pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
- if (cb.CharAt(pos + 1) == '\n') {
+ if (cb.CharAt(pos + 1) == '\n') {
// CRLF
if (eolModeSet == SC_EOL_CR) {
DeleteChars(pos + 1, 1); // Delete the LF
} else {
pos++;
}
- } else {
+ } else {
// CR
if (eolModeSet == SC_EOL_CRLF) {
InsertString(pos + 1, "\n", 1); // Insert LF
EndUndoAction();
}
-int Document::ParaDown(int pos) {
- int line = LineFromPosition(pos);
- while (line < LinesTotal() && LineStart(line) != LineEnd(line)) { // skip non-empty lines
- line++;
- }
- while (line < LinesTotal() && LineStart(line) == LineEnd(line)) { // skip empty lines
- line++;
+bool Document::IsWhiteLine(int line) {
+ int currentChar = LineStart(line);
+ int endLine = LineEnd(line);
+ while (currentChar < endLine) {
+ if (cb.CharAt(currentChar) != ' ' && cb.CharAt(currentChar) != '\t') {
+ return false;
+ }
+ ++currentChar;
}
- if (line < LinesTotal())
- return LineStart(line);
- else // end of a document
- return LineEnd(line-1);
+ return true;
}
int Document::ParaUp(int pos) {
int line = LineFromPosition(pos);
line--;
- while (line >= 0 && LineStart(line) == LineEnd(line)) { // skip empty lines
+ while (line >= 0 && IsWhiteLine(line)) { // skip empty lines
line--;
}
- while (line >= 0 && LineStart(line) != LineEnd(line)) { // skip non-empty lines
+ while (line >= 0 && !IsWhiteLine(line)) { // skip non-empty lines
line--;
}
line++;
return LineStart(line);
}
+int Document::ParaDown(int pos) {
+ int line = LineFromPosition(pos);
+ while (line < LinesTotal() && !IsWhiteLine(line)) { // skip non-empty lines
+ line++;
+ }
+ while (line < LinesTotal() && IsWhiteLine(line)) { // skip empty lines
+ line++;
+ }
+ if (line < LinesTotal())
+ return LineStart(line);
+ else // end of a document
+ return LineEnd(line-1);
+}
+
Document::charClassification Document::WordCharClass(unsigned char ch) {
if ((SC_CP_UTF8 == dbcsCodePage) && (ch >= 0x80))
return ccWord;
pdoc(pdoc_), end(end_) {
}
+ virtual ~DocumentIndexer() {
+ }
+
virtual char CharAt(int index) {
if (index < 0 || index >= end)
return 0;
if (line == lineRangeStart) {
if ((startPos != endOfLine) && (searchEnd == '$'))
continue; // Can't match end of line if start position before end of line
- endOfLine = startPos+1;
+ endOfLine = startPos;
}
}
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+1)) && (repetitions--)) {
- success = pre->Execute(di, pos+1, endOfLine+1);
+ while (success && (pre->eopat[0] <= endOfLine) && (repetitions--)) {
+ success = pre->Execute(di, pos+1, endOfLine);
if (success) {
- if (pre->eopat[0] <= (minPos+1)) {
+ if (pre->eopat[0] <= minPos) {
pos = pre->bopat[0];
lenRet = pre->eopat[0] - pre->bopat[0];
} else {
char firstChar = s[0];
if (!caseSensitive)
firstChar = static_cast<char>(MakeUpperCase(firstChar));
- int pos = startPos;
+ int pos = forward ? startPos : (startPos - 1);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
char ch = CharAt(pos);
if (caseSensitive) {
if (ch == firstChar) {
bool found = true;
+ if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
ch = CharAt(pos + posMatch);
if (ch != s[posMatch])
} else {
if (MakeUpperCase(ch) == firstChar) {
bool found = true;
+ if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
ch = CharAt(pos + posMatch);
if (MakeUpperCase(ch) != MakeUpperCase(s[posMatch]))
}
void Document::ChangeCase(Range r, bool makeUpperCase) {
- for (int pos = r.start; pos < r.end; pos++) {
+ for (int pos = r.start; pos < r.end;) {
int len = LenChar(pos);
- if (dbcsCodePage && (len > 1)) {
- pos += len;
- } else {
+ if (len == 1) {
char ch = CharAt(pos);
if (makeUpperCase) {
if (IsLowerCase(ch)) {
}
}
}
+ pos += len;
}
}
return false;
} else {
enteredCount++;
- int prevEndStyled = endStyled;
bool didChange = false;
- int lastChange = 0;
+ int startMod = 0;
+ int endMod = 0;
for (int iPos = 0; iPos < length; iPos++, endStyled++) {
PLATFORM_ASSERT(endStyled < Length());
if (cb.SetStyleAt(endStyled, styles[iPos], stylingMask)) {
+ if (!didChange) {
+ startMod = endStyled;
+ }
didChange = true;
- lastChange = iPos;
+ endMod = endStyled;
}
}
if (didChange) {
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
- prevEndStyled, lastChange);
+ startMod, endMod - startMod + 1);
NotifyModified(mh);
}
enteredCount--;
}
return pos;
}
+
+static char BraceOpposite(char ch) {
+ switch (ch) {
+ case '(':
+ return ')';
+ case ')':
+ return '(';
+ case '[':
+ return ']';
+ case ']':
+ return '[';
+ case '{':
+ return '}';
+ case '}':
+ return '{';
+ case '<':
+ return '>';
+ case '>':
+ return '<';
+ default:
+ return '\0';
+ }
+}
+
+// TODO: should be able to extend styled region to find matching brace
+int Document::BraceMatch(int position, int /*maxReStyle*/) {
+ char chBrace = CharAt(position);
+ char chSeek = BraceOpposite(chBrace);
+ if (chSeek == '\0')
+ return - 1;
+ char styBrace = static_cast<char>(StyleAt(position) & stylingBitsMask);
+ int direction = -1;
+ if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
+ direction = 1;
+ int depth = 1;
+ position = position + direction;
+ while ((position >= 0) && (position < Length())) {
+ position = MovePositionOutsideChar(position, direction);
+ char chAtPos = CharAt(position);
+ char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
+ if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
+ if (chAtPos == chBrace)
+ depth++;
+ if (chAtPos == chSeek)
+ depth--;
+ if (depth == 0)
+ return position;
+ }
+ position = position + direction;
+ }
+ return - 1;
+}
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
// Gateways to modifying document
+ void ModifiedAt(int pos);
bool DeleteChars(int pos, int len);
bool InsertStyledString(int position, char *s, int insertLength);
int Undo();
char StyleAt(int position) { return cb.StyleAt(position); }
int GetMark(int line) { return cb.GetMark(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 WordPartLeft(int pos);
int WordPartRight(int pos);
int ExtendStyleRange(int pos, int delta, bool singleLine = false);
+ bool IsWhiteLine(int line);
int ParaUp(int pos);
int ParaDown(int pos);
int IndentSize() { return actualIndentInChars; }
+ int BraceMatch(int position, int maxReStyle);
private:
+ void CheckReadOnly();
+
charClassification WordCharClass(unsigned char ch);
bool IsWordStartAt(int pos);
bool IsWordEndAt(int pos);
bool IsWordAt(int start, int end);
- void ModifiedAt(int pos);
void NotifyModifyAttempt();
void NotifySavePoint(bool atSavePoint);
int foldLevelPrev;
DocModification(int modificationType_, int position_=0, int length_=0,
- int linesAdded_=0, const char *text_=0) :
+ int linesAdded_=0, const char *text_=0, int line_=0) :
modificationType(modificationType_),
position(position_),
length(length_),
linesAdded(linesAdded_),
text(text_),
- line(0),
+ line(line_),
foldLevelNow(0),
foldLevelPrev(0) {}
- DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
+ DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
modificationType(modificationType_),
- position(act.position / 2),
+ position(act.position),
length(act.lenData),
linesAdded(linesAdded_),
text(act.data),
}
char DocumentAccessor::StyleAt(int position) {
- return pdoc->StyleAt(position);
+ // Mask off all bits which aren't in the 'mask'.
+ return static_cast<char>(pdoc->StyleAt(position) & mask);
}
int DocumentAccessor::GetLine(int position) {
}
void DocumentAccessor::StartAt(unsigned int start, char chMask) {
+ // Store the mask specified for use with StyleAt.
+ mask = chMask;
pdoc->StartStyling(start, chMask);
startPosStyling = start;
}
char chWhile;
unsigned int startSeg;
int startPosStyling;
+ int mask;
bool InternalIsLeadByte(char ch);
void Fill(int position);
DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) :
Accessor(), pdoc(pdoc_), props(props_), id(id_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
- startSeg(0), startPosStyling(0) {
+ startSeg(0), startPosStyling(0),
+ mask(127) { // Initialize the mask to be big enough for any lexer.
}
~DocumentAccessor();
bool Match(int pos, const char *s);
#include "Document.h"
#include "Editor.h"
+/*
+ return whether this modification represents an operation that
+ may reasonably be deferred (not done now OR [possibly] at all)
+*/
+static bool CanDeferToLastStep(const DocModification& mh) {
+ if (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE))
+ return true; // CAN skip
+ if (!(mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)))
+ return false; // MUST do
+ if (mh.modificationType & SC_MULTISTEPUNDOREDO)
+ return true; // CAN skip
+ return false; // PRESUMABLY must do
+}
+
+static bool CanEliminate(const DocModification& mh) {
+ return
+ (mh.modificationType & (SC_MOD_BEFOREINSERT|SC_MOD_BEFOREDELETE)) != 0;
+}
+
+/*
+ return whether this modification represents the FINAL step
+ in a [possibly lengthy] multi-step Undo/Redo sequence
+*/
+static bool IsLastStep(const DocModification& mh) {
+ return
+ (mh.modificationType & (SC_PERFORMED_UNDO|SC_PERFORMED_REDO)) != 0
+ && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
+ && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0
+ && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0;
+}
+
Caret::Caret() :
active(false), on(false), period(500) {}
edgeColumn(0),
chars(0),
styles(0),
+ styleBitsSet(0),
indicators(0),
positions(0),
hsStart(0),
LineLayoutCache::LineLayoutCache() :
level(0), length(0), size(0), cache(0),
- allInvalidated(false), styleClock(-1) {
+ allInvalidated(false), styleClock(-1), useCount(0) {
Allocate(0);
}
}
void LineLayoutCache::Allocate(int length_) {
+ PLATFORM_ASSERT(cache == NULL);
allInvalidated = false;
length = length_;
size = length;
}
void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) {
+ PLATFORM_ASSERT(useCount == 0);
int lengthForLevel = 0;
if (level == llcCaret) {
lengthForLevel = 1;
}
if (lengthForLevel > size) {
Deallocate();
- } else if (lengthForLevel < length) {
- for (int i = lengthForLevel; i < length; i++) {
- delete cache[i];
- cache[i] = 0;
- }
- }
- if (!cache) {
Allocate(lengthForLevel);
+ } else {
+ if (lengthForLevel < length) {
+ for (int i = lengthForLevel; i < length; i++) {
+ delete cache[i];
+ cache[i] = 0;
+ }
+ }
+ length = lengthForLevel;
}
+ PLATFORM_ASSERT(length == lengthForLevel);
+ PLATFORM_ASSERT(cache != NULL || length == 0);
}
void LineLayoutCache::Deallocate() {
+ PLATFORM_ASSERT(useCount == 0);
for (int i = 0; i < length; i++)
delete cache[i];
delete []cache;
cache = 0;
length = 0;
+ size = 0;
}
void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) {
pos = 0;
} else if (level == llcPage) {
if (lineNumber == lineCaret) {
- pos = length;
+ pos = 0;
} else {
- pos = lineNumber % length;
+ pos = 1 + (lineNumber % (length - 1));
}
} else if (level == llcDocument) {
pos = lineNumber;
}
if (pos >= 0) {
+ PLATFORM_ASSERT(useCount == 0);
if (cache && (pos < length)) {
if (cache[pos]) {
if ((cache[pos]->lineNumber != lineNumber) ||
cache[pos]->lineNumber = lineNumber;
cache[pos]->inCache = true;
ret = cache[pos];
+ useCount++;
}
}
}
if (ll) {
if (!ll->inCache) {
delete ll;
- }
+ } else {
+ useCount--;
+ }
}
}
scrollWidth = 2000;
verticalScrollBarVisible = true;
endAtLastLine = true;
+ caretSticky = false;
pixmapLine = Surface::Allocate();
pixmapSelMargin = Surface::Allocate();
topLine = 0;
posTopLine = 0;
- lengthForEncode = 0;
+ lengthForEncode = -1;
needUpdateUI = true;
braces[0] = invalidPosition;
wrapVisualStartIndent = 0;
actualWrapVisualStartIndent = 0;
+ convertPastes = true;
+
hsStart = -1;
hsEnd = -1;
pixmapSelMargin->Release();
pixmapSelPattern->Release();
pixmapIndentGuide->Release();
+ pixmapIndentGuideHighlight->Release();
}
void Editor::InvalidateStyleData() {
//wMain.InvalidateAll();
}
-void Editor::RedrawSelMargin() {
+void Editor::RedrawSelMargin(int line) {
if (!AbandonPaint()) {
if (vs.maskInLine) {
Redraw();
} else {
PRectangle rcSelMargin = GetClientRectangle();
rcSelMargin.right = vs.fixedColumnWidth;
+ if (line != -1) {
+ int position = pdoc->LineStart(line);
+ PRectangle rcLine = RectangleFromRange(position, position);
+ rcSelMargin.top = rcLine.top;
+ rcSelMargin.bottom = rcLine.bottom;
+ }
wMain.InvalidateRectangle(rcSelMargin);
}
}
return Platform::Maximum(currentPos, anchor);
}
+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)
currentPos = currentPos_;
anchor = anchor_;
}
- if (selType == selRectangle) {
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
- }
+ SetRectangularRange();
ClaimSelection();
}
InvalidateSelection(currentPos_, currentPos_);
currentPos = currentPos_;
}
- if (selType == selRectangle) {
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
- }
+ SetRectangularRange();
ClaimSelection();
}
SetTopLine(topLineNew);
ShowCaretAtCurrentPosition();
// Perform redraw rather than scroll if many lines would be redrawn anyway.
+#ifndef UNDER_CE
if (abs(linesToMove) <= 10) {
ScrollText(linesToMove);
} else {
Redraw();
}
+#else
+ Redraw();
+#endif
if (moveThumb) {
SetVerticalScrollPos();
}
posLineEnd = posLineStart + ll->maxLineLength;
}
if (ll->validity == LineLayout::llCheckTextAndStyle) {
- int lineLength = 0;
- for (int cid = posLineStart; cid < posLineEnd; cid++) {
- char chDoc = pdoc->CharAt(cid);
- if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
- lineLength++;
+ int lineLength = posLineEnd - posLineStart;
+ if (!vstyle.viewEOL) {
+ int cid = posLineEnd - 1;
+ while ((cid > posLineStart) && IsEOLChar(pdoc->CharAt(cid))) {
+ cid--;
+ lineLength--;
}
}
if (lineLength == ll->numCharsInLine) {
- int numCharsInLine = 0;
// See if chars, styles, indicators, are all the same
bool allSame = true;
const int styleMask = pdoc->stylingBitsMask;
// Check base line layout
- for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) {
+ char styleByte = 0;
+ int numCharsInLine = 0;
+ while (numCharsInLine < lineLength) {
+ int charInDoc = numCharsInLine + posLineStart;
char chDoc = pdoc->CharAt(charInDoc);
- if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
- char styleByte = pdoc->StyleAt(charInDoc);
+ styleByte = pdoc->StyleAt(charInDoc);
+ allSame = allSame &&
+ (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask));
+ allSame = allSame &&
+ (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
+ if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed)
allSame = allSame &&
- (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask));
+ (ll->chars[numCharsInLine] == chDoc);
+ else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
allSame = allSame &&
- (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask));
- if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
- else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
- allSame = allSame &&
- (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
- else
- allSame = allSame &&
- (ll->chars[numCharsInLine] == chDoc);
- numCharsInLine++;
- }
+ (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc)));
+ else // Style::caseUpper
+ allSame = allSame &&
+ (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc)));
+ numCharsInLine++;
}
+ allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled
if (allSame) {
ll->validity = LineLayout::llPositions;
} else {
char styleByte = 0;
int styleMask = pdoc->stylingBitsMask;
+ ll->styleBitsSet = 0;
// Fill base line layout
for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
char chDoc = pdoc->CharAt(charInDoc);
styleByte = pdoc->StyleAt(charInDoc);
+ ll->styleBitsSet |= styleByte;
if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
ll->chars[numCharsInLine] = chDoc;
ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
bool lastSegItalics = false;
Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font;
+ int ctrlCharWidth[32] = {0};
bool isControlNext = IsControlCharacter(ll->chars[0]);
for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) {
bool isControl = isControlNext;
ll->positions[charInLine + 1] = ((((startsegx + 2) /
tabWidth) + 1) * tabWidth) - startsegx;
} else if (controlCharSymbol < 32) {
- const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
- // +3 For a blank on front and rounded edge each side:
- ll->positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
+ if (ctrlCharWidth[ll->chars[charInLine]] == 0) {
+ const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]);
+ // +3 For a blank on front and rounded edge each side:
+ ctrlCharWidth[ll->chars[charInLine]] =
+ surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3;
+ }
+ ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]];
} else {
char cc[2] = { static_cast<char>(controlCharSymbol), '\0' };
surface->MeasureWidths(ctrlCharsFont, cc, 1,
continue;
}
if (p > 0) {
- if (ll->styles[p] != ll->styles[p - 1]) {
+ if (wrapState == eWrapChar){
+ lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1)
+ - posLineStart;
+ p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart;
+ continue;
+ } else if (ll->styles[p] != ll->styles[p - 1]) {
lastGoodBreak = p;
} else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) {
lastGoodBreak = p;
}
}
}
+ } else if (rcSegment.left > rcLine.right) {
+ break;
}
startseg = i + 1;
}
rcUL.bottom = rcUL.top + 1;
surface->FillRectangle(rcUL, textFore);
}
+ } else if (rcSegment.left > rcLine.right) {
+ break;
}
startseg = i + 1;
}
}
// Draw indicators
- int indStart[INDIC_MAX + 1] = {0};
- for (int indica = 0; indica <= INDIC_MAX; indica++)
- indStart[indica] = 0;
-
- for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) {
- if ((indicPos == lineStart) || (indicPos == lineEnd) ||
- (ll->indicators[indicPos] != ll->indicators[indicPos + 1])) {
- int mask = 1 << pdoc->stylingBits;
- for (int indicnum = 0; mask < 0x100; indicnum++) {
- if ((indicPos == lineStart) || (indicPos == lineEnd)) {
- indStart[indicnum] = ll->positions[indicPos];
- } else if ((ll->indicators[indicPos + 1] & mask) && !(ll->indicators[indicPos] & mask)) {
- indStart[indicnum] = ll->positions[indicPos + 1];
- }
- if ((ll->indicators[indicPos] & mask) &&
- ((indicPos == lineEnd) || !(ll->indicators[indicPos + 1] & mask))) {
- int endIndicator = indicPos;
- if (endIndicator >= lineEnd)
- endIndicator = lineEnd-1;
+ // foreach indicator...
+ for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) {
+ if (!(mask & ll->styleBitsSet)) {
+ mask <<= 1;
+ continue;
+ }
+ int startPos = -1;
+ // foreach style pos in line...
+ for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) {
+ // look for starts...
+ if (startPos < 0) {
+ // NOT in indicator run, looking for START
+ if (indicPos < lineEnd && (ll->indicators[indicPos] & mask))
+ startPos = indicPos;
+ }
+ // ... or ends
+ if (startPos >= 0) {
+ // IN indicator run, looking for END
+ if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) {
+ // AT end of indicator run, DRAW it!
PRectangle rcIndic(
- indStart[indicnum] + xStart - subLineStart,
+ ll->positions[startPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent,
- ll->positions[endIndicator + 1] + xStart - subLineStart,
+ ll->positions[indicPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent + 3);
vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine);
+ // RESET control var
+ startPos = -1;
}
- mask = mask << 1;
}
}
+ mask <<= 1;
}
// End of the drawing of the current line
if (!twoPhaseDraw) {
if (bufferedDraw) {
if (!pixmapLine->Initialised()) {
PRectangle rcClient = GetClientRectangle();
- pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(),
+ pixmapLine->InitPixMap(rcClient.Width(), vs.lineHeight,
surfaceWindow, wMain.GetID());
pixmapSelMargin->InitPixMap(vs.fixedColumnWidth,
rcClient.Height(), surfaceWindow, wMain.GetID());
//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;
ll->selStart = SelectionStart();
ll->selEnd = SelectionEnd();
} else {
- lineIterator.SetAt(lineDoc);
ll->selStart = lineIterator.startPos;
ll->selEnd = lineIterator.endPos;
}
visibleLine++;
//gdk_flush();
}
+ ll.Set(0);
//if (durPaint < 0.00000001)
// durPaint = 0.00000001;
int nMax = MaxScrollPos();
int nPage = LinesOnScreen();
bool modified = ModifyScrollBars(nMax + nPage - 1, nPage);
+ if (modified) {
+ DwellEnd(true);
+ }
// TODO: ensure always showing as many lines as possible
// May not be, if, for example, window made larger
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);
}
}
if (pdoc->InsertString(currentPos, s, len)) {
SetEmptySelection(currentPos + len);
}
+ if (charReplaceAction) {
+ pdoc->EndUndoAction();
+ }
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
if (treatAsDBCS) {
NotifyChar((static_cast<unsigned char>(s[0]) << 8) |
currentPos = 0;
SetTopLine(0);
SetVerticalScrollPos();
- InvalidateStyleRedraw(); // RPD: patch #1106564
+ InvalidateStyleRedraw();
}
void Editor::ClearDocumentStyle() {
if (pdoc->CanUndo()) {
InvalidateCaret();
int newPos = pdoc->Undo();
- SetEmptySelection(newPos);
+ if (newPos >= 0)
+ SetEmptySelection(newPos);
EnsureCaretVisible();
}
}
void Editor::Redo() {
if (pdoc->CanRedo()) {
int newPos = pdoc->Redo();
- SetEmptySelection(newPos);
+ if (newPos >= 0)
+ SetEmptySelection(newPos);
EnsureCaretVisible();
}
}
void Editor::NotifyFocus(bool) {}
void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_STYLENEEDED;
scn.position = endStyleNeeded;
NotifyParent(scn);
}
void Editor::NotifyChar(int ch) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_CHARADDED;
scn.ch = ch;
NotifyParent(scn);
}
void Editor::NotifySavePoint(bool isSavePoint) {
- SCNotification scn;
+ SCNotification scn = {0};
if (isSavePoint) {
scn.nmhdr.code = SCN_SAVEPOINTREACHED;
} else {
}
void Editor::NotifyModifyAttempt() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MODIFYATTEMPTRO;
NotifyParent(scn);
}
void Editor::NotifyDoubleClick(Point, bool) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_DOUBLECLICK;
NotifyParent(scn);
}
void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
}
void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_HOTSPOTCLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
}
void Editor::NotifyUpdateUI() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_UPDATEUI;
NotifyParent(scn);
}
void Editor::NotifyPainted() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_PAINTED;
NotifyParent(scn);
}
x += vs.ms[margin].width;
}
if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MARGINCLICK;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0);
}
void Editor::NotifyNeedShown(int pos, int len) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_NEEDSHOWN;
scn.position = pos;
scn.length = len;
}
void Editor::NotifyDwelling(Point pt, bool state) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND;
scn.position = PositionFromLocationClose(pt);
scn.x = pt.x;
}
void Editor::NotifyZoom() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_ZOOM;
NotifyParent(scn);
}
}
void Editor::NotifyMove(int position) {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_POSCHANGED;
scn.position = position;
NotifyParent(scn);
}
void Editor::CheckModificationForWrap(DocModification mh) {
- if ((mh.modificationType & SC_MOD_INSERTTEXT) ||
- (mh.modificationType & SC_MOD_DELETETEXT)) {
+ if (mh.modificationType & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT)) {
llc.Invalidate(LineLayout::llCheckTextAndStyle);
if (wrapState != eWrapNone) {
int lineDoc = pdoc->LineFromPosition(mh.position);
// Some lines are hidden so may need shown.
// TODO: check if the modified area is hidden.
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
- NotifyNeedShown(mh.position, mh.length);
+ NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length);
}
CheckModificationForWrap(mh);
if (mh.linesAdded != 0) {
// Avoid scrolling of display if change before current display
- if (mh.position < posTopLine) {
+ if (mh.position < posTopLine && !CanDeferToLastStep(mh)) {
int newTop = Platform::Clamp(topLine + mh.linesAdded, 0, MaxScrollPos());
if (newTop != topLine) {
SetTopLine(newTop);
//Platform::DebugPrintf("** %x Doc Changed\n", this);
// TODO: could invalidate from mh.startModification to end of screen
//InvalidateRange(mh.position, mh.position + mh.length);
- if (paintState == notPainting) {
+ if (paintState == notPainting && !CanDeferToLastStep(mh)) {
Redraw();
}
} else {
//Platform::DebugPrintf("** %x Line Changed %d .. %d\n", this,
// mh.position, mh.position + mh.length);
- if (paintState == notPainting) {
+ if (paintState == notPainting && mh.length && !CanEliminate(mh)) {
InvalidateRange(mh.position, mh.position + mh.length);
}
}
}
- if (mh.linesAdded != 0) {
+ if (mh.linesAdded != 0 && !CanDeferToLastStep(mh)) {
SetScrollBars();
}
if (mh.modificationType & SC_MOD_CHANGEMARKER) {
- if (paintState == notPainting) {
- RedrawSelMargin();
+ if ((paintState == notPainting) || !PaintContainsMargin()) {
+ if (mh.modificationType & SC_MOD_CHANGEFOLD) {
+ // Fold changes can affect the drawing of following lines so redraw whole margin
+ RedrawSelMargin();
+ } else {
+ RedrawSelMargin(mh.line);
+ }
}
}
+ // NOW pay the piper WRT "deferred" visual updates
+ if (IsLastStep(mh)) {
+ SetScrollBars();
+ Redraw();
+ }
+
// If client wants to see this modification
if (mh.modificationType & modEventMask) {
if ((mh.modificationType & SC_MOD_CHANGESTYLE) == 0) {
NotifyChange(); // Send EN_CHANGE
}
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MODIFIED;
scn.position = mh.position;
scn.modificationType = mh.modificationType;
/* Do nothing */
}
-void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long lParam) {
+void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
// Enumerates all macroable messages
switch (iMessage) {
case SCI_LINEENDRECTEXTEND:
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
+ case SCI_SELECTIONDUPLICATE:
break;
// Filter out all others like display changes. Also, newlines are redundant
}
// Send notification
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_MACRORECORD;
scn.message = iMessage;
scn.wParam = wParam;
}
}
-void Editor::LineDuplicate() {
- int line = pdoc->LineFromPosition(currentPos);
- int start = pdoc->LineStart(line);
- int end = pdoc->LineEnd(line);
- char *thisLine = CopyRange(start, end);
- const char *eol = StringFromEOLMode(pdoc->eolMode);
- pdoc->InsertString(end, eol);
- pdoc->InsertString(end + istrlen(eol), thisLine, end - start);
- delete []thisLine;
+void Editor::Duplicate(bool forLine) {
+ int start = SelectionStart();
+ int end = SelectionEnd();
+ if (start == end) {
+ forLine = true;
+ }
+ if (forLine) {
+ int line = pdoc->LineFromPosition(currentPos);
+ start = pdoc->LineStart(line);
+ end = pdoc->LineEnd(line);
+ }
+ char *text = CopyRange(start, end);
+ if (forLine) {
+ const char *eol = StringFromEOLMode(pdoc->eolMode);
+ pdoc->InsertString(end, eol);
+ pdoc->InsertString(end + istrlen(eol), text, end - start);
+ } else {
+ pdoc->InsertString(end, text, end - start);
+ }
+ delete []text;
}
void Editor::CancelModes() {
}
SetLastXChosen();
EnsureCaretVisible();
+ // Avoid blinking during rapid typing:
+ ShowCaretAtCurrentPosition();
}
void Editor::CursorUpOrDown(int direction, selTypes sel) {
MovePositionTo(posNew, sel);
}
+void Editor::ParaUpOrDown(int direction, selTypes sel) {
+ int lineDoc, savedPos = currentPos;
+ do {
+ MovePositionTo(direction > 0 ? pdoc->ParaDown(currentPos) : pdoc->ParaUp(currentPos), sel);
+ lineDoc = pdoc->LineFromPosition(currentPos);
+ if (direction > 0) {
+ if (currentPos >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
+ if (sel == noSel) {
+ MovePositionTo(pdoc->LineEndPosition(savedPos));
+ }
+ break;
+ }
+ }
+ } while (!cs.GetVisible(lineDoc));
+}
+
int Editor::StartEndDisplayLine(int pos, bool start) {
RefreshStyleData();
int line = pdoc->LineFromPosition(pos);
CursorUpOrDown(1, selRectangle);
break;
case SCI_PARADOWN:
- MovePositionTo(pdoc->ParaDown(currentPos));
+ ParaUpOrDown(1);
break;
case SCI_PARADOWNEXTEND:
- MovePositionTo(pdoc->ParaDown(currentPos), selStream);
+ ParaUpOrDown(1, selStream);
break;
case SCI_LINESCROLLDOWN:
ScrollTo(topLine + 1);
CursorUpOrDown(-1, selRectangle);
break;
case SCI_PARAUP:
- MovePositionTo(pdoc->ParaUp(currentPos));
+ ParaUpOrDown(-1);
break;
case SCI_PARAUPEXTEND:
- MovePositionTo(pdoc->ParaUp(currentPos), selStream);
+ ParaUpOrDown(-1, selStream);
break;
case SCI_LINESCROLLUP:
ScrollTo(topLine - 1);
break;
case SCI_DELETEBACK:
DelCharBack(true);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_DELETEBACKNOTLINE:
DelCharBack(false);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_TAB:
Indent(true);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_BACKTAB:
Indent(false);
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
case SCI_NEWLINE:
LineTranspose();
break;
case SCI_LINEDUPLICATE:
- LineDuplicate();
+ Duplicate(true);
+ break;
+ case SCI_SELECTIONDUPLICATE:
+ Duplicate(false);
break;
case SCI_LOWERCASE:
ChangeCaseOfSelection(false);
NotifyHotSpotClicked(newPos, shift, ctrl, alt);
}
if (!shift) {
- inDragDrop = PointInSelection(pt);
+ inDragDrop = PointInSelection(pt) && !SelectionEmpty();
}
if (inDragDrop) {
SetMouseCapture(false);
SetEmptySelection(newPos);
}
selType = alt ? selRectangle : selStream;
- xStartSelect = xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
selectionType = selChar;
originalAnchorPos = currentPos;
+ SetRectangularRange();
}
}
}
}
}
// Display regular (drag) cursor over selection
- if (PointInSelection(pt)) {
+ if (PointInSelection(pt) && !SelectionEmpty()) {
DisplayCursor(Window::cursorArrow);
} else if (PointIsHotspot(pt)) {
DisplayCursor(Window::cursorHand);
}
void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
- //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture());
+ //Platform::DebugPrintf("ButtonUp %d\n", HaveMouseCapture());
if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) {
DisplayCursor(Window::cursorReverseArrow);
SetSelection(newPos);
}
}
- // Now we rely on the current pos to compute rectangular selection
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
+ SetRectangularRange();
lastClickTime = curTime;
lastClick = pt;
lastXChosen = pt.x;
if (timer.ticksToWait <= 0) {
caret.on = !caret.on;
timer.ticksToWait = caret.period;
- InvalidateCaret();
+ if (caret.active) {
+ InvalidateCaret();
+ }
}
}
if ((dwellDelay < SC_TIME_FOREVER) &&
}
}
-static bool IsIn(int a, int minimum, int maximum) {
- return (a >= minimum) && (a <= maximum);
+bool Editor::PaintContains(PRectangle rc) {
+ return rcPaint.Contains(rc);
}
-static bool IsOverlap(int mina, int maxa, int minb, int maxb) {
- return
- IsIn(mina, minb, maxb) ||
- IsIn(maxa, minb, maxb) ||
- IsIn(minb, mina, maxa) ||
- IsIn(maxb, mina, maxa);
+bool Editor::PaintContainsMargin() {
+ PRectangle rcSelMargin = GetClientRectangle();
+ rcSelMargin.right = vs.fixedColumnWidth;
+ return PaintContains(rcSelMargin);
}
void Editor::CheckForChangeOutsidePaint(Range r) {
if (!r.Valid())
return;
+ PRectangle rcRange = RectangleFromRange(r.start, r.end);
PRectangle rcText = GetTextRectangle();
- // Determine number of lines displayed including a possible partially displayed last line
- int linesDisplayed = (rcText.bottom - rcText.top - 1) / vs.lineHeight + 1;
- int bottomLine = topLine + linesDisplayed - 1;
-
- int lineRangeStart = cs.DisplayFromDoc(pdoc->LineFromPosition(r.start));
- int lineRangeEnd = cs.DisplayFromDoc(pdoc->LineFromPosition(r.end));
- if (!IsOverlap(topLine, bottomLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("No overlap (%d-%d) with window(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, topLine, bottomLine);
- return;
+ if (rcRange.top < rcText.top) {
+ rcRange.top = rcText.top;
}
-
- // Assert rcPaint contained within or equal to rcText
- if (rcPaint.top > rcText.top) {
- // does range intersect rcText.top .. rcPaint.top
- int paintTopLine = ((rcPaint.top - rcText.top - 1) / vs.lineHeight) + topLine;
- // paintTopLine is the top line of the paint rectangle or the line just above if that line is completely inside the paint rectangle
- if (IsOverlap(topLine, paintTopLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("Change (%d-%d) in top npv(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, topLine, paintTopLine);
- AbandonPaint();
- return;
- }
+ if (rcRange.bottom > rcText.bottom) {
+ rcRange.bottom = rcText.bottom;
}
- if (rcPaint.bottom < rcText.bottom) {
- // does range intersect rcPaint.bottom .. rcText.bottom
- int paintBottomLine = ((rcPaint.bottom - rcText.top - 1) / vs.lineHeight + 1) + topLine;
- // paintTopLine is the bottom line of the paint rectangle or the line just below if that line is completely inside the paint rectangle
- if (IsOverlap(paintBottomLine, bottomLine, lineRangeStart, lineRangeEnd)) {
- //Platform::DebugPrintf("Change (%d-%d) in bottom npv(%d-%d)\n",
- // lineRangeStart, lineRangeEnd, paintBottomLine, bottomLine);
- AbandonPaint();
- return;
- }
+
+ if (!PaintContains(rcRange)) {
+ AbandonPaint();
}
}
}
-char BraceOpposite(char ch) {
- switch (ch) {
- case '(':
- return ')';
- case ')':
- return '(';
- case '[':
- return ']';
- case ']':
- return '[';
- case '{':
- return '}';
- case '}':
- return '{';
- case '<':
- return '>';
- case '>':
- return '<';
- default:
- return '\0';
- }
-}
-
-// TODO: should be able to extend styled region to find matching brace
-// TODO: may need to make DBCS safe
-// so should be moved into Document
-int Editor::BraceMatch(int position, int /*maxReStyle*/) {
- char chBrace = pdoc->CharAt(position);
- char chSeek = BraceOpposite(chBrace);
- if (chSeek == '\0')
- return - 1;
- char styBrace = static_cast<char>(
- pdoc->StyleAt(position) & pdoc->stylingBitsMask);
- int direction = -1;
- if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
- direction = 1;
- int depth = 1;
- position = position + direction;
- while ((position >= 0) && (position < pdoc->Length())) {
- char chAtPos = pdoc->CharAt(position);
- char styAtPos = static_cast<char>(pdoc->StyleAt(position) & pdoc->stylingBitsMask);
- if ((position > pdoc->GetEndStyled()) || (styAtPos == styBrace)) {
- if (chAtPos == chBrace)
- depth++;
- if (chAtPos == chSeek)
- depth--;
- if (depth == 0)
- return position;
- }
- position = position + direction;
- }
- return - 1;
-}
-
void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) {
if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) {
if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) {
NeedWrapping();
pdoc->AddWatcher(this, 0);
- Redraw();
SetScrollBars();
+ Redraw();
}
/**
return 0;
}
+int Editor::WrapCount(int line) {
+ AutoSurface surface(this);
+ AutoLineLayout ll(llc, RetrieveLineLayout(line));
+
+ if (surface && ll) {
+ LayoutLine(line, surface, vs, ll, wrapWidth);
+ return ll->lines;
+ } else {
+ return 1;
+ }
+}
+
static bool ValidMargin(unsigned long wParam) {
return wParam < ViewStyle::margins;
}
case SCI_PASTE:
Paste();
- SetLastXChosen();
+ if (!caretSticky) {
+ SetLastXChosen();
+ }
EnsureCaretVisible();
break;
break;
case SCI_CANUNDO:
- return pdoc->CanUndo() ? 1 : 0;
+ return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0;
case SCI_EMPTYUNDOBUFFER:
pdoc->DeleteUndoHistory();
}
case SCI_CANREDO:
- return pdoc->CanRedo() ? 1 : 0;
+ return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0;
case SCI_MARKERLINEFROMHANDLE:
return pdoc->LineFromHandle(wParam);
if (lParam == 0) {
return 1 + lineEnd - lineStart;
}
+ PLATFORM_ASSERT(wParam > 0);
char *ptr = CharPtrFromSPtr(lParam);
unsigned int iPlace = 0;
for (unsigned int iChar = lineStart; iChar < lineEnd && iPlace < wParam - 1; iChar++) {
return pdoc->ExtendWordSelect(wParam, 1, lParam != 0);
case SCI_SETWRAPMODE:
- wrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone;
+ switch(wParam){
+ case SC_WRAP_WORD:
+ wrapState = eWrapWord;
+ break;
+ case SC_WRAP_CHAR:
+ wrapState = eWrapChar;
+ break;
+ default:
+ wrapState = eWrapNone;
+ break;
+ }
xOffset = 0;
InvalidateStyleRedraw();
ReconfigureScrollBars();
case SCI_GETENDATLASTLINE:
return endAtLastLine;
+ case SCI_SETCARETSTICKY:
+ PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
+ if (caretSticky != (wParam != 0)) {
+ caretSticky = wParam != 0;
+ }
+ break;
+
+ case SCI_GETCARETSTICKY:
+ return caretSticky;
+
+ case SCI_TOGGLECARETSTICKY:
+ caretSticky = !caretSticky;
+ break;
+
case SCI_GETCOLUMN:
return pdoc->GetColumn(wParam);
int markerID = pdoc->AddMark(wParam, lParam);
return markerID;
}
+ case SCI_MARKERADDSET:
+ if (lParam != 0)
+ pdoc->AddMarkSet(wParam, lParam);
+ break;
case SCI_MARKERDELETE:
pdoc->DeleteMark(wParam, lParam);
case SCI_DOCLINEFROMVISIBLE:
return cs.DocFromDisplay(wParam);
+ case SCI_WRAPCOUNT:
+ return WrapCount(wParam);
+
case SCI_SETFOLDLEVEL: {
int prev = pdoc->SetLevel(wParam, lParam);
if (prev != lParam)
case SCI_LINEENDRECTEXTEND:
case SCI_PAGEUPRECTEXTEND:
case SCI_PAGEDOWNRECTEXTEND:
+ case SCI_SELECTIONDUPLICATE:
return KeyCommand(iMessage);
case SCI_BRACEHIGHLIGHT:
case SCI_BRACEMATCH:
// wParam is position of char to find brace for,
// lParam is maximum amount of text to restyle to find it
- return BraceMatch(wParam, lParam);
+ return pdoc->BraceMatch(wParam, lParam);
case SCI_GETVIEWEOL:
return vs.viewEOL;
InvalidateStyleRedraw();
break;
+ case SCI_SETPASTECONVERTENDINGS:
+ convertPastes = wParam != 0;
+ break;
+
+ case SCI_GETPASTECONVERTENDINGS:
+ return convertPastes ? 1 : 0;
+
default:
return DefWndProc(iMessage, wParam, lParam);
}
int edgeColumn;
char *chars;
unsigned char *styles;
+ int styleBitsSet;
char *indicators;
int *positions;
char bracePreviousStyles[2];
LineLayout **cache;
bool allInvalidated;
int styleClock;
+ int useCount;
void Allocate(int length_);
void AllocateForLevel(int linesOnScreen, int linesInDoc);
public:
int scrollWidth;
bool verticalScrollBarVisible;
bool endAtLastLine;
+ bool caretSticky;
Surface *pixmapLine;
Surface *pixmapSelMargin;
int hsEnd;
// Wrapping support
- enum { eWrapNone, eWrapWord } wrapState;
+ enum { eWrapNone, eWrapWord, eWrapChar } wrapState;
bool backgroundWrapEnabled;
int wrapWidth;
int docLineLastWrapped;
int wrapVisualStartIndent;
int actualWrapVisualStartIndent;
+ bool convertPastes;
+
Document *pdoc;
Editor();
bool AbandonPaint();
void RedrawRect(PRectangle rc);
void Redraw();
- void RedrawSelMargin();
+ void RedrawSelMargin(int line=-1);
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
bool SelectionEmpty();
int SelectionStart();
int SelectionEnd();
+ void SetRectangularRange();
void InvalidateSelection(int currentPos_, int anchor_);
void SetSelection(int currentPos_, int anchor_);
void SetSelection(int currentPos_);
void PageMove(int direction, selTypes sel=noSel, bool stuttered = false);
void ChangeCaseOfSelection(bool makeUpperCase);
void LineTranspose();
- void LineDuplicate();
+ void Duplicate(bool forLine);
virtual void CancelModes();
void NewLine();
void CursorUpOrDown(int direction, selTypes sel=noSel);
+ void ParaUpOrDown(int direction, selTypes sel=noSel);
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
+ virtual bool PaintContains(PRectangle rc);
+ bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
- int BraceMatch(int position, int maxReStyle);
void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
void SetDocPointer(Document *document);
void GetHotSpotRange(int& hsStart, int& hsEnd);
int CodePage() const;
+ int WrapCount(int line);
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},
{'T', SCI_CTRL, SCI_LINETRANSPOSE},
- {'D', SCI_CTRL, SCI_LINEDUPLICATE},
+ {'D', SCI_CTRL, SCI_SELECTIONDUPLICATE},
{'U', SCI_CTRL, SCI_LOWERCASE},
{'U', SCI_CSHIFT, SCI_UPPERCASE},
{0,0,0},
const LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
-LexerModule::LexerModule(int language_, LexerFunction fnLexer_,
- const char *languageName_, LexerFunction fnFolder_,
- const char * const wordListDescriptions_[]) :
+LexerModule::LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_,
+ LexerFunction fnFolder_,
+ const char * const wordListDescriptions_[],
+ int styleBits_) :
language(language_),
fnLexer(fnLexer_),
fnFolder(fnFolder_),
wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
languageName(languageName_) {
next = base;
base = this;
}
}
-const char * LexerModule::GetWordListDescription(int index) const {
+const char *LexerModule::GetWordListDescription(int index) const {
static const char *emptyStr = "";
PLATFORM_ASSERT(index < GetNumWordLists());
}
}
+int LexerModule::GetStyleBitsNeeded() const {
+ return styleBits;
+}
+
const LexerModule *LexerModule::Find(int language) {
const LexerModule *lm = base;
while (lm) {
//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
LINK_LEXER(lmAda);
+ LINK_LEXER(lmAns1);
LINK_LEXER(lmAPDL);
LINK_LEXER(lmAsm);
- LINK_LEXER(lmAsn1);
+ LINK_LEXER(lmASP);
LINK_LEXER(lmAU3);
LINK_LEXER(lmAVE);
LINK_LEXER(lmBaan);
LINK_LEXER(lmBash);
+ LINK_LEXER(lmBatch);
+ LINK_LEXER(lmBlitzBasic);
LINK_LEXER(lmBullant);
+ LINK_LEXER(lmCaml);
LINK_LEXER(lmClw);
LINK_LEXER(lmClwNoCase);
LINK_LEXER(lmConf);
LINK_LEXER(lmCPP);
LINK_LEXER(lmCPPNoCase);
- LINK_LEXER(lmTCL);
- LINK_LEXER(lmNncrontab);
+ LINK_LEXER(lmCsound);
LINK_LEXER(lmCss);
+ LINK_LEXER(lmDiff);
LINK_LEXER(lmEiffel);
LINK_LEXER(lmEiffelkw);
LINK_LEXER(lmErlang);
+ LINK_LEXER(lmErrorList);
LINK_LEXER(lmESCRIPT);
+ LINK_LEXER(lmF77);
+ LINK_LEXER(lmFlagShip);
LINK_LEXER(lmForth);
LINK_LEXER(lmFortran);
- LINK_LEXER(lmF77);
+ LINK_LEXER(lmFreeBasic);
LINK_LEXER(lmGui4Cli);
+ LINK_LEXER(lmHaskell);
LINK_LEXER(lmHTML);
- LINK_LEXER(lmXML);
- LINK_LEXER(lmASP);
- LINK_LEXER(lmPHP);
LINK_LEXER(lmKix);
+ LINK_LEXER(lmLatex);
LINK_LEXER(lmLISP);
+ LINK_LEXER(lmLot);
LINK_LEXER(lmLout);
LINK_LEXER(lmLua);
+ LINK_LEXER(lmMake);
LINK_LEXER(lmMatlab);
- LINK_LEXER(lmOctave);
LINK_LEXER(lmMETAPOST);
LINK_LEXER(lmMMIXAL);
- LINK_LEXER(lmLot);
LINK_LEXER(lmMSSQL);
+ LINK_LEXER(lmNncrontab);
LINK_LEXER(lmNsis);
- LINK_LEXER(lmBatch);
- LINK_LEXER(lmDiff);
- LINK_LEXER(lmProps);
- LINK_LEXER(lmMake);
- LINK_LEXER(lmErrorList);
- LINK_LEXER(lmLatex);
LINK_LEXER(lmNull);
+ LINK_LEXER(lmOctave);
LINK_LEXER(lmPascal);
LINK_LEXER(lmPB);
LINK_LEXER(lmPerl);
+ LINK_LEXER(lmPHP);
+ LINK_LEXER(lmPHPSCRIPT);
LINK_LEXER(lmPOV);
+ LINK_LEXER(lmProps);
LINK_LEXER(lmPS);
+ LINK_LEXER(lmPureBasic);
LINK_LEXER(lmPython);
+ LINK_LEXER(lmREBOL);
LINK_LEXER(lmRuby);
LINK_LEXER(lmScriptol);
+ LINK_LEXER(lmSmalltalk);
LINK_LEXER(lmSpecman);
LINK_LEXER(lmSQL);
+ LINK_LEXER(lmTADS3);
+ LINK_LEXER(lmTCL);
LINK_LEXER(lmTeX);
LINK_LEXER(lmVB);
LINK_LEXER(lmVBScript);
LINK_LEXER(lmVerilog);
LINK_LEXER(lmVHDL);
+ LINK_LEXER(lmXML);
LINK_LEXER(lmYAML);
//--Autogenerated -- end of automatically generated section
// Added fold.compact support set with fold.compact=1
// Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
// it will now only happen when fold.comment=2.
-//
+// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
+// Typed Characters now show as "default" till they match any table.
+// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
+// Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
+// Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
+// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
+// Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator.
+// Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account
+// - Added folding support for With...EndWith
+// - Added support for a DOT in variable names
+// - Fixed Underscore in CommentBlock
+// May 23, 2005 - Fixed the SentKey lexing in case of a missing }
+// Aug 11, 2005 - Fixed possible bug with s_save length > 100.
+// Aug 23, 2005 - Added Switch/endswitch support to the folding logic.
+//
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Scintilla source code edit control
static inline bool IsAWordStart(const int ch)
{
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$');
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.');
}
static inline bool IsAOperator(char ch) {
// split the portion of the sendkey in the part before and after the spaces
while ( ( (cTemp = szLine[nPos]) != '\0'))
{
- if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
+ // skip leading Ctrl/Shift/ALt state
+ if ((cTemp == '#' || cTemp == '!' || cTemp == '^') && (szLine[nPos+1] == '{') )
+ {
+ }
+ else if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space
{
nFlag = 1;
// Add } to the end of the first bit for table lookup later.
} // GetSendKey()
+//
+// Routine to check the last "none comment" character on a line to see if its a continuation
+//
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
+{
+ int nsPos = styler.LineStart(szLine);
+ int nePos = styler.LineStart(szLine+1) - 2;
+ //int stylech = styler.StyleAt(nsPos);
+ while (nsPos < nePos)
+ {
+ //stylech = styler.StyleAt(nePos);
+ int stylech = styler.StyleAt(nsPos);
+ if (!(stylech == SCE_AU3_COMMENT)) {
+ char ch = styler.SafeGetCharAt(nePos);
+ if (!isspacechar(ch)) {
+ if (ch == '_')
+ return true;
+ else
+ return false;
+ }
+ }
+ nePos--; // skip to next char
+ } // End While
+ return false;
+} // IsContinuationLine()
+
+//
+// syntax highlighting logic
static void ColouriseAU3Doc(unsigned int startPos,
int length, int initStyle,
WordList *keywordlists[],
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ // find the first previous line without continuation character at the end
+ int lineCurrent = styler.GetLine(startPos);
+ int s_startPos = startPos;
+ // When not inside a Block comment: find First line without _
+ if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
+ (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent); // get start position
+ initStyle = 0; // reset the start style to 0
+ }
+ }
+ // Set the new length to include it from the start and set the start position
+ length = length + s_startPos - startPos; // correct the total length to process
styler.StartAt(startPos);
-
+
StyleContext sc(startPos, length, initStyle, styler);
char si; // string indicator "=1 '=2
- si=0;
+ char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
+ char ci; // comment indicator 0=not linecomment(;)
+ char s_save[100];
+ si=0;
+ ni=0;
+ ci=0;
//$$$
for (; sc.More(); sc.Forward()) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
+ // **********************************************
+ // save the total current word for eof processing
+ if (IsAWordChar(sc.ch) || 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';
+ }
+ }
+ // **********************************************
+ //
switch (sc.state)
{
case SCE_AU3_COMMENTBLOCK:
{
- if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0)))
- {
+ //Reset at line end
+ if (sc.atLineEnd) {
+ ci=0;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ //skip rest of line when a ; is encountered
+ if (sc.chPrev == ';') {
+ ci=2;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ // skip rest of the line
+ if (ci==2)
+ break;
+ // check when first character is detected on the line
+ if (ci==0) {
+ if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
+ ci=1;
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ break;
+ }
+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
- {sc.SetState(SCE_AU3_COMMENT);} // set to comment line for the rest of the line
+ sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line
else
- {sc.SetState(SCE_AU3_COMMENTBLOCK);}
+ ci=2; // line doesn't begin with #CE so skip the rest of the line
}
break;
}
}
case SCE_AU3_OPERATOR:
{
- sc.SetState(SCE_AU3_DEFAULT);
+ // check if its a COMobject
+ if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_AU3_COMOBJ);
+ }
+ else {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
break;
}
case SCE_AU3_SPECIAL:
{
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
+ if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
break;
}
case SCE_AU3_KEYWORD:
sc.ChangeState(SCE_AU3_SPECIAL);
sc.SetState(SCE_AU3_SPECIAL);
}
+ else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
+ sc.ChangeState(SCE_AU3_EXPAND);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
else if (strcmp(s, "_") == 0) {
sc.ChangeState(SCE_AU3_OPERATOR);
sc.SetState(SCE_AU3_DEFAULT);
}
}
}
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_AU3_DEFAULT);}
break;
}
- case SCE_AU3_NUMBER:
+ case SCE_AU3_NUMBER:
{
- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
- break;
+ // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
+ //
+ // test for Hex notation
+ if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
+ {
+ ni = 2;
+ break;
+ }
+ // test for E notation
+ if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
+ {
+ ni = 3;
+ break;
+ }
+ // Allow Hex characters inside hex numeric strings
+ if ((ni == 2) &&
+ (sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
+ sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
+ {
+ break;
+ }
+ // test for 1 dec point only
+ if (sc.ch == '.')
+ {
+ if (ni==0)
+ {
+ ni=1;
+ }
+ else
+ {
+ ni=9;
+ }
+ break;
+ }
+ // end of numeric string ?
+ if (!(IsADigit(sc.ch)))
+ {
+ if (ni==9)
+ {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ }
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
+ }
+ case SCE_AU3_VARIABLE:
+ {
+ // Check if its a COMObject
+ if (sc.ch == '.' && !IsADigit(sc.chNext)) {
+ sc.SetState(SCE_AU3_OPERATOR);
+ }
+ else if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
}
- case SCE_AU3_VARIABLE:
- {
- if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
- break;
+ case SCE_AU3_COMOBJ:
+ {
+ if (!(IsAWordChar(sc.ch))) {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ break;
}
case SCE_AU3_STRING:
{
{
sc.ForwardSetState(SCE_AU3_DEFAULT);
}
- if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ if (sc.atLineEnd)
+ {
+ // at line end and not found a continuation char then reset to default
+ int lineCurrent = styler.GetLine(sc.currentPos);
+ if (!IsContinuationLine(lineCurrent,styler))
+ {
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
// find Sendkeys in a STRING
if (sc.ch == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
// check if next portion is again a sendkey
if (sc.atLineEnd)
{
+ sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_DEFAULT);
si = 0; // reset string indicator
}
- if (sc.ch == '{' && sc.chPrev != '{') {sc.SetState(SCE_AU3_SENT);}
+ //if (sc.ch == '{' && sc.chPrev != '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
+ else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
else if (sc.ch == '\"') {
else if (sc.ch == '\'') {
sc.SetState(SCE_AU3_STRING);
si = 2; }
- else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_AU3_NUMBER);}
+ else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+ {
+ sc.SetState(SCE_AU3_NUMBER);
+ ni = 0;
+ }
else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
}
} //for (; sc.More(); sc.Forward())
- sc.Complete();
+
+ //*************************************
+ // Colourize the last word correctly
+ //*************************************
+ if (sc.state == SCE_AU3_KEYWORD)
+ {
+ if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
+ {
+ sc.ChangeState(SCE_AU3_COMMENTBLOCK);
+ sc.SetState(SCE_AU3_COMMENTBLOCK);
+ }
+ else if (keywords.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_KEYWORD);
+ sc.SetState(SCE_AU3_KEYWORD);
+ }
+ else if (keywords2.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_FUNCTION);
+ sc.SetState(SCE_AU3_FUNCTION);
+ }
+ else if (keywords3.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_MACRO);
+ sc.SetState(SCE_AU3_MACRO);
+ }
+ else if (keywords5.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_PREPROCESSOR);
+ sc.SetState(SCE_AU3_PREPROCESSOR);
+ }
+ else if (keywords6.InList(s_save)) {
+ sc.ChangeState(SCE_AU3_SPECIAL);
+ sc.SetState(SCE_AU3_SPECIAL);
+ }
+ else if (keywords7.InList(s_save) && sc.atLineEnd) {
+ sc.ChangeState(SCE_AU3_EXPAND);
+ sc.SetState(SCE_AU3_EXPAND);
+ }
+ else {
+ sc.ChangeState(SCE_AU3_DEFAULT);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ if (sc.state == SCE_AU3_SENT)
+ {
+ // Send key string ended
+ if (sc.chPrev == '}' && sc.ch != '}')
+ {
+ // set color to SENDKEY when valid sendkey .. else set back to regular string
+ char sk[100];
+ // split {111 222} and return {111} and check if 222 is valid.
+ // if return code = 1 then invalid 222 so must be string
+ if (GetSendKey(s_save,sk))
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ // if single char between {?} then its ok as sendkey for a single character
+ else if (strlen(sk) == 3)
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ // if sendkey {111} is in table then ok as sendkey
+ else if (keywords4.InList(sk))
+ {
+ sc.ChangeState(SCE_AU3_SENT);
+ }
+ else
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ }
+ sc.SetState(SCE_AU3_STRING);
+ }
+ // check if next portion is again a sendkey
+ if (sc.atLineEnd)
+ {
+ sc.ChangeState(SCE_AU3_STRING);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
+ }
+ //*************************************
+ sc.Complete();
}
//
} // GetStyleFirstWord()
-//
-// Routine to check the last "none comment" character on a line to see if its a continuation
-//
-static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
-{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine+1) - 2;
- //int stylech = styler.StyleAt(nsPos);
- while (nsPos < nePos)
- {
- //stylech = styler.StyleAt(nePos);
- int stylech = styler.StyleAt(nsPos);
- if (!(stylech == SCE_AU3_COMMENT)) {
- char ch = styler.SafeGetCharAt(nePos);
- if (!isspacechar(ch)) {
- if (ch == '_')
- return true;
- else
- return false;
- }
- }
- nePos--; // skip to next char
- } // End While
- return false;
-} // IsContinuationLine()
-
//
static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
// create new fold for these words
if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
- strcmp(szKeyword,"#region") == 0 ) {
+ strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
levelNext++;
}
- // create double Fold for select because Case will subtract one of the current level
- if (strcmp(szKeyword,"select") == 0) {
+ // create double Fold for select&switch because Case will subtract one of the current level
+ if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
levelNext++;
levelNext++;
}
// end the fold for these words before the current line
if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
- strcmp(szKeyword,"wend") == 0){
+ strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
levelNext--;
levelCurrent--;
}
levelCurrent--;
}
// end the double fold for this word before the current line
- if (strcmp(szKeyword,"endselect") == 0 ) {
+ if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
levelNext--;
levelNext--;
levelCurrent--;
"#autoit Sent keys",
"#autoit Pre-processors",
"#autoit Special",
+ "#autoit Expand",
0
};
LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) {
levelCurrent++;
}
- if ((strcmp(s, "end") == 0)) {
+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
+ // Normally "elseif" and "then" will be on the same line and will cancel
+ // each other out. // As implemented, this does not support fold.at.else.
levelCurrent--;
}
}
0, };
-LexerModule lmAsn1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
+LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
/** @file LexBash.cxx
** Lexer for Bash.
**/
-// Copyright 2004 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 2004-2005 by Neil Hodgson <neilh@scintilla.org>
// Adapted from LexPerl by Kein-Hong Man <mkh@pl.jaring.my> 2004
// The License.txt file describes the conditions under which this software may be distributed.
char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
HereDocCls() {
State = 0;
+ Quote = 0;
+ Quoted = false;
+ Indent = 0;
DelimiterLength = 0;
Delimiter = new char[HERE_DELIM_MAX];
Delimiter[0] = '\0';
HereDoc.Quoted = false;
HereDoc.DelimiterLength = 0;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- if (chNext == '\'') { // a quoted here-doc delimiter (' only)
+ if (chNext == '\'' || chNext == '\"') { // a quoted here-doc delimiter (' or ")
i++;
ch = chNext;
chNext = chNext2;
HereDoc.Indent = true;
HereDoc.State = 0;
} else if (isalpha(chNext) || chNext == '_' || chNext == '\\'
- || chNext == '-' || chNext == '+') {
+ || chNext == '-' || chNext == '+' || 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;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
}
} else { // an unquoted here-doc delimiter
- if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+') {
+ if (isalnum(ch) || ch == '_' || ch == '-' || ch == '+' || ch == '!') {
HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
} else if (ch == '\\') {
styler.ColourTo(lengthDoc - 1, state);
}
+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 void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && (style == SCE_SH_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
+ // 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 (ch == '{') {
levelCurrent++;
--- /dev/null
+// Scintilla source code edit control
+/** @file LexBasic.cxx
+ ** Lexer for BlitzBasic and PureBasic.
+ **/
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics
+// and derivatives. Once they diverge enough, might want to split it into multiple
+// lexers for more code clearity.
+//
+// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.
+
+// Folding only works for simple things like functions or types.
+
+// You may want to have a look at my ctags lexer as well, if you additionally to coloring
+// and folding need to extract things like label tags in your editor.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.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"
+
+/* Bits:
+ * 1 - whitespace
+ * 2 - operator
+ * 4 - identifier
+ * 8 - decimal digit
+ * 16 - hex digit
+ * 32 - bin digit
+ */
+static int character_classification[128] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
+ 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
+ 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
+};
+
+static bool IsSpace(int c) {
+ return c < 128 && (character_classification[c] & 1);
+}
+
+static bool IsOperator(int c) {
+ return c < 128 && (character_classification[c] & 2);
+}
+
+static bool IsIdentifier(int c) {
+ return c < 128 && (character_classification[c] & 4);
+}
+
+static bool IsDigit(int c) {
+ return c < 128 && (character_classification[c] & 8);
+}
+
+static bool IsHexDigit(int c) {
+ return c < 128 && (character_classification[c] & 16);
+}
+
+static bool IsBinDigit(int c) {
+ return c < 128 && (character_classification[c] & 32);
+}
+
+static int LowerCase(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler, char comment_char) {
+ bool wasfirst = true, isfirst = true; // true if first token in a line
+ styler.StartAt(startPos);
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ // Can't use sc.More() here else we miss the last character
+ for (; ; sc.Forward()) {
+ if (sc.state == SCE_B_IDENTIFIER) {
+ if (!IsIdentifier(sc.ch)) {
+ // Labels
+ if (wasfirst && sc.Match(':')) {
+ sc.ChangeState(SCE_B_LABEL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else {
+ char s[100];
+ int kstates[4] = {
+ SCE_B_KEYWORD,
+ SCE_B_KEYWORD2,
+ SCE_B_KEYWORD3,
+ SCE_B_KEYWORD4,
+ };
+ sc.GetCurrentLowered(s, sizeof(s));
+ for (int i = 0; i < 4; i++) {
+ if (keywordlists[i]->InList(s)) {
+ sc.ChangeState(kstates[i]);
+ }
+ }
+ // Types, must set them as operator else they will be
+ // matched as number/constant
+ if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||
+ sc.Match('#')) {
+ sc.SetState(SCE_B_OPERATOR);
+ } else {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+ }
+ } else if (sc.state == SCE_B_OPERATOR) {
+ if (!IsOperator(sc.ch) || sc.Match('#'))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_LABEL) {
+ if (!IsIdentifier(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_CONSTANT) {
+ if (!IsIdentifier(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_NUMBER) {
+ if (!IsDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_HEXNUMBER) {
+ if (!IsHexDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_BINNUMBER) {
+ if (!IsBinDigit(sc.ch))
+ sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.state == SCE_B_STRING) {
+ if (sc.ch == '"') {
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_B_ERROR);
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_COMMENT) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_B_DEFAULT);
+ }
+ }
+
+ if (sc.atLineStart)
+ isfirst = true;
+
+ if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
+ if (isfirst && sc.Match('.')) {
+ sc.SetState(SCE_B_LABEL);
+ } else if (isfirst && sc.Match('#')) {
+ wasfirst = isfirst;
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (sc.Match(comment_char)) {
+ sc.SetState(SCE_B_COMMENT);
+ } else if (sc.Match('"')) {
+ sc.SetState(SCE_B_STRING);
+ } else if (IsDigit(sc.ch)) {
+ sc.SetState(SCE_B_NUMBER);
+ } else if (sc.Match('$')) {
+ sc.SetState(SCE_B_HEXNUMBER);
+ } else if (sc.Match('%')) {
+ sc.SetState(SCE_B_BINNUMBER);
+ } else if (sc.Match('#')) {
+ sc.SetState(SCE_B_CONSTANT);
+ } else if (IsOperator(sc.ch)) {
+ sc.SetState(SCE_B_OPERATOR);
+ } else if (IsIdentifier(sc.ch)) {
+ wasfirst = isfirst;
+ sc.SetState(SCE_B_IDENTIFIER);
+ } else if (!IsSpace(sc.ch)) {
+ sc.SetState(SCE_B_ERROR);
+ }
+ }
+
+ if (!IsSpace(sc.ch))
+ isfirst = false;
+
+ if (!sc.More())
+ break;
+ }
+ sc.Complete();
+}
+
+static int CheckBlitzFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckPureFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "procedure") ||
+ !strcmp(token, "enumeration") ||
+ !strcmp(token, "interface") ||
+ !strcmp(token, "structure")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "endprocedure") ||
+ !strcmp(token, "endenumeration") ||
+ !strcmp(token, "endinterface") ||
+ !strcmp(token, "endstructure")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckFreeFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "sub") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end sub") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+static void FoldBasicDoc(unsigned int startPos, int length,
+ Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
+ 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 = CheckFoldPoint(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++;
+ }
+ } 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;
+ }
+ }
+ }
+ 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;
+ }
+ }
+}
+
+static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
+}
+
+static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
+}
+
+static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
+}
+
+static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
+}
+
+static void FoldPureBasicDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
+}
+
+static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+ FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
+}
+
+static const char * const blitzbasicWordListDesc[] = {
+ "BlitzBasic Keywords",
+ "user1",
+ "user2",
+ "user3",
+ 0
+};
+
+static const char * const purebasicWordListDesc[] = {
+ "PureBasic Keywords",
+ "PureBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+static const char * const freebasicWordListDesc[] = {
+ "FreeBasic Keywords",
+ "FreeBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
+ FoldBlitzBasicDoc, blitzbasicWordListDesc);
+
+LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
+ FoldPureBasicDoc, purebasicWordListDesc);
+
+LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
+ FoldFreeBasicDoc, freebasicWordListDesc);
+
// Scintilla source code edit control
/** @file LexClw.cxx
** Lexer for Clarion.
+ ** 2004/12/17 Updated Lexer
**/
-// Copyright 2003 by Ron Schofield <ron@schofieldcomputer.com>
+// Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com>
// 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 <ctype.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SciLexer.h"
-static char MakeUpperCase(char ch) {
- if (ch < 'a' || ch > 'z')
- return ch;
- else
- return static_cast<char>(ch - 'a' + 'A');
+// Is an end of line character
+inline bool IsEOL(const int ch) {
+
+ return(ch == '\n');
+}
+
+// Convert character to uppercase
+static char CharacterUpper(char chChar) {
+
+ if (chChar < 'a' || chChar > 'z') {
+ return(chChar);
+ }
+ else {
+ return(static_cast<char>(chChar - 'a' + 'A'));
+ }
}
-static void MakeUpperCaseString(char *s) {
- while (*s) {
- *s = MakeUpperCase(*s);
- s++;
+// Convert string to uppercase
+static void StringUpper(char *szString) {
+
+ while (*szString) {
+ *szString = CharacterUpper(*szString);
+ szString++;
}
}
// Is a label start character
inline bool IsALabelStart(const int iChar) {
+
return(isalpha(iChar) || iChar == '_');
}
// Is a label character
inline bool IsALabelCharacter(const int iChar) {
- return(isalnum(iChar) || iChar == '_' || iChar == ':');
+
+ return(isalnum(iChar) || iChar == '_' || iChar == ':');
}
-// Is the character is a ! and the the next character is not a !
-inline bool IsACommentStart(StyleContext &scDoc) {
- return(scDoc.ch == '!' && scDoc.chNext != '!');
+// Is the character is a ! and the the next character is not a !
+inline bool IsACommentStart(const int iChar) {
+
+ return(iChar == '!');
}
// Is the character a Clarion hex character (ABCDEF)
inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) {
+
// Case insensitive.
if (!bCaseSensitive) {
if (strchr("ABCDEFabcdef", iChar) != NULL) {
// Is the character a Clarion base character (B=Binary, O=Octal, H=Hex)
inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) {
+
// Case insensitive.
if (!bCaseSensitive) {
// If character is a numeric base character
// Set the correct numeric constant state
inline bool SetNumericConstantState(StyleContext &scDoc) {
+
int iPoints = 0; // Point counter
- char cNumericString[100]; // Numeric string buffer
+ char cNumericString[512]; // Numeric string buffer
// Buffer the current numberic string
scDoc.GetCurrent(cNumericString, sizeof(cNumericString));
break;
default :
break;
- }
+ }
}
// If points found (can be more than one for improper formatted number
if (iPoints > 0) {
}
}
+// Get the next word in uppercase from the current position (keyword lookahead)
+inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) {
+
+ unsigned int iIndex = 0; // Buffer Index
+
+ // Loop through the remaining string from the current position
+ for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) {
+ // Get the character from the buffer using the offset
+ char cCharacter = styler[iOffset];
+ if (IsEOL(cCharacter)) {
+ break;
+ }
+ // If the character is alphabet character
+ if (isalpha(cCharacter)) {
+ // Add UPPERCASE character to the word buffer
+ cWord[iIndex++] = CharacterUpper(cCharacter);
+ }
+ }
+ // Add null termination
+ cWord[iIndex] = '\0';
+ // If no word was found
+ if (iIndex == 0) {
+ // Return failure
+ return(false);
+ }
+ // Else word was found
+ else {
+ // Return success
+ return(true);
+ }
+}
+
// Clarion Language Colouring Procedure
-static void ColouriseClwDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
+static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) {
+
+ int iParenthesesLevel = 0; // Parenthese Level
+ int iColumn1Label = false; // Label starts in Column 1
+
+ WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
+ WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
+ WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions
+ WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions
+ WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types
+ WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes
+ WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates
+ WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
+ WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
- int iParenthesesLevel=0; // Parenthese Level
+ const char wlProcReservedKeywordList[] =
+ "PROCEDURE FUNCTION";
+ WordList wlProcReservedKeywords;
+ wlProcReservedKeywords.Set(wlProcReservedKeywordList);
- WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords
- WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives
- WordList &wlBuiltInProcsFuncs = *wlKeywords[2]; // Builtin Procedures and Functions
- WordList &wlStructsDataTypes = *wlKeywords[3]; // Structures and Data Types
- WordList &wlAttributes = *wlKeywords[4]; // Procedure Attributes
- WordList &wlStandardEquates = *wlKeywords[5]; // Standard Equates
- WordList &wlReservedWords = *wlKeywords[6]; // Clarion Reserved Keywords
+ const char wlCompilerKeywordList[] =
+ "COMPILE OMIT";
+ WordList wlCompilerKeywords;
+ wlCompilerKeywords.Set(wlCompilerKeywordList);
+
+ const char wlLegacyStatementsList[] =
+ "BOF EOF FUNCTION POINTER SHARE";
+ WordList wlLegacyStatements;
+ wlLegacyStatements.Set(wlLegacyStatementsList);
StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler);
if (!IsALabelCharacter(scDoc.ch)) {
// If the character is a . (dot syntax)
if (scDoc.ch == '.') {
+ // Turn off column 1 label flag as label now cannot be reserved work
+ iColumn1Label = false;
// Uncolour the . (dot) to default state, move forward one character,
// and change back to the label state.
scDoc.SetState(SCE_CLW_DEFAULT);
scDoc.Forward();
scDoc.SetState(SCE_CLW_LABEL);
}
- // Else terminate the label state
+ // Else check label
else {
- char cLabel[100]; // Label buffer
+ char cLabel[512]; // Label buffer
// Buffer the current label string
scDoc.GetCurrent(cLabel,sizeof(cLabel));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
- MakeUpperCaseString(cLabel);
+ StringUpper(cLabel);
}
- // If label string is in the Clarion reserved keyword list
- if (wlReservedWords.InList(cLabel)){
- // change to error state
+ // Else if UPPERCASE label string is in the Clarion compiler keyword list
+ if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){
+ // change the label to error state
+ scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
+ }
+ // Else if UPPERCASE label string is in the Clarion reserved keyword list
+ else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){
+ // change the label to error state
scDoc.ChangeState(SCE_CLW_ERROR);
}
+ // Else if UPPERCASE label string is
+ else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
+ char cWord[512]; // Word buffer
+ // Get the next word from the current position
+ if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) {
+ // If the next word is a procedure reserved word
+ if (wlProcReservedKeywords.InList(cWord)) {
+ // Change the label to error state
+ scDoc.ChangeState(SCE_CLW_ERROR);
+ }
+ }
+ }
// Else if label string is in the compiler directive keyword list
else if (wlCompilerDirectives.InList(cLabel)) {
// change the state to compiler directive state
else if (scDoc.state == SCE_CLW_KEYWORD) {
// If character is : (colon)
if (scDoc.ch == ':') {
- char cEquate[100]; // Equate buffer
+ char cEquate[512]; // Equate buffer
// Move forward to include : (colon) in buffer
scDoc.Forward();
// Buffer the equate string
scDoc.GetCurrent(cEquate,sizeof(cEquate));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
- MakeUpperCaseString(cEquate);
+ StringUpper(cEquate);
}
// If statement string is in the equate list
if (wlStandardEquates.InList(cEquate)) {
}
// If the character is not a valid label character
else if (!IsALabelCharacter(scDoc.ch)) {
- char cStatement[100]; // Statement buffer
+ char cStatement[512]; // Statement buffer
// Buffer the statement string
scDoc.GetCurrent(cStatement,sizeof(cStatement));
// If case insensitive, convert string to UPPERCASE to match passed keywords.
if (!bCaseSensitive) {
- MakeUpperCaseString(cStatement);
+ StringUpper(cStatement);
}
// If statement string is in the Clarion keyword list
if (wlClarionKeywords.InList(cStatement)) {
- // Set to the Clarion keyword state
+ // Change the statement string to the Clarion keyword state
scDoc.ChangeState(SCE_CLW_KEYWORD);
}
// Else if statement string is in the compiler directive keyword list
else if (wlCompilerDirectives.InList(cStatement)) {
- // Set to the compiler directive state
+ // Change the statement string to the compiler directive state
scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE);
}
+ // Else if statement string is in the runtime expressions keyword list
+ else if (wlRuntimeExpressions.InList(cStatement)) {
+ // Change the statement string to the runtime expressions state
+ scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS);
+ }
// Else if statement string is in the builtin procedures and functions keyword list
else if (wlBuiltInProcsFuncs.InList(cStatement)) {
- // Set to the builtin procedures and functions state
+ // Change the statement string to the builtin procedures and functions state
scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION);
}
// Else if statement string is in the tructures and data types keyword list
else if (wlStructsDataTypes.InList(cStatement)) {
- // Set to the structures and data types state
+ // Change the statement string to the structures and data types state
scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE);
}
// Else if statement string is in the procedure attribute keyword list
else if (wlAttributes.InList(cStatement)) {
- // Set to the procedure attribute state
+ // Change the statement string to the procedure attribute state
scDoc.ChangeState(SCE_CLW_ATTRIBUTE);
}
// Else if statement string is in the standard equate keyword list
else if (wlStandardEquates.InList(cStatement)) {
- // Set to the standard equate state
+ // Change the statement string to the standard equate state
scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE);
}
+ // Else if statement string is in the deprecated or legacy keyword list
+ else if (wlLegacyStatements.InList(cStatement)) {
+ // Change the statement string to the standard equate state
+ scDoc.ChangeState(SCE_CLW_DEPRECATED);
+ }
+ // Else the statement string doesn't match any work list
+ else {
+ // Change the statement string to the default state
+ scDoc.ChangeState(SCE_CLW_DEFAULT);
+ }
// Terminate the keyword state and set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
// Increment the parenthese level
iParenthesesLevel++;
}
- // Else if the character is a ) (close parenthese)
+ // Else if the character is a ) (close parenthese)
else if (scDoc.ch == ')') {
// If the parenthese level is set to zero
// parentheses matched
if (!iParenthesesLevel) {
scDoc.SetState(SCE_CLW_DEFAULT);
- }
+ }
// Else parenthese level is greater than zero
// still looking for matching parentheses
else {
|| IsAHexCharacter(scDoc.ch, bCaseSensitive)
|| scDoc.ch == '.'
|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
- // If the number was a real
+ // If the number was a real
if (SetNumericConstantState(scDoc)) {
// Colour the matched string to the real constant state
scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
// Beginning of Line Handling
if (scDoc.atLineStart) {
+ // Reset the column 1 label flag
+ iColumn1Label = false;
// If column 1 character is a label start character
if (IsALabelStart(scDoc.ch)) {
+ // Label character is found in column 1
+ // so set column 1 label flag and clear last column 1 label
+ iColumn1Label = true;
// Set the state to label
scDoc.SetState(SCE_CLW_LABEL);
}
// Set to default state
scDoc.SetState(SCE_CLW_DEFAULT);
}
- // else if the start of a comment or is an * (asterisk)
- else if (IsACommentStart(scDoc) || scDoc.ch == '*' ) {
+ // else if comment start (!) or is an * (asterisk)
+ else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
}
}
// Default Handling
else {
- // If in default state
+ // If in default state
if (scDoc.state == SCE_CLW_DEFAULT) {
// If is a letter could be a possible statement
if (isalpha(scDoc.ch)) {
scDoc.SetState(SCE_CLW_INTEGER_CONSTANT);
}
// else if the start of a comment or a | (line continuation)
- else if (IsACommentStart(scDoc) || scDoc.ch == '|') {
+ else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
- }
+ }
// else if the character is a ' (single quote)
else if (scDoc.ch == '\'') {
- // If the character is also a ' (single quote)
+ // If the character is also a ' (single quote)
// Embedded Apostrophe
if (scDoc.chNext == '\'') {
// Move forward colouring it as default state
// move to the next character and then set the state to comment.
scDoc.ForwardSetState(SCE_CLW_STRING);
}
- }
- // else the character is an @ (apersand)
+ }
+ // else the character is an @ (ampersand)
else if (scDoc.ch == '@') {
// Case insensitive.
if (!bCaseSensitive) {
scDoc.SetState(SCE_CLW_PICTURE_STRING);
}
}
- }
+ }
}
}
}
}
// Clarion Language Case Sensitive Colouring Procedure
-static void ColouriseClwDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
- ColouriseClwDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
+static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+
+ ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true);
}
// Clarion Language Case Insensitive Colouring Procedure
-static void ColouriseClwDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
- ColouriseClwDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
+static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+
+ ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false);
+}
+
+// Fill Buffer
+
+static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) {
+
+ unsigned int uiPos = 0;
+
+ while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) {
+ szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos]));
+ uiPos++;
+ }
+ szBuffer[uiPos] = '\0';
+}
+
+// Classify Clarion Fold Point
+
+static int ClassifyClarionFoldPoint(int iLevel, const char* szString) {
+
+ if (!(isdigit(szString[0]) || (szString[0] == '.'))) {
+ if (strcmp(szString, "PROCEDURE") == 0) {
+ // iLevel = SC_FOLDLEVELBASE + 1;
+ }
+ else if (strcmp(szString, "MAP") == 0 ||
+ strcmp(szString,"ACCEPT") == 0 ||
+ strcmp(szString,"BEGIN") == 0 ||
+ strcmp(szString,"CASE") == 0 ||
+ strcmp(szString,"EXECUTE") == 0 ||
+ strcmp(szString,"IF") == 0 ||
+ strcmp(szString,"ITEMIZE") == 0 ||
+ strcmp(szString,"INTERFACE") == 0 ||
+ strcmp(szString,"JOIN") == 0 ||
+ strcmp(szString,"LOOP") == 0 ||
+ strcmp(szString,"MODULE") == 0 ||
+ strcmp(szString,"RECORD") == 0) {
+ iLevel++;
+ }
+ else if (strcmp(szString, "APPLICATION") == 0 ||
+ strcmp(szString, "CLASS") == 0 ||
+ strcmp(szString, "DETAIL") == 0 ||
+ strcmp(szString, "FILE") == 0 ||
+ strcmp(szString, "FOOTER") == 0 ||
+ strcmp(szString, "FORM") == 0 ||
+ strcmp(szString, "GROUP") == 0 ||
+ strcmp(szString, "HEADER") == 0 ||
+ strcmp(szString, "INTERFACE") == 0 ||
+ strcmp(szString, "MENU") == 0 ||
+ strcmp(szString, "MENUBAR") == 0 ||
+ strcmp(szString, "OLE") == 0 ||
+ strcmp(szString, "OPTION") == 0 ||
+ strcmp(szString, "QUEUE") == 0 ||
+ strcmp(szString, "REPORT") == 0 ||
+ strcmp(szString, "SHEET") == 0 ||
+ strcmp(szString, "TAB") == 0 ||
+ strcmp(szString, "TOOLBAR") == 0 ||
+ strcmp(szString, "VIEW") == 0 ||
+ strcmp(szString, "WINDOW") == 0) {
+ iLevel++;
+ }
+ else if (strcmp(szString, "END") == 0 ||
+ strcmp(szString, "UNTIL") == 0 ||
+ strcmp(szString, "WHILE") == 0) {
+ iLevel--;
+ }
+ }
+ return(iLevel);
}
// Clarion Language Folding Procedure
-#ifdef FOLDING_IMPLEMENTED
-static void FoldClwDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) {
+static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) {
+
+ unsigned int uiEndPos = uiStartPos + iLength;
+ int iLineCurrent = accStyler.GetLine(uiStartPos);
+ int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int iLevelCurrent = iLevelPrev;
+ char chNext = accStyler[uiStartPos];
+ int iStyle = iInitStyle;
+ int iStyleNext = accStyler.StyleAt(uiStartPos);
+ int iVisibleChars = 0;
+ int iLastStart = 0;
+
+ for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) {
+
+ char chChar = chNext;
+ chNext = accStyler.SafeGetCharAt(uiPos + 1);
+ int iStylePrev = iStyle;
+ iStyle = iStyleNext;
+ iStyleNext = accStyler.StyleAt(uiPos + 1);
+ bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
+
+ if (iStylePrev == SCE_CLW_DEFAULT) {
+ if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
+ // Store last word start point.
+ iLastStart = uiPos;
+ }
+ }
+
+ if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) {
+ if(iswordchar(chChar) && !iswordchar(chNext)) {
+ char chBuffer[100];
+ FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer));
+ iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer);
+ // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) {
+ // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE);
+ // iLevelPrev = SC_FOLDLEVELBASE;
+ // }
+ }
+ }
+
+ if (bEOL) {
+ int iLevel = iLevelPrev;
+ if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0))
+ iLevel |= SC_FOLDLEVELHEADERFLAG;
+ if (iLevel != accStyler.LevelAt(iLineCurrent)) {
+ accStyler.SetLevel(iLineCurrent,iLevel);
+ }
+ iLineCurrent++;
+ iLevelPrev = iLevelCurrent;
+ iVisibleChars = 0;
+ }
+
+ if (!isspacechar(chChar))
+ iVisibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags
+ // as they will be filled in later.
+ int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext);
}
-#endif
// Word List Descriptions
static const char * const rgWordListDescriptions[] = {
"Clarion Keywords",
"Compiler Directives",
"Built-in Procedures and Functions",
+ "Runtime Expressions",
"Structure and Data Types",
"Attributes",
"Standard Equates",
- "Reserved Words",
+ "Reserved Words (Labels)",
+ "Reserved Words (Procedure Labels)",
0,
};
// Case Sensitive Clarion Language Lexer
-LexerModule lmClw(SCLEX_CLW, ColouriseClwDocSensitive, "clw", NULL, rgWordListDescriptions);
+LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions);
// Case Insensitive Clarion Language Lexer
-LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClwDocInsensitive, "clwnocase", NULL, rgWordListDescriptions);
+LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions);
// Scintilla source code edit control
/** @file LexCPP.cxx
- ** Lexer for C++, C, Java, and Javascript.
+ ** Lexer for C++, C, Java, and JavaScript.
**/
-// Copyright 1998-2002 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>
#define KEYWORD_BOXHEADER 1
#define KEYWORD_FOLDCONTRACTED 2
-static bool IsOKBeforeRE(const int ch) {
+static bool IsOKBeforeRE(int ch) {
return (ch == '(') || (ch == '=') || (ch == ',');
}
-static inline bool IsAWordChar(const int ch) {
+static inline bool IsAWordChar(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordStart(int ch) {
+ return (ch < 0x80) && (isalpha(ch) || ch == '_');
}
-static inline bool IsADoxygenChar(const int ch) {
- return (islower(ch) || ch == '$' || ch == '@' ||
- ch == '\\' || ch == '&' || ch == '<' ||
- ch == '>' || ch == '#' || ch == '{' ||
- ch == '}' || ch == '[' || ch == ']');
+static inline bool IsADoxygenChar(int ch) {
+ return (ch < 0x80 && islower(ch)) || ch == '$' || ch == '@' ||
+ ch == '\\' || ch == '&' || ch == '<' ||
+ ch == '>' || ch == '#' || ch == '{' ||
+ ch == '}' || ch == '[' || ch == ']';
}
-static inline bool IsStateComment(const int state) {
- return ((state == SCE_C_COMMENT) ||
- (state == SCE_C_COMMENTLINE) ||
- (state == SCE_C_COMMENTDOC) ||
- (state == SCE_C_COMMENTDOCKEYWORD) ||
- (state == SCE_C_COMMENTDOCKEYWORDERROR));
-}
-
-static inline bool IsStateString(const int state) {
- return ((state == SCE_C_STRING) || (state == SCE_C_VERBATIM));
+static bool IsSpaceEquiv(int state) {
+ return (state <= SCE_C_COMMENTDOC) ||
+ // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE
+ (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) ||
+ (state == SCE_C_COMMENTDOCKEYWORDERROR);
}
static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
- // Do not leak onto next line
- if (initStyle == SCE_C_STRINGEOL)
- initStyle = SCE_C_DEFAULT;
-
int chPrevNonWhite = ' ';
int visibleChars = 0;
bool lastWordWasUUID = false;
+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
+ bool continuationLine = false;
+
+ if (initStyle == SCE_C_PREPROCESSOR) {
+ // Set continuationLine if last character of previous line is '\'
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ int chBack = styler.SafeGetCharAt(startPos-1, 0);
+ int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
+ int lineEndChar = '!';
+ if (chBack2 == '\r' && chBack == '\n') {
+ lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
+ } else if (chBack == '\n' || chBack == '\r') {
+ lineEndChar = chBack2;
+ }
+ continuationLine = lineEndChar == '\\';
+ }
+ }
+
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (startPos > 0) {
+ int back = startPos;
+ while (--back && IsSpaceEquiv(styler.StyleAt(back)))
+ ;
+ if (styler.StyleAt(back) == SCE_C_OPERATOR) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ }
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
- if (sc.atLineStart && (sc.state == SCE_C_STRING)) {
- // Prevent SCE_C_STRINGEOL from leaking back to previous line
- sc.SetState(SCE_C_STRING);
+ if (sc.atLineStart) {
+ if (sc.state == SCE_C_STRING) {
+ // Prevent SCE_C_STRINGEOL from leaking back to previous line which
+ // ends with a line continuation by locking in the state upto this position.
+ sc.SetState(SCE_C_STRING);
+ }
+ // Reset states to begining of colourise so no surprises
+ // if different sets of lines lexed.
+ visibleChars = 0;
+ lastWordWasUUID = false;
}
// Handle line continuation generically.
if (sc.ch == '\r' && sc.chNext == '\n') {
sc.Forward();
}
+ continuationLine = true;
continue;
}
}
// Determine if the current state should terminate.
- if (sc.state == SCE_C_OPERATOR) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (sc.state == SCE_C_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
- } else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (keywords.InList(s)) {
- lastWordWasUUID = strcmp(s, "uuid") == 0;
- sc.ChangeState(SCE_C_WORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_C_WORD2);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_C_GLOBALCLASS);
- }
+ switch (sc.state) {
+ case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_PREPROCESSOR) {
- if (stylingWithinPreprocessor) {
- if (IsASpace(sc.ch)) {
+ break;
+ case SCE_C_NUMBER:
+ // We accept almost anything because of hex. and number suffixes
+ if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_C_DEFAULT);
}
- } else {
- if ((sc.ch == '\r') || (sc.ch == '\n') || (sc.Match('/', '*')) || (sc.Match('/', '/'))) {
+ break;
+ case SCE_C_IDENTIFIER:
+ if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ char s[1000];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (keywords.InList(s)) {
+ lastWordWasUUID = strcmp(s, "uuid") == 0;
+ sc.ChangeState(SCE_C_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_C_WORD2);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_C_GLOBALCLASS);
+ }
sc.SetState(SCE_C_DEFAULT);
}
- }
- } else if (sc.state == SCE_C_COMMENT) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_COMMENTDOC) {
- if (sc.Match('*', '/')) {
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.ch == '@' || sc.ch == '\\') {
- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
- }
- } else if (sc.state == SCE_C_COMMENTLINE || sc.state == SCE_C_COMMENTLINEDOC) {
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_C_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_C_COMMENTDOCKEYWORD) {
- if (sc.Match('*', '/')) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
- sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (!IsADoxygenChar(sc.ch)) {
- char s[100];
- if (caseSensitive) {
- sc.GetCurrent(s, sizeof(s));
+ break;
+ case SCE_C_PREPROCESSOR:
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (stylingWithinPreprocessor) {
+ if (IsASpace(sc.ch)) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
} else {
- sc.GetCurrentLowered(s, sizeof(s));
- }
- if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ if (sc.Match('/', '*') || sc.Match('/', '/')) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
}
- sc.SetState(SCE_C_COMMENTDOC);
- }
- } else if (sc.state == SCE_C_STRING) {
- if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ break;
+ case SCE_C_COMMENT:
+ if (sc.Match('*', '/')) {
sc.Forward();
+ sc.ForwardSetState(SCE_C_DEFAULT);
}
- } else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
- sc.ForwardSetState(SCE_C_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_C_CHARACTER) {
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
- sc.ForwardSetState(SCE_C_DEFAULT);
- visibleChars = 0;
- } else if (sc.ch == '\\') {
- if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ break;
+ case SCE_C_COMMENTDOC:
+ if (sc.Match('*', '/')) {
sc.Forward();
+ sc.ForwardSetState(SCE_C_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_C_COMMENTDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ }
}
- } else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- }
- } else if (sc.state == SCE_C_REGEX) {
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == '/') {
- sc.ForwardSetState(SCE_C_DEFAULT);
- } else if (sc.ch == '\\') {
- // Gobble up the quoted character
- if (sc.chNext == '\\' || sc.chNext == '/') {
- sc.Forward();
+ break;
+ case SCE_C_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
}
- }
- } else if (sc.state == SCE_C_VERBATIM) {
- if (sc.ch == '\"') {
- if (sc.chNext == '\"') {
+ break;
+ case SCE_C_COMMENTLINEDOC:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_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_C_COMMENTLINEDOC;
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_C_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
sc.Forward();
- } else {
sc.ForwardSetState(SCE_C_DEFAULT);
+ } else if (!IsADoxygenChar(sc.ch)) {
+ char s[100];
+ if (caseSensitive) {
+ sc.GetCurrent(s, sizeof(s));
+ } else {
+ sc.GetCurrentLowered(s, sizeof(s));
+ }
+ if (!isspace(sc.ch) || !keywords3.InList(s + 1)) {
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_C_STRING:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_C_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_CHARACTER:
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_C_STRINGEOL);
+ } else if (sc.ch == '\\') {
+ if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+ sc.Forward();
+ }
+ } else if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_REGEX:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '/') {
+ sc.Forward();
+ while ((sc.ch < 0x80) && islower(sc.ch))
+ sc.Forward(); // gobble regex flags
+ sc.SetState(SCE_C_DEFAULT);
+ } else if (sc.ch == '\\') {
+ // Gobble up the quoted character
+ if (sc.chNext == '\\' || sc.chNext == '/') {
+ sc.Forward();
+ }
+ }
+ break;
+ case SCE_C_STRINGEOL:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_C_DEFAULT);
+ }
+ break;
+ case SCE_C_VERBATIM:
+ if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_C_DEFAULT);
+ }
+ }
+ break;
+ case SCE_C_UUID:
+ if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ sc.SetState(SCE_C_DEFAULT);
}
- }
- } else if (sc.state == SCE_C_UUID) {
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
- sc.SetState(SCE_C_DEFAULT);
- }
}
// Determine if a new state should be entered.
else
sc.SetState(SCE_C_COMMENTLINE);
} else if (sc.ch == '/' && IsOKBeforeRE(chPrevNonWhite)) {
- sc.SetState(SCE_C_REGEX);
+ sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
} else if (sc.ch == '\"') {
sc.SetState(SCE_C_STRING);
} else if (sc.ch == '\'') {
do {
sc.Forward();
} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
- if (sc.ch == '\r' || sc.ch == '\n') {
+ if (sc.atLineEnd) {
sc.SetState(SCE_C_DEFAULT);
}
} else if (isoperator(static_cast<char>(sc.ch))) {
}
}
- if (sc.atLineEnd) {
- // Reset states to begining of colourise so no surprises
- // if different sets of lines lexed.
- chPrevNonWhite = ' ';
- visibleChars = 0;
- lastWordWasUUID = false;
- }
- if (!IsASpace(sc.ch)) {
+ if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
chPrevNonWhite = sc.ch;
visibleChars++;
}
+ continuationLine = false;
}
sc.Complete();
}
static bool IsStreamCommentStyle(int style) {
return style == SCE_C_COMMENT ||
- style == SCE_C_COMMENTDOC ||
- style == SCE_C_COMMENTDOCKEYWORD ||
- style == SCE_C_COMMENTDOCKEYWORDERROR;
+ style == SCE_C_COMMENTDOC ||
+ style == SCE_C_COMMENTDOCKEYWORD ||
+ style == SCE_C_COMMENTDOCKEYWORDERROR;
}
// Store both the current line's fold level and the next lines in the
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)
+ 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)
+ sc.SetState(SCE_CSS_ATTRIBUTE);
+ break;
+ case ']':
+ if (lastState == SCE_CSS_ATTRIBUTE)
+ sc.SetState(SCE_CSS_TAG);
+ break;
case '{':
if (lastState == SCE_CSS_DIRECTIVE)
sc.SetState(SCE_CSS_DEFAULT);
sc.SetState(SCE_CSS_VALUE);
break;
case '.':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+ 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)
sc.SetState(SCE_CSS_CLASS);
break;
case '#':
- if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT)
+ 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)
sc.SetState(SCE_CSS_ID);
break;
case ',':
} else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
} else if (IsCssOperator(static_cast<char>(sc.ch))
+ && (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
&& (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
) {
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCaml.cxx
+ ** Lexer for Objective Caml.
+ **/
+// Copyright 2005 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.
+ 20050205 Quick compiler standards/"cleanliness" adjustment.
+ 20050206 Added cast for IsLeadByte().
+ 20050209 Changes to "external" build support.
+ 20050306 Fix for 1st-char-in-doc "corner" case.
+ 20050502 Fix for [harmless] one-past-the-end coloring.
+ 20050515 Refined numeric token recognition logic.
+ 20051125 Added 2nd "optional" keywords class.
+ 20051129 Support "magic" (read-only) comments for RCaml.
+ 20051204 Swtich to using StyleContext infrastructure.
+*/
+
+#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"
+
+// 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 */
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
+};
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+/*
+ (actually seems to work!)
+*/
+#include "WindowAccessor.h"
+#include "ExternalLexer.h"
+
+#if PLAT_WIN
+#include <windows.h>
+#endif
+
+static void ColouriseCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static void FoldCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler);
+
+static void InternalLexOrFold(int lexOrFold, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props);
+
+static const char* LexerName = "caml";
+
+#ifdef TRACE
+void Platform::DebugPrintf(const char *format, ...) {
+ char buffer[2000];
+ va_list pArguments;
+ va_start(pArguments, format);
+ vsprintf(buffer,format,pArguments);
+ va_end(pArguments);
+ Platform::DebugDisplay(buffer);
+}
+#else
+void Platform::DebugPrintf(const char *, ...) {
+}
+#endif
+
+bool Platform::IsDBCSLeadByte(int codePage, char ch) {
+ return ::IsDBCSLeadByteEx(codePage, ch) != 0;
+}
+
+long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
+ return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam);
+}
+
+long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) {
+ return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam,
+ reinterpret_cast<LPARAM>(lParam));
+}
+
+void EXT_LEXER_DECL Fold(unsigned int lexer, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ lexer;
+ // build expected data structures and do the Fold
+ InternalLexOrFold(1, startPos, length, initStyle, words, window, props);
+
+}
+
+int EXT_LEXER_DECL GetLexerCount()
+{
+ return 1; // just us [Objective] Caml lexers here!
+}
+
+void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ Index;
+ // return as much of our lexer name as will fit (what's up with Index?)
+ if (buflength > 0) {
+ buflength--;
+ int n = strlen(LexerName);
+ if (n > buflength)
+ n = buflength;
+ memcpy(name, LexerName, n), name[n] = '\0';
+ }
+}
+
+void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ lexer;
+ // build expected data structures and do the Lex
+ InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
+}
+
+static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
+ int initStyle, char *words[], WindowID window, char *props)
+{
+ // create and initialize a WindowAccessor (including contained PropSet)
+ PropSet ps;
+ ps.SetMultiple(props);
+ WindowAccessor wa(window, ps);
+ // create and initialize WordList(s)
+ int nWL = 0;
+ for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed
+ WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs
+ int i = 0;
+ for (; i < nWL; i++) {
+ wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION)
+ wl[i]->Set(words[i]);
+ }
+ wl[i] = 0;
+ // call our "internal" folder/lexer (... then do Flush!)
+ if (foldOrLex)
+ FoldCamlDoc(startPos, length, initStyle, wl, wa);
+ else
+ ColouriseCamlDoc(startPos, length, initStyle, wl, wa);
+ wa.Flush();
+ // clean up before leaving
+ for (i = nWL - 1; i >= 0; i--)
+ delete wl[i];
+ delete [] wl;
+}
+
+static
+#endif /* BUILD_AS_EXTERNAL_LEXER */
+
+void ColouriseCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ // 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 int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
+
+ // foreach char in range...
+ while (sc.More()) {
+ // set up [per-char] state info
+ int state2 = -1; // (ASSUME no state change)
+ int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
+ bool advance = true; // (ASSUME scanner "eats" 1 char)
+
+ // step state machine
+ switch (sc.state & 0x0f) {
+ case SCE_CAML_DEFAULT:
+ chToken = sc.currentPos; // save [possible] token start (JIC)
+ // it's wide open; what do we have?
+ if (iscamlf(sc.ch))
+ state2 = SCE_CAML_IDENTIFIER;
+ else if (sc.Match('`') && iscamlf(sc.chNext))
+ state2 = SCE_CAML_TAGNAME;
+ else if (sc.Match('#') && isdigit(sc.chNext))
+ state2 = SCE_CAML_LINENUM;
+ else if (isdigit(sc.ch)) {
+ 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?) */
+ state2 = SCE_CAML_CHAR, chLit = 0;
+ 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_OPERATOR;
+ break;
+
+ case SCE_CAML_IDENTIFIER:
+ // [try to] interpret as [additional] identifier char
+ if (!(iscaml(sc.ch) || sc.Match('\''))) {
+ const int n = sc.currentPos - chToken;
+ if (n < 24) {
+ // length is believable as keyword, [re-]construct token
+ char t[24];
+ for (int i = -n; i < 0; i++)
+ t[n + i] = static_cast<char>(sc.GetRelative(i));
+ t[n] = '\0';
+ // special-case "_" token as KEYWORD
+ if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD);
+ else if (keywords2.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD2);
+ else if (keywords3.InList(t))
+ sc.ChangeState(SCE_CAML_KEYWORD3);
+ }
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ }
+ break;
+
+ case SCE_CAML_TAGNAME:
+ // [try to] interpret as [additional] tagname char
+ if (!(iscaml(sc.ch) || sc.Match('\'')))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;
+
+ /*case SCE_CAML_KEYWORD:
+ case SCE_CAML_KEYWORD2:
+ case SCE_CAML_KEYWORD3:
+ // [try to] interpret as [additional] keyword char
+ if (!iscaml(ch))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ break;*/
+
+ case SCE_CAML_LINENUM:
+ // [try to] interpret as [additional] linenum directive char
+ if (!isdigit(sc.ch))
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ 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 */) {
+ // check for INCLUSIVE termination
+ if (o && strchr(")]};,", sc.ch)) {
+ if ((sc.Match(')') && sc.chPrev == '(')
+ || (sc.Match(']') && sc.chPrev == '['))
+ // special-case "()" and "[]" tokens as KEYWORDS
+ sc.ChangeState(SCE_CAML_KEYWORD);
+ chColor++;
+ } else
+ advance = false;
+ state2 = SCE_CAML_DEFAULT;
+ }
+ break;
+ }
+
+ 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))
+ break;
+ // how about an integer suffix?
+ if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
+ && (iscamld(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))
+ break;
+ // with an exponent? (I)
+ if ((sc.Match('e') || sc.Match('E'))
+ && (iscamld(sc.chPrev) || sc.chPrev == '.'))
+ break;
+ // with an exponent? (II)
+ if ((sc.Match('+') || sc.Match('-'))
+ && (sc.chPrev == 'e' || sc.chPrev == 'E'))
+ break;
+ }
+ // it looks like we have run out of number
+ state2 = SCE_CAML_DEFAULT, advance = false;
+ 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)
+ // 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;
+
+ 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++;
+ break;
+
+ case SCE_CAML_COMMENT:
+ case SCE_CAML_COMMENT1:
+ case SCE_CAML_COMMENT2:
+ case SCE_CAML_COMMENT3:
+ // 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++;
+ // [try to] interpret as [additional] comment char
+ else if (sc.Match(')') && sc.chPrev == '*') {
+ if (nesting)
+ state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
+ else
+ state2 = SCE_CAML_DEFAULT;
+ chColor++;
+ // enable "magic" (read-only) comment AS REQUIRED
+ } else if (useMagic && sc.currentPos - chToken == 4
+ && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
+ sc.state |= 0x10; // (switch to read-only comment style)
+ break;
+ }
+
+ // 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
+ if (advance)
+ sc.Forward();
+ }
+
+ // do any required terminal char coloring (JIC)
+ sc.Complete();
+}
+
+#ifdef BUILD_AS_EXTERNAL_LEXER
+static
+#endif /* BUILD_AS_EXTERNAL_LEXER */
+void FoldCamlDoc(
+ unsigned int startPos, int length,
+ int initStyle,
+ WordList *keywordlists[],
+ Accessor &styler)
+{
+ // below useless evaluation(s) to supress "not used" warnings
+ startPos || length || initStyle || keywordlists[0] || styler.Length();
+}
+
+static const char * const camlWordListDesc[] = {
+ "Keywords", // primary Objective Caml keywords
+ "Keywords2", // "optional" keywords (typically from Pervasives)
+ "Keywords3", // "optional" keywords (typically typenames)
+ 0
+};
+
+#ifndef BUILD_AS_EXTERNAL_LEXER
+LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc);
+#endif /* BUILD_AS_EXTERNAL_LEXER */
--- /dev/null
+// Scintilla source code edit control
+/** @file LexCsound.cxx
+ ** Lexer for Csound (Orchestra & Score)
+ ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
+ **/
+// 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 <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+ ch == '_' || ch == '?');
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
+ ch == '%' || ch == '@' || ch == '$' || ch == '?');
+}
+
+static inline bool IsCsoundOperator(char ch) {
+ if (isalnum(ch))
+ return false;
+ // '.' left out as it is used to make up numbers
+ if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
+ ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
+ ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
+ ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
+ ch == '%' || ch == ':')
+ return true;
+ return false;
+}
+
+static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &opcode = *keywordlists[0];
+ WordList &headerStmt = *keywordlists[1];
+ WordList &otherKeyword = *keywordlists[2];
+
+ // Do not leak onto next line
+ if (initStyle == SCE_CSOUND_STRINGEOL)
+ initStyle = SCE_CSOUND_DEFAULT;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ 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;
+ }
+ }
+
+ // Determine if the current state should terminate.
+ if (sc.state == SCE_CSOUND_OPERATOR) {
+ if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }else if (sc.state == SCE_CSOUND_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ } else if (sc.state == SCE_CSOUND_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch) ) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+
+ if (opcode.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_OPCODE);
+ } else if (headerStmt.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_HEADERSTMT);
+ } else if (otherKeyword.InList(s)) {
+ sc.ChangeState(SCE_CSOUND_USERKEYWORD);
+ } else if (s[0] == 'p') {
+ sc.ChangeState(SCE_CSOUND_PARAM);
+ } else if (s[0] == 'a') {
+ sc.ChangeState(SCE_CSOUND_ARATE_VAR);
+ } else if (s[0] == 'k') {
+ sc.ChangeState(SCE_CSOUND_KRATE_VAR);
+ } else if (s[0] == 'i') { // covers both i-rate variables and i-statements
+ sc.ChangeState(SCE_CSOUND_IRATE_VAR);
+ } else if (s[0] == 'g') {
+ sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
+ }
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+ else if (sc.state == SCE_CSOUND_COMMENT ) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+ else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
+ (sc.state == SCE_CSOUND_KRATE_VAR) ||
+ (sc.state == SCE_CSOUND_IRATE_VAR)) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_CSOUND_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_CSOUND_DEFAULT) {
+ if (sc.ch == ';'){
+ sc.SetState(SCE_CSOUND_COMMENT);
+ } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
+ sc.SetState(SCE_CSOUND_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_CSOUND_IDENTIFIER);
+ } else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_CSOUND_OPERATOR);
+ } else if (sc.ch == 'p') {
+ sc.SetState(SCE_CSOUND_PARAM);
+ } else if (sc.ch == 'a') {
+ sc.SetState(SCE_CSOUND_ARATE_VAR);
+ } else if (sc.ch == 'k') {
+ sc.SetState(SCE_CSOUND_KRATE_VAR);
+ } else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
+ sc.SetState(SCE_CSOUND_IRATE_VAR);
+ } else if (sc.ch == 'g') {
+ sc.SetState(SCE_CSOUND_GLOBAL_VAR);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int stylePrev = 0;
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; 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 ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
+ char s[20];
+ unsigned int j = 0;
+ while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
+ s[j] = styler[i + j];
+ j++;
+ }
+ s[j] = '\0';
+
+ if (strcmp(s, "instr") == 0)
+ levelCurrent++;
+ if (strcmp(s, "endin") == 0)
+ levelCurrent--;
+ }
+
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ stylePrev = style;
+ }
+ // 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 csoundWordListDesc[] = {
+ "Opcodes",
+ "Header Statements",
+ "User keywords",
+ 0
+};
+
+LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
--- /dev/null
+// Scintilla source code edit control
+/** @file LexFlagShip.cxx
+ ** Lexer for FlagShip
+ ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
+ **/
+// Copyright 2005 by Randy Butler
+// 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 <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static bool IsFlagShipComment(Accessor &styler, int pos, int len) {
+ return len>0 && styler[pos]=='\'';
+}
+
+static inline bool IsTypeCharacter(int ch) {
+ return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
+}
+
+// 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 ||
+ (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsADateCharacter(const int ch) {
+ return (ch < 0x80) &&
+ (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
+}
+
+
+static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ //bool FSScriptSyntax = true;
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+
+ styler.StartAt(startPos);
+
+ int visibleChars = 0;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ if (sc.state == SCE_FS_OPERATOR) {
+ sc.SetState(SCE_FS_DEFAULT);
+ } else if (sc.state == SCE_FS_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD2);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD3);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD4);
+ }// Else, it is really an identifier...
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_NUMBER) {
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_STRING) {
+ // VB doubles quotes to preserve them, so just end this string
+ // state now as a following quote will start again
+ if (sc.ch == '\"') {
+ if (tolower(sc.chNext) == 'c') {
+ sc.Forward();
+ }
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_FS_STRINGEOL);
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_COMMENT) {
+ if (sc.Match('*', '/')) { // new code
+ sc.Forward();
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ //if (sc.atLineEnd) { // old code
+ // sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_COMMENTLINE) { //new code
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_FS_DEFAULT);
+ visibleChars = 0;
+ }
+ } else if (sc.state == SCE_FS_PREPROCESSOR) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ } else if (sc.state == SCE_FS_DATE) {
+ if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ }
+ }
+
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_FS_DEFAULT) {
+ if (sc.Match('/', '*')) { // New code
+ sc.SetState(SCE_FS_COMMENT);
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ //if (sc.ch == '\'') { // Old code
+ // sc.SetState(SCE_FS_COMMENT); // old code
+ } else if (sc.Match('/', '/')) { // New code
+ sc.SetState(SCE_FS_COMMENTLINE);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_FS_STRING);
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ // Preprocessor commands are alone on their line
+ sc.SetState(SCE_FS_PREPROCESSOR);
+ } else if (sc.ch == '#') {
+ int n = 1;
+ int chSeek = ' ';
+ while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
+ chSeek = sc.GetRelative(n);
+ n++;
+ }
+ if (IsADigit(chSeek)) {
+ sc.SetState(SCE_FS_DATE);
+ } else {
+ sc.SetState(SCE_FS_OPERATOR);
+ }
+ } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
+ sc.SetState(SCE_FS_NUMBER);
+ } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
+ sc.SetState(SCE_FS_NUMBER);
+ } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_FS_NUMBER);
+ } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
+ sc.SetState(SCE_FS_IDENTIFIER);
+ } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
+ sc.SetState(SCE_FS_OPERATOR);
+ }
+ }
+
+ if (sc.atLineEnd) {
+ visibleChars = 0;
+ }
+ if (!IsASpace(sc.ch)) {
+ visibleChars++;
+ }
+ }
+ sc.Complete();
+}
+
+static void FoldFlagShipDoc(unsigned int startPos, int length, int,
+ WordList *[], Accessor &styler) {
+
+ int endPos = startPos + length;
+
+ // Backtrack to previous line in case need to fix its fold status
+ int lineCurrent = styler.GetLine(startPos);
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+ int spaceFlags = 0;
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsFlagShipComment);
+ char chNext = styler[startPos];
+ for (int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ int lev = indentCurrent;
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsFlagShipComment);
+ if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
+ // Only non whitespace lines can be headers
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
+ // Line after is blank so check the next - maybe should continue further?
+ int spaceFlags2 = 0;
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsFlagShipComment);
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ }
+ }
+ indentCurrent = indentNext;
+ styler.SetLevel(lineCurrent, lev);
+ lineCurrent++;
+ }
+ }
+}
+
+
+static const char * const FSWordListDesc[] = {
+ "Keywords",
+ "functions",
+ "user2",
+ "user3",
+ 0
+};
+
+LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
+
+
+
int style = initStyle;
/***************************************/
int lastStart = 0;
- char prevWord[32] = "", Label[6] = "";
+ char prevWord[32] = "";
+ char Label[6] = "";
// Variables for do label folding.
- static int doLabels[100], posLabel=-1;
+ static int doLabels[100];
+ static int posLabel=-1;
/***************************************/
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
if (!noforward) sc.Forward();
}
- styler.ColourTo(sc.currentPos, sc.state);
+ sc.Complete();
}
// Main folding function called by Scintilla - (based on props (.ini) files function)
/** @file LexHTML.cxx
** Lexer for HTML.
**/
-// Copyright 1998-2003 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>
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
-static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
+static inline int MakeLowerCase(int ch) {
+ if (ch < 'A' || ch > 'Z')
+ return ch;
+ else
+ return ch - 'A' + 'a';
+}
+
+static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
+ size_t i = 0;
+ for (; (i < end - start + 1) && (i < len-1); i++) {
+ s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
}
s[i] = '\0';
+}
+
+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));
//Platform::DebugPrintf("Scripting indicator [%s]\n", s);
if (strstr(s, "src")) // External script
return eScriptNone;
static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) {
int iResult = 0;
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (0 == strncmp(s, "php", 3)) {
iResult = 3;
}
if (wordIsNumber) {
chAttr = SCE_H_NUMBER;
} else {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s))
chAttr = SCE_H_ATTRIBUTE;
}
for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) {
char ch = styler[cPos];
if ((ch != '<') && (ch != '/')) {
- s[i++] = caseSensitive ? ch : static_cast<char>(tolower(ch));
+ s[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch));
}
}
if (wordIsNumber)
chAttr = SCE_HB_NUMBER;
else {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s)) {
chAttr = SCE_HB_WORD;
if (strcmp(s, "rem") == 0)
if (wordIsNumber)
chAttr = SCE_HPHP_NUMBER;
else {
- char s[100 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 100; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- }
- s[i] = '\0';
+ char s[100];
+ GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s))
chAttr = SCE_HPHP_WORD;
}
return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
}
+static bool IsScriptCommentState(const int state) {
+ return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT ||
+ state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
+}
+
static bool isLineEnd(char ch) {
return ch == '\r' || ch == '\n';
}
static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
int j;
+ while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
+ i++;
phpStringDelimiter[0] = '\n';
for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
if (j - i < phpStringDelimiterSize - 2)
char chPrev = ' ';
char ch = ' ';
char chPrevNonWhite = ' ';
+ // look back to set chPrevNonWhite properly for better regex colouring
+ if (scriptLanguage == eScriptJS && startPos > 0) {
+ int back = startPos;
+ int style = 0;
+ while (--back) {
+ style = styler.StyleAt(back);
+ if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC)
+ // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
+ break;
+ }
+ if (style == SCE_HJ_SYMBOLS) {
+ chPrevNonWhite = styler.SafeGetCharAt(back);
+ }
+ }
+
styler.StartSegment(startPos);
const int lengthDoc = startPos + length;
for (int i = startPos; i < lengthDoc; i++) {
const char chPrev2 = chPrev;
chPrev = ch;
- if (ch != ' ' && ch != '\t')
+ if (!isspacechar(ch) && state != SCE_HJ_COMMENT &&
+ state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC)
chPrevNonWhite = ch;
ch = styler[i];
char chNext = styler.SafeGetCharAt(i + 1);
case SCE_H_SINGLESTRING:
case SCE_HJ_COMMENT:
case SCE_HJ_COMMENTDOC:
- // SCE_HJ_COMMENTLINE removed as this is a common thing done to hide
- // the end of script marker from some JS interpreters.
- //case SCE_HJ_COMMENTLINE:
+ //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
+ // the end of script marker from some JS interpreters.
case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX:
case SCE_HP_TRIPLEDOUBLE:
break;
default :
+ // check if the closing tag is a script tag
+ if (state == SCE_HJ_COMMENTLINE) {
+ char tag[7]; // room for the <script> tag
+ char chr; // current char
+ int j=0;
+ chr = styler.SafeGetCharAt(i+2);
+ while (j < 6 && !isspacechar(chr)) {
+ tag[j++] = static_cast<char>(MakeLowerCase(chr));
+ chr = styler.SafeGetCharAt(i+2+j);
+ }
+ tag[j] = '\0';
+ if (strcmp(tag, "script") != 0) break;
+ }
// closing tag of the script (it's a closing HTML tag anyway)
styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_TAGUNKNOWN;
!isPHPStringState(state) &&
(state != SCE_HPHP_COMMENT) &&
(ch == '<') &&
- (chNext == '?')) {
+ (chNext == '?') &&
+ !IsScriptCommentState(state) ) {
scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment() + 2, i + 10, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
- // fold whole script
- if (foldHTMLPreprocessor){
+ // Fold whole script, but not if the XML first tag (all XML-like tags in this case)
+ if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent++;
- if (scriptLanguage == eScriptXML)
- levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case)
}
// should be better
ch = styler.SafeGetCharAt(i);
}
// handle the start of ASP pre-processor = Non-HTML
- else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%')) {
+ else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
/////////////////////////////////////
// handle the start of SGML language (DTD)
else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
- (chPrev == '<') &&
- (ch == '!') &&
- (StateToPrint != SCE_H_CDATA) && (!IsCommentState(StateToPrint))) {
+ (chPrev == '<') &&
+ (ch == '!') &&
+ (StateToPrint != SCE_H_CDATA) &&
+ (!IsCommentState(StateToPrint)) &&
+ (!IsScriptCommentState(StateToPrint)) ) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
state = SCE_H_COMMENT; // wait for a pending command
- }
- else if (isWordCdata(i + 1, i + 7, styler)) {
+ styler.ColourTo(i + 2, SCE_H_COMMENT);
+ i += 2; // follow styling after the --
+ } else if (isWordCdata(i + 1, i + 7, styler)) {
state = SCE_H_CDATA;
} else {
styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
|| (inScriptType == eNonHtmlScriptPreProc)) && (
((scriptLanguage == eScriptPHP) && (ch == '?') && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT)) ||
((scriptLanguage != eScriptNone) && !isStringState(state) &&
- (ch == '%'))
+ ((ch == '%') || (ch == '?')))
) && (chNext == '>')) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
if (state == SCE_H_ASPAT) {
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
- scriptLanguage = eScriptNone;
- // unfold all scripting languages
- if (foldHTMLPreprocessor)
+ // Unfold all scripting languages, except for XML tag
+ if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
+ }
+ scriptLanguage = eScriptNone;
continue;
}
/////////////////////////////////////
if (ch == '/' && chPrev == '*') {
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
+ ch = ' ';
}
break;
case SCE_HJ_COMMENTLINE:
if (ch == '\r' || ch == '\n') {
styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType));
state = SCE_HJ_DEFAULT;
+ ch = ' ';
}
break;
case SCE_HJ_DOUBLESTRING:
break;
case SCE_HJ_REGEX:
if (ch == '\r' || ch == '\n' || ch == '/') {
+ if (ch == '/') {
+ while (isascii(chNext) && islower(chNext)) { // gobble regex flags
+ i++;
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ }
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
} else if (ch == '\\') {
}
break;
case SCE_HPHP_NUMBER:
- if (!IsADigit(ch) && ch != '.' && ch != 'e' && ch != 'E' && (ch != '-' || (chPrev != 'e' && chPrev != 'E'))) {
+ // recognize bases 8,10 or 16 integers OR floating-point numbers
+ if (!IsADigit(ch)
+ && strchr(".xXabcdefABCDEF", ch) == NULL
+ && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) {
styler.ColourTo(i - 1, SCE_HPHP_NUMBER);
if (isoperator(ch))
state = SCE_HPHP_OPERATOR;
sc.Complete();
}
+static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+ if(startPos == 0) initStyle = SCE_HPHP_DEFAULT;
+ ColouriseHyperTextDoc(startPos,length,initStyle,keywordlists,styler);
+}
+
static const char * const htmlWordListDesc[] = {
"HTML elements and attributes",
"JavaScript keywords",
0,
};
-LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc);
-LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc);
-LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc);
-LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc);
+static const char * const phpscriptWordListDesc[] = {
+ "", //Unused
+ "", //Unused
+ "", //Unused
+ "", //Unused
+ "PHP keywords",
+ "", //Unused
+ 0,
+};
+
+LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc, 7);
+LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc, 7);
+// SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
+LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 7);
+LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 7);
+LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 7);
--- /dev/null
+/******************************************************************
+ * LexHaskell.cxx
+ *
+ * A haskell lexer for the scintilla code control.
+ * Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
+ * External lexer stuff inspired from the caml external lexer.
+ *
+ * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
+ *
+ *
+ * TODO:
+ * * Implement a folder :)
+ * * Nice Character-lexing (stuff inside '\''), LexPython has
+ * this.
+ *
+ *
+ *****************************************************************/
+
+#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 BUILD_AS_EXTERNAL_LEXER
+
+#include "ExternalLexer.h"
+#include "WindowAccessor.h"
+
+#define BUILD_EXTERNAL_LEXER 0
+
+#endif
+
+// Max level of nested comments
+#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
+
+
+enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
+
+static inline bool IsNewline(const int ch) {
+ return (ch == '\n' || ch == '\r');
+}
+
+static inline bool IsWhitespace(const int ch) {
+ return ( ch == ' '
+ || ch == '\t'
+ || IsNewline(ch) );
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
+}
+
+static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+
+ int kwLast = kwOther;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ for (; sc.More(); sc.Forward()) {
+
+ // Check for state end
+ // Operator
+ if (sc.state == SCE_HA_OPERATOR) {
+ kwLast = kwOther;
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ // String
+ else if (sc.state == SCE_HA_STRING) {
+ if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Char
+ else if (sc.state == SCE_HA_CHARACTER) {
+ if (sc.ch == '\'') {
+ sc.ForwardSetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Number
+ else if (sc.state == SCE_HA_NUMBER) {
+ if (!IsADigit(sc.ch)) {
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Types, constructors, etc.
+ else if (sc.state == SCE_HA_CAPITAL) {
+ if (!IsAWordChar(sc.ch) || sc.ch == '.') {
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ }
+ // Identifier
+ else if (sc.state == SCE_HA_IDENTIFIER) {
+ if (!IsAWordChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ int style = SCE_HA_IDENTIFIER;
+ if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
+ style = SCE_HA_IMPORT;
+ } else if (keywords.InList(s)) {
+ style = SCE_HA_KEYWORD;
+ } else if (kwLast == kwData) {
+ style = SCE_HA_DATA;
+ } else if (kwLast == kwClass) {
+ style = SCE_HA_CLASS;
+ } else if (kwLast == kwModule) {
+ style = SCE_HA_MODULE;
+ } else if (isupper(s[0])) {
+ style = SCE_HA_CAPITAL;
+ }
+ sc.ChangeState(style);
+ sc.SetState(SCE_HA_DEFAULT);
+ if (style == SCE_HA_KEYWORD) {
+ if (0 == strcmp(s, "class"))
+ kwLast = kwClass;
+ else if (0 == strcmp(s, "data"))
+ kwLast = kwData;
+ else if (0 == strcmp(s, "instance"))
+ kwLast = kwInstance;
+ else if (0 == strcmp(s, "import"))
+ kwLast = kwImport;
+ else if (0 == strcmp(s, "module"))
+ kwLast = kwModule;
+ else
+ kwLast = kwOther;
+ } else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
+ style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
+ style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
+ kwLast = kwOther;
+ }
+ }
+ }
+ // Comments
+ // Oneliner
+ else if (sc.state == SCE_HA_COMMENTLINE) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_HA_DEFAULT);
+ }
+ // Nested
+ else if (sc.state >= SCE_HA_COMMENTBLOCK) {
+ if (sc.Match("{-")) {
+ if (sc.state < SCE_HA_COMMENTMAX)
+ sc.SetState(sc.state + 1);
+ }
+ else if (sc.Match("-}")) {
+ sc.Forward();
+ if (sc.state == SCE_HA_COMMENTBLOCK)
+ sc.ForwardSetState(SCE_HA_DEFAULT);
+ else
+ sc.ForwardSetState(sc.state - 1);
+ }
+ }
+ // New state?
+ if (sc.state == SCE_HA_DEFAULT) {
+ // Digit
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_HA_NUMBER);
+ }
+ // Comment line
+ else if (sc.Match("--")) {
+ sc.SetState(SCE_HA_COMMENTLINE);
+ // Comment block
+ }
+ else if (sc.Match("{-")) {
+ sc.SetState(SCE_HA_COMMENTBLOCK);
+ }
+ // String
+ else if (sc.Match('\"')) {
+ sc.SetState(SCE_HA_STRING);
+ }
+ // Character
+ else if (sc.Match('\'') && IsWhitespace(sc.GetRelative(-1)) ) {
+ sc.SetState(SCE_HA_CHARACTER);
+ }
+ // Stringstart
+ else if (sc.Match('\"')) {
+ sc.SetState(SCE_HA_STRING);
+ }
+ // Operator
+ else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_HA_OPERATOR);
+ }
+ // Keyword
+ else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_HA_IDENTIFIER);
+ }
+
+ }
+ }
+ sc.Complete();
+}
+
+// External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet.
+// Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com
+#ifdef BUILD_EXTERNAL_LEXER
+static const char* LexerName = "haskell";
+
+void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
+ char *words[], WindowID window, char *props)
+{
+ PropSet ps;
+ ps.SetMultiple(props);
+ WindowAccessor wa(window, ps);
+
+ int nWL = 0;
+ for (; words[nWL]; nWL++) ;
+ WordList** wl = new WordList* [nWL + 1];
+ int i = 0;
+ for (; i<nWL; i++)
+ {
+ wl[i] = new WordList();
+ wl[i]->Set(words[i]);
+ }
+ wl[i] = 0;
+
+ ColorizeHaskellDoc(startPos, length, initStyle, wl, wa);
+ wa.Flush();
+ for (i=nWL-1;i>=0;i--)
+ delete wl[i];
+ delete [] wl;
+}
+
+void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle,
+ char *words[], WindowID window, char *props)
+{
+
+}
+
+int EXT_LEXER_DECL GetLexerCount()
+{
+ return 1;
+}
+
+void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
+{
+ if (buflength > 0) {
+ buflength--;
+ int n = strlen(LexerName);
+ if (n > buflength)
+ n = buflength;
+ memcpy(name, LexerName, n), name[n] = '\0';
+ }
+}
+#endif
+
+LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
+
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
+#include "StyleContext.h"
+#define SCE_LISP_CHARACTER 29
+#define SCE_LISP_MACRO 30
+#define SCE_LISP_MACRO_DISPATCH 31
static inline bool isLispoperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
- if (ch == '\'' || ch == '(' || ch == ')' )
+ if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' )
return true;
return false;
}
}
-static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
PLATFORM_ASSERT(end >= start);
char s[100];
unsigned int i;
else {
if (keywords.InList(s)) {
chAttr = SCE_LISP_KEYWORD;
+ } else if (keywords_kw.InList(s)) {
+ chAttr = SCE_LISP_KEYWORD_KW;
+ } else if ((s[0] == '*' && s[i-1] == '*') ||
+ (s[0] == '+' && s[i-1] == '+')) {
+ chAttr = SCE_LISP_SPECIAL;
}
}
styler.ColourTo(end, chAttr);
Accessor &styler) {
WordList &keywords = *keywordlists[0];
+ WordList &keywords_kw = *keywordlists[1];
styler.StartAt(startPos);
- int state = initStyle;
+ int state = initStyle, radix = -1;
char chNext = styler[startPos];
unsigned int lengthDoc = startPos + length;
styler.StartSegment(startPos);
}
if (state == SCE_LISP_DEFAULT) {
- if (isLispwordstart(ch)) {
+ if (ch == '#') {
+ styler.ColourTo(i - 1, state);
+ radix = -1;
+ state = SCE_LISP_MACRO_DISPATCH;
+ } else if (isLispwordstart(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_IDENTIFIER;
}
else if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
}
else if (ch == '\"') {
styler.ColourTo(i - 1, state);
state = SCE_LISP_STRING;
}
- } else if (state == SCE_LISP_IDENTIFIER) {
+ } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) {
if (!isLispwordstart(ch)) {
- classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler);
+ if (state == SCE_LISP_IDENTIFIER) {
+ classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler);
+ } else {
+ styler.ColourTo(i - 1, state);
+ }
state = SCE_LISP_DEFAULT;
} /*else*/
if (isLispoperator(ch) || ch=='\'') {
styler.ColourTo(i - 1, state);
styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
+ }
+ } else if (state == SCE_LISP_MACRO_DISPATCH) {
+ if (!isdigit(ch)) {
+ if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
+ state = SCE_LISP_DEFAULT;
+ } else {
+ switch (ch) {
+ case '|': state = SCE_LISP_MULTI_COMMENT; break;
+ case 'o':
+ case 'O': radix = 8; state = SCE_LISP_MACRO; break;
+ case 'x':
+ case 'X': radix = 16; state = SCE_LISP_MACRO; break;
+ case 'b':
+ case 'B': radix = 2; state = SCE_LISP_MACRO; break;
+ case '\\': state = SCE_LISP_CHARACTER; break;
+ case ':':
+ case '-':
+ case '+': state = SCE_LISP_MACRO; break;
+ case '\'': if (isLispwordstart(chNext)) {
+ state = SCE_LISP_SPECIAL;
+ } else {
+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ state = SCE_LISP_DEFAULT;
+ }
+ break;
+ default: if (isLispoperator(ch)) {
+ styler.ColourTo(i - 1, SCE_LISP_DEFAULT);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ }
+ state = SCE_LISP_DEFAULT;
+ break;
+ }
+ }
+ }
+ } else if (state == SCE_LISP_MACRO) {
+ if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) {
+ state = SCE_LISP_SPECIAL;
+ } else {
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_CHARACTER) {
+ if (isLispoperator(ch)) {
+ styler.ColourTo(i, SCE_LISP_SPECIAL);
+ state = SCE_LISP_DEFAULT;
+ } else if (isLispwordstart(ch)) {
+ styler.ColourTo(i, SCE_LISP_SPECIAL);
+ state = SCE_LISP_SPECIAL;
+ } else {
+ state = SCE_LISP_DEFAULT;
+ }
+ } else if (state == SCE_LISP_SPECIAL) {
+ if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_LISP_DEFAULT;
+ }
+ if (isLispoperator(ch) || ch=='\'') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_LISP_OPERATOR);
+ if (ch=='\'' && isLispwordstart(chNext)) {
+ state = SCE_LISP_SYMBOL;
+ }
}
-
} else {
if (state == SCE_LISP_COMMENT) {
if (atEOL) {
styler.ColourTo(i - 1, state);
state = SCE_LISP_DEFAULT;
}
+ } else if (state == SCE_LISP_MULTI_COMMENT) {
+ if (ch == '|' && chNext == '#') {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ styler.ColourTo(i, state);
+ state = SCE_LISP_DEFAULT;
+ }
} else if (state == SCE_LISP_STRING) {
if (ch == '\\') {
if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
}
static const char * const lispWordListDesc[] = {
+ "Functions and special operators",
"Keywords",
0
};
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SciLexer.h"
-static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
+// Extended to accept accented characters
+static inline bool IsAWordChar(int ch) {
+ return ch >= 0x80 ||
+ (isalnum(ch) || ch == '.' || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordStart(int ch) {
+ return ch >= 0x80 ||
+ (isalpha(ch) || ch == '_');
}
-static inline bool IsANumberChar(const int 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) &&
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.
+static int LongDelimCheck(StyleContext &sc) {
+ int sep = 1;
+ while (sc.GetRelative(sep) == '=' && sep < 0xFF)
+ sep++;
+ if (sc.GetRelative(sep) == sc.ch)
+ return sep;
+ return 0;
+}
+
static void ColouriseLuaDoc(
unsigned int startPos,
int length,
WordList &keywords8 = *keywordlists[7];
int currentLine = styler.GetLine(startPos);
- // Initialize the literal string [[ ... ]] nesting level, if we are inside such a string.
- int literalStringLevel = 0;
- if (initStyle == SCE_LUA_LITERALSTRING) {
- literalStringLevel = styler.GetLineState(currentLine - 1);
- }
- // Initialize the block comment --[[ ... ]] nesting level, if we are inside such a comment
- int blockCommentLevel = 0;
- if (initStyle == SCE_LUA_COMMENT) {
- blockCommentLevel = styler.GetLineState(currentLine - 1);
+ // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
+ // if we are inside such a string. Block comment was introduced in Lua 5.0,
+ // blocks with separators [=[ ... ]=] in Lua 5.1.
+ int nestLevel = 0;
+ int sepCount = 0;
+ if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
+ int lineState = styler.GetLineState(currentLine - 1);
+ nestLevel = lineState >> 8;
+ sepCount = lineState & 0xFF;
}
// Do not leak onto next line
- if (initStyle == SCE_LUA_STRINGEOL) {
+ if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {
initStyle = SCE_LUA_DEFAULT;
}
currentLine = styler.GetLine(sc.currentPos);
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
- // Inside a literal string, we set the line state
- styler.SetLineState(currentLine, literalStringLevel);
- break;
- case SCE_LUA_COMMENT: // Block comment
- // Inside a block comment, we set the line state
- styler.SetLineState(currentLine, blockCommentLevel);
+ case SCE_LUA_COMMENT:
+ // Inside a literal string or block comment, we set the line state
+ styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
break;
default:
// Reset the line state
}
sc.SetState(SCE_LUA_DEFAULT);
}
- } else if (sc.state == SCE_LUA_COMMENTLINE ) {
+ } else if (sc.state == SCE_LUA_COMMENTLINE || sc.state == SCE_LUA_PREPROCESSOR) {
if (sc.atLineEnd) {
- sc.SetState(SCE_LUA_DEFAULT);
- }
- } else if (sc.state == SCE_LUA_PREPROCESSOR ) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_LUA_DEFAULT);
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
if (sc.ch == '\\') {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
- } else if (sc.state == SCE_LUA_LITERALSTRING) {
- if (sc.Match('[', '[')) {
- literalStringLevel++;
- sc.Forward();
- sc.SetState(SCE_LUA_LITERALSTRING);
- } else if (sc.Match(']', ']') && literalStringLevel > 0) {
- literalStringLevel--;
- sc.Forward();
- if (literalStringLevel == 0) {
- sc.ForwardSetState(SCE_LUA_DEFAULT);
+ } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) {
+ if (sc.ch == '[') {
+ int sep = LongDelimCheck(sc);
+ if (sep == 1 && sepCount == 1) { // [[-only allowed to nest
+ nestLevel++;
+ sc.Forward();
}
- }
- } else if (sc.state == SCE_LUA_COMMENT) { // Lua 5.0's block comment
- if (sc.Match('[', '[')) {
- blockCommentLevel++;
- sc.Forward();
- } else if (sc.Match(']', ']') && blockCommentLevel > 0) {
- blockCommentLevel--;
- sc.Forward();
- if (blockCommentLevel == 0) {
+ } else if (sc.ch == ']') {
+ int sep = LongDelimCheck(sc);
+ if (sep == 1 && sepCount == 1) { // un-nest with ]]-only
+ nestLevel--;
+ sc.Forward();
+ if (nestLevel == 0) {
+ sc.ForwardSetState(SCE_LUA_DEFAULT);
+ }
+ } else if (sep > 1 && sep == sepCount) { // ]=]-style delim
+ sc.Forward(sep);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
}
sc.SetState(SCE_LUA_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_LUA_IDENTIFIER);
- } else if (sc.Match('\"')) {
+ } else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
- } else if (sc.Match('\'')) {
+ } else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
- } else if (sc.Match('[', '[')) {
- literalStringLevel = 1;
- sc.SetState(SCE_LUA_LITERALSTRING);
- sc.Forward();
- } else if (sc.Match("--[[")) { // Lua 5.0's block comment
- blockCommentLevel = 1;
- sc.SetState(SCE_LUA_COMMENT);
- sc.Forward(3);
+ } else if (sc.ch == '[') {
+ sepCount = LongDelimCheck(sc);
+ if (sepCount == 0) {
+ sc.SetState(SCE_LUA_OPERATOR);
+ } else {
+ nestLevel = 1;
+ sc.SetState(SCE_LUA_LITERALSTRING);
+ sc.Forward(sepCount);
+ }
} else if (sc.Match('-', '-')) {
sc.SetState(SCE_LUA_COMMENTLINE);
- sc.Forward();
+ if (sc.Match("--[")) {
+ sc.Forward(2);
+ sepCount = LongDelimCheck(sc);
+ if (sepCount > 0) {
+ nestLevel = 1;
+ sc.ChangeState(SCE_LUA_COMMENT);
+ sc.Forward(sepCount);
+ }
+ } else {
+ sc.Forward();
+ }
} 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))) {
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_LUA_WORD) {
- if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e') {
+ if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
for (unsigned int j = 0; j < 8; j++) {
if (!iswordchar(styler[i + j])) {
break;
s[j + 1] = '\0';
}
- if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0)) {
+ if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) {
levelCurrent++;
}
- if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) {
+ if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) {
levelCurrent--;
}
}
} else if (ch == '}' || ch == ')') {
levelCurrent--;
}
+ } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
}
if (atEOL) {
"Basic functions",
"String, (table) & math functions",
"(coroutines), I/O & system facilities",
- "XXX",
- "XXX",
+ "user1",
+ "user2",
+ "user3",
+ "user4",
0
};
/** @file LexMSSQL.cxx
** Lexer for MSSQL.
**/
-// Copyright 1998-2002 by Filip Yaghob <fy@eg.cz>
+// By Filip Yaghob <fyaghob@gmail.com>
#include <stdlib.h>
#define KW_MSSQL_STORED_PROCEDURES 5
#define KW_MSSQL_OPERATORS 6
-//~ val SCE_MSSQL_DEFAULT=0
-//~ val SCE_MSSQL_COMMENT=1
-//~ val SCE_MSSQL_LINE_COMMENT=2
-//~ val SCE_MSSQL_NUMBER=3
-//~ val SCE_MSSQL_STRING=4
-//~ val SCE_MSSQL_OPERATOR=5
-//~ val SCE_MSSQL_IDENTIFIER=6
-//~ val SCE_MSSQL_VARIABLE=7
-//~ val SCE_MSSQL_COLUMN_NAME=8
-//~ val SCE_MSSQL_STATEMENT=9
-//~ val SCE_MSSQL_DATATYPE=10
-//~ val SCE_MSSQL_SYSTABLE=11
-//~ val SCE_MSSQL_GLOBAL_VARIABLE=12
-//~ val SCE_MSSQL_FUNCTION=13
-//~ val SCE_MSSQL_STORED_PROCEDURE=14
-//~ val SCE_MSSQL_DEFAULT_PREF_DATATYPE 15
-//~ val SCE_MSSQL_COLUMN_NAME_2 16
-
static bool isMSSQLOperator(char ch) {
if (isascii(ch) && isalnum(ch))
return false;
bool fold = styler.GetPropertyInt("fold") != 0;
int lineCurrent = styler.GetLine(startPos);
int spaceFlags = 0;
-/*
- WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS];
- WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES];
- WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
- WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
- WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS];
- char s[100];
- int iixx = 0;
- s[0] = 's'; s[1] = 'e'; s[2] = 'l'; s[3] = 'e'; s[4] = 'c'; s[5] = 't'; s[6] = 0;
- if (kwStatements.InList(s))
- iixx = 1;
- s[0] = 's'; s[1] = 'e'; s[2] = 'r'; s[3] = 'v'; s[4] = 'e'; s[5] = 'r'; s[6] = 'n'; s[7] = 'a'; s[8] = 'm'; s[9] = 'e'; s[10] = 0;
- if (kwGlobalVariables.InList(s))
- iixx += 2;
-*/
int state = initStyle;
int prevState = initStyle;
char chPrev = ' ';
styler.ColourTo(lengthDoc - 1, state);
}
+static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
+ char s[10];
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ // Comment folding
+ if (foldComment) {
+ if (!inComment && (style == SCE_MSSQL_COMMENT))
+ levelCurrent++;
+ else if (inComment && (style != SCE_MSSQL_COMMENT))
+ levelCurrent--;
+ inComment = (style == SCE_MSSQL_COMMENT);
+ }
+ if (style == SCE_MSSQL_STATEMENT) {
+ // Folding between begin and end
+ if (ch == 'b' || ch == 'e') {
+ for (unsigned int j = 0; j < 5; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
+ }
+ s[j] = styler[i + j];
+ s[j + 1] = '\0';
+ }
+ if (strcmp(s, "begin") == 0) {
+ levelCurrent++;
+ }
+ if (strcmp(s, "end") == 0) {
+ levelCurrent--;
+ }
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
static const char * const sqlWordListDesc[] = {
"Statements",
"Data Types",
0,
};
-LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", 0, sqlWordListDesc);
+LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
// 0 no keyword highlighting
- // 1 metapost keyword highlighting
- // 2+ metafun keyword highlighting
+ // 1 metapost keyword hightlighting
+ // 2+ metafun keyword hightlighting
int extraInterface = 0 ;
/** @file LexNsis.cxx
** Lexer for NSIS
**/
-// Copyright 2003, 2004 by Angelo Mandato <angelo [at] spaceblue [dot] com>
-// Last Updated: 02/22/2004
+// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
+// Last Updated: 03/13/2005
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#define SCE_NSIS_MACRODEF 12
#define SCE_NSIS_STRINGVAR 13
#define SCE_NSIS_NUMBER 14
+// ADDED for Scintilla v1.63
+#define SCE_NSIS_SECTIONGROUP 15
+#define SCE_NSIS_PAGEEX 16
+#define SCE_NSIS_FUNCTIONDEF 17
+#define SCE_NSIS_COMMENTBOX 18
*/
static bool isNsisNumber(char ch)
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
+static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
+{
+ int nNextLine = -1;
+ for( unsigned int i = start; i < end; i++ )
+ {
+ char cNext = styler.SafeGetCharAt( i );
+ if( cNext == '\n' )
+ {
+ nNextLine = i+1;
+ break;
+ }
+ }
+
+ if( nNextLine == -1 ) // We never foudn the next line...
+ return false;
+
+ for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
+ {
+ char cNext = styler.SafeGetCharAt( firstChar );
+ if( cNext == ' ' )
+ continue;
+ if( cNext == '\t' )
+ continue;
+ if( cNext == '!' )
+ {
+ if( styler.Match(firstChar, "!else") )
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
static int NsisCmp( char *s1, char *s2, bool bIgnoreCase )
{
if( bIgnoreCase )
return strcmp( s1, s2 );
}
-static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler )
+static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
{
+ int style = styler.StyleAt(end);
+
// If the word is too long, it is not what we are looking for
- if( end - start > 13 )
+ if( end - start > 20 )
return foldlevel;
- // Check the style at this point, if it is not valid, then return zero
- if( styler.StyleAt(end) != SCE_NSIS_FUNCTION && styler.StyleAt(end) != SCE_NSIS_SECTIONDEF &&
- styler.StyleAt(end) != SCE_NSIS_SUBSECTIONDEF && styler.StyleAt(end) != SCE_NSIS_IFDEFINEDEF &&
- styler.StyleAt(end) != SCE_NSIS_MACRODEF )
- return foldlevel;
+ if( foldUtilityCmd )
+ {
+ // Check the style at this point, if it is not valid, then return zero
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
+ style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
+ return foldlevel;
+ }
+ else
+ {
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
+ return foldlevel;
+ }
int newFoldlevel = foldlevel;
bool bIgnoreCase = false;
if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
bIgnoreCase = true;
- char s[15]; // The key word we are looking for has atmost 13 characters
- for (unsigned int i = 0; i < end - start + 1 && i < 14; i++)
+ char s[20]; // The key word we are looking for has atmost 13 characters
+ for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
{
s[i] = static_cast<char>( styler[ start + i ] );
s[i + 1] = '\0';
newFoldlevel++;
else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
newFoldlevel--;
+ else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
+ newFoldlevel++;
}
else
{
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 )
+ if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
newFoldlevel++;
- else if( NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 )
+ else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
newFoldlevel--;
}
-
+
return newFoldlevel;
}
if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
return SCE_NSIS_IFDEFINEDEF;
+ if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
+ return SCE_NSIS_IFDEFINEDEF;
+
+ if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
+ return SCE_NSIS_SECTIONGROUP;
+
if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
return SCE_NSIS_SECTIONDEF;
if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
return SCE_NSIS_SUBSECTIONDEF;
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
- return SCE_NSIS_FUNCTION;
+ if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
+ return SCE_NSIS_PAGEEX;
+
+ if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
+ return SCE_NSIS_FUNCTIONDEF;
if ( Functions.InList(s) )
return SCE_NSIS_FUNCTION;
bool bHasSimpleNsisNumber = true;
for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
{
- if( s[j] == '\0' || s[j] == '\r' || s[j] == '\n' )
- break;
-
if( !isNsisNumber( s[j] ) )
{
bHasSimpleNsisNumber = false;
static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_NSIS_DEFAULT;
+ if( startPos > 0 )
+ state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
+
styler.StartAt( startPos );
styler.GetLine( startPos );
break;
}
+
+ if( cCurrChar == '/' && cNextChar == '*' )
+ {
+ styler.ColourTo(i-1,state);
+ state = SCE_NSIS_COMMENTBOX;
+ break;
+ }
+
break;
case SCE_NSIS_COMMENT:
if( cNextChar == '\n' || cNextChar == '\r' )
{
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
+ // Special case:
+ if( cCurrChar == '\\' )
+ {
+ styler.ColourTo(i-2,state);
+ styler.ColourTo(i,SCE_NSIS_DEFAULT);
+ }
+ else
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
}
break;
case SCE_NSIS_STRINGDQ:
- if( cCurrChar == '"' || cNextChar == '\r' || cNextChar == '\n' )
+ case SCE_NSIS_STRINGLQ:
+ case SCE_NSIS_STRINGRQ:
+
+ if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
+ break; // Ignore the next character, even if it is a quote of some sort
+
+ if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
{
- styler.ColourTo(i,SCE_NSIS_STRINGDQ);
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
- break;
- case SCE_NSIS_STRINGLQ:
- if( cCurrChar == '`' || cNextChar == '\r' || cNextChar == '\n' )
- {
- styler.ColourTo(i,SCE_NSIS_STRINGLQ);
+
+ if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
+ {
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
- break;
- case SCE_NSIS_STRINGRQ:
- if( cCurrChar == '\'' || cNextChar == '\r' || cNextChar == '\n' )
+
+ if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
{
- styler.ColourTo(i,SCE_NSIS_STRINGRQ);
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
+
+ if( cNextChar == '\r' || cNextChar == '\n' )
+ {
+ int nCurLine = styler.GetLine(i+1);
+ int nBack = i;
+ // We need to check if the previous line has a \ in it...
+ bool bNextLine = false;
+
+ while( nBack > 0 )
+ {
+ if( styler.GetLine(nBack) != nCurLine )
+ break;
+
+ char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
+
+ if( cTemp == '\\' )
+ {
+ bNextLine = true;
+ break;
+ }
+ if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
+ break;
+
+ nBack--;
+ }
+
+ if( bNextLine )
+ {
+ styler.ColourTo(i+1,state);
+ }
+ if( bNextLine == false )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ }
break;
+
case SCE_NSIS_FUNCTION:
// NSIS KeyWord:
state = SCE_NSIS_DEFAULT;
else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
{
- state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
+ state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
styler.ColourTo( i, state);
state = SCE_NSIS_DEFAULT;
}
}
}
break;
+ case SCE_NSIS_COMMENTBOX:
+
+ if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ break;
}
- if( state == SCE_NSIS_COMMENT )
+ if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
{
styler.ColourTo(i,state);
}
bVarInString = false;
bIngoreNextDollarSign = true;
}
- else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
+ else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
{
+ styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
bVarInString = false;
- bIngoreNextDollarSign = true;
+ bIngoreNextDollarSign = false;
}
// Covers "$INSTDIR and user vars like $MYVAR"
}
// Colourise remaining document
- switch( state )
- {
- case SCE_NSIS_COMMENT:
- case SCE_NSIS_STRINGDQ:
- case SCE_NSIS_STRINGLQ:
- case SCE_NSIS_STRINGRQ:
- case SCE_NSIS_VARIABLE:
- case SCE_NSIS_STRINGVAR:
- styler.ColourTo(nLengthDoc-1,state); break;
-
- default:
- styler.ColourTo(nLengthDoc-1,SCE_NSIS_DEFAULT); break;
- }
+ styler.ColourTo(nLengthDoc-1,state);
}
static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
if( styler.GetPropertyInt("fold") == 0 )
return;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
+ bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
+ bool blockComment = false;
+
int lineCurrent = styler.GetLine(startPos);
unsigned int safeStartPos = styler.LineStart( lineCurrent );
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
+ int style = styler.StyleAt(safeStartPos);
+ if( style == SCE_NSIS_COMMENTBOX )
+ {
+ if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
+ levelNext++;
+ blockComment = true;
+ }
for (unsigned int i = safeStartPos; i < startPos + length; i++)
{
char chCurr = styler.SafeGetCharAt(i);
+ style = styler.StyleAt(i);
+ if( blockComment && style != SCE_NSIS_COMMENTBOX )
+ {
+ levelNext--;
+ blockComment = false;
+ }
+ else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
+ {
+ levelNext++;
+ blockComment = true;
+ }
- if( bArg1 ) //&& chCurr != '\n' )
+ if( bArg1 && !blockComment)
{
if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
+ {
nWordStart = i;
- else if( !isNsisLetter(chCurr) && nWordStart > -1 )
+ }
+ else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
{
- int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler );
- if( newLevel != levelNext )
+ int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
+
+ if( newLevel == levelNext )
+ {
+ if( foldAtElse && foldUtilityCmd )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+ }
+ else
levelNext = newLevel;
bArg1 = false;
}
if( chCurr == '\n' )
{
+ if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+
// If we are on a new line...
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext)
+ if (levelUse < levelNext )
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
+
static inline bool AtEOL(Accessor &styler, unsigned int i) {
return (styler[i] == '\n') ||
- ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
+ ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
+}
+
+// Tests for BATCH Operators
+static bool IsBOperator(char ch) {
+ return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') ||
+ (ch == '|') || (ch == '?') || (ch == '*');
+}
+
+// Tests for BATCH Separators
+static bool IsBSeparator(char ch) {
+ return (ch == ':') || (ch == '\\') || (ch == '.') || (ch == ';') ||
+ (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
}
static void ColouriseBatchLine(
WordList &keywords,
Accessor &styler) {
- unsigned int i = 0;
- unsigned int state = SCE_BAT_DEFAULT;
+ 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
+ unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length
+ bool forFound = false; // No Local Variable without FOR statement
+ // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords
+ // Toggling Regular Keyword Checking off improves readability
+ // Other Regular Keywords and External Commands / Programs might also benefit from toggling
+ // Need a more robust algorithm to properly toggle Regular Keyword Checking
+ bool continueProcessing = true; // Used to toggle Regular Keyword Checking
+ // Special Keywords are those that allow certain characters without whitespace after the command
+ // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path=
+ // Special Keyword Buffer used to determine if the first n characters is a Keyword
+ char sKeywordBuffer[10]; // Special Keyword Buffer
+ bool sKeywordFound; // Exit Special Keyword for-loop if found
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip initial spaces
- i++;
- }
- if (lineBuffer[i] == '@') { // Hide command (ECHO OFF)
- styler.ColourTo(startLine + i, SCE_BAT_HIDE);
- i++;
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip next spaces
- i++;
- }
+ // Skip initial spaces
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
}
- if (lineBuffer[i] == ':') {
- // Label
- if (lineBuffer[i + 1] == ':') {
- // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ // Set External Command / Program Location
+ cmdLoc = offset;
+
+ // Check for Fake Label (Comment) or Real Label - return if found
+ if (lineBuffer[offset] == ':') {
+ if (lineBuffer[offset + 1] == ':') {
+ // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
styler.ColourTo(endPos, SCE_BAT_COMMENT);
- } else { // Real label
+ } else {
+ // Colorize Real Label
styler.ColourTo(endPos, SCE_BAT_LABEL);
}
- } else {
- // Check if initial word is a keyword
- char wordBuffer[21];
- unsigned int wbl = 0, offset = i;
- // Copy word in buffer
- for (; offset < lengthLine && wbl < 20 &&
+ return;
+ // Check for Drive Change (Drive Change is internal command) - return if found
+ } else if ((isalpha(lineBuffer[offset])) &&
+ (lineBuffer[offset + 1] == ':') &&
+ ((isspacechar(lineBuffer[offset + 2])) ||
+ (((lineBuffer[offset + 2] == '\\')) &&
+ (isspacechar(lineBuffer[offset + 3]))))) {
+ // Colorize Regular Keyword
+ styler.ColourTo(endPos, SCE_BAT_WORD);
+ return;
+ }
+
+ // Check for Hide Command (@ECHO OFF/ON)
+ 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 (!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 (!isspacechar(lineBuffer[offset])) {
+ cmdLoc = offset;
+ }
+ }
+ }
+ // Skip next spaces
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
+ offset++;
+ }
+
+ // Read remainder of line word-at-a-time or remainder-of-word-at-a-time
+ while (offset < lengthLine) {
+ if (offset > startLine) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Copy word from Line Buffer into Word Buffer
+ wbl = 0;
+ for (; offset < lengthLine && wbl < 80 &&
!isspacechar(lineBuffer[offset]); wbl++, offset++) {
wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
}
wordBuffer[wbl] = '\0';
- // Check if it is a comment
+ wbo = 0;
+
+ // Check for Comment - return if found
if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
styler.ColourTo(endPos, SCE_BAT_COMMENT);
- return ;
+ return;
}
- // Check if it is in the list
- if (keywords.InList(wordBuffer)) {
- styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword
- } else {
- // Search end of word (can be a long path)
- while (offset < lengthLine &&
- !isspacechar(lineBuffer[offset])) {
- offset++;
+ // Check for Separator
+ if (IsBSeparator(wordBuffer[0])) {
+ // Check for External Command / Program
+ if ((cmdLoc == offset - wbl) &&
+ ((wordBuffer[0] == ':') ||
+ (wordBuffer[0] == '\\') ||
+ (wordBuffer[0] == '.'))) {
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize External Command / Program
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ } else {
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);
+ }
+ // Check for Regular Keyword in list
+ } else if ((keywords.InList(wordBuffer)) &&
+ (continueProcessing)) {
+ // Local Variables do not exist if no FOR statement
+ if (CompareCaseInsensitive(wordBuffer, "for") == 0) {
+ forFound = true;
+ }
+ // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking
+ if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "goto") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "prompt") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "set") == 0)) {
+ continueProcessing = false;
+ }
+ // Identify External Command / Program Location for ERRORLEVEL, and EXIST
+ if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "exist") == 0)) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip comparison
+ while ((cmdLoc < lengthLine) &&
+ (!isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH
+ } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "do") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) ||
+ (CompareCaseInsensitive(wordBuffer, "lh") == 0)) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ }
+ // Colorize Regular keyword
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD);
+ // No need to Reset Offset
+ // Check for Special Keyword in list, External Command / Program, or Default Text
+ } else if ((wordBuffer[0] != '%') &&
+ (!IsBOperator(wordBuffer[0])) &&
+ (continueProcessing)) {
+ // Check for Special Keyword
+ // Affected Commands are in Length range 2-6
+ // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected
+ sKeywordFound = false;
+ for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) {
+ wbo = 0;
+ // Copy Keyword Length from Word Buffer into Special Keyword Buffer
+ for (; wbo < keywordLength; wbo++) {
+ sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]);
+ }
+ sKeywordBuffer[wbo] = '\0';
+ // Check for Special Keyword in list
+ if ((keywords.InList(sKeywordBuffer)) &&
+ ((IsBOperator(wordBuffer[wbo])) ||
+ (IsBSeparator(wordBuffer[wbo])))) {
+ sKeywordFound = true;
+ // ECHO requires no further Regular Keyword Checking
+ if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) {
+ continueProcessing = false;
+ }
+ // Colorize Special Keyword as Regular Keyword
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
}
- styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program
}
- // Remainder of the line: colourise the variables.
-
- while (offset < lengthLine) {
- if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
- styler.ColourTo(startLine + offset - 1, state);
- if (Is0To9(lineBuffer[offset + 1])) {
- styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
- offset += 2;
- } else if (lineBuffer[offset + 1] == '%' &&
- !isspacechar(lineBuffer[offset + 2])) {
- // Should be safe, as there is CRLF at the end of the line...
- styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER);
- offset += 3;
+ // Check for External Command / Program or Default Text
+ if (!sKeywordFound) {
+ wbo = 0;
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Reset External Command / Program Location
+ cmdLoc = offset - (wbl - wbo);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ // CHOICE requires no further Regular Keyword Checking
+ if (CompareCaseInsensitive(wordBuffer, "choice") == 0) {
+ continueProcessing = false;
+ }
+ // Check for START (and its switches) - What follows is External Command \ Program
+ if (CompareCaseInsensitive(wordBuffer, "start") == 0) {
+ // Reset External Command / Program Location
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Reset External Command / Program Location if command switch detected
+ if (lineBuffer[cmdLoc] == '/') {
+ // Skip command switch
+ while ((cmdLoc < lengthLine) &&
+ (!isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ }
+ }
+ // Colorize External command / program
+ styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND);
+ // No need to Reset Offset
+ // Check for Default Text
} else {
- state = SCE_BAT_IDENTIFIER;
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
+ }
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ }
+ // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a)
+ } 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++;
+ }
+ // Check for Argument (%n)
+ if ((Is0To9(wordBuffer[1])) &&
+ (wordBuffer[wbo] != '%')) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - 2);
+ }
+ // Colorize Argument
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ // Check for Environment Variable (%x...%)
+ } else if ((wordBuffer[1] != '%') &&
+ (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 Local Variable (%%a)
+ } else if ((forFound) &&
+ (wordBuffer[1] == '%') &&
+ (wordBuffer[2] != '%') &&
+ (!IsBOperator(wordBuffer[2])) &&
+ (!IsBSeparator(wordBuffer[2]))) {
+ // Check for External Command / Program
+ if (cmdLoc == offset - wbl) {
+ cmdLoc = offset - (wbl - 3);
+ }
+ // Colorize Local Variable
+ styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 3);
+ }
+ // Check for Operator
+ } else if (IsBOperator(wordBuffer[0])) {
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+ // Check for Comparison Operator
+ if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) {
+ // Identify External Command / Program Location for IF
+ cmdLoc = offset;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
+ }
+ // Colorize Comparison Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 2);
+ // Check for Pipe Operator
+ } else if (wordBuffer[0] == '|') {
+ // Reset External Command / Program Location
+ cmdLoc = offset - wbl + 1;
+ // Skip next spaces
+ while ((cmdLoc < lengthLine) &&
+ (isspacechar(lineBuffer[cmdLoc]))) {
+ cmdLoc++;
}
- } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') {
- styler.ColourTo(startLine + offset, state);
- state = SCE_BAT_DEFAULT;
- } else if (state == SCE_BAT_DEFAULT &&
- (lineBuffer[offset] == '*' ||
- lineBuffer[offset] == '?' ||
- lineBuffer[offset] == '=' ||
- lineBuffer[offset] == '<' ||
- lineBuffer[offset] == '>' ||
- lineBuffer[offset] == '|')) {
- styler.ColourTo(startLine + offset - 1, state);
- styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR);
+ // Colorize Pipe Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ // Check for Other Operator
+ } else {
+ // Check for > Operator
+ if (wordBuffer[0] == '>') {
+ // Turn Keyword and External Command / Program checking back on
+ continueProcessing = true;
+ }
+ // Colorize Other Operator
+ styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - 1);
+ }
+ // Check for Default Text
+ } else {
+ // Read up to %, Operator or Separator
+ while ((wbo < wbl) &&
+ (wordBuffer[wbo] != '%') &&
+ (!IsBOperator(wordBuffer[wbo])) &&
+ (!IsBSeparator(wordBuffer[wbo]))) {
+ wbo++;
}
+ // Colorize Default Text
+ styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT);
+ // Reset Offset to re-process remainder of word
+ offset -= (wbl - wbo);
+ }
+ // Skip next spaces - nothing happens if Offset was Reset
+ while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) {
offset++;
}
- // if (endPos > startLine + offset - 1) {
- styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed
- // }
}
-
+ // Colorize Default Text for remainder of line - currently not lexed
+ styler.ColourTo(endPos, SCE_BAT_DEFAULT);
}
-// ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
-// IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
-// FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
-// ToDo: %n (parameters), %EnvironmentVariable% colourising
-// ToDo: Colourise = > >> < | "
static void ColouriseBatchDoc(
unsigned int startPos,
int nextLevel = prevLevel;
if (prevLevel & SC_FOLDLEVELHEADERFLAG)
nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1;
-
+
int lineType = styler.StyleAt(curLineStart);
if (lineType == SCE_DIFF_COMMAND)
nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG;
nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG;
} else if (lineType == SCE_DIFF_POSITION)
nextLevel = (SC_FOLDLEVELBASE + 3) | SC_FOLDLEVELHEADERFLAG;
-
+
if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel))
styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG);
styler.SetLevel(curLine, nextLevel);
prevLevel = nextLevel;
-
+
curLineStart = styler.LineStart(++curLine);
} while (static_cast<int>(startPos) + length > curLineStart);
}
lineCurrent++;
visibleChars = 0;
- headerPoint=false;
+ headerPoint = false;
}
if (!isspacechar(ch))
visibleChars++;
}
}
-static bool strstart(char *haystack, char *needle) {
+static bool strstart(const char *haystack, const char *needle) {
return strncmp(haystack, needle, strlen(needle)) == 0;
}
-static void ColouriseErrorListLine(
- char *lineBuffer,
- unsigned int lengthLine,
- // unsigned int startLine,
- unsigned int endPos,
- Accessor &styler) {
- const int unRecognized = 99;
+static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine) {
if (lineBuffer[0] == '>') {
// Command or return status
- styler.ColourTo(endPos, SCE_ERR_CMD);
+ return SCE_ERR_CMD;
} else if (lineBuffer[0] == '<') {
// Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
- styler.ColourTo(endPos, SCE_ERR_DEFAULT);
+ return SCE_ERR_DEFAULT;
} else if (lineBuffer[0] == '!') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_CHANGED);
+ return SCE_ERR_DIFF_CHANGED;
} else if (lineBuffer[0] == '+') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_ADDITION);
- } else if (lineBuffer[0] == '-' && lineBuffer[1] == '-' && lineBuffer[2] == '-') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_MESSAGE);
+ if (strstart(lineBuffer, "+++ ")) {
+ return SCE_ERR_DIFF_MESSAGE;
+ } else {
+ return SCE_ERR_DIFF_ADDITION;
+ }
} else if (lineBuffer[0] == '-') {
- styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION);
+ if (strstart(lineBuffer, "--- ")) {
+ return SCE_ERR_DIFF_MESSAGE;
+ } else {
+ return SCE_ERR_DIFF_DELETION;
+ }
} else if (strstart(lineBuffer, "cf90-")) {
// Absoft Pro Fortran 90/95 v8.2 error and/or warning message
- styler.ColourTo(endPos, SCE_ERR_ABSF);
+ return SCE_ERR_ABSF;
} else if (strstart(lineBuffer, "fortcom:")) {
// Intel Fortran Compiler v8.0 error/warning message
- styler.ColourTo(endPos, SCE_ERR_IFORT);
+ return SCE_ERR_IFORT;
} else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
- styler.ColourTo(endPos, SCE_ERR_PYTHON);
+ return SCE_ERR_PYTHON;
} else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) {
- styler.ColourTo(endPos, SCE_ERR_PHP);
+ return SCE_ERR_PHP;
} else if ((strstart(lineBuffer, "Error ") ||
- strstart(lineBuffer, "Warning ")) &&
- strstr(lineBuffer, " at (") &&
- strstr(lineBuffer, ") : ") &&
- (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
+ strstart(lineBuffer, "Warning ")) &&
+ strstr(lineBuffer, " at (") &&
+ strstr(lineBuffer, ") : ") &&
+ (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) {
// Intel Fortran Compiler error/warning message
- styler.ColourTo(endPos, SCE_ERR_IFC);
+ return SCE_ERR_IFC;
} else if (strstart(lineBuffer, "Error ")) {
// Borland error message
- styler.ColourTo(endPos, SCE_ERR_BORLAND);
+ return SCE_ERR_BORLAND;
} else if (strstart(lineBuffer, "Warning ")) {
// Borland warning message
- styler.ColourTo(endPos, SCE_ERR_BORLAND);
+ return SCE_ERR_BORLAND;
} else if (strstr(lineBuffer, "at line " ) &&
(strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, "file ") &&
(strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
// Lua 4 error message
- styler.ColourTo(endPos, SCE_ERR_LUA);
+ return SCE_ERR_LUA;
} else if (strstr(lineBuffer, " at " ) &&
(strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, " line ") &&
(strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
- (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
+ (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
// perl error message
- styler.ColourTo(endPos, SCE_ERR_PERL);
+ return SCE_ERR_PERL;
} else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
- strstr(lineBuffer, ":line ")) {
+ strstr(lineBuffer, ":line ")) {
// A .NET traceback
- styler.ColourTo(endPos, SCE_ERR_NET);
+ return SCE_ERR_NET;
} else if (strstart(lineBuffer, "Line ") &&
- strstr(lineBuffer, ", file ")) {
+ strstr(lineBuffer, ", file ")) {
// Essential Lahey Fortran error message
- styler.ColourTo(endPos, SCE_ERR_ELF);
+ return SCE_ERR_ELF;
} else if (strstart(lineBuffer, "line ") &&
- strstr(lineBuffer, " column ")) {
+ strstr(lineBuffer, " column ")) {
// HTML tidy style: line 42 column 1
- styler.ColourTo(endPos, SCE_ERR_TIDY);
+ return SCE_ERR_TIDY;
} else if (strstart(lineBuffer, "\tat ") &&
- strstr(lineBuffer, "(") &&
- strstr(lineBuffer, ".java:")) {
+ strstr(lineBuffer, "(") &&
+ strstr(lineBuffer, ".java:")) {
// Java stack back trace
- styler.ColourTo(endPos, SCE_ERR_JAVA_STACK);
+ return SCE_ERR_JAVA_STACK;
} else {
- // Look for GCC <filename>:<line>:message
- // Look for Microsoft <filename>(line) :message
- // Look for Microsoft <filename>(line,pos)message
- // Look for CTags \tmessage
- // Look for Lua 5 traceback \t<filename>:<line>:message
+ // Look for one of the following formats:
+ // GCC: <filename>:<line>:<message>
+ // Microsoft: <filename>(<line>) :<message>
+ // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal
+ // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal
+ // Microsoft: <filename>(<line>,<column>)<message>
+ // CTags: \t<message>
+ // Lua 5 traceback: \t<filename>:<line>:<message>
bool initialTab = (lineBuffer[0] == '\t');
- int state = 0;
+ enum { stInitial,
+ stGccStart, stGccDigit, stGcc,
+ stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet,
+ stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags,
+ stUnrecognized
+ } state = stInitial;
for (unsigned int i = 0; i < lengthLine; i++) {
char ch = lineBuffer[i];
char chNext = ' ';
- if ((i+1) < lengthLine)
- chNext = lineBuffer[i+1];
- if (state == 0) {
+ if ((i + 1) < lengthLine)
+ chNext = lineBuffer[i + 1];
+ if (state == stInitial) {
if (ch == ':') {
// May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix)
if ((chNext != '\\') && (chNext != '/')) {
// This check is not completely accurate as may be on
// GTK+ with a file name that includes ':'.
- state = 1;
+ state = stGccStart;
}
} else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) {
// May be Microsoft
// Check against '0' often removes phone numbers
- state = 10;
+ state = stMsStart;
} else if ((ch == '\t') && (!initialTab)) {
// May be CTags
- state = 20;
+ state = stCtagsStart;
}
- } else if (state == 1) {
- state = Is1To9(ch) ? 2 : unRecognized;
- } else if (state == 2) {
+ } else if (state == stGccStart) { // <filename>:
+ state = Is1To9(ch) ? stGccDigit : stUnrecognized;
+ } else if (state == stGccDigit) { // <filename>:<line>
if (ch == ':') {
- state = 3; // :9.*: is GCC
+ state = stGcc; // :9.*: is GCC
break;
} else if (!Is0To9(ch)) {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 10) {
- state = Is0To9(ch) ? 11 : unRecognized;
- } else if (state == 11) {
+ } else if (state == stMsStart) { // <filename>(
+ state = Is0To9(ch) ? stMsDigit : stUnrecognized;
+ } else if (state == stMsDigit) { // <filename>(<line>
if (ch == ',') {
- state = 14;
+ state = stMsDigitComma;
} else if (ch == ')') {
- state = 12;
+ state = stMsBracket;
} else if ((ch != ' ') && !Is0To9(ch)) {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 12) {
+ } else if (state == stMsBracket) { // <filename>(<line>)
if ((ch == ' ') && (chNext == ':')) {
- state = 13;
+ state = stMsVc;
+ } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) {
+ // Possibly Delphi.. don't test against chNext as it's one of the strings below.
+ char word[512];
+ unsigned int j, chPos;
+ unsigned numstep;
+ chPos = 0;
+ if (ch == ' ')
+ numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
+ else
+ numstep = 2; // otherwise add 2.
+ for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
+ word[chPos++] = lineBuffer[j];
+ word[chPos] = 0;
+ if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
+ !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") ||
+ !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) {
+ state = stMsVc;
+ } else
+ state = stUnrecognized;
} else {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 14) {
+ } else if (state == stMsDigitComma) { // <filename>(<line>,
if (ch == ')') {
- state = 15;
+ state = stMsDotNet;
break;
} else if ((ch != ' ') && !Is0To9(ch)) {
- state = unRecognized;
+ state = stUnrecognized;
}
- } else if (state == 20) {
- if ((lineBuffer[i-1] == '\t') &&
- ((ch == '/' && lineBuffer[i+1] == '^') || Is0To9(ch))) {
- state = 24;
+ } else if (state == stCtagsStart) {
+ if ((lineBuffer[i - 1] == '\t') &&
+ ((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) {
+ state = stCtags;
break;
- } else if ((ch == '/') && (lineBuffer[i+1] == '^')) {
- state = 21;
+ } else if ((ch == '/') && (lineBuffer[i + 1] == '^')) {
+ state = stCtagsStartString;
}
- } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) {
- state = 22;
+ } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) {
+ state = stCtagsStringDollar;
break;
}
}
- if (state == 3) {
- styler.ColourTo(endPos, SCE_ERR_GCC);
- } else if ((state == 13) || (state == 14) || (state == 15)) {
- styler.ColourTo(endPos, SCE_ERR_MS);
- } else if ((state == 22) || (state == 24)) {
- styler.ColourTo(endPos, SCE_ERR_CTAG);
+ if (state == stGcc) {
+ return SCE_ERR_GCC;
+ } else if ((state == stMsVc) || (state == stMsDotNet)) {
+ return SCE_ERR_MS;
+ } else if ((state == stCtagsStringDollar) || (state == stCtags)) {
+ return SCE_ERR_CTAG;
} else {
- styler.ColourTo(endPos, SCE_ERR_DEFAULT);
+ return SCE_ERR_DEFAULT;
}
}
}
+static void ColouriseErrorListLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int endPos,
+ Accessor &styler) {
+ styler.ColourTo(endPos, RecogniseErrorListLine(lineBuffer, lengthLine));
+}
+
static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[1024];
+ char lineBuffer[10000];
styler.StartAt(startPos);
styler.StartSegment(startPos);
unsigned int linePos = 0;
** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language).
** Written by Philippe Lhoste but this is mostly a derivative of LexCPP...
**/
-// Copyright 1998-2003 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.
// Some points that distinguish from a simple C lexer:
#include "Scintilla.h"
#include "SciLexer.h"
-static inline bool IsAWordChar(const int ch) {
+static inline bool IsAWordChar(int ch) {
return ch < 0x80 && (isalnum(ch) || ch == '_');
}
-static inline bool IsAWordStart(const int ch) {
+static inline bool IsAWordStart(int ch) {
return ch < 0x80 && isalpha(ch);
}
-static inline bool IsANumberChar(const int 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) &&
}
// Do not leak onto next line
- if (initStyle == SCE_POV_STRINGEOL) {
+ if (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) {
initStyle = SCE_POV_DEFAULT;
}
- StyleContext sc(startPos, length, initStyle, styler);
short stringLen = 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
}
} else if (sc.state == SCE_POV_DIRECTIVE) {
if (!IsAWordChar(sc.ch)) {
- char s[100], *p;
+ char s[100];
+ char *p;
sc.GetCurrent(s, sizeof(s));
p = s;
// Skip # and whitespace between # and directive word
}
} else if (sc.state == SCE_POV_COMMENTLINE) {
if (sc.atLineEnd) {
- sc.SetState(SCE_POV_DEFAULT);
+ sc.ForwardSetState(SCE_POV_DEFAULT);
}
} else if (sc.state == SCE_POV_STRING) {
if (sc.ch == '\\') {
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
-#include <fcntl.h>
#include "Platform.h"
/** @file LexPerl.cxx
** Lexer for subset of Perl.
**/
-// Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my> 2003-2004
-// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2005 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 <stdlib.h>
#include "Scintilla.h"
#include "SciLexer.h"
-#define PERLNUM_DECIMAL 1
-#define PERLNUM_NON_DEC 2
-#define PERLNUM_FLOAT 3
-#define PERLNUM_VECTOR 4
-#define PERLNUM_V_VECTOR 5
+#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
+
+#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
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
return false;
}
-static int classifyWordPerl(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
+static bool isPerlKeyword(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_PL_IDENTIFIER;
- if (keywords.InList(s))
- chAttr = SCE_PL_WORD;
- styler.ColourTo(end, chAttr);
- return chAttr;
+ 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';
+ return keywords.InList(s);
}
static inline bool isEndVar(char ch) {
}
static inline char actualNumStyle(int numberStyle) {
- switch (numberStyle) {
- case PERLNUM_VECTOR:
- case PERLNUM_V_VECTOR:
- return SCE_PL_STRING;
- case PERLNUM_DECIMAL:
- case PERLNUM_NON_DEC:
- case PERLNUM_FLOAT:
- default:
- return SCE_PL_NUMBER;
- }
+ 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 bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) {
char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf
HereDocCls() {
State = 0;
+ Quote = 0;
+ Quoted = false;
DelimiterLength = 0;
Delimiter = new char[HERE_DELIM_MAX];
Delimiter[0] = '\0';
|| state == SCE_PL_CHARACTER
|| state == SCE_PL_NUMBER
|| state == SCE_PL_IDENTIFIER
+ || state == SCE_PL_ERROR
) {
while ((startPos > 1) && (styler.StyleAt(startPos - 1) == state)) {
startPos--;
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;
+ }
+
styler.StartAt(startPos);
char chPrev = styler.SafeGetCharAt(startPos - 1);
if (startPos == 0)
if (isdigit(ch) || (isdigit(chNext) &&
(ch == '.' || ch == 'v'))) {
state = SCE_PL_NUMBER;
+ backflag = BACK_NONE;
numState = PERLNUM_DECIMAL;
dotCount = 0;
if (ch == '0') { // hex,bin,octal
- if (chNext == 'x' || chNext == 'b' || isdigit(chNext)) {
- numState = PERLNUM_NON_DEC;
- }
+ if (chNext == 'x') {
+ numState = PERLNUM_HEX;
+ } else if (chNext == 'b') {
+ numState = PERLNUM_BINARY;
+ } else if (isdigit(chNext)) {
+ numState = PERLNUM_OCTAL;
+ }
+ if (numState != PERLNUM_DECIMAL) {
+ i++;
+ ch = chNext;
+ chNext = chNext2;
+ }
} else if (ch == 'v') { // vector
numState = PERLNUM_V_VECTOR;
}
} else if (iswordstart(ch)) {
- if (chPrev == '>' && styler.SafeGetCharAt(i - 2) == '-') {
- state = SCE_PL_IDENTIFIER; // part of "->" expr
- if ((!iswordchar(chNext) && chNext != '\'')
- || (chNext == '.' && chNext2 == '.')) {
- // We need that if length of word == 1!
- styler.ColourTo(i, SCE_PL_IDENTIFIER);
- state = SCE_PL_DEFAULT;
- }
- } else if (ch == 's' && !isNonQuote(chNext)) {
+ // 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;
Quote.New(2);
} else if (ch == 'm' && !isNonQuote(chNext)) {
} else if (ch == 't' && chNext == 'r' && !isNonQuote(chNext2)) {
state = SCE_PL_REGSUBST;
Quote.New(2);
- i++;
- chNext = chNext2;
+ 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;
- i++;
- chNext = chNext2;
Quote.New(1);
+ kw++;
} else if (ch == 'x' && (chNext == '=' || // repetition
- (chNext != '_' && !isalnum(chNext)) ||
- (isdigit(chPrev) && isdigit(chNext)))) {
- styler.ColourTo(i, SCE_PL_OPERATOR);
- } else {
- state = SCE_PL_WORD;
- if ((!iswordchar(chNext) && chNext != '\'')
- || (chNext == '.' && chNext2 == '.')) {
- // We need that if length of word == 1!
- // This test is copied from the SCE_PL_WORD handler.
- classifyWordPerl(styler.GetStartSegment(), i, keywords, styler);
- state = SCE_PL_DEFAULT;
- }
- }
+ (chNext != '_' && !isalnum(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 == '&')
+ // &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 ((!iswordchar(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 {
+ styler.ColourTo(i, SCE_PL_WORD);
+ state = SCE_PL_DEFAULT;
+ backflag = BACK_KEYWORD;
+ backPos = i;
+ }
+ ch = styler.SafeGetCharAt(i);
+ chNext = styler.SafeGetCharAt(i + 1);
+ // a repetition operator 'x'
+ } else if (state == SCE_PL_OPERATOR) {
+ styler.ColourTo(i, SCE_PL_OPERATOR);
+ state = SCE_PL_DEFAULT;
+ // 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
Quote.New(1);
Quote.Open(ch);
}
+ 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);
chNext = chNext2;
}
}
+ backflag = BACK_NONE;
} else if (ch == '@') {
if (isalpha(chNext) || chNext == '#' || chNext == '$'
- || chNext == '_' || chNext == '+') {
+ || chNext == '_' || chNext == '+' || chNext == '-') {
state = SCE_PL_ARRAY;
} else if (chNext != '{' && chNext != '[') {
styler.ColourTo(i, SCE_PL_ARRAY);
- i++;
- ch = ' ';
} else {
styler.ColourTo(i, SCE_PL_ARRAY);
}
+ backflag = BACK_NONE;
} else if (ch == '%') {
- if (isalpha(chNext) || chNext == '#' || chNext == '$' || chNext == '_') {
+ if (isalpha(chNext) || chNext == '#' || chNext == '$'
+ || chNext == '_' || chNext == '!' || chNext == '^') {
state = SCE_PL_HASH;
+ i++;
+ ch = chNext;
+ chNext = chNext2;
} else if (chNext == '{') {
styler.ColourTo(i, SCE_PL_HASH);
} else {
styler.ColourTo(i, SCE_PL_OPERATOR);
}
+ backflag = BACK_NONE;
} else if (ch == '*') {
- if (isalpha(chNext) || chNext == '_' || chNext == '{') {
+ char strch[2];
+ strch[0] = chNext;
+ strch[1] = '\0';
+ if (isalpha(chNext) || chNext == '_' ||
+ NULL != strstr("^/|,\\\";#%^:?<>)[]", strch)) {
state = SCE_PL_SYMBOLTABLE;
+ i++;
+ ch = chNext;
+ chNext = chNext2;
+ } else if (chNext == '{') {
+ styler.ColourTo(i, SCE_PL_SYMBOLTABLE);
} else {
if (chNext == '*') { // exponentiation
i++;
}
styler.ColourTo(i, SCE_PL_OPERATOR);
}
- } else if (ch == '/') {
+ backflag = BACK_NONE;
+ } else if (ch == '/' || (ch == '<' && chNext == '<')) {
// 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.
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;
char bkch;
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--;
bk--;
}
break;
+ case SCE_PL_SCALAR: // for $var<< case
+ hereDocScalar = true;
+ break;
// other styles uses the default, preferRE=false
case SCE_PL_WORD:
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;
}
}
- if (preferRE) {
- state = SCE_PL_REGEX;
- Quote.New(1);
- Quote.Open(ch);
- } else {
- styler.ColourTo(i, SCE_PL_OPERATOR);
- }
- } else if (ch == '<' && chNext == '<') {
- state = SCE_PL_HERE_DELIM;
- HereDoc.State = 0;
+ 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;
+ styler.ColourTo(i, SCE_PL_OPERATOR);
+ }
+ } else { // handle regexp
+ if (preferRE) {
+ state = SCE_PL_REGEX;
+ Quote.New(1);
+ Quote.Open(ch);
+ } else { // / operator
+ styler.ColourTo(i, SCE_PL_OPERATOR);
+ }
+ }
+ backflag = BACK_NONE;
} else if (ch == '<') {
// looks forward for matching > on same line
unsigned int fw = i + 1;
while (fw < lengthDoc) {
char fwch = styler.SafeGetCharAt(fw);
- if (isEOLChar(fwch) || isspacechar(fwch))
+ if (fwch == ' ') {
+ if (styler.SafeGetCharAt(fw-1) != '\\' ||
+ styler.SafeGetCharAt(fw-2) != '\\')
+ break;
+ } else if (isEOLChar(fwch) || isspacechar(fwch)) {
break;
- else if (fwch == '>') {
+ } else if (fwch == '>') {
if ((fw - i) == 2 && // '<=>' case
styler.SafeGetCharAt(fw-1) == '=') {
styler.ColourTo(fw, SCE_PL_OPERATOR);
fw++;
}
styler.ColourTo(i, SCE_PL_OPERATOR);
+ backflag = BACK_NONE;
} 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
i++;
ch = chNext;
chNext = chNext2;
+ backflag = BACK_NONE;
} else if (isPerlOperator(ch)) {
if (ch == '.' && chNext == '.') { // .. and ...
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
styler.ColourTo(i, SCE_PL_OPERATOR);
+ backflag = BACK_OPERATOR;
+ backPos = i;
} else {
// keep colouring defaults to make restart easier
styler.ColourTo(i, SCE_PL_DEFAULT);
if (chNext == '.') {
// double dot is always an operator
goto numAtEnd;
- } else if (numState == PERLNUM_NON_DEC || numState == PERLNUM_FLOAT) {
+ } else if (numState <= PERLNUM_FLOAT) {
// non-decimal number or float exponent, consume next dot
styler.ColourTo(i - 1, SCE_PL_NUMBER);
styler.ColourTo(i, SCE_PL_OPERATOR);
if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
if (isalpha(ch)) {
if (dotCount == 0) { // change to word
- state = SCE_PL_WORD;
+ state = SCE_PL_IDENTIFIER;
} else { // vector then word
goto numAtEnd;
}
if (!isdigit(ch)) { // float then word
goto numAtEnd;
}
- } else {// (numState == PERLNUM_NON_DEC)
- // allow alphanum for bin,hex,oct for now
- }
+ } 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:
state = SCE_PL_DEFAULT;
goto restartLexer;
}
- } else if (state == SCE_PL_WORD) {
- if ((!iswordchar(chNext) && chNext != '\'')
- || chNext == '.') {
- // ".." is always an operator if preceded by a SCE_PL_WORD.
- // "." never used in Perl variable names
- // Archaic Perl has quotes inside names
- if (isMatch(styler, lengthDoc, styler.GetStartSegment(), "__DATA__")
- || isMatch(styler, lengthDoc, styler.GetStartSegment(), "__END__")) {
- styler.ColourTo(i, SCE_PL_DATASECTION);
- state = SCE_PL_DATASECTION;
- } else {
- classifyWordPerl(styler.GetStartSegment(), i, keywords, styler);
- state = SCE_PL_DEFAULT;
- ch = ' ';
- }
- }
} else if (state == SCE_PL_IDENTIFIER) {
- if ((!iswordchar(chNext) && chNext != '\'')
- || chNext == '.') {
+ if (!iswordstart(chNext) && chNext != '\'') {
styler.ColourTo(i, SCE_PL_IDENTIFIER);
state = SCE_PL_DEFAULT;
ch = ' ';
// 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
+ if (chNext == '\'' || chNext == '"' || chNext == '`') {
+ // a quoted here-doc delimiter
i++;
ch = chNext;
chNext = chNext2;
HereDoc.Quoted = true;
- } else if (isalpha(chNext) || chNext == '_') {
- // an unquoted here-doc delimiter, no special handling
} else if (isspacechar(chNext) || isdigit(chNext) || chNext == '\\'
- || chNext == '=' || 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;
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
}
} 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);
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) {
- if (ch == '=' && isEOLChar(chPrev)) {
- 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;
+ } 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;
+ }
+ }
}
}
} else if (state == SCE_PL_SCALAR // variable names
chNext = chNext2;
}
else if (isEndVar(ch)) {
- if ((state == SCE_PL_SCALAR || state == SCE_PL_ARRAY)
- && i == (styler.GetStartSegment() + 1)) {
+ if (i == (styler.GetStartSegment() + 1)) {
// Special variable: $(, $_ etc.
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
styler.ColourTo(lengthDoc - 1, state);
}
+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];
+ int style = styler.StyleAt(i);
+ if (ch == '#' && style == SCE_PL_COMMENTLINE)
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ // Custom folding of POD and packages
+ bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+ bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
- int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelPrev = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
int styleNext = styler.StyleAt(startPos);
+ // Used at end of line to determine if the line was a package definition
+ bool isPackageLine = false;
+ bool isPodHeading = false;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && (style == SCE_PL_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
- levelCurrent++;
- } else if (chNext2 == '}') {
- levelCurrent--;
- }
- }
- }
+ bool atLineStart = isEOLChar(chPrev) || 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 (ch == '{') {
levelCurrent++;
levelCurrent--;
}
}
+ // Custom POD folding
+ if (foldPOD && atLineStart) {
+ int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
+ if (style == SCE_PL_POD) {
+ if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
+ levelCurrent++;
+ else if (styler.Match(i, "=cut"))
+ levelCurrent--;
+ 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"))
+ 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;
+ }
+ }
+ // Custom package folding
+ if (foldPackage && atLineStart) {
+ if (style == SCE_PL_WORD && styler.Match(i, "package")) {
+ isPackageLine = true;
+ }
+ }
+
if (atEOL) {
int lev = levelPrev;
+ if (isPodHeading) {
+ lev = levelPrev - 1;
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ isPodHeading = false;
+ }
+ // Check if line was a package declaration
+ // because packages need "special" treatment
+ if (isPackageLine) {
+ lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
+ levelCurrent = SC_FOLDLEVELBASE + 1;
+ isPackageLine = false;
+ }
+ lev |= levelCurrent << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
}
if (!isspacechar(ch))
visibleChars++;
+ chPrev = ch;
}
// 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;
}
WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
+ } else if (keywords2.InList(s)) {
+ style = SCE_P_WORD2;
}
sc.ChangeState(style);
sc.SetState(SCE_P_DEFAULT);
kwLast = kwImport;
else
kwLast = kwOther;
- } else if (style == SCE_P_CLASSNAME) {
- kwLast = kwOther;
- } else if (style == SCE_P_DEFNAME) {
+ } else {
kwLast = kwOther;
}
}
if (sc.ch == '\r' || sc.ch == '\n') {
sc.SetState(SCE_P_DEFAULT);
}
+ } else if (sc.state == SCE_P_DECORATOR) {
+ if (sc.ch == '\r' || sc.ch == '\n') {
+ sc.SetState(SCE_P_DEFAULT);
+ }
} else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
if (sc.ch == '\\') {
if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
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))) {
unsigned int nextIndex = 0;
sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
static const char * const pythonWordListDesc[] = {
"Keywords",
+ "Highlighted identifiers",
0
};
--- /dev/null
+// Scintilla source code edit control
+/** @file LexRebol.cxx
+ ** Lexer for REBOL.
+ ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste
+ **
+ ** History:
+ ** 2005-04-07 First release.
+ ** 2005-04-10 Closing parens and brackets go now in default style
+ ** String and comment nesting should be more safe
+ **/
+// Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm>
+// 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 "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+
+static inline bool IsAWordChar(const int ch) {
+ return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
+}
+
+static inline bool IsAWordStart(const int ch, const int ch2) {
+ return ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) ||
+ (isalpha(ch) || ch == '?' || ch == '!' || ch == '\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
+}
+
+static inline bool IsAnOperator(const int ch, const int ch2, const int ch3) {
+ // One char operators
+ if (IsASpaceOrTab(ch2)) {
+ return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?';
+ }
+
+ // Two char operators
+ if (IsASpaceOrTab(ch3)) {
+ return (ch == '*' && ch2 == '*') ||
+ (ch == '/' && ch2 == '/') ||
+ (ch == '<' && (ch2 == '=' || ch2 == '>')) ||
+ (ch == '>' && ch2 == '=') ||
+ (ch == '=' && (ch2 == '=' || ch2 == '?')) ||
+ (ch == '?' && ch2 == '?');
+ }
+
+ return false;
+}
+
+static inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) {
+ return (ch == '#' && ch2 == '{') ||
+ (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) ||
+ (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' );
+}
+
+
+static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
+
+ WordList &keywords = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
+ WordList &keywords7 = *keywordlists[6];
+ WordList &keywords8 = *keywordlists[7];
+
+ int currentLine = styler.GetLine(startPos);
+ // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string.
+ int stringLevel = 0;
+ if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) {
+ stringLevel = styler.GetLineState(currentLine - 1);
+ }
+
+ bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK;
+ int dotCount = 0;
+
+ // Do not leak onto next line
+ if (initStyle == SCE_REBOL_COMMENTLINE) {
+ initStyle = SCE_REBOL_DEFAULT;
+ }
+
+ StyleContext sc(startPos, length, initStyle, styler);
+ if (startPos == 0) {
+ sc.SetState(SCE_REBOL_PREFACE);
+ }
+ for (; sc.More(); sc.Forward()) {
+
+ //--- What to do at line end ?
+ if (sc.atLineEnd) {
+ // Can be either inside a {} string or simply at eol
+ if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK &&
+ sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE)
+ sc.SetState(SCE_REBOL_DEFAULT);
+
+ // Update the line state, so it can be seen by next line
+ currentLine = styler.GetLine(sc.currentPos);
+ switch (sc.state) {
+ case SCE_REBOL_BRACEDSTRING:
+ case SCE_REBOL_COMMENTBLOCK:
+ // Inside a braced string, we set the line state
+ styler.SetLineState(currentLine, stringLevel);
+ break;
+ default:
+ // Reset the line state
+ styler.SetLineState(currentLine, 0);
+ break;
+ }
+
+ // continue with next char
+ continue;
+ }
+
+ //--- What to do on white-space ?
+ if (IsASpaceOrTab(sc.ch))
+ {
+ // Return to default if any of these states
+ if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER ||
+ sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR ||
+ sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE ||
+ sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME ||
+ sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE ||
+ sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Specialize state ?
+ // URL, Email look like identifier
+ if (sc.state == SCE_REBOL_IDENTIFIER)
+ {
+ if (sc.ch == ':' && !IsASpace(sc.chNext)) {
+ sc.ChangeState(SCE_REBOL_URL);
+ } else if (sc.ch == '@') {
+ sc.ChangeState(SCE_REBOL_EMAIL);
+ } else if (sc.ch == '$') {
+ sc.ChangeState(SCE_REBOL_MONEY);
+ }
+ }
+ // Words look like identifiers
+ if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) {
+ // Keywords ?
+ if (!IsAWordChar(sc.ch) || sc.Match('/')) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ blockComment = strcmp(s, "comment") == 0;
+ if (keywords8.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD8);
+ } else if (keywords7.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD7);
+ } else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD6);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD5);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD4);
+ } else if (keywords3.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD3);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD2);
+ } else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_REBOL_WORD);
+ }
+ // Keep same style if there are refinements
+ if (!sc.Match('/')) {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+ // special numbers
+ } else if (sc.state == SCE_REBOL_NUMBER) {
+ switch (sc.ch) {
+ case 'x': sc.ChangeState(SCE_REBOL_PAIR);
+ break;
+ case ':': sc.ChangeState(SCE_REBOL_TIME);
+ break;
+ case '-':
+ case '/': sc.ChangeState(SCE_REBOL_DATE);
+ break;
+ case '.': if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE);
+ break;
+ }
+ }
+
+ //--- Determine if the current state should terminate
+ if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) {
+ if (sc.ch == '^' && sc.chNext == '\"') {
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) {
+ if (sc.ch == '}') {
+ if (--stringLevel == 0) {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.ch == '{') {
+ stringLevel++;
+ }
+ } else if (sc.state == SCE_REBOL_BINARY) {
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_TAG) {
+ if (sc.ch == '>') {
+ sc.ForwardSetState(SCE_REBOL_DEFAULT);
+ }
+ } else if (sc.state == SCE_REBOL_PREFACE) {
+ if (sc.MatchIgnoreCase("rebol"))
+ {
+ int i;
+ for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++);
+ if (sc.GetRelative(i) == '[')
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Parens and bracket changes to default style when the current is a number
+ if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE ||
+ sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL ||
+ sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) {
+ if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') {
+ sc.SetState(SCE_REBOL_DEFAULT);
+ }
+ }
+
+ //--- Determine if a new state should be entered.
+ if (sc.state == SCE_REBOL_DEFAULT) {
+ if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) {
+ sc.SetState(SCE_REBOL_OPERATOR);
+ } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) {
+ sc.SetState(SCE_REBOL_BINARY);
+ } else if (IsAWordStart(sc.ch, sc.chNext)) {
+ sc.SetState(SCE_REBOL_IDENTIFIER);
+ } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') {
+ dotCount = 0;
+ sc.SetState(SCE_REBOL_NUMBER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_REBOL_QUOTEDSTRING);
+ } else if (sc.ch == '{') {
+ sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING);
+ ++stringLevel;
+ } else if (sc.ch == ';') {
+ sc.SetState(SCE_REBOL_COMMENTLINE);
+ } else if (sc.ch == '$') {
+ sc.SetState(SCE_REBOL_MONEY);
+ } else if (sc.ch == '%') {
+ sc.SetState(SCE_REBOL_FILE);
+ } else if (sc.ch == '<') {
+ sc.SetState(SCE_REBOL_TAG);
+ } else if (sc.ch == '#' && sc.chNext == '"') {
+ sc.SetState(SCE_REBOL_CHARACTER);
+ sc.Forward();
+ } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) {
+ sc.SetState(SCE_REBOL_ISSUE);
+ }
+ }
+ }
+ sc.Complete();
+}
+
+
+static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+ Accessor &styler) {
+ unsigned int lengthDoc = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+ int levelCurrent = levelPrev;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ for (unsigned int i = startPos; i < lengthDoc; 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_REBOL_DEFAULT) {
+ if (ch == '[') {
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ }
+ if (!isspacechar(ch))
+ visibleChars++;
+ }
+ // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+ int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+ styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const rebolWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, "rebol", FoldRebolDoc, rebolWordListDesc);
+
#include "Scintilla.h"
#include "SciLexer.h"
-static void ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+//XXX Identical to Perl, put in common area
+static inline bool isEOLChar(char ch) {
+ return (ch == '\r') || (ch == '\n');
+}
+
+#define isSafeASCII(ch) ((unsigned int)(ch) <= 127)
+// This one's redundant, but makes for more readable code
+#define isHighBitChar(ch) ((unsigned int)(ch) > 127)
+
+static inline bool isSafeAlpha(char ch) {
+ return (isSafeASCII(ch) && isalpha(ch)) || ch == '_';
+}
+
+static inline bool isSafeAlnum(char ch) {
+ return (isSafeASCII(ch) && isalnum(ch)) || ch == '_';
+}
+
+static inline bool isSafeAlnumOrHigh(char ch) {
+ return isHighBitChar(ch) || isalnum(ch) || ch == '_';
+}
+
+static inline bool isSafeDigit(char ch) {
+ return isSafeASCII(ch) && isdigit(ch);
+}
+
+static inline bool isSafeWordcharOrHigh(char ch) {
+ return isHighBitChar(ch) || iswordchar(ch);
+}
+
+static bool inline iswhitespace(char ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+#define MAX_KEYWORD_LENGTH 200
+
+#define STYLE_MASK 63
+#define actual_style(style) (style & STYLE_MASK)
+
+static bool followsDot(unsigned int pos, Accessor &styler) {
+ styler.Flush();
+ for (; pos >= 1; --pos) {
+ int style = actual_style(styler.StyleAt(pos));
+ char ch;
+ switch (style) {
+ case SCE_RB_DEFAULT:
+ ch = styler[pos];
+ if (ch == ' ' || ch == '\t') {
+ //continue
+ } else {
+ return false;
+ }
+ break;
+
+ case SCE_RB_OPERATOR:
+ return styler[pos] == '.';
+
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+// Forward declarations
+static bool keywordIsAmbiguous(const char *prevWord);
+static bool keywordDoStartsLoop(int pos,
+ Accessor &styler);
+static bool keywordIsModifier(const char *word,
+ int pos,
+ Accessor &styler);
+
+static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) {
char s[100];
- bool wordIsNumber = isdigit(styler[start]) != 0;
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- s[i + 1] = '\0';
+ unsigned int i, j;
+ unsigned int lim = end - start + 1; // num chars to copy
+ if (lim >= MAX_KEYWORD_LENGTH) {
+ lim = MAX_KEYWORD_LENGTH - 1;
+ }
+ for (i = start, j = 0; j < lim; i++, j++) {
+ s[j] = styler[i];
}
- char chAttr = SCE_P_IDENTIFIER;
+ s[j] = '\0';
+ int chAttr;
if (0 == strcmp(prevWord, "class"))
- chAttr = SCE_P_CLASSNAME;
+ chAttr = SCE_RB_CLASSNAME;
else if (0 == strcmp(prevWord, "module"))
- chAttr = SCE_P_CLASSNAME;
+ chAttr = SCE_RB_MODULE_NAME;
else if (0 == strcmp(prevWord, "def"))
- chAttr = SCE_P_DEFNAME;
- else if (wordIsNumber)
- chAttr = SCE_P_NUMBER;
- else if (keywords.InList(s))
- chAttr = SCE_P_WORD;
- // make sure that dot-qualifiers inside the word are lexed correct
- else for (unsigned int i = 0; i < end - start + 1; i++) {
- if (styler[start + i] == '.') {
- styler.ColourTo(start + i - 1, chAttr);
- styler.ColourTo(start + i, SCE_P_OPERATOR);
+ chAttr = SCE_RB_DEFNAME;
+ else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
+ if (keywordIsAmbiguous(s)
+ && keywordIsModifier(s, start, styler)) {
+
+ // Demoted keywords are colored as keywords,
+ // but do not affect changes in indentation.
+ //
+ // Consider the word 'if':
+ // 1. <<if test ...>> : normal
+ // 2. <<stmt if test>> : demoted
+ // 3. <<lhs = if ...>> : normal: start a new indent level
+ // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
+
+ chAttr = SCE_RB_WORD_DEMOTED;
+ } else {
+ chAttr = SCE_RB_WORD;
+ }
+ } else
+ chAttr = SCE_RB_IDENTIFIER;
+ styler.ColourTo(end, chAttr);
+ if (chAttr == SCE_RB_WORD) {
+ strcpy(prevWord, s);
+ } else {
+ prevWord[0] = 0;
+ }
+ return chAttr;
+}
+
+
+//XXX Identical to Perl, put in common area
+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++;
}
- styler.ColourTo(end, chAttr);
- strcpy(prevWord, s);
+ return true;
}
-static bool IsRbComment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]=='#';
+// Do Ruby better -- find the end of the line, work back,
+// and then check for leading white space
+
+// Precondition: the here-doc target can be indented
+static bool lookingAtHereDocDelim(Accessor &styler,
+ int pos,
+ int lengthDoc,
+ const char *HereDocDelim)
+{
+ if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) {
+ return false;
+ }
+ while (--pos > 0) {
+ char ch = styler[pos];
+ if (isEOLChar(ch)) {
+ return true;
+ } else if (ch != ' ' && ch != '\t') {
+ return false;
+ }
+ }
+ return false;
}
-static bool IsRbStringStart(char ch, char chNext, char chNext2) {
- if (ch == '\'' || ch == '"')
- return true;
- if (ch == 'u' || ch == 'U') {
- if (chNext == '"' || chNext == '\'')
- return true;
- if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
- return true;
- }
- if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\''))
- return true;
+//XXX Identical to Perl, put in common area
+static char opposite(char ch) {
+ if (ch == '(')
+ return ')';
+ if (ch == '[')
+ return ']';
+ if (ch == '{')
+ return '}';
+ if (ch == '<')
+ return '>';
+ return ch;
+}
+
+// Null transitions when we see we've reached the end
+// and need to relex the curr char.
- return false;
+static void redo_char(int &i, char &ch, char &chNext, char &chNext2,
+ int &state) {
+ i--;
+ chNext2 = chNext;
+ chNext = ch;
+ state = SCE_RB_DEFAULT;
}
-static bool IsRbWordStart(char ch, char chNext, char chNext2) {
- return (iswordchar(ch) && !IsRbStringStart(ch, chNext, chNext2));
+static void advance_char(int &i, char &ch, char &chNext, char &chNext2) {
+ i++;
+ ch = chNext;
+ chNext = 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 GetRbStringState(Accessor &styler, int i, int *nextIndex) {
- char ch = styler.SafeGetCharAt(i);
- char chNext = styler.SafeGetCharAt(i + 1);
+// precondition: startPos points to one after the EOL char
+static bool currLineContainsHereDelims(int& startPos,
+ Accessor &styler) {
+ if (startPos <= 1)
+ return false;
- // Advance beyond r, u, or ur prefix, 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') {
- if (chNext == 'r' || chNext == 'R')
- i += 2;
- else
- i += 1;
- ch = styler.SafeGetCharAt(i);
- chNext = styler.SafeGetCharAt(i + 1);
- }
+ int pos;
+ for (pos = startPos - 1; pos > 0; pos--) {
+ char ch = styler.SafeGetCharAt(pos);
+ if (isEOLChar(ch)) {
+ // Leave the pointers where they are -- there are no
+ // here doc delims on the current line, even if
+ // the EOL isn't default style
+
+ return false;
+ } else {
+ styler.Flush();
+ if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) {
+ break;
+ }
+ }
+ }
+ if (pos == 0) {
+ return false;
+ }
+ // Update the pointers so we don't have to re-analyze the string
+ startPos = pos;
+ return true;
+}
- if (ch != '"' && ch != '\'') {
- *nextIndex = i + 1;
- return SCE_P_DEFAULT;
- }
- if (i>0 && styler.SafeGetCharAt(i-1) == '$') {
- *nextIndex = i + 1;
- return SCE_P_DEFAULT;
- }
+static bool isEmptyLine(int pos,
+ Accessor &styler) {
+ int spaceFlags = 0;
+ int lineCurrent = styler.GetLine(pos);
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+ return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0;
+}
- if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) {
- *nextIndex = i + 3;
+static bool RE_CanFollowKeyword(const char *keyword) {
+ if (!strcmp(keyword, "and")
+ || !strcmp(keyword, "begin")
+ || !strcmp(keyword, "break")
+ || !strcmp(keyword, "case")
+ || !strcmp(keyword, "do")
+ || !strcmp(keyword, "else")
+ || !strcmp(keyword, "elsif")
+ || !strcmp(keyword, "if")
+ || !strcmp(keyword, "next")
+ || !strcmp(keyword, "return")
+ || !strcmp(keyword, "when")
+ || !strcmp(keyword, "unless")
+ || !strcmp(keyword, "until")
+ || !strcmp(keyword, "not")
+ || !strcmp(keyword, "or")) {
+ return true;
+ }
+ return false;
+}
- if (ch == '"')
- return SCE_P_TRIPLEDOUBLE;
- else
- return SCE_P_TRIPLE;
- } else {
- *nextIndex = i + 1;
+// Look at chars up to but not including endPos
+// Don't look at styles in case we're looking forward
- if (ch == '"')
- return SCE_P_STRING;
- else
- return SCE_P_CHARACTER;
- }
+static int skipWhitespace(int startPos,
+ int endPos,
+ Accessor &styler) {
+ for (int i = startPos; i < endPos; i++) {
+ if (!iswhitespace(styler[i])) {
+ return i;
+ }
+ }
+ return endPos;
+}
+
+// This routine looks for false positives like
+// undef foo, <<
+// There aren't too many.
+//
+// iPrev points to the start of <<
+
+static bool sureThisIsHeredoc(int iPrev,
+ Accessor &styler,
+ char *prevWord) {
+
+ // Not so fast, since Ruby's so dynamic. Check the context
+ // to make sure we're OK.
+ int prevStyle;
+ int lineStart = styler.GetLine(iPrev);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+
+ // Find the first word after some whitespace
+ int firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler);
+ if (firstWordPosn >= iPrev) {
+ // Have something like {^ <<}
+ //XXX Look at the first previous non-comment non-white line
+ // to establish the context. Not too likely though.
+ return true;
+ } else {
+ switch (prevStyle = styler.StyleAt(firstWordPosn)) {
+ case SCE_RB_WORD:
+ case SCE_RB_WORD_DEMOTED:
+ case SCE_RB_IDENTIFIER:
+ break;
+ default:
+ return true;
+ }
+ }
+ int firstWordEndPosn = firstWordPosn;
+ char *dst = prevWord;
+ for (;;) {
+ if (firstWordEndPosn >= iPrev ||
+ styler.StyleAt(firstWordEndPosn) != prevStyle) {
+ *dst = 0;
+ break;
+ }
+ *dst++ = styler[firstWordEndPosn];
+ firstWordEndPosn += 1;
+ }
+ //XXX Write a style-aware thing to regex scintilla buffer objects
+ if (!strcmp(prevWord, "undef")
+ || !strcmp(prevWord, "def")
+ || !strcmp(prevWord, "alias")) {
+ // These keywords are what we were looking for
+ return false;
+ }
+ return true;
+}
+
+// Routine that saves us from allocating a buffer for the here-doc target
+// targetEndPos points one past the end of the current target
+static bool haveTargetMatch(int currPos,
+ int lengthDoc,
+ int targetStartPos,
+ int targetEndPos,
+ Accessor &styler) {
+ if (lengthDoc - currPos < targetEndPos - targetStartPos) {
+ return false;
+ }
+ int i, j;
+ for (i = targetStartPos, j = currPos;
+ i < targetEndPos && j < lengthDoc;
+ i++, j++) {
+ if (styler[i] != styler[j]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// We need a check because the form
+// [identifier] <<[target]
+// is ambiguous. The Ruby lexer/parser resolves it by
+// looking to see if [identifier] names a variable or a
+// function. If it's the first, it's the start of a here-doc.
+// If it's a var, it's an operator. This lexer doesn't
+// maintain a symbol table, so it looks ahead to see what's
+// going on, in cases where we have
+// ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target]
+//
+// If there's no occurrence of [target] on a line, assume we don't.
+
+// return true == yes, we have no heredocs
+
+static bool sureThisIsNotHeredoc(int lt2StartPos,
+ Accessor &styler) {
+ int prevStyle;
+ // Use full document, not just part we're styling
+ int lengthDoc = styler.Length();
+ int lineStart = styler.GetLine(lt2StartPos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ const bool definitely_not_a_here_doc = true;
+ const bool looks_like_a_here_doc = false;
+
+ // Find the first word after some whitespace
+ int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);
+ if (firstWordPosn >= lt2StartPos) {
+ return definitely_not_a_here_doc;
+ }
+ prevStyle = styler.StyleAt(firstWordPosn);
+ // If we have '<<' following a keyword, it's not a heredoc
+ if (prevStyle != SCE_RB_IDENTIFIER) {
+ return definitely_not_a_here_doc;
+ }
+ int newStyle = prevStyle;
+ // Some compilers incorrectly warn about uninit newStyle
+ for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
+ // Inner loop looks at the name
+ for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) {
+ newStyle = styler.StyleAt(firstWordPosn);
+ if (newStyle != prevStyle) {
+ break;
+ }
+ }
+ // Do we have '::' or '.'?
+ if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) {
+ char ch = styler[firstWordPosn];
+ if (ch == '.') {
+ // yes
+ } else if (ch == ':') {
+ if (styler.StyleAt(++firstWordPosn) != SCE_RB_OPERATOR) {
+ return definitely_not_a_here_doc;
+ } else if (styler[firstWordPosn] != ':') {
+ return definitely_not_a_here_doc;
+ }
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ // Skip next batch of white-space
+ firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);
+ if (firstWordPosn != lt2StartPos) {
+ // Have [[^ws[identifier]ws[*something_else*]ws<<
+ return definitely_not_a_here_doc;
+ }
+ // OK, now 'j' will point to the current spot moving ahead
+ int j = firstWordPosn + 1;
+ if (styler.StyleAt(j) != SCE_RB_OPERATOR || styler[j] != '<') {
+ // This shouldn't happen
+ return definitely_not_a_here_doc;
+ }
+ int nextLineStartPosn = styler.LineStart(lineStart + 1);
+ if (nextLineStartPosn >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ }
+ j = skipWhitespace(j + 1, nextLineStartPosn, styler);
+ if (j >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ }
+ bool allow_indent;
+ int target_start, target_end;
+ // From this point on no more styling, since we're looking ahead
+ if (styler[j] == '-') {
+ allow_indent = true;
+ j++;
+ } else {
+ allow_indent = false;
+ }
+
+ // Allow for quoted targets.
+ char target_quote = 0;
+ switch (styler[j]) {
+ case '\'':
+ case '"':
+ case '`':
+ target_quote = styler[j];
+ j += 1;
+ }
+
+ if (isSafeAlnum(styler[j])) {
+ // Init target_end because some compilers think it won't
+ // be initialized by the time it's used
+ target_start = target_end = j;
+ j++;
+ } else {
+ return definitely_not_a_here_doc;
+ }
+ for (; j < lengthDoc; j++) {
+ if (!isSafeAlnum(styler[j])) {
+ if (target_quote && styler[j] != target_quote) {
+ // unquoted end
+ return definitely_not_a_here_doc;
+ }
+
+ // And for now make sure that it's a newline
+ // don't handle arbitrary expressions yet
+
+ target_end = j;
+ if (target_quote) {
+ // Now we can move to the character after the string delimiter.
+ j += 1;
+ }
+ j = skipWhitespace(j, lengthDoc, styler);
+ if (j >= lengthDoc) {
+ return definitely_not_a_here_doc;
+ } else {
+ char ch = styler[j];
+ if (ch == '#' || isEOLChar(ch)) {
+ // This is OK, so break and continue;
+ break;
+ } else {
+ return definitely_not_a_here_doc;
+ }
+ }
+ }
+ }
+
+ // Just look at the start of each line
+ int last_line = styler.GetLine(lengthDoc - 1);
+ // But don't go too far
+ if (last_line > lineStart + 50) {
+ last_line = lineStart + 50;
+ }
+ for (int line_num = lineStart + 1; line_num <= last_line; line_num++) {
+ if (allow_indent) {
+ j = skipWhitespace(styler.LineStart(line_num), lengthDoc, styler);
+ } else {
+ j = styler.LineStart(line_num);
+ }
+ // target_end is one past the end
+ if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) {
+ // We got it
+ return looks_like_a_here_doc;
+ }
+ }
+ return definitely_not_a_here_doc;
+}
+
+//todo: if we aren't looking at a stdio character,
+// move to the start of the first line that is not in a
+// multi-line construct
+
+static void synchronizeDocStart(unsigned int& startPos,
+ int &length,
+ int &initStyle,
+ Accessor &styler,
+ bool skipWhiteSpace=false) {
+
+ styler.Flush();
+ int style = actual_style(styler.StyleAt(startPos));
+ switch (style) {
+ case SCE_RB_STDIN:
+ case SCE_RB_STDOUT:
+ case SCE_RB_STDERR:
+ // Don't do anything else with these.
+ return;
+ }
+
+ int pos = startPos;
+ // Quick way to characterize each line
+ int lineStart;
+ for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) {
+ // Now look at the style before the previous line's EOL
+ pos = styler.LineStart(lineStart) - 1;
+ if (pos <= 10) {
+ lineStart = 0;
+ break;
+ }
+ char ch = styler.SafeGetCharAt(pos);
+ char chPrev = styler.SafeGetCharAt(pos - 1);
+ if (ch == '\n' && chPrev == '\r') {
+ pos--;
+ }
+ if (styler.SafeGetCharAt(pos - 1) == '\\') {
+ // Continuation line -- keep going
+ } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) {
+ // Part of multi-line construct -- keep going
+ } else if (currLineContainsHereDelims(pos, styler)) {
+ // Keep going, with pos and length now pointing
+ // at the end of the here-doc delimiter
+ } else if (skipWhiteSpace && isEmptyLine(pos, styler)) {
+ // Keep going
+ } else {
+ break;
+ }
+ }
+ pos = styler.LineStart(lineStart);
+ length += (startPos - pos);
+ startPos = pos;
+ initStyle = SCE_RB_DEFAULT;
}
static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
- int lengthDoc = startPos + length;
+ // Lexer for Ruby 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];
- // Backtrack to previous line in case need to fix its tab whinging
- if (startPos > 0) {
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0) {
- startPos = styler.LineStart(lineCurrent-1);
- if (startPos == 0)
- initStyle = SCE_P_DEFAULT;
- else
- initStyle = styler.StyleAt(startPos-1);
+ class HereDocCls {
+ public:
+ int State;
+ // States
+ // 0: '<<' encountered
+ // 1: collect the delimiter
+ // 1b: text between the end of the delimiter and the EOL
+ // 2: here doc text (lines after the delimiter)
+ char Quote; // the char after '<<'
+ bool Quoted; // true if Quote in ('\'','"','`')
+ int DelimiterLength; // strlen(Delimiter)
+ char Delimiter[256]; // the Delimiter, limit of 256: from Perl
+ bool CanBeIndented;
+ HereDocCls() {
+ State = 0;
+ DelimiterLength = 0;
+ Delimiter[0] = '\0';
+ CanBeIndented = false;
}
- }
+ };
+ HereDocCls HereDoc;
- // Ruby uses a different mask because bad indentation is marked by oring with 32
- styler.StartAt(startPos, 127);
+ class QuoteCls {
+ public:
+ int Count;
+ char Up;
+ char Down;
+ QuoteCls() {
+ this->New();
+ }
+ void New() {
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ }
+ void Open(char u) {
+ Count++;
+ Up = u;
+ Down = opposite(Up);
+ }
+ };
+ QuoteCls Quote;
- WordList &keywords = *keywordlists[0];
+ int numDots = 0; // For numbers --
+ // Don't start lexing in the middle of a num
+
+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
+ false);
- int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
- char prevWord[200];
+ bool preferRE = true;
+ int state = initStyle;
+ int lengthDoc = startPos + length;
+
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
prevWord[0] = '\0';
if (length == 0)
- return ;
+ return;
- int state = initStyle & 31;
-
- int nextIndex = 0;
- char chPrev = ' ';
- char chPrev2 = ' ';
- char chNext = styler[startPos];
+ char chPrev = styler.SafeGetCharAt(startPos - 1);
+ char chNext = styler.SafeGetCharAt(startPos);
+ // Ruby uses a different mask because bad indentation is marked by oring with 32
+ styler.StartAt(startPos, 127);
styler.StartSegment(startPos);
- bool atStartLine = true;
- int spaceFlags = 0;
- for (int i = startPos; i < lengthDoc; i++) {
-
- if (atStartLine) {
- char chBad = static_cast<char>(64);
- char chGood = static_cast<char>(0);
- char chFlags = chGood;
- if (whingeLevel == 1) {
- chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood;
- } else if (whingeLevel == 2) {
- chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood;
- } else if (whingeLevel == 3) {
- chFlags = (spaceFlags & wsSpace) ? chBad : chGood;
- } else if (whingeLevel == 4) {
- chFlags = (spaceFlags & wsTab) ? chBad : chGood;
- }
- styler.SetFlags(chFlags, static_cast<char>(state));
- atStartLine = false;
- }
+ static int q_states[] = {SCE_RB_STRING_Q,
+ SCE_RB_STRING_QQ,
+ SCE_RB_STRING_QR,
+ SCE_RB_STRING_QW,
+ SCE_RB_STRING_QW,
+ SCE_RB_STRING_QX};
+ static const char* q_chars = "qQrwWx";
+
+ for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
char chNext2 = styler.SafeGetCharAt(i + 2);
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
- if ((state == SCE_P_DEFAULT) || (state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE)) {
- // Perform colourisation of white space and triple quoted strings at end of each line to allow
- // tab marking to work inside white space and triple quoted strings
- styler.ColourTo(i, state);
- }
- atStartLine = true;
- }
-
- if (styler.IsLeadByte(ch)) {
- chNext = styler.SafeGetCharAt(i + 2);
+ if (styler.IsLeadByte(ch)) {
+ chNext = chNext2;
chPrev = ' ';
- chPrev2 = ' ';
i += 1;
continue;
}
+
+ // skip on DOS/Windows
+ //No, don't, because some things will get tagged on,
+ // so we won't recognize keywords, for example
+#if 0
+ if (ch == '\r' && chNext == '\n') {
+ continue;
+ }
+#endif
+
+ if (HereDoc.State == 1 && isEOLChar(ch)) {
+ // Begin of here-doc (the line after the here-doc delimiter):
+ HereDoc.State = 2;
+ styler.ColourTo(i-1, state);
+ // Don't check for a missing quote, just jump into
+ // the here-doc state
+ state = SCE_RB_HERE_Q;
+ }
- if (state == SCE_P_STRINGEOL) {
- if (ch != '\r' && ch != '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_P_DEFAULT;
- }
- }
- if (state == SCE_P_DEFAULT) {
- if (IsRbWordStart(ch, chNext, chNext2)) {
- styler.ColourTo(i - 1, state);
- state = SCE_P_WORD;
+ // Regular transitions
+ if (state == SCE_RB_DEFAULT) {
+ if (isSafeDigit(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_NUMBER;
+ numDots = 0;
+ } else if (isHighBitChar(ch) || iswordstart(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_WORD;
} else if (ch == '#') {
styler.ColourTo(i - 1, state);
- state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
- } else if (ch == '=' && chNext == 'b') {
+ state = SCE_RB_COMMENTLINE;
+ } else if (ch == '=') {
// =begin indicates the start of a comment (doc) block
- if(styler.SafeGetCharAt(i + 2) == 'e' && styler.SafeGetCharAt(i + 3) == 'g' && styler.SafeGetCharAt(i + 4) == 'i' && styler.SafeGetCharAt(i + 5) == 'n') {
+ 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))) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_POD;
+ } else {
styler.ColourTo(i - 1, state);
- state = SCE_P_TRIPLEDOUBLE; //SCE_C_COMMENT;
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ preferRE = true;
}
- } else if (IsRbStringStart(ch, chNext, chNext2)) {
+ } else if (ch == '"') {
styler.ColourTo(i - 1, state);
- state = GetRbStringState(styler, i, &nextIndex);
- if (nextIndex != i + 1) {
- i = nextIndex - 1;
- ch = ' ';
- chPrev = ' ';
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (isoperator(ch)) {
+ state = SCE_RB_STRING;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '\'') {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_CHARACTER;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '`') {
styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_P_OPERATOR);
- }
- } else if (state == SCE_P_WORD) {
- if (!iswordchar(ch)) {
- ClassifyWordRb(styler.GetStartSegment(), i - 1, keywords, styler, prevWord);
- state = SCE_P_DEFAULT;
- if (ch == '#') {
- state = chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE;
- } else if (IsRbStringStart(ch, chNext, chNext2)) {
- styler.ColourTo(i - 1, state);
- state = GetRbStringState(styler, i, &nextIndex);
- if (nextIndex != i + 1) {
- i = nextIndex - 1;
- ch = ' ';
- chPrev = ' ';
+ state = SCE_RB_BACKTICKS;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '@') {
+ // Instance or class var
+ styler.ColourTo(i - 1, state);
+ if (chNext == '@') {
+ state = SCE_RB_CLASS_VAR;
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ state = SCE_RB_INSTANCE_VAR;
+ }
+ } else if (ch == '$') {
+ // Check for a builtin global
+ styler.ColourTo(i - 1, state);
+ // Recognize it bit by bit
+ state = SCE_RB_GLOBAL;
+ } else if (ch == '/' && preferRE) {
+ // Ambigous operator
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_REGEX;
+ Quote.New();
+ Quote.Open(ch);
+ } else if (ch == '<' && chNext == '<' && chNext2 != '=') {
+
+ // Recognise the '<<' symbol - either a here document or a binary op
+ styler.ColourTo(i - 1, state);
+ i++;
+ chNext = chNext2;
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+
+ if (! (strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) {
+ // It's definitely not a here-doc,
+ // based on Ruby's lexer/parser in the
+ // heredoc_identifier routine.
+ // Nothing else to do.
+ } else if (preferRE) {
+ if (sureThisIsHeredoc(i - 1, styler, prevWord)) {
+ state = SCE_RB_HERE_DELIM;
+ HereDoc.State = 0;
+ }
+ // else leave it in default state
+ } else {
+ if (sureThisIsNotHeredoc(i - 1, styler)) {
+ // leave state as default
+ // We don't have all the heuristics Perl has for indications
+ // of a here-doc, because '<<' is overloadable and used
+ // for so many other classes.
+ } else {
+ state = SCE_RB_HERE_DELIM;
+ HereDoc.State = 0;
+ }
+ }
+ preferRE = (state != SCE_RB_HERE_DELIM);
+ } else if (ch == ':') {
+ styler.ColourTo(i - 1, state);
+ if (chNext == ':') {
+ // Mark "::" as an operator, not symbol start
+ styler.ColourTo(i + 1, SCE_RB_OPERATOR);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else if (isSafeWordcharOrHigh(chNext)) {
+ state = SCE_RB_SYMBOL;
+ } else if (strchr("[*!~+-*/%=<>&^|", chNext)) {
+ // Do the operator analysis in-line, looking ahead
+ // Based on the table in pickaxe 2nd ed., page 339
+ bool doColoring = true;
+ switch (chNext) {
+ case '[':
+ if (chNext2 == ']' ) {
+ char ch_tmp = styler.SafeGetCharAt(i + 3);
+ if (ch_tmp == '=') {
+ i += 3;
+ ch = ch_tmp;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ i += 2;
+ ch = chNext2;
+ chNext = ch_tmp;
+ }
+ } else {
+ doColoring = false;
+ }
+ break;
+
+ case '*':
+ if (chNext2 == '*') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ case '!':
+ if (chNext2 == '=' || chNext2 == '~') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ case '<':
+ if (chNext2 == '<') {
+ i += 2;
+ ch = chNext2;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext2 == '=') {
+ char ch_tmp = styler.SafeGetCharAt(i + 3);
+ if (ch_tmp == '>') { // <=> operator
+ i += 3;
+ ch = ch_tmp;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ i += 2;
+ ch = chNext2;
+ chNext = ch_tmp;
+ }
+ } else {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ break;
+
+ default:
+ // Simple one-character operators
+ advance_char(i, ch, chNext, chNext2);
+ break;
+ }
+ if (doColoring) {
+ styler.ColourTo(i, SCE_RB_SYMBOL);
+ state = SCE_RB_DEFAULT;
+ }
+ } else if (!preferRE) {
+ // Don't color symbol strings (yet)
+ // Just color the ":" and color rest as string
+ styler.ColourTo(i, SCE_RB_SYMBOL);
+ state = SCE_RB_DEFAULT;
+ } else {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ state = SCE_RB_DEFAULT;
+ preferRE = true;
+ }
+ } else if (ch == '%') {
+ styler.ColourTo(i - 1, state);
+ bool have_string = false;
+ if (strchr(q_chars, chNext) && !isSafeWordcharOrHigh(chNext2)) {
+ Quote.New();
+ const char *hit = strchr(q_chars, chNext);
+ if (hit != NULL) {
+ state = q_states[hit - q_chars];
+ Quote.Open(chNext2);
+ i += 2;
+ ch = chNext2;
chNext = styler.SafeGetCharAt(i + 1);
+ have_string = true;
+ }
+ } else if (!isSafeWordcharOrHigh(chNext)) {
+ // Ruby doesn't allow high bit chars here,
+ // but the editor host might
+ state = SCE_RB_STRING_QQ;
+ Quote.Open(chNext);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ have_string = true;
+ }
+ if (!have_string) {
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ // stay in default
+ preferRE = true;
+ }
+ } else if (isoperator(ch) || ch == '.') {
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_RB_OPERATOR);
+ // If we're ending an expression or block,
+ // assume it ends an object, and the ambivalent
+ // constructs are binary operators
+ //
+ // So if we don't have one of these chars,
+ // we aren't ending an object exp'n, and ops
+ // like : << / are unary operators.
+
+ preferRE = (strchr(")}].", ch) == NULL);
+ // Stay in default state
+ } else if (isEOLChar(ch)) {
+ // Make sure it's a true line-end, with no backslash
+ if ((ch == '\r' || (ch == '\n' && chPrev != '\r'))
+ && chPrev != '\\') {
+ // Assume we've hit the end of the statement.
+ preferRE = true;
+ }
+ }
+ } else if (state == SCE_RB_WORD) {
+ if (ch == '.' || !isSafeWordcharOrHigh(ch)) {
+ // Words include x? in all contexts,
+ // and <letters>= after either 'def' or a dot
+ // Move along until a complete word is on our left
+
+ // Default accessor treats '.' as word-chars,
+ // but we don't for now.
+
+ if (ch == '='
+ && isSafeWordcharOrHigh(chPrev)
+ && (chNext == '('
+ || strchr(" \t\n\r", chNext) != NULL)
+ && (!strcmp(prevWord, "def")
+ || followsDot(styler.GetStartSegment(), styler))) {
+ // <name>= is a name only when being def'd -- Get it the next time
+ // This means that <name>=<name> is always lexed as
+ // <name>, (op, =), <name>
+ } else if ((ch == '?' || ch == '!')
+ && isSafeWordcharOrHigh(chPrev)
+ && !isSafeWordcharOrHigh(chNext)) {
+ // <name>? is a name -- Get it the next time
+ // But <name>?<name> is always lexed as
+ // <name>, (op, ?), <name>
+ // Same with <name>! to indicate a method that
+ // modifies its target
+ } else if (isEOLChar(ch)
+ && isMatch(styler, lengthDoc, i - 7, "__END__")) {
+ styler.ColourTo(i, SCE_RB_DATASECTION);
+ state = SCE_RB_DATASECTION;
+ // No need to handle this state -- we'll just move to the end
+ preferRE = false;
+ } else {
+ int wordStartPos = styler.GetStartSegment();
+ int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord);
+ switch (word_style) {
+ case SCE_RB_WORD:
+ preferRE = RE_CanFollowKeyword(prevWord);
+ break;
+
+ case SCE_RB_WORD_DEMOTED:
+ preferRE = true;
+ break;
+
+ case SCE_RB_IDENTIFIER:
+ if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
+ preferRE = true;
+ } else if (isEOLChar(ch)) {
+ preferRE = true;
+ } else {
+ preferRE = false;
+ }
+ break;
+ default:
+ preferRE = false;
+ }
+ if (ch == '.') {
+ // We might be redefining an operator-method
+ preferRE = false;
+ }
+ // And if it's the first
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ }
+ }
+ } else if (state == SCE_RB_NUMBER) {
+ if (isSafeAlnumOrHigh(ch) || ch == '_') {
+ // Keep going
+ } else if (ch == '.' && ++numDots == 1) {
+ // Keep going
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_COMMENTLINE) {
+ if (isEOLChar(ch)) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ // Use whatever setting we had going into the comment
+ }
+ } else if (state == SCE_RB_HERE_DELIM) {
+ // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
+ // Slightly different: if we find an immediate '-',
+ // the target can appear indented.
+
+ if (HereDoc.State == 0) { // '<<' encountered
+ HereDoc.State = 1;
+ HereDoc.DelimiterLength = 0;
+ if (ch == '-') {
+ HereDoc.CanBeIndented = true;
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ } else {
+ HereDoc.CanBeIndented = false;
+ }
+ if (isEOLChar(ch)) {
+ // Bail out of doing a here doc if there's no target
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else {
+ HereDoc.Quote = ch;
+
+ if (ch == '\'' || ch == '"' || ch == '`') {
+ HereDoc.Quoted = true;
+ HereDoc.Delimiter[0] = '\0';
+ } else {
+ HereDoc.Quoted = false;
+ HereDoc.Delimiter[0] = ch;
+ HereDoc.Delimiter[1] = '\0';
+ HereDoc.DelimiterLength = 1;
+ }
+ }
+ } else if (HereDoc.State == 1) { // collect the delimiter
+ if (isEOLChar(ch)) {
+ // End the quote now, and go back for more
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ i--;
+ chNext = ch;
+ chNext2 = chNext;
+ preferRE = false;
+ } else if (HereDoc.Quoted) {
+ if (ch == HereDoc.Quote) { // closing quote => end of delimiter
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ } else {
+ if (ch == '\\' && !isEOLChar(chNext)) {
+ advance_char(i, ch, chNext, chNext2);
+ }
+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ }
+ } else { // an unquoted here-doc delimiter
+ if (isSafeAlnumOrHigh(ch) || ch == '_') {
+ HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state);
+ preferRE = false;
}
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_P_OPERATOR);
- }
- }
- } else {
- if (state == SCE_P_COMMENTLINE || state == SCE_P_COMMENTBLOCK) {
- if (ch == '\r' || ch == '\n') {
+ }
+ if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) {
styler.ColourTo(i - 1, state);
- state = SCE_P_DEFAULT;
- }
- } else if (state == SCE_P_STRING) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourTo(i - 1, state);
- state = SCE_P_STRINGEOL;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\"') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
+ state = SCE_RB_ERROR;
+ preferRE = false;
}
- } else if (state == SCE_P_CHARACTER) {
- if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
- styler.ColourTo(i - 1, state);
- state = SCE_P_STRINGEOL;
- } else if (ch == '\\') {
- if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
- i++;
+ }
+ } else if (state == SCE_RB_HERE_Q) {
+ // Not needed: HereDoc.State == 2
+ // Indentable here docs: look backwards
+ // Non-indentable: look forwards, like in Perl
+ //
+ // Why: so we can quickly resolve things like <<-" abc"
+
+ if (!HereDoc.CanBeIndented) {
+ if (isEOLChar(chPrev)
+ && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
+ styler.ColourTo(i - 1, state);
+ i += HereDoc.DelimiterLength - 1;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if (isEOLChar(chNext)) {
+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
+ state = SCE_RB_DEFAULT;
+ HereDoc.State = 0;
+ preferRE = false;
+ }
+ // Otherwise we skipped through the here doc faster.
+ }
+ } else if (isEOLChar(chNext)
+ && lookingAtHereDocDelim(styler,
+ i - HereDoc.DelimiterLength + 1,
+ lengthDoc,
+ HereDoc.Delimiter)) {
+ styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state);
+ styler.ColourTo(i, SCE_RB_HERE_DELIM);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ HereDoc.State = 0;
+ }
+ } else if (state == SCE_RB_CLASS_VAR
+ || state == SCE_RB_INSTANCE_VAR
+ || state == SCE_RB_SYMBOL) {
+ if (!isSafeWordcharOrHigh(ch)) {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_GLOBAL) {
+ if (!isSafeWordcharOrHigh(ch)) {
+ // handle special globals here as well
+ if (chPrev == '$') {
+ if (ch == '-') {
+ // Include the next char, like $-a
+ advance_char(i, ch, chNext, chNext2);
+ }
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ } else {
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
+ }
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_POD) {
+ // PODs end with ^=end\s, -- any whitespace can follow =end
+ if (strchr(" \t\n\r", ch) != NULL
+ && i > 5
+ && isEOLChar(styler[i - 5])
+ && isMatch(styler, lengthDoc, i - 4, "=end")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) {
+ if (ch == '\\' && Quote.Up != '\\') {
+ // Skip one
+ advance_char(i, ch, chNext, chNext2);
+ } else if (ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ // Include the options
+ while (isSafeAlpha(chNext)) {
+ i++;
ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- } else if (ch == '\'') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
- }
- } else if (state == SCE_P_TRIPLE) {
- if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
- }
- } else if (state == SCE_P_TRIPLEDOUBLE) {
- // =end terminates the comment block
- if (ch == 'd' && chPrev == 'n' && chPrev2 == 'e') {
- if (styler.SafeGetCharAt(i - 3) == '=') {
- styler.ColourTo(i, state);
- state = SCE_P_DEFAULT;
- }
- }
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (ch == Quote.Up) {
+ // Only if close quoter != open quoter
+ Quote.Count++;
+
+ } else if (ch == '#' ) {
+ //todo: distinguish comments from pound chars
+ // for now, handle as comment
+ styler.ColourTo(i - 1, state);
+ bool inEscape = false;
+ while (++i < lengthDoc) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\\') {
+ inEscape = true;
+ } else if (isEOLChar(ch)) {
+ // Comment inside a regex
+ styler.ColourTo(i - 1, SCE_RB_COMMENTLINE);
+ break;
+ } else if (inEscape) {
+ inEscape = false; // don't look at char
+ } else if (ch == Quote.Down) {
+ // Have the regular handler deal with this
+ // to get trailing modifiers.
+ i--;
+ ch = styler[i];
+ break;
+ }
+ }
+ chNext = styler.SafeGetCharAt(i + 1);
+ chNext2 = styler.SafeGetCharAt(i + 2);
+ }
+ // Quotes of all kinds...
+ } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
+ state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
+ state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
+ state == SCE_RB_BACKTICKS) {
+ if (!Quote.Down && !isspacechar(ch)) {
+ Quote.Open(ch);
+ } else if (ch == '\\' && Quote.Up != '\\') {
+ //Riddle me this: Is it safe to skip *every* escaped char?
+ advance_char(i, ch, chNext, chNext2);
+ } else if (ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0) {
+ styler.ColourTo(i, state);
+ state = SCE_RB_DEFAULT;
+ preferRE = false;
+ }
+ } else if (ch == Quote.Up) {
+ Quote.Count++;
+ }
+ }
+
+ if (state == SCE_RB_ERROR) {
+ break;
+ }
+ chPrev = ch;
+ }
+ if (state == SCE_RB_WORD) {
+ // We've ended on a word, possibly at EOF, and need to
+ // classify it.
+ (void) ClassifyWordRb(styler.GetStartSegment(), lengthDoc - 1, keywords, styler, prevWord);
+ } else {
+ styler.ColourTo(lengthDoc - 1, state);
+ }
+}
+
+// Helper functions for folding, disambiguation keywords
+// Assert that there are no high-bit chars
+
+static void getPrevWord(int pos,
+ char *prevWord,
+ Accessor &styler,
+ int word_state)
+{
+ int i;
+ styler.Flush();
+ for (i = pos - 1; i > 0; i--) {
+ if (actual_style(styler.StyleAt(i)) != word_state) {
+ i++;
+ break;
+ }
+ }
+ if (i < pos - MAX_KEYWORD_LENGTH) // overflow
+ i = pos - MAX_KEYWORD_LENGTH;
+ char *dst = prevWord;
+ for (; i <= pos; i++) {
+ *dst++ = styler[i];
+ }
+ *dst = 0;
+}
+
+static bool keywordIsAmbiguous(const char *prevWord)
+{
+ // Order from most likely used to least likely
+ // Lots of ways to do a loop in Ruby besides 'while/until'
+ if (!strcmp(prevWord, "if")
+ || !strcmp(prevWord, "do")
+ || !strcmp(prevWord, "while")
+ || !strcmp(prevWord, "unless")
+ || !strcmp(prevWord, "until")) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Demote keywords in the following conditions:
+// if, while, unless, until modify a statement
+// do after a while or until, as a noise word (like then after if)
+
+static bool keywordIsModifier(const char *word,
+ int pos,
+ Accessor &styler)
+{
+ if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
+ return keywordDoStartsLoop(pos, styler);
+ }
+ char ch;
+ int style = SCE_RB_DEFAULT;
+ int lineStart = styler.GetLine(pos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ while (--pos >= lineStartPosn) {
+ style = actual_style(styler.StyleAt(pos));
+ if (style == SCE_RB_DEFAULT) {
+ if (iswhitespace(ch = styler[pos])) {
+ //continue
+ } else if (ch == '\r' || ch == '\n') {
+ // Scintilla's LineStart() and GetLine() routines aren't
+ // platform-independent, so if we have text prepared with
+ // a different system we can't rely on it.
+ return false;
}
+ } else {
+ break;
}
- chPrev2 = chPrev;
- chPrev = ch;
- }
- if (state == SCE_P_WORD) {
- ClassifyWordRb(styler.GetStartSegment(), lengthDoc-1, keywords, styler, prevWord);
- } else {
- styler.ColourTo(lengthDoc-1, state);
- }
+ }
+ if (pos < lineStartPosn) {
+ return false; //XXX not quite right if the prev line is a continuation
+ }
+ // First things where the action is unambiguous
+ switch (style) {
+ case SCE_RB_DEFAULT:
+ case SCE_RB_COMMENTLINE:
+ case SCE_RB_POD:
+ case SCE_RB_CLASSNAME:
+ case SCE_RB_DEFNAME:
+ case SCE_RB_MODULE_NAME:
+ return false;
+ case SCE_RB_OPERATOR:
+ break;
+ case SCE_RB_WORD:
+ // Watch out for uses of 'else if'
+ //XXX: Make a list of other keywords where 'if' isn't a modifier
+ // and can appear legitimately
+ // Formulate this to avoid warnings from most compilers
+ if (strcmp(word, "if") == 0) {
+ char prevWord[MAX_KEYWORD_LENGTH + 1];
+ getPrevWord(pos, prevWord, styler, SCE_RB_WORD);
+ return strcmp(prevWord, "else") != 0;
+ }
+ return true;
+ default:
+ return true;
+ }
+ // Assume that if the keyword follows an operator,
+ // usually it's a block assignment, like
+ // a << if x then y else z
+
+ ch = styler[pos];
+ switch (ch) {
+ case ')':
+ case ']':
+ case '}':
+ return true;
+ default:
+ return false;
+ }
}
-static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- int lengthDoc = startPos + length;
+#define WHILE_BACKWARDS "elihw"
+#define UNTIL_BACKWARDS "litnu"
+
+// Nothing fancy -- look to see if we follow a while/until somewhere
+// on the current line
+
+static bool keywordDoStartsLoop(int pos,
+ Accessor &styler)
+{
+ char ch;
+ int style;
+ int lineStart = styler.GetLine(pos);
+ int lineStartPosn = styler.LineStart(lineStart);
+ styler.Flush();
+ while (--pos >= lineStartPosn) {
+ style = actual_style(styler.StyleAt(pos));
+ if (style == SCE_RB_DEFAULT) {
+ if ((ch = styler[pos]) == '\r' || ch == '\n') {
+ // Scintilla's LineStart() and GetLine() routines aren't
+ // platform-independent, so if we have text prepared with
+ // a different system we can't rely on it.
+ return false;
+ }
+ } else if (style == SCE_RB_WORD) {
+ // Check for while or until, but write the word in backwards
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ char *dst = prevWord;
+ int wordLen = 0;
+ int start_word;
+ for (start_word = pos;
+ start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD;
+ start_word--) {
+ if (++wordLen < MAX_KEYWORD_LENGTH) {
+ *dst++ = styler[start_word];
+ }
+ }
+ *dst = 0;
+ // Did we see our keyword?
+ if (!strcmp(prevWord, WHILE_BACKWARDS)
+ || !strcmp(prevWord, UNTIL_BACKWARDS)) {
+ return true;
+ }
+ // We can move pos to the beginning of the keyword, and then
+ // accept another decrement, as we can never have two contiguous
+ // keywords:
+ // word1 word2
+ // ^
+ // <- move to start_word
+ // ^
+ // <- loop decrement
+ // ^ # pointing to end of word1 is fine
+ pos = start_word;
+ }
+ }
+ return false;
+}
+
+/*
+ * Folding Ruby
+ *
+ * The language is quite complex to analyze without a full parse.
+ * For example, this line shouldn't affect fold level:
+ *
+ * print "hello" if feeling_friendly?
+ *
+ * Neither should this:
+ *
+ * print "hello" \
+ * if feeling_friendly?
+ *
+ *
+ * But this should:
+ *
+ * if feeling_friendly? #++
+ * print "hello" \
+ * print "goodbye"
+ * end #--
+ *
+ * So we cheat, by actually looking at the existing indentation
+ * levels for each line, and just echoing it back. Like Python.
+ * Then if we get better at it, we'll take braces into consideration,
+ * which always affect folding levels.
+
+ * How the keywords should work:
+ * No effect:
+ * __FILE__ __LINE__ BEGIN END alias and
+ * defined? false in nil not or self super then
+ * true undef
+
+ * Always increment:
+ * begin class def do for module when {
+ *
+ * Always decrement:
+ * end }
+ *
+ * Increment if these start a statement
+ * if unless until while -- do nothing if they're modifiers
- // Backtrack to previous line in case need to fix its fold status
+ * These end a block if there's no modifier, but don't bother
+ * break next redo retry return yield
+ *
+ * These temporarily de-indent, but re-indent
+ * case else elsif ensure rescue
+ *
+ * This means that the folder reflects indentation rather
+ * than setting it. The language-service updates indentation
+ * when users type return and finishes entering de-denters.
+ *
+ * Later offer to fold POD, here-docs, strings, and blocks of comments
+ */
+
+static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+ synchronizeDocStart(startPos, length, initStyle, styler, // ref args
+ false);
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- if (startPos == 0)
- initStyle = SCE_P_DEFAULT;
- else
- initStyle = styler.StyleAt(startPos-1);
- }
- }
- int state = initStyle & 31;
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsRbComment);
- if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
- indentCurrent |= SC_FOLDLEVELWHITEFLAG;
+ int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent)
+ & SC_FOLDLEVELNUMBERMASK
+ & ~SC_FOLDLEVELBASE);
+ int levelCurrent = levelPrev;
char chNext = styler[startPos];
- for (int i = startPos; i < lengthDoc; i++) {
+ int styleNext = styler.StyleAt(startPos);
+ int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1);
+ bool buffer_ends_with_eol = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
- int style = styler.StyleAt(i) & 31;
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsRbComment);
- if ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE))
- indentNext |= SC_FOLDLEVELWHITEFLAG;
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsRbComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
+ int style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (style == SCE_RB_COMMENTLINE) {
+ if (foldComment && stylePrev != SCE_RB_COMMENTLINE) {
+ if (chNext == '{') {
+ levelCurrent++;
+ } else if (chNext == '}') {
+ levelCurrent--;
}
+ }
+ } else if (style == SCE_RB_OPERATOR) {
+ if (strchr("[{(", ch)) {
+ levelCurrent++;
+ } else if (strchr(")}]", ch)) {
+ // Don't decrement below 0
+ if (levelCurrent > 0)
+ levelCurrent--;
}
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
+ } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) {
+ // Look at the keyword on the left and decide what to do
+ char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero
+ prevWord[0] = 0;
+ getPrevWord(i, prevWord, styler, SCE_RB_WORD);
+ if (!strcmp(prevWord, "end")) {
+ // Don't decrement below 0
+ if (levelCurrent > 0)
+ levelCurrent--;
+ } else if ( !strcmp(prevWord, "if")
+ || !strcmp(prevWord, "def")
+ || !strcmp(prevWord, "class")
+ || !strcmp(prevWord, "module")
+ || !strcmp(prevWord, "begin")
+ || !strcmp(prevWord, "case")
+ || !strcmp(prevWord, "do")
+ || !strcmp(prevWord, "while")
+ || !strcmp(prevWord, "unless")
+ || !strcmp(prevWord, "until")
+ || !strcmp(prevWord, "for")
+ ) {
+ levelCurrent++;
+ }
+ }
+ if (atEOL) {
+ int lev = levelPrev;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE);
lineCurrent++;
- }
- }
+ levelPrev = levelCurrent;
+ visibleChars = 0;
+ buffer_ends_with_eol = true;
+ } else if (!isspacechar(ch)) {
+ visibleChars++;
+ buffer_ends_with_eol = false;
+ }
+ }
+ // 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) {
+ lineCurrent++;
+ int new_lev = levelCurrent;
+ if (visibleChars == 0 && foldCompact)
+ new_lev |= SC_FOLDLEVELWHITEFLAG;
+ if ((levelCurrent > levelPrev) && (visibleChars > 0))
+ new_lev |= SC_FOLDLEVELHEADERFLAG;
+ levelCurrent = new_lev;
+ }
+ styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE);
}
static const char * const rubyWordListDesc[] = {
// Scintilla source code edit control
/** @file LexSQL.cxx
- ** Lexer for SQL.
+ ** Lexer for SQL, including PL/SQL and SQL*Plus.
**/
-// Copyright 1998-2002 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 "PropSet.h"
#include "Accessor.h"
+#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
-static void classifyWordSQL(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
- char s[100];
- bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
- for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
- s[i] = static_cast<char>(tolower(styler[start + i]));
- s[i + 1] = '\0';
- }
- char chAttr = SCE_C_IDENTIFIER;
- if (wordIsNumber)
- chAttr = SCE_C_NUMBER;
- else {
- if (keywords.InList(s))
- chAttr = SCE_C_WORD;
- }
- styler.ColourTo(end, chAttr);
+static 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 void ColouriseSQLDoc(unsigned int startPos, int length,
- int initStyle, WordList *keywordlists[], Accessor &styler) {
+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 == '+');
+}
- WordList &keywords = *keywordlists[0];
- styler.StartAt(startPos);
+static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+ Accessor &styler) {
+
+ WordList &keywords1 = *keywordlists[0];
+ WordList &keywords2 = *keywordlists[1];
+ WordList &kw_pldoc = *keywordlists[2];
+ WordList &kw_sqlplus = *keywordlists[3];
+ WordList &kw_user1 = *keywordlists[4];
+ WordList &kw_user2 = *keywordlists[5];
+ WordList &kw_user3 = *keywordlists[6];
+ WordList &kw_user4 = *keywordlists[7];
+
+ StyleContext sc(startPos, length, initStyle, styler);
- bool fold = styler.GetPropertyInt("fold") != 0;
bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+ bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
+ int styleBeforeDCKeyword = SCE_C_DEFAULT;
+ bool fold = styler.GetPropertyInt("fold") != 0;
int lineCurrent = styler.GetLine(startPos);
- int spaceFlags = 0;
-
- int state = initStyle;
- char chPrev = ' ';
- char chNext = styler[startPos];
- styler.StartSegment(startPos);
- unsigned int lengthDoc = startPos + length;
- for (unsigned int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ for (; sc.More(); sc.Forward()) {
+ // Fold based on indentation
+ if (sc.atLineStart) {
+ int spaceFlags = 0;
int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
- int lev = indentCurrent;
+ int level = indentCurrent;
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Only non whitespace lines can be headers
int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
+ level |= SC_FOLDLEVELHEADERFLAG;
}
}
if (fold) {
- styler.SetLevel(lineCurrent, lev);
+ styler.SetLevel(lineCurrent, level);
}
}
- 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_SQL_OPERATOR:
+ sc.SetState(SCE_SQL_DEFAULT);
+ break;
+ case SCE_SQL_NUMBER:
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ if (!IsANumberChar(sc.ch)) {
+ sc.SetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_IDENTIFIER:
+ if (!IsAWordChar(sc.ch)) {
+ int nextState = SCE_SQL_DEFAULT;
+ char s[1000];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords1.InList(s)) {
+ sc.ChangeState(SCE_SQL_WORD);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(SCE_SQL_WORD2);
+ } else if (kw_sqlplus.InListAbbreviated(s, '~')) {
+ sc.ChangeState(SCE_SQL_SQLPLUS);
+ if (strncmp(s, "rem", 3) == 0) {
+ nextState = SCE_SQL_SQLPLUS_COMMENT;
+ } else if (strncmp(s, "pro", 3) == 0) {
+ nextState = SCE_SQL_SQLPLUS_PROMPT;
+ }
+ } else if (kw_user1.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER1);
+ } else if (kw_user2.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER2);
+ } else if (kw_user3.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER3);
+ } else if (kw_user4.InList(s)) {
+ sc.ChangeState(SCE_SQL_USER4);
+ }
+ sc.SetState(nextState);
+ }
+ break;
+ case SCE_SQL_QUOTEDIDENTIFIER:
+ if (sc.ch == 0x60) {
+ if (sc.chNext == 0x60) {
+ sc.Forward(); // Ignore it
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SQL_COMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_COMMENTDOC:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // 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_SQL_COMMENTDOC;
+ sc.SetState(SCE_SQL_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_SQL_COMMENTLINE:
+ case SCE_SQL_COMMENTLINEDOC:
+ case SCE_SQL_SQLPLUS_COMMENT:
+ case SCE_SQL_SQLPLUS_PROMPT:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_SQL_DEFAULT);
+ }
+ break;
+ case SCE_SQL_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {
+ sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ } else if (!IsADoxygenChar(sc.ch)) {
+ char s[100];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {
+ sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_SQL_CHARACTER:
+ if (sqlBackslashEscapes && sc.ch == '\\') {
+ sc.Forward();
+ } else if (sc.ch == '\'') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
+ case SCE_SQL_STRING:
+ if (sc.ch == '\\') {
+ // Escape sequence
+ sc.Forward();
+ } else if (sc.ch == '\"') {
+ if (sc.chNext == '\"') {
+ sc.Forward();
+ } else {
+ sc.ForwardSetState(SCE_SQL_DEFAULT);
+ }
+ }
+ break;
}
- if (state == SCE_C_DEFAULT) {
- if (iswordstart(ch)) {
- styler.ColourTo(i - 1, state);
- state = SCE_C_WORD;
- } else if (ch == '/' && chNext == '*') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_COMMENTLINE;
- } else if (ch == '#') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_COMMENTLINEDOC;
- } else if (ch == '\'') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_CHARACTER;
- } else if (ch == '"') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_STRING;
- } else if (isoperator(ch)) {
- styler.ColourTo(i - 1, state);
- styler.ColourTo(i, SCE_C_OPERATOR);
- }
- } else if (state == SCE_C_WORD) {
- if (!iswordchar(ch)) {
- classifyWordSQL(styler.GetStartSegment(), i - 1, keywords, styler);
- state = SCE_C_DEFAULT;
- if (ch == '/' && chNext == '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '#') {
- state = SCE_C_COMMENTLINEDOC;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (ch == '"') {
- state = SCE_C_STRING;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_C_OPERATOR);
+ // Determine if a new state should be entered.
+ if (sc.state == SCE_SQL_DEFAULT) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_SQL_NUMBER);
+ } else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_SQL_IDENTIFIER);
+ } else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
+ sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
+ } else if (sc.Match('/', '*')) {
+ if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
+ sc.SetState(SCE_SQL_COMMENTDOC);
+ } else {
+ sc.SetState(SCE_SQL_COMMENT);
}
+ sc.Forward(); // Eat the * so it isn't used for the end of the comment
+ } else if (sc.Match('-', '-')) {
+ // MySQL requires a space or control char after --
+ // http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
+ // Perhaps we should enforce that with proper property:
+//~ } else if (sc.Match("-- ")) {
+ sc.SetState(SCE_SQL_COMMENTLINE);
+ } else if (sc.ch == '#') {
+ sc.SetState(SCE_SQL_COMMENTLINEDOC);
+ } else if (sc.ch == '\'') {
+ sc.SetState(SCE_SQL_CHARACTER);
+ } else if (sc.ch == '\"') {
+ sc.SetState(SCE_SQL_STRING);
+ } else if (isoperator(static_cast<char>(sc.ch))) {
+ sc.SetState(SCE_SQL_OPERATOR);
}
- } else {
- if (state == SCE_C_COMMENT) {
- if (ch == '/' && chPrev == '*') {
- if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_C_COMMENT) &&
- (styler.GetStartSegment() == startPos)))) {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- }
+ }
+ }
+ sc.Complete();
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_SQL_COMMENT ||
+ style == SCE_SQL_COMMENTDOC ||
+ style == SCE_SQL_COMMENTDOCKEYWORD ||
+ style == SCE_SQL_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.
+static void FoldSQLDoc(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;
+ 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) & SC_FOLDLEVELNUMBERMASK;
+ }
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ bool endFound = false;
+ 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 (foldComment && (style == SCE_SQL_COMMENTLINE)) {
+ // MySQL needs -- comments to be followed by space or control char
+ if ((ch == '-') && (chNext == '-')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ char chNext3 = styler.SafeGetCharAt(i + 3);
+ if (chNext2 == '{' || chNext3 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}' || chNext3 == '}') {
+ levelNext--;
}
- } else if (state == SCE_C_COMMENTLINE || state == SCE_C_COMMENTLINEDOC) {
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_C_DEFAULT;
+ }
+ }
+ if (style == SCE_SQL_OPERATOR) {
+ if (ch == '(') {
+ levelNext++;
+ } else if (ch == ')') {
+ levelNext--;
+ }
+ }
+ // If new keyword (cannot trigger on elseif or nullif, does less tests)
+ if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
+ const int MAX_KW_LEN = 6; // Maximum length of folding keywords
+ char s[MAX_KW_LEN + 2];
+ unsigned int j = 0;
+ for (; j < MAX_KW_LEN + 1; j++) {
+ if (!iswordchar(styler[i + j])) {
+ break;
}
- } else if (state == SCE_C_CHARACTER) {
- if (sqlBackslashEscapes && ch == '\\') {
- i++;
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- } else if (ch == '\'') {
- if (chNext == '\'') {
- i++;
- } else {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- i++;
- }
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
+ s[j] = static_cast<char>(tolower(styler[i + j]));
+ }
+ if (j == MAX_KW_LEN + 1) {
+ // Keyword too long, don't test it
+ s[0] = '\0';
+ } else {
+ s[j] = '\0';
+ }
+ if (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0) {
+ if (endFound) {
+ // ignore
+ endFound = false;
+ } else {
+ levelNext++;
}
- } else if (state == SCE_C_STRING) {
- if (ch == '"') {
- if (chNext == '"') {
- i++;
- } else {
- styler.ColourTo(i, state);
- state = SCE_C_DEFAULT;
- i++;
- }
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
+ } 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) {
+ endFound = true;
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE) {
+ levelNext = SC_FOLDLEVELBASE;
}
}
- if (state == SCE_C_DEFAULT) { // One of the above succeeded
- if (ch == '/' && chNext == '*') {
- state = SCE_C_COMMENT;
- } else if (ch == '-' && chNext == '-') {
- state = SCE_C_COMMENTLINE;
- } else if (ch == '#') {
- state = SCE_C_COMMENTLINEDOC;
- } else if (ch == '\'') {
- state = SCE_C_CHARACTER;
- } else if (ch == '"') {
- state = SCE_C_STRING;
- } else if (iswordstart(ch)) {
- state = SCE_C_WORD;
- } else if (isoperator(ch)) {
- styler.ColourTo(i, SCE_C_OPERATOR);
- }
+ }
+ if (atEOL) {
+ int level = levelCurrent;
+ if (visibleChars == 0 && foldCompact) {
+ // Empty line
+ level |= SC_FOLDLEVELWHITEFLAG;
}
+ if (visibleChars > 0 && levelNext > levelCurrent) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (level != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, level);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+ endFound = false;
+ }
+ if (!isspacechar(ch)) {
+ visibleChars++;
}
- chPrev = ch;
}
- styler.ColourTo(lengthDoc - 1, state);
}
static const char * const sqlWordListDesc[] = {
"Keywords",
+ "Database Objects",
+ "PLDoc",
+ "SQL*Plus",
+ "User Keywords 1",
+ "User Keywords 2",
+ "User Keywords 3",
+ "User Keywords 4",
0
};
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", 0, sqlWordListDesc);
+LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", FoldSQLDoc, sqlWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexSmalltalk.cxx
+ ** Lexer for Smalltalk language.
+ ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com
+ **/
+// 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 "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+/*
+| lexTable classificationBlock charClasses |
+charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
+lexTable := ByteArray new: 128.
+classificationBlock := [ :charClass :chars |
+ | flag |
+ flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
+ chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
+
+classificationBlock
+ value: #DecDigit value: '0123456789';
+ value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ value: #Special value: '()[]{};.^:';
+ value: #BinSel value: '~@%&*-+=|\/,<>?!';
+ value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
+
+((String new: 500) streamContents: [ :stream |
+ stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
+ lexTable keysAndValuesDo: [ :index :value |
+ ((index - 1) rem: 16) == 0 ifTrue: [
+ stream crLf; tab]
+ ifFalse: [
+ stream space].
+ stream print: value.
+ index ~= 256 ifTrue: [
+ stream nextPut: $,]].
+ stream crLf; nextPutAll: '};'; crLf.
+
+ charClasses keysAndValuesDo: [ :index :name |
+ stream
+ crLf;
+ nextPutAll: (
+ ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
+ expandMacrosWith: name with: (1 bitShift: (index - 1)))
+ ]]) edit
+*/
+
+// autogenerated {{{{
+
+static int ClassificationTable[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16,
+ 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2,
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0,
+};
+
+static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}
+static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}
+static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}
+static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}
+static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}
+// autogenerated }}}}
+
+static inline bool isAlphaNumeric(int ch) {
+ return isDecDigit(ch) || isLetter(ch);
+}
+
+static inline bool isDigitOfRadix(int ch, int radix)
+{
+ if (isDecDigit(ch))
+ return (ch - '0') < radix;
+ else if (!isUpper(ch))
+ return false;
+ else
+ return (ch - 'A' + 10) < radix;
+}
+
+static inline void skipComment(StyleContext& sc)
+{
+ while (sc.More() && sc.ch != '\"')
+ sc.Forward();
+}
+
+static inline void skipString(StyleContext& sc)
+{
+ while (sc.More()) {
+ if (sc.ch == '\'') {
+ if (sc.chNext != '\'')
+ return;
+ sc.Forward();
+ }
+ sc.Forward();
+ }
+}
+
+static void handleHash(StyleContext& sc)
+{
+ if (isSpecial(sc.chNext)) {
+ sc.SetState(SCE_ST_SPECIAL);
+ return;
+ }
+
+ sc.SetState(SCE_ST_SYMBOL);
+ sc.Forward();
+ if (sc.ch == '\'') {
+ sc.Forward();
+ skipString(sc);
+ }
+ else {
+ if (isLetter(sc.ch)) {
+ while (isAlphaNumeric(sc.chNext) || sc.chNext == ':')
+ sc.Forward();
+ }
+ else if (isBinSel(sc.ch)) {
+ while (isBinSel(sc.chNext))
+ sc.Forward();
+ }
+ }
+}
+
+static inline void handleSpecial(StyleContext& sc)
+{
+ if (sc.ch == ':' && sc.chNext == '=') {
+ sc.SetState(SCE_ST_ASSIGN);
+ sc.Forward();
+ }
+ else {
+ if (sc.ch == '^')
+ sc.SetState(SCE_ST_RETURN);
+ else
+ sc.SetState(SCE_ST_SPECIAL);
+ }
+}
+
+static inline void skipInt(StyleContext& sc, int radix)
+{
+ while (isDigitOfRadix(sc.chNext, radix))
+ sc.Forward();
+}
+
+static void handleNumeric(StyleContext& sc)
+{
+ char num[256];
+ int nl;
+ int radix;
+
+ sc.SetState(SCE_ST_NUMBER);
+ num[0] = static_cast<char>(sc.ch);
+ nl = 1;
+ while (isDecDigit(sc.chNext)) {
+ num[nl++] = static_cast<char>(sc.chNext);
+ sc.Forward();
+ if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check
+ break;
+ }
+ if (sc.chNext == 'r') {
+ num[nl] = 0;
+ if (num[0] == '-')
+ radix = atoi(num + 1);
+ else
+ radix = atoi(num);
+ sc.Forward();
+ if (sc.chNext == '-')
+ sc.Forward();
+ skipInt(sc, radix);
+ }
+ else
+ radix = 10;
+ if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix))
+ return;
+ sc.Forward();
+ skipInt(sc, radix);
+ if (sc.chNext == 's') {
+ // ScaledDecimal
+ sc.Forward();
+ while (isDecDigit(sc.chNext))
+ sc.Forward();
+ return;
+ }
+ else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q')
+ return;
+ sc.Forward();
+ if (sc.chNext == '+' || sc.chNext == '-')
+ sc.Forward();
+ skipInt(sc, radix);
+}
+
+static inline void handleBinSel(StyleContext& sc)
+{
+ sc.SetState(SCE_ST_BINARY);
+ while (isBinSel(sc.chNext))
+ sc.Forward();
+}
+
+static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
+{
+ char ident[256];
+ int il;
+ int state;
+ bool doubleColonPresent;
+
+ sc.SetState(SCE_ST_DEFAULT);
+
+ ident[0] = static_cast<char>(sc.ch);
+ il = 1;
+ while (isAlphaNumeric(sc.chNext)) {
+ ident[il++] = static_cast<char>(sc.chNext);
+ sc.Forward();
+ if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check
+ break;
+ }
+
+ if (sc.chNext == ':') {
+ doubleColonPresent = true;
+ ident[il++] = ':';
+ sc.Forward();
+ }
+ else
+ doubleColonPresent = false;
+ ident[il] = 0;
+
+ if (specialSelectorList->InList(ident))
+ state = SCE_ST_SPEC_SEL;
+ else if (doubleColonPresent)
+ state = SCE_ST_KWSEND;
+ else if (isUpper(ident[0]))
+ state = SCE_ST_GLOBAL;
+ else {
+ if (!strcmp(ident, "self"))
+ state = SCE_ST_SELF;
+ else if (!strcmp(ident, "super"))
+ state = SCE_ST_SUPER;
+ else if (!strcmp(ident, "nil"))
+ state = SCE_ST_NIL;
+ else if (!strcmp(ident, "true") || !strcmp(ident, "false"))
+ state = SCE_ST_BOOL;
+ else
+ state = SCE_ST_DEFAULT;
+ }
+
+ sc.ChangeState(state);
+}
+
+static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *wordLists[], Accessor &styler)
+{
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ if (initStyle == SCE_ST_COMMENT) {
+ skipComment(sc);
+ if (sc.More())
+ sc.Forward();
+ }
+ else if (initStyle == SCE_ST_STRING) {
+ skipString(sc);
+ if (sc.More())
+ sc.Forward();
+ }
+
+ for (; sc.More(); sc.Forward()) {
+ int ch;
+
+ ch = sc.ch;
+ if (ch == '\"') {
+ sc.SetState(SCE_ST_COMMENT);
+ sc.Forward();
+ skipComment(sc);
+ }
+ else if (ch == '\'') {
+ sc.SetState(SCE_ST_STRING);
+ sc.Forward();
+ skipString(sc);
+ }
+ else if (ch == '#')
+ handleHash(sc);
+ else if (ch == '$') {
+ sc.SetState(SCE_ST_CHARACTER);
+ sc.Forward();
+ }
+ else if (isSpecial(ch))
+ handleSpecial(sc);
+ else if (isDecDigit(ch))
+ handleNumeric(sc);
+ else if (isLetter(ch))
+ handleLetter(sc, wordLists[0]);
+ else if (isBinSel(ch)) {
+ if (ch == '-' && isDecDigit(sc.chNext))
+ handleNumeric(sc);
+ else
+ handleBinSel(sc);
+ }
+ else
+ sc.SetState(SCE_ST_DEFAULT);
+ }
+ sc.Complete();
+}
+
+static const char* const smalltalkWordListDesc[] = {
+ "Special selectors",
+ 0
+};
+
+LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc);
--- /dev/null
+// Scintilla source code edit control
+/** @file LexTADS3.cxx
+ ** Lexer for TADS3.
+ **/
+/* Copyright 2005 by Michael Cartmell
+ * Parts copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+ * In particular FoldTADS3Doc is derived from FoldCppDoc
+ * The License.txt file describes the conditions under which this software may
+ * be distributed.
+ */
+
+/*
+ * TADS3 is a language designed by Michael J. Roberts for the writing of text
+ * based games. TADS comes from Text Adventure Development System. It has good
+ * support for the processing and outputting of formatted text and much of a
+ * TADS program listing consists of strings.
+ *
+ * TADS has two types of strings, those enclosed in single quotes (') and those
+ * enclosed in double quotes ("). These strings have different symantics and
+ * can be given different highlighting if desired.
+ *
+ * There can be embedded within both types of strings html tags
+ * ( <tag key=value> ), library directives ( <.directive> ), and message
+ * parameters ( {The doctor's/his} ).
+ *
+ * Double quoted strings can also contain interpolated expressions
+ * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions
+ * may themselves contain single or double quoted strings, although the double
+ * quoted strings may not contain interpolated expressions.
+ *
+ * These embedded constructs influence the output and formatting and are an
+ * important part of a program and require highlighting.
+ *
+ * LINKS
+ * http://www.tads.org/
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+static const int T3_SINGLE_QUOTE = 1;
+static const int T3_INT_EXPRESSION = 2;
+
+static inline bool IsEOL(const int ch, const int chNext) {
+ return (ch == '\r' && chNext != '\n') || (ch == '\n');
+}
+
+static inline bool IsASpaceOrTab(const int ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+static inline bool IsATADS3Operator(const int ch) {
+ return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
+ || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
+ || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'
+ || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'
+ || ch == '@' || ch == '&' || ch == '~';
+}
+
+static inline bool IsAWordChar(const int ch) {
+ return isalnum(ch) || ch == '_' || ch == '.';
+}
+
+static inline bool IsAWordStart(const int ch) {
+ return isalpha(ch) || ch == '_';
+}
+
+static inline bool IsAHexDigit(const int ch) {
+ int lch = tolower(ch);
+ return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c'
+ || lch == 'd' || lch == 'e' || lch == 'f';
+}
+
+static inline bool IsAnHTMLChar(int ch) {
+ return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';
+}
+
+static inline bool IsADirectiveChar(int ch) {
+ return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/';
+}
+
+static inline bool IsANumberStart(StyleContext &sc) {
+ return isdigit(sc.ch)
+ || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext));
+}
+
+inline static void ColouriseTADS3Operator(StyleContext &sc) {
+ int initState = sc.state;
+ sc.SetState(SCE_T3_OPERATOR);
+ sc.ForwardSetState(initState);
+}
+
+static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = sc.ch;
+ if (endState == SCE_T3_HTML_STRING) {
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '"';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ chQuote = '\'';
+ } else {
+ endState = SCE_T3_D_STRING;
+ chQuote = '\'';
+ }
+ } else {
+ sc.SetState(SCE_T3_HTML_STRING);
+ sc.Forward();
+ }
+ int chString = chQuote == '"'? '\'': '"';
+
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.ch == chString) {
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))
+ || sc.Match('\\', static_cast<char>(chString))) {
+ sc.Forward(2);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3HTMLTagStart(StyleContext &sc) {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.Forward();
+ if (sc.ch == '/') {
+ sc.Forward();
+ }
+ while (IsAnHTMLChar(sc.ch)) {
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = '"';
+ int chString = '\'';
+ switch (endState) {
+ case SCE_T3_S_STRING:
+ ColouriseTADS3HTMLTagStart(sc);
+ sc.SetState(SCE_T3_HTML_DEFAULT);
+ chQuote = '\'';
+ chString = '"';
+ break;
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ ColouriseTADS3HTMLTagStart(sc);
+ sc.SetState(SCE_T3_HTML_DEFAULT);
+ break;
+ case SCE_T3_HTML_DEFAULT:
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ chString = '"';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ } else {
+ endState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.Match('/', '>')) {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.ch == '>') {
+ sc.SetState(SCE_T3_HTML_TAG);
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.SetState(endState);
+ return;
+ }
+ if (sc.ch == chString) {
+ ColouriseTADSHTMLString(sc, lineState);
+ } else if (sc.ch == '=') {
+ ColouriseTADS3Operator(sc);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3Keyword(StyleContext &sc,
+ WordList *keywordlists[], unsigned int endPos) {
+ char s[250];
+ WordList &keywords = *keywordlists[0];
+ WordList &userwords1 = *keywordlists[1];
+ WordList &userwords2 = *keywordlists[2];
+ WordList &userwords3 = *keywordlists[3];
+ int initState = sc.state;
+ sc.SetState(SCE_T3_IDENTIFIER);
+ while (sc.More() && (IsAWordChar(sc.ch))) {
+ sc.Forward();
+ }
+ sc.GetCurrent(s, sizeof(s));
+ if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
+ // have to find if "in" is next
+ int n = 1;
+ while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))
+ n++;
+ if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {
+ sc.Forward(n+2);
+ sc.ChangeState(SCE_T3_KEYWORD);
+ }
+ } else if (keywords.InList(s)) {
+ sc.ChangeState(SCE_T3_KEYWORD);
+ } else if (userwords3.InList(s)) {
+ sc.ChangeState(SCE_T3_USER3);
+ } else if (userwords2.InList(s)) {
+ sc.ChangeState(SCE_T3_USER2);
+ } else if (userwords1.InList(s)) {
+ sc.ChangeState(SCE_T3_USER1);
+ }
+ sc.SetState(initState);
+}
+
+static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {
+ int endState = sc.state;
+ int chQuote = '"';
+ switch (endState) {
+ case SCE_T3_S_STRING:
+ sc.SetState(SCE_T3_MSG_PARAM);
+ sc.Forward();
+ chQuote = '\'';
+ break;
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ sc.SetState(SCE_T3_MSG_PARAM);
+ sc.Forward();
+ break;
+ case SCE_T3_MSG_PARAM:
+ if (lineState&T3_SINGLE_QUOTE) {
+ endState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ } else if (lineState&T3_INT_EXPRESSION) {
+ endState = SCE_T3_X_STRING;
+ } else {
+ endState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+ while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == '\\') {
+ sc.Forward();
+ }
+ sc.Forward();
+ }
+ if (sc.ch == chQuote) {
+ sc.SetState(endState);
+ } else {
+ sc.ForwardSetState(endState);
+ }
+}
+
+static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {
+ int initState = sc.state;
+ int chQuote = '"';
+ switch (initState) {
+ case SCE_T3_S_STRING:
+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
+ sc.Forward(2);
+ chQuote = '\'';
+ break;
+ case SCE_T3_D_STRING:
+ sc.SetState(SCE_T3_LIB_DIRECTIVE);
+ sc.Forward(2);
+ break;
+ case SCE_T3_LIB_DIRECTIVE:
+ if (lineState&T3_SINGLE_QUOTE) {
+ initState = SCE_T3_S_STRING;
+ chQuote = '\'';
+ } else {
+ initState = SCE_T3_D_STRING;
+ }
+ break;
+ }
+ while (sc.More() && IsADirectiveChar(sc.ch)) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ sc.Forward();
+ };
+ if (sc.ch == '>' || !sc.More()) {
+ sc.ForwardSetState(initState);
+ } else if (sc.ch == chQuote) {
+ sc.SetState(initState);
+ } else {
+ sc.ChangeState(initState);
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3String(StyleContext &sc, int &lineState) {
+ int chQuote = sc.ch;
+ int endState = sc.state;
+ switch (sc.state) {
+ case SCE_T3_DEFAULT:
+ case SCE_T3_X_DEFAULT:
+ if (chQuote == '"') {
+ if (sc.state == SCE_T3_DEFAULT) {
+ sc.SetState(SCE_T3_D_STRING);
+ } else {
+ sc.SetState(SCE_T3_X_STRING);
+ }
+ lineState &= ~T3_SINGLE_QUOTE;
+ } else {
+ sc.SetState(SCE_T3_S_STRING);
+ lineState |= T3_SINGLE_QUOTE;
+ }
+ sc.Forward();
+ break;
+ case SCE_T3_S_STRING:
+ chQuote = '\'';
+ endState = lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;
+ break;
+ case SCE_T3_D_STRING:
+ chQuote = '"';
+ endState = SCE_T3_DEFAULT;
+ break;
+ case SCE_T3_X_STRING:
+ chQuote = '"';
+ endState = SCE_T3_X_DEFAULT;
+ break;
+ }
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.ch == chQuote) {
+ sc.ForwardSetState(endState);
+ return;
+ }
+ if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
+ lineState |= T3_INT_EXPRESSION;
+ sc.SetState(SCE_T3_X_DEFAULT);
+ sc.Forward(2);
+ return;
+ }
+ if (sc.Match('\\', static_cast<char>(chQuote))) {
+ sc.Forward(2);
+ } else if (sc.ch == '{') {
+ ColouriseTADS3MsgParam(sc, lineState);
+ } else if (sc.Match('<', '.')) {
+ ColouriseTADS3LibDirective(sc, lineState);
+ } else if (sc.ch == '<') {
+ ColouriseTADS3HTMLTag(sc, lineState);
+ } else {
+ sc.Forward();
+ }
+ }
+}
+
+static void ColouriseTADS3Comment(StyleContext &sc, int endState) {
+ sc.SetState(SCE_T3_BLOCK_COMMENT);
+ while (sc.More()) {
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ if (sc.Match('*', '/')) {
+ sc.Forward(2);
+ sc.SetState(endState);
+ return;
+ }
+ sc.Forward();
+ }
+}
+
+static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
+ sc.SetState(initState);
+ while (sc.More()) {
+ if (sc.ch == '\\') {
+ sc.Forward();
+ if (IsEOL(sc.ch, sc.chNext)) {
+ return;
+ }
+ }
+ if (IsEOL(sc.ch, sc.chNext)) {
+ sc.SetState(endState);
+ return;
+ }
+ sc.Forward();
+ }
+}
+
+static void ColouriseTADS3Number(StyleContext &sc) {
+ int endState = sc.state;
+ bool inHexNumber = false;
+ bool seenE = false;
+ bool seenDot = sc.ch == '.';
+ sc.SetState(SCE_T3_NUMBER);
+ if (sc.More()) {
+ sc.Forward();
+ }
+ if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {
+ inHexNumber = true;
+ sc.Forward();
+ }
+ while (sc.More()) {
+ if (inHexNumber) {
+ if (!IsAHexDigit(sc.ch)) {
+ break;
+ }
+ } else if (!isdigit(sc.ch)) {
+ if (!seenE && tolower(sc.ch) == 'e') {
+ seenE = true;
+ seenDot = true;
+ if (sc.chNext == '+' || sc.chNext == '-') {
+ sc.Forward();
+ }
+ } else if (!seenDot && sc.ch == '.') {
+ seenDot = true;
+ } else {
+ break;
+ }
+ }
+ sc.Forward();
+ }
+ sc.SetState(endState);
+}
+
+static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) {
+ int visibleChars = 0;
+ int bracketLevel = 0;
+ int lineState = 0;
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ if (lineCurrent > 0) {
+ lineState = styler.GetLineState(lineCurrent-1);
+ }
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ while (sc.More()) {
+
+ if (IsEOL(sc.ch, sc.chNext)) {
+ styler.SetLineState(lineCurrent, lineState);
+ lineCurrent++;
+ visibleChars = 0;
+ sc.Forward();
+ if (sc.ch == '\n') {
+ sc.Forward();
+ }
+ }
+
+ switch(sc.state) {
+ case SCE_T3_PREPROCESSOR:
+ case SCE_T3_LINE_COMMENT:
+ ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
+ break;
+ case SCE_T3_S_STRING:
+ case SCE_T3_D_STRING:
+ case SCE_T3_X_STRING:
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ break;
+ case SCE_T3_MSG_PARAM:
+ ColouriseTADS3MsgParam(sc, lineState);
+ break;
+ case SCE_T3_LIB_DIRECTIVE:
+ ColouriseTADS3LibDirective(sc, lineState);
+ break;
+ case SCE_T3_HTML_DEFAULT:
+ ColouriseTADS3HTMLTag(sc, lineState);
+ break;
+ case SCE_T3_HTML_STRING:
+ ColouriseTADSHTMLString(sc, lineState);
+ break;
+ case SCE_T3_BLOCK_COMMENT:
+ ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
+ SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
+ break;
+ case SCE_T3_DEFAULT:
+ case SCE_T3_X_DEFAULT:
+ if (IsASpaceOrTab(sc.ch)) {
+ sc.Forward();
+ } else if (sc.ch == '#' && visibleChars == 0) {
+ ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
+ } else if (sc.Match('/', '*')) {
+ ColouriseTADS3Comment(sc, sc.state);
+ visibleChars++;
+ } else if (sc.Match('/', '/')) {
+ ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
+ } else if (sc.ch == '"') {
+ bracketLevel = 0;
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ } else if (sc.ch == '\'') {
+ ColouriseTADS3String(sc, lineState);
+ visibleChars++;
+ } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
+ && sc.Match('>', '>')) {
+ sc.Forward(2);
+ sc.SetState(SCE_T3_D_STRING);
+ lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION);
+ } else if (IsATADS3Operator(sc.ch)) {
+ if (sc.state == SCE_T3_X_DEFAULT) {
+ if (sc.ch == '(') {
+ bracketLevel++;
+ } else if (sc.ch == ')') {
+ bracketLevel--;
+ }
+ }
+ ColouriseTADS3Operator(sc);
+ visibleChars++;
+ } else if (IsANumberStart(sc)) {
+ ColouriseTADS3Number(sc);
+ visibleChars++;
+ } else if (IsAWordStart(sc.ch)) {
+ ColouriseTADS3Keyword(sc, keywordlists, endPos);
+ visibleChars++;
+ } else if (sc.Match("...")) {
+ sc.SetState(SCE_T3_IDENTIFIER);
+ sc.Forward(3);
+ sc.SetState(SCE_T3_DEFAULT);
+ } else {
+ sc.Forward();
+ visibleChars++;
+ }
+ break;
+ default:
+ sc.SetState(SCE_T3_DEFAULT);
+ sc.Forward();
+ }
+ }
+ sc.Complete();
+}
+
+/*
+ TADS3 has two styles of top level block (TLB). Eg
+
+ // default style
+ silverKey : Key 'small silver key' 'small silver key'
+ "A small key glints in the sunlight. "
+ ;
+
+ and
+
+ silverKey : Key {
+ 'small silver key'
+ 'small silver key'
+ "A small key glints in the sunlight. "
+ }
+
+ Some constructs mandate one or the other, but usually the author has may choose
+ either.
+
+ T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
+ seen and is also used to match the closing ';' of the default style.
+
+ T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
+ what characters may be seen without incrementing the block level. The general
+ pattern is identifier <punc> identifier, acceptable punctuation characters
+ are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
+ characters are syntactically correct, eg parentheses match. A ')' always
+ signifies the start of a block. We just need to check if it is followed by a
+ '{', in which case we let the brace handling code handle the folding level.
+
+ expectingIdentifier == false && expectingIdentifier == false
+ Before the start of a TLB.
+
+ expectingIdentifier == true && expectingIdentifier == true
+ Currently in an identifier. Will accept identifier or punctuation.
+
+ expectingIdentifier == true && expectingIdentifier == false
+ Just seen a punctuation character & now waiting for an identifier to start.
+
+ expectingIdentifier == false && expectingIdentifier == truee
+ We were in an identifier and have seen space. Now waiting to see a punctuation
+ character
+
+ Space, comments & preprocessor directives are always acceptable and are
+ equivalent.
+*/
+
+static const int T3_SEENSTART = 1 << 12;
+static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
+static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
+
+static inline bool IsStringTransition(int s1, int s2) {
+ return s1 != s2
+ && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
+ || s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)
+ && s2 != SCE_T3_LIB_DIRECTIVE
+ && s2 != SCE_T3_MSG_PARAM
+ && s2 != SCE_T3_HTML_TAG
+ && s2 != SCE_T3_HTML_STRING;
+}
+
+static inline bool IsATADS3Punctuation(const int ch) {
+ return ch == ':' || ch == ',' || ch == '(' || ch == ')';
+}
+
+static inline bool IsAnIdentifier(const int style) {
+ return style == SCE_T3_IDENTIFIER
+ || style == SCE_T3_USER1
+ || style == SCE_T3_USER2
+ || style == SCE_T3_USER3;
+}
+
+static inline bool IsSpaceEquivalent(const int ch, const int style) {
+ return isspace(ch)
+ || style == SCE_T3_BLOCK_COMMENT
+ || style == SCE_T3_LINE_COMMENT
+ || style == SCE_T3_PREPROCESSOR;
+}
+
+static char peekAhead(unsigned int startPos, unsigned int endPos,
+ Accessor &styler) {
+ for (unsigned int i = startPos; i < endPos; i++) {
+ int style = styler.StyleAt(i);
+ char ch = styler[i];
+ if (!IsSpaceEquivalent(ch, style)) {
+ if (IsAnIdentifier(style)) {
+ return 'a';
+ }
+ if (IsATADS3Punctuation(ch)) {
+ return ':';
+ }
+ if (ch == '{') {
+ return '{';
+ }
+ return '*';
+ }
+ }
+ return ' ';
+}
+
+static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle,
+ WordList *[], Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int seenStart = levelCurrent & T3_SEENSTART;
+ int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;
+ int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;
+ levelCurrent &= SC_FOLDLEVELNUMBERMASK;
+ int levelMinCurrent = levelCurrent;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char ch = chNext;
+ int stylePrev = style;
+ bool redo = false;
+ for (unsigned int i = startPos; i < endPos; i++) {
+ if (redo) {
+ redo = false;
+ i--;
+ } else {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ }
+ bool atEOL = IsEOL(ch, chNext);
+
+ if (levelNext == SC_FOLDLEVELBASE) {
+ if (IsSpaceEquivalent(ch, style)) {
+ if (expectingPunctuation) {
+ expectingIdentifier = 0;
+ }
+ if (style == SCE_T3_BLOCK_COMMENT) {
+ levelNext++;
+ }
+ } else if (ch == '{') {
+ levelNext++;
+ seenStart = 0;
+ } else if (ch == '\'' || ch == '"' || ch == '[') {
+ levelNext++;
+ if (seenStart) {
+ redo = true;
+ }
+ } else if (ch == ';') {
+ seenStart = 0;
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ } else if (expectingIdentifier && expectingPunctuation) {
+ if (IsATADS3Punctuation(ch)) {
+ if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
+ levelNext++;
+ } else {
+ expectingPunctuation = 0;
+ }
+ } else if (!IsAnIdentifier(style)) {
+ levelNext++;
+ }
+ } else if (expectingIdentifier && !expectingPunctuation) {
+ if (!IsAnIdentifier(style)) {
+ levelNext++;
+ } else {
+ expectingPunctuation = T3_EXPECTINGPUNCTUATION;
+ }
+ } else if (!expectingIdentifier && expectingPunctuation) {
+ if (!IsATADS3Punctuation(ch)) {
+ levelNext++;
+ } else {
+ if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
+ levelNext++;
+ } else {
+ expectingIdentifier = T3_EXPECTINGIDENTIFIER;
+ expectingPunctuation = 0;
+ }
+ }
+ } else if (!expectingIdentifier && !expectingPunctuation) {
+ if (IsAnIdentifier(style)) {
+ seenStart = T3_SEENSTART;
+ expectingIdentifier = T3_EXPECTINGIDENTIFIER;
+ expectingPunctuation = T3_EXPECTINGPUNCTUATION;
+ }
+ }
+
+ if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ }
+
+ } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart
+ && ch == ';' && style == SCE_T3_OPERATOR ) {
+ levelNext--;
+ seenStart = 0;
+ } else if (style == SCE_T3_BLOCK_COMMENT) {
+ if (stylePrev != SCE_T3_BLOCK_COMMENT) {
+ levelNext++;
+ } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ } else if (ch == '\'' || ch == '"') {
+ if (IsStringTransition(style, stylePrev)) {
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (IsStringTransition(style, styleNext)) {
+ levelNext--;
+ }
+ } else if (style == SCE_T3_OPERATOR) {
+ if (ch == '{' || ch == '[') {
+ // Measure the minimum before a '{' to allow
+ // folding on "} else {"
+ if (levelMinCurrent > levelNext) {
+ levelMinCurrent = levelNext;
+ }
+ levelNext++;
+ } else if (ch == '}' || ch == ']') {
+ levelNext--;
+ }
+ }
+
+ if (atEOL) {
+ if (seenStart && levelNext == SC_FOLDLEVELBASE) {
+ switch (peekAhead(i+1, endPos, styler)) {
+ case ' ':
+ case '{':
+ break;
+ case '*':
+ levelNext++;
+ break;
+ case 'a':
+ if (expectingPunctuation) {
+ levelNext++;
+ }
+ break;
+ case ':':
+ if (expectingIdentifier) {
+ levelNext++;
+ }
+ break;
+ }
+ if (levelNext != SC_FOLDLEVELBASE) {
+ expectingIdentifier = 0;
+ expectingPunctuation = 0;
+ }
+ }
+ int lev = levelMinCurrent | (levelNext | expectingIdentifier
+ | expectingPunctuation | seenStart) << 16;
+ if (levelMinCurrent < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ levelMinCurrent = levelCurrent;
+ }
+ }
+}
+
+static const char * const tads3WordList[] = {
+ "TADS3 Keywords",
+ "User defined 1",
+ "User defined 2",
+ "User defined 3",
+ 0
+};
+
+LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList);
// Hooks into the system:
static const char * const texWordListDesc[] = {
- "TeX, eTeX, pdfTeX, Omega"
+ "TeX, eTeX, pdfTeX, Omega",
"ConTeXt Dutch",
"ConTeXt English",
"ConTeXt German",
/** @file LexVB.cxx
** Lexer for Visual Basic and VBScript.
**/
-// Copyright 1998-2003 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 "Scintilla.h"
#include "SciLexer.h"
+// Internal state, highlighted as number
+#define SCE_B_FILENUMBER SCE_B_DEFAULT+100
+
+
static bool IsVBComment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]=='\'';
+ return len > 0 && styler[pos] == '\'';
}
static inline bool IsTypeCharacter(int ch) {
static inline bool IsAWordStart(int ch) {
return ch >= 0x80 ||
- (isalnum(ch) || ch == '_');
+ (isalpha(ch) || ch == '_');
}
-static inline bool IsADateCharacter(const int 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) &&
- (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
}
static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
styler.StartAt(startPos);
int visibleChars = 0;
+ int fileNbDigits = 0;
+
+ // Do not leak onto next line
+ if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
+ initStyle = SCE_B_DEFAULT;
+ }
StyleContext sc(startPos, length, initStyle, styler);
}
}
} else if (sc.state == SCE_B_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
+ // We stop the number definition on non-numerical non-dot non-eE non-sign char
+ // Also accepts A-F for hex. numbers
+ if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
sc.SetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_STRING) {
}
} else if (sc.state == SCE_B_COMMENT) {
if (sc.atLineEnd) {
- sc.SetState(SCE_B_DEFAULT);
+ sc.ForwardSetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_PREPROCESSOR) {
if (sc.atLineEnd) {
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ }
+ } else if (sc.state == SCE_B_FILENUMBER) {
+ if (IsADigit(sc.ch)) {
+ fileNbDigits++;
+ if (fileNbDigits > 3) {
+ sc.ChangeState(SCE_B_DATE);
+ }
+ } else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
+ // Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
+ // Too bad if date is format #27, Oct, 2003# or something like that...
+ // Use regular number state
+ sc.ChangeState(SCE_B_NUMBER);
sc.SetState(SCE_B_DEFAULT);
+ } else if (sc.ch == '#') {
+ sc.ChangeState(SCE_B_DATE);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else {
+ sc.ChangeState(SCE_B_DATE);
+ }
+ if (sc.state != SCE_B_FILENUMBER) {
+ fileNbDigits = 0;
}
} else if (sc.state == SCE_B_DATE) {
- if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
+ if (sc.atLineEnd) {
+ sc.ChangeState(SCE_B_STRINGEOL);
+ sc.ForwardSetState(SCE_B_DEFAULT);
+ } else if (sc.ch == '#') {
sc.ForwardSetState(SCE_B_DEFAULT);
}
}
// Preprocessor commands are alone on their line
sc.SetState(SCE_B_PREPROCESSOR);
} else if (sc.ch == '#') {
- int n = 1;
- int chSeek = ' ';
- while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
- chSeek = sc.GetRelative(n);
- n++;
- }
- if (IsADigit(chSeek)) {
- sc.SetState(SCE_B_DATE);
- } else {
- sc.SetState(SCE_B_OPERATOR);
- }
+ // It can be a date literal, ending with #, or a file number, from 1 to 511
+ // The date literal depends on the locale, so anything can go between #'s.
+ // Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
+ // So we set the FILENUMBER state, and switch to DATE if it isn't a file number
+ sc.SetState(SCE_B_FILENUMBER);
} else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
+ // Hexadecimal number
sc.SetState(SCE_B_NUMBER);
+ sc.Forward();
} else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
+ // Octal number
sc.SetState(SCE_B_NUMBER);
+ sc.Forward();
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_B_NUMBER);
} else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
sc.SetState(SCE_B_IDENTIFIER);
- } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
+ } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division
sc.SetState(SCE_B_OPERATOR);
}
}
surface->LineTo(right - 5, centreY + 5);
right += 4;
}
- } else { // SC_MARK_SHORTARROW
+ } else if (markType == SC_MARK_SHORTARROW) {
Point pts[] = {
Point(centreX, centreY + dimOn2),
Point(centreX + dimOn2, centreY),
};
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
fore.allocated, back.allocated);
+ } else { // SC_MARK_FULLRECT
+ surface->FillRectangle(rcWhole, back.allocated);
}
}
// End SString functions
+bool PropSet::caseSensitiveFilenames = false;
+
PropSet::PropSet() {
superPS = 0;
for (int root = 0; root < hashRoots; root++)
VarChain(const char*var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
bool contains(const char *testVar) const {
- return (var && (0 == strcmp(var, testVar)))
+ return (var && (0 == strcmp(var, testVar)))
|| (link && link->contains(testVar));
}
return true;
}
-static bool IsSuffixCaseInsensitive(const char *target, const char *suffix) {
+static bool IsSuffix(const char *target, const char *suffix, bool caseSensitive) {
size_t lentarget = strlen(target);
size_t lensuffix = strlen(suffix);
if (lensuffix > lentarget)
return false;
+ if (caseSensitive) {
+ for (int i = static_cast<int>(lensuffix) - 1; i >= 0; i--) {
+ if (target[i + lentarget - lensuffix] != suffix[i])
+ return false;
+ }
+ } else {
for (int i = static_cast<int>(lensuffix) - 1; i >= 0; i--) {
if (MakeUpperCase(target[i + lentarget - lensuffix]) !=
MakeUpperCase(suffix[i]))
return false;
}
+ }
return true;
}
char delchr = *del;
*del = '\0';
if (*keyfile == '*') {
- if (IsSuffixCaseInsensitive(filename, keyfile + 1)) {
+ if (IsSuffix(filename, keyfile + 1, caseSensitiveFilenames)) {
*del = delchr;
delete []keyptr;
return p->val;
list = 0;
len = 0;
sorted = false;
+ sortedNoCase = false;
}
void WordList::Set(const char *s) {
list = StringDup(s);
sorted = false;
+ sortedNoCase = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
wordsNoCase = new char * [len + 1];
memcpy(wordsNoCase, words, (len + 1) * sizeof (*words));
void WordList::SetFromAllocated() {
sorted = false;
+ sortedNoCase = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
wordsNoCase = new char * [len + 1];
memcpy(wordsNoCase, words, (len + 1) * sizeof (*words));
return CompareCaseInsensitive(*(char**)(a1), *(char**)(a2));
}
-static void SortWordList(char **words, char **wordsNoCase, unsigned int len) {
+static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
cmpString);
+}
+
+static void SortWordListNoCase(char **wordsNoCase, unsigned int len) {
qsort(reinterpret_cast<void*>(wordsNoCase), len, sizeof(*wordsNoCase),
cmpStringNoCase);
}
return false;
if (!sorted) {
sorted = true;
- SortWordList(words, wordsNoCase, len);
+ 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--) {
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;
+}
+
/**
* Returns an element (complete) of the wordlist array which has
* the same beginning as the passed string.
if (0 == words)
return NULL;
- if (!sorted) {
- sorted = true;
- SortWordList(words, wordsNoCase, len);
- }
if (ignoreCase) {
+ if (!sortedNoCase) {
+ sortedNoCase = true;
+ SortWordListNoCase(wordsNoCase, len);
+ }
while (start <= end) { // binary searching loop
pivot = (start + end) >> 1;
word = wordsNoCase[pivot];
while (end < len-1 && !CompareNCaseInsensitive(wordStart, wordsNoCase[end+1], searchLen)) {
end++;
}
-
+
// Finds first word in a series of equal words
for (pivot = start; pivot <= end; pivot++) {
word = wordsNoCase[pivot];
end = pivot - 1;
}
} else { // preserve the letter case
+ if (!sorted) {
+ sorted = true;
+ SortWordList(words, len);
+ }
while (start <= end) { // binary searching loop
pivot = (start + end) >> 1;
word = words[pivot];
while (end < len-1 && !strncmp(wordStart, words[end+1], searchLen)) {
end++;
}
-
+
// Finds first word in a series of equal words
pivot = start;
while (pivot <= end) {
if (0 == words)
return NULL;
- if (!sorted) {
- sorted = true;
- SortWordList(words, wordsNoCase, len);
- }
if (ignoreCase) {
+ if (!sortedNoCase) {
+ sortedNoCase = true;
+ SortWordListNoCase(wordsNoCase, len);
+ }
while (start <= end) { // Binary searching loop
pivot = (start + end) / 2;
cond = CompareNCaseInsensitive(wordStart, wordsNoCase[pivot], searchLen);
}
}
} else { // Preserve the letter case
+ if (!sorted) {
+ sorted = true;
+ SortWordList(words, len);
+ }
while (start <= end) { // Binary searching loop
pivot = (start + end) / 2;
cond = strncmp(wordStart, words[pivot], searchLen);
class CharacterIndexer {
public:
virtual char CharAt(int index)=0;
+ virtual ~CharacterIndexer() {
+ }
};
class RESearch {
ScintillaBase::ScintillaBase() {
displayPopupMenu = true;
listType = 0;
+ maxListWidth = 0;
#ifdef SCI_LEXER
lexLanguage = SCLEX_CONTAINER;
+ performingStyle = false;
lexCurrent = 0;
for (int wl = 0;wl < numWordLists;wl++)
keyWordLists[wl] = new WordList;
return;
}
}
- ac.Start(wMain, idAutoComplete, currentPos, lenEntered, vs.lineHeight, IsUnicodeMode());
+ ac.Start(wMain, idAutoComplete, currentPos, LocationFromPosition(currentPos),
+ lenEntered, vs.lineHeight, IsUnicodeMode());
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom);
ac.lb->SetPositionRelative(rcac, wMain);
ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
- ac.lb->SetAverageCharWidth(vs.styles[STYLE_DEFAULT].aveCharWidth);
+ unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
+ ac.lb->SetAverageCharWidth(aveCharWidth);
ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
ac.SetList(list);
PRectangle rcList = ac.lb->GetDesiredRect();
int heightAlloced = rcList.bottom - rcList.top;
widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left);
+ if (maxListWidth != 0)
+ widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
// Make an allowance for large strings in list
rcList.left = pt.x - ac.lb->CaretFromEdge();
rcList.right = rcList.left + widthLB;
}
rcList.bottom = rcList.top + heightAlloced;
ac.lb->SetPositionRelative(rcList, wMain);
- ac.Show();
+ ac.Show(true);
if (lenEntered != 0) {
AutoCompleteMoveToCurrentWord();
}
selected[0] = '\0';
if (item != -1) {
ac.lb->GetValue(item, selected, sizeof(selected));
+ } else {
+ ac.Cancel();
+ return;
}
- ac.Cancel();
- if (item == -1)
+
+ ac.Show(false);
+
+ listSelected = selected;
+ SCNotification scn = {0};
+ scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
+ scn.message = 0;
+ scn.wParam = listType;
+ scn.listType = listType;
+ Position firstPos = ac.posStart - ac.startLen;
+ scn.lParam = firstPos;
+ scn.text = listSelected.c_str();
+ NotifyParent(scn);
+
+ if (!ac.Active())
return;
+ ac.Cancel();
- if (listType > 0) {
- userListSelected = selected;
- SCNotification scn;
- scn.nmhdr.code = SCN_USERLISTSELECTION;
- scn.message = 0;
- scn.wParam = listType;
- scn.listType = listType;
- scn.lParam = 0;
- scn.text = userListSelected.c_str();
- NotifyParent(scn);
+ if (listType > 0)
return;
- }
- Position firstPos = ac.posStart - ac.startLen;
Position endPos = currentPos;
if (ac.dropRestOfWord)
endPos = pdoc->ExtendWordSelect(endPos, 1, true);
}
void ScintillaBase::CallTipClick() {
- SCNotification scn;
+ SCNotification scn = {0};
scn.nmhdr.code = SCN_CALLTIPCLICK;
scn.position = ct.clickPlace;
NotifyParent(scn);
}
void ScintillaBase::Colourise(int start, int end) {
- int lengthDoc = pdoc->Length();
- if (end == -1)
- end = lengthDoc;
- int len = end - start;
-
- PLATFORM_ASSERT(len >= 0);
- PLATFORM_ASSERT(start + len <= lengthDoc);
-
- //WindowAccessor styler(wMain.GetID(), props);
- DocumentAccessor styler(pdoc, props, wMain.GetID());
-
- int styleStart = 0;
- if (start > 0)
- styleStart = styler.StyleAt(start - 1);
- styler.SetCodePage(pdoc->dbcsCodePage);
-
- if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
- lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- if (styler.GetPropertyInt("fold")) {
- lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
+ if (!performingStyle) {
+ // Protect against reentrance, which may occur, for example, when
+ // fold points are discovered while performing styling and the folding
+ // code looks for child lines which may trigger styling.
+ performingStyle = true;
+
+ int lengthDoc = pdoc->Length();
+ if (end == -1)
+ end = lengthDoc;
+ int len = end - start;
+
+ PLATFORM_ASSERT(len >= 0);
+ PLATFORM_ASSERT(start + len <= lengthDoc);
+
+ //WindowAccessor styler(wMain.GetID(), props);
+ DocumentAccessor styler(pdoc, props, wMain.GetID());
+
+ int styleStart = 0;
+ if (start > 0)
+ styleStart = styler.StyleAt(start - 1);
+ styler.SetCodePage(pdoc->dbcsCodePage);
+
+ if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
+ lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
styler.Flush();
+ if (styler.GetPropertyInt("fold")) {
+ lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
+ styler.Flush();
+ }
}
+
+ performingStyle = false;
}
}
#endif
case SCI_AUTOCGETDROPRESTOFWORD:
return ac.dropRestOfWord;
+ case SCI_AUTOCSETMAXHEIGHT:
+ ac.lb->SetVisibleRows(wParam);
+ break;
+
+ case SCI_AUTOCGETMAXHEIGHT:
+ return ac.lb->GetVisibleRows();
+
+ case SCI_AUTOCSETMAXWIDTH:
+ maxListWidth = wParam;
+ break;
+
+ case SCI_AUTOCGETMAXWIDTH:
+ return maxListWidth;
+
case SCI_REGISTERIMAGE:
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break;
return lexLanguage;
case SCI_COLOURISE:
- Colourise(wParam, lParam);
+ if (lexLanguage == SCLEX_CONTAINER) {
+ pdoc->ModifiedAt(wParam);
+ NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
+ } else {
+ Colourise(wParam, lParam);
+ }
Redraw();
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_GETPROPERTYEXPANDED: {
+ SString val = props.GetExpanded(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_GETPROPERTYINT:
+ return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
+
case SCI_SETKEYWORDS:
if (wParam < numWordLists) {
keyWordLists[wParam]->Clear();
SetLexerLanguage(reinterpret_cast<const char *>(lParam));
break;
+ case SCI_GETSTYLEBITSNEEDED:
+ return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
#endif
default:
CallTip ct;
int listType; ///< 0 is an autocomplete list
- SString userListSelected; ///< Receives listbox selected string
+ SString listSelected; ///< Receives listbox selected string
+ int maxListWidth; /// Maximum width of list, in average character widths
+
+ bool performingStyle; ///< Prevent reentrance
#ifdef SCI_LEXER
int lexLanguage;
currentPos(startPos),
atLineStart(true),
atLineEnd(false),
- state(initStyle),
+ state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
ch(0),
chNext(0) {
return currentPos - styler.GetStartSegment();
}
int GetRelative(int n) {
- return styler.SafeGetCharAt(currentPos+n);
+ return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
}
bool Match(char ch0) {
return ch == ch0;
return false;
s++;
for (int n=2; *s; n++) {
- if (*s != tolower((styler.SafeGetCharAt(currentPos+n))))
+ if (*s !=
+ tolower(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
return false;
s++;
}
height = atoi(line0);
line0 = NextField(line0);
nColours = atoi(line0);
+ line0 = NextField(line0);
+ if (atoi(line0) != 1) {
+ // Only one char per pixel is supported
+ return;
+ }
codes = new char[nColours];
colours = new ColourPair[nColours];
for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) {
set[i]->Init(textForm);
+ set[i]->CopyDesiredColours();
return;
}
}
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_AUTOCOMP_SELECTION )
}
+// Add a set of markers to a line.
+void wxStyledTextCtrl::MarkerAddSet(int line, int set) {
+ SendMsg(2466, line, set);
+}
+
// Set a margin to be either numeric or symbolic.
void wxStyledTextCtrl::SetMarginType(int margin, int marginType) {
SendMsg(2240, margin, marginType);
SendMsg(2286, separatorCharacter, 0);
}
+// Set the maximum width, in characters, of auto-completion and user lists.
+// Set to 0 to autosize to fit longest item, which is the default.
+void wxStyledTextCtrl::AutoCompSetMaxWidth(int characterCount) {
+ SendMsg(2208, characterCount, 0);
+}
+
+// Get the maximum width, in characters, of auto-completion and user lists.
+int wxStyledTextCtrl::AutoCompGetMaxWidth() {
+ return SendMsg(2209, 0, 0);
+}
+
+// Set the maximum height, in rows, of auto-completion and user lists.
+// The default is 5 rows.
+void wxStyledTextCtrl::AutoCompSetMaxHeight(int rowCount) {
+ SendMsg(2210, rowCount, 0);
+}
+
+// Set the maximum height, in rows, of auto-completion and user lists.
+int wxStyledTextCtrl::AutoCompGetMaxHeight() {
+ return SendMsg(2211, 0, 0);
+}
+
// Set the number of spaces used for one level of indentation.
void wxStyledTextCtrl::SetIndent(int indentSize) {
SendMsg(2122, indentSize, 0);
return SendMsg(2221, lineDisplay, 0);
}
+// The number of display lines needed to wrap a document line
+int wxStyledTextCtrl::WrapCount(int line) {
+ return SendMsg(2235, line, 0);
+}
+
// Set the fold level of a line.
// This encodes an integer level along with flags indicating whether the
// line is a header and whether it is effectively white space.
// Retrieve whether the maximum scroll position has the last
// line at the bottom of the view.
-int wxStyledTextCtrl::GetEndAtLastLine() {
- return SendMsg(2278, 0, 0);
+bool wxStyledTextCtrl::GetEndAtLastLine() {
+ return SendMsg(2278, 0, 0) != 0;
}
// Retrieve the height of a particular line of text in pixels.
SendMsg(2446, bytes, 0);
}
-// Find the position of a column on a line taking into account tabs and
+// Find the position of a column on a line taking into account tabs and
// multi-byte characters. If beyond end of line, return line end position.
int wxStyledTextCtrl::FindColumn(int line, int column) {
return SendMsg(2456, line, column);
}
+// Can the caret preferred x position only be changed by explicit movement commands?
+bool wxStyledTextCtrl::GetCaretSticky() {
+ return SendMsg(2457, 0, 0) != 0;
+}
+
+// Stop the caret preferred x position changing when the user types.
+void wxStyledTextCtrl::SetCaretSticky(bool useCaretStickyBehaviour) {
+ SendMsg(2458, useCaretStickyBehaviour, 0);
+}
+
+// Switch between sticky and non-sticky: meant to be bound to a key.
+void wxStyledTextCtrl::ToggleCaretSticky() {
+ SendMsg(2459, 0, 0);
+}
+
+// Enable/Disable convert-on-paste for line endings
+void wxStyledTextCtrl::SetPasteConvertEndings(bool convert) {
+ SendMsg(2467, convert, 0);
+}
+
+// Get convert-on-paste setting
+bool wxStyledTextCtrl::GetPasteConvertEndings() {
+ return SendMsg(2468, 0, 0) != 0;
+}
+
+// Duplicate the selection. If selection empty duplicate the line containing the caret.
+void wxStyledTextCtrl::SelectionDuplicate() {
+ SendMsg(2469, 0, 0);
+}
+
// Start notifying the container of all key presses and commands.
void wxStyledTextCtrl::StartRecord() {
SendMsg(3001, 0, 0);
SendMsg(4006, 0, (long)(const char*)wx2stc(language));
}
+// Retrieve a 'property' value previously set with SetProperty.
+wxString wxStyledTextCtrl::GetProperty(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTY, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(4008, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);
+}
+
+// Retrieve a 'property' value previously set with SetProperty,
+// with '$()' variable replacement on returned buffer.
+wxString wxStyledTextCtrl::GetPropertyExpanded(const wxString& key) {
+ int len = SendMsg(SCI_GETPROPERTYEXPANDED, (long)(const char*)wx2stc(key), NULL);
+ if (!len) return wxEmptyString;
+
+ wxMemoryBuffer mbuf(len+1);
+ char* buf = (char*)mbuf.GetWriteBuf(len+1);
+ SendMsg(4009, (long)(const char*)wx2stc(key), (long)buf);
+ mbuf.UngetWriteBuf(len);
+ mbuf.AppendByte(0);
+ return stc2wx(buf);
+}
+
+// Retrieve a 'property' value previously set with SetProperty,
+// interpreted as an int AFTER any '$()' variable replacement.
+int wxStyledTextCtrl::GetPropertyInt(const wxString& key) {
+ return SendMsg(4010, (long)(const char*)wx2stc(key), 0);
+}
+
+// Retrieve the number of bits the current lexer needs for styling.
+int wxStyledTextCtrl::GetStyleBitsNeeded() {
+ return SendMsg(4011, 0, 0);
+}
+
// END of generated section
//----------------------------------------------------------------------
case wxSTC_CHARSET_THAI:
encoding = wxFONTENCODING_ISO8859_11;
break;
+
+ case wxSTC_CHARSET_CYRILLIC:
+ encoding = wxFONTENCODING_ISO8859_5;
+ break;
+
+ case wxSTC_CHARSET_8859_15:
+ encoding = wxFONTENCODING_ISO8859_15;;
+ break;
}
// We just have Scintilla track the wxFontEncoding for us. It gets used
evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
break;
+ case SCN_AUTOCSELECTION:
+ evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION);
+ break;
+
default:
return;
}
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_CLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_HOTSPOT_DCLICK )
DEFINE_EVENT_TYPE( wxEVT_STC_CALLTIP_CLICK )
+DEFINE_EVENT_TYPE( wxEVT_STC_AUTOCOMP_SELECTION )
case wxSTC_CHARSET_THAI:
encoding = wxFONTENCODING_ISO8859_11;
break;
+
+ case wxSTC_CHARSET_CYRILLIC:
+ encoding = wxFONTENCODING_ISO8859_5;
+ break;
+
+ case wxSTC_CHARSET_8859_15:
+ encoding = wxFONTENCODING_ISO8859_15;;
+ break;
}
// We just have Scintilla track the wxFontEncoding for us. It gets used
evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
break;
+ case SCN_AUTOCSELECTION:
+ evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION);
+ break;
+
default:
return;
}
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_CLICK, 1673)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_HOTSPOT_DCLICK, 1674)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_CALLTIP_CLICK, 1675)
+ DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_STC, wxEVT_STC_AUTOCOMP_SELECTION, 1676)
END_DECLARE_EVENT_TYPES()
#else
enum {
wxEVT_STC_ZOOM,
wxEVT_STC_HOTSPOT_CLICK,
wxEVT_STC_HOTSPOT_DCLICK,
- wxEVT_STC_CALLTIP_CLICK
+ wxEVT_STC_CALLTIP_CLICK,
+ wxEVT_STC_AUTOCOMP_SELECTION
};
#endif
#define EVT_STC_HOTSPOT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_CLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_HOTSPOT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_HOTSPOT_DCLICK, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#define EVT_STC_CALLTIP_CLICK(id, fn)) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_CALLTIP_CLICK id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
-
+#define EVT_STC_AUTOCOMP_SELECTION(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_STC_AUTOCOMP_SELECTION id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxStyledTextEventFunction, & fn ), (wxObject *) NULL ),
#endif
//----------------------------------------------------------------------
#ifndef SWIG
#if wxUSE_UNICODE
-wxString stc2wx(const char* str);
-wxString stc2wx(const char* str, size_t len);
-const wxWX2MBbuf wx2stc(const wxString& str);
+WXDLLIMPEXP_STC wxString stc2wx(const char* str);
+WXDLLIMPEXP_STC wxString stc2wx(const char* str, size_t len);
+WXDLLIMPEXP_STC const wxWX2MBbuf wx2stc(const wxString& str);
#else // not UNICODE
DocStr(wxStyledTextCtrl::MarkerDefineBitmap,
"Define a marker from a bitmap", "");
+DocStr(wxStyledTextCtrl::MarkerAddSet,
+"Add a set of markers to a line.", "");
+
DocStr(wxStyledTextCtrl::SetMarginType,
"Set a margin to be either numeric or symbolic.", "");
"Change the type-separator character in the string setting up an auto-completion list.
Default is '?' but can be changed if items contain '?'.", "");
+DocStr(wxStyledTextCtrl::AutoCompSetMaxWidth,
+"Set the maximum width, in characters, of auto-completion and user lists.
+Set to 0 to autosize to fit longest item, which is the default.", "");
+
+DocStr(wxStyledTextCtrl::AutoCompGetMaxWidth,
+"Get the maximum width, in characters, of auto-completion and user lists.", "");
+
+DocStr(wxStyledTextCtrl::AutoCompSetMaxHeight,
+"Set the maximum height, in rows, of auto-completion and user lists.
+The default is 5 rows.", "");
+
+DocStr(wxStyledTextCtrl::AutoCompGetMaxHeight,
+"Set the maximum height, in rows, of auto-completion and user lists.", "");
+
DocStr(wxStyledTextCtrl::SetIndent,
"Set the number of spaces used for one level of indentation.", "");
DocStr(wxStyledTextCtrl::DocLineFromVisible,
"Find the document line of a display line taking hidden lines into account.", "");
+DocStr(wxStyledTextCtrl::WrapCount,
+"The number of display lines needed to wrap a document line", "");
+
DocStr(wxStyledTextCtrl::SetFoldLevel,
"Set the fold level of a line.
This encodes an integer level along with flags indicating whether the
"Enlarge the document to a particular size of text bytes.", "");
DocStr(wxStyledTextCtrl::FindColumn,
-"Find the position of a column on a line taking into account tabs and
+"Find the position of a column on a line taking into account tabs and
multi-byte characters. If beyond end of line, return line end position.", "");
+DocStr(wxStyledTextCtrl::GetCaretSticky,
+"Can the caret preferred x position only be changed by explicit movement commands?", "");
+
+DocStr(wxStyledTextCtrl::SetCaretSticky,
+"Stop the caret preferred x position changing when the user types.", "");
+
+DocStr(wxStyledTextCtrl::ToggleCaretSticky,
+"Switch between sticky and non-sticky: meant to be bound to a key.", "");
+
+DocStr(wxStyledTextCtrl::SetPasteConvertEndings,
+"Enable/Disable convert-on-paste for line endings", "");
+
+DocStr(wxStyledTextCtrl::GetPasteConvertEndings,
+"Get convert-on-paste setting", "");
+
+DocStr(wxStyledTextCtrl::SelectionDuplicate,
+"Duplicate the selection. If selection empty duplicate the line containing the caret.", "");
+
DocStr(wxStyledTextCtrl::StartRecord,
"Start notifying the container of all key presses and commands.", "");
DocStr(wxStyledTextCtrl::SetLexerLanguage,
"Set the lexing language of the document based on string name.", "");
+
+DocStr(wxStyledTextCtrl::GetProperty,
+"Retrieve a 'property' value previously set with SetProperty.", "");
+
+DocStr(wxStyledTextCtrl::GetPropertyExpanded,
+"Retrieve a 'property' value previously set with SetProperty,
+with '$()' variable replacement on returned buffer.", "");
+
+DocStr(wxStyledTextCtrl::GetPropertyInt,
+"Retrieve a 'property' value previously set with SetProperty,
+interpreted as an int AFTER any '$()' variable replacement.", "");
+
+DocStr(wxStyledTextCtrl::GetStyleBitsNeeded,
+"Retrieve the number of bits the current lexer needs for styling.", "");
%rename(STC_MARK_DOTDOTDOT) wxSTC_MARK_DOTDOTDOT;
%rename(STC_MARK_ARROWS) wxSTC_MARK_ARROWS;
%rename(STC_MARK_PIXMAP) wxSTC_MARK_PIXMAP;
+%rename(STC_MARK_FULLRECT) wxSTC_MARK_FULLRECT;
%rename(STC_MARK_CHARACTER) wxSTC_MARK_CHARACTER;
%rename(STC_MARKNUM_FOLDEREND) wxSTC_MARKNUM_FOLDEREND;
%rename(STC_MARKNUM_FOLDEROPENMID) wxSTC_MARKNUM_FOLDEROPENMID;
%rename(STC_CHARSET_MAC) wxSTC_CHARSET_MAC;
%rename(STC_CHARSET_OEM) wxSTC_CHARSET_OEM;
%rename(STC_CHARSET_RUSSIAN) wxSTC_CHARSET_RUSSIAN;
+%rename(STC_CHARSET_CYRILLIC) wxSTC_CHARSET_CYRILLIC;
%rename(STC_CHARSET_SHIFTJIS) wxSTC_CHARSET_SHIFTJIS;
%rename(STC_CHARSET_SYMBOL) wxSTC_CHARSET_SYMBOL;
%rename(STC_CHARSET_TURKISH) wxSTC_CHARSET_TURKISH;
%rename(STC_CHARSET_ARABIC) wxSTC_CHARSET_ARABIC;
%rename(STC_CHARSET_VIETNAMESE) wxSTC_CHARSET_VIETNAMESE;
%rename(STC_CHARSET_THAI) wxSTC_CHARSET_THAI;
+%rename(STC_CHARSET_8859_15) wxSTC_CHARSET_8859_15;
%rename(STC_CASE_MIXED) wxSTC_CASE_MIXED;
%rename(STC_CASE_UPPER) wxSTC_CASE_UPPER;
%rename(STC_CASE_LOWER) wxSTC_CASE_LOWER;
%rename(STC_TIME_FOREVER) wxSTC_TIME_FOREVER;
%rename(STC_WRAP_NONE) wxSTC_WRAP_NONE;
%rename(STC_WRAP_WORD) wxSTC_WRAP_WORD;
+%rename(STC_WRAP_CHAR) wxSTC_WRAP_CHAR;
%rename(STC_WRAPVISUALFLAG_NONE) wxSTC_WRAPVISUALFLAG_NONE;
%rename(STC_WRAPVISUALFLAG_END) wxSTC_WRAPVISUALFLAG_END;
%rename(STC_WRAPVISUALFLAG_START) wxSTC_WRAPVISUALFLAG_START;
%rename(STC_PERFORMED_USER) wxSTC_PERFORMED_USER;
%rename(STC_PERFORMED_UNDO) wxSTC_PERFORMED_UNDO;
%rename(STC_PERFORMED_REDO) wxSTC_PERFORMED_REDO;
+%rename(STC_MULTISTEPUNDOREDO) wxSTC_MULTISTEPUNDOREDO;
%rename(STC_LASTSTEPINUNDOREDO) wxSTC_LASTSTEPINUNDOREDO;
%rename(STC_MOD_CHANGEMARKER) wxSTC_MOD_CHANGEMARKER;
%rename(STC_MOD_BEFOREINSERT) wxSTC_MOD_BEFOREINSERT;
%rename(STC_MOD_BEFOREDELETE) wxSTC_MOD_BEFOREDELETE;
+%rename(STC_MULTILINEUNDOREDO) wxSTC_MULTILINEUNDOREDO;
%rename(STC_MODEVENTMASKALL) wxSTC_MODEVENTMASKALL;
%rename(STC_KEY_DOWN) wxSTC_KEY_DOWN;
%rename(STC_KEY_UP) wxSTC_KEY_UP;
%rename(STC_KEY_ADD) wxSTC_KEY_ADD;
%rename(STC_KEY_SUBTRACT) wxSTC_KEY_SUBTRACT;
%rename(STC_KEY_DIVIDE) wxSTC_KEY_DIVIDE;
+%rename(STC_SCMOD_NORM) wxSTC_SCMOD_NORM;
%rename(STC_SCMOD_SHIFT) wxSTC_SCMOD_SHIFT;
%rename(STC_SCMOD_CTRL) wxSTC_SCMOD_CTRL;
%rename(STC_SCMOD_ALT) wxSTC_SCMOD_ALT;
%rename(STC_LEX_NNCRONTAB) wxSTC_LEX_NNCRONTAB;
%rename(STC_LEX_BULLANT) wxSTC_LEX_BULLANT;
%rename(STC_LEX_VBSCRIPT) wxSTC_LEX_VBSCRIPT;
-%rename(STC_LEX_ASP) wxSTC_LEX_ASP;
-%rename(STC_LEX_PHP) wxSTC_LEX_PHP;
%rename(STC_LEX_BAAN) wxSTC_LEX_BAAN;
%rename(STC_LEX_MATLAB) wxSTC_LEX_MATLAB;
%rename(STC_LEX_SCRIPTOL) wxSTC_LEX_SCRIPTOL;
%rename(STC_LEX_BASH) wxSTC_LEX_BASH;
%rename(STC_LEX_ASN1) wxSTC_LEX_ASN1;
%rename(STC_LEX_VHDL) wxSTC_LEX_VHDL;
+%rename(STC_LEX_CAML) wxSTC_LEX_CAML;
+%rename(STC_LEX_BLITZBASIC) wxSTC_LEX_BLITZBASIC;
+%rename(STC_LEX_PUREBASIC) wxSTC_LEX_PUREBASIC;
+%rename(STC_LEX_HASKELL) wxSTC_LEX_HASKELL;
+%rename(STC_LEX_PHPSCRIPT) wxSTC_LEX_PHPSCRIPT;
+%rename(STC_LEX_TADS3) wxSTC_LEX_TADS3;
+%rename(STC_LEX_REBOL) wxSTC_LEX_REBOL;
+%rename(STC_LEX_SMALLTALK) wxSTC_LEX_SMALLTALK;
+%rename(STC_LEX_FLAGSHIP) wxSTC_LEX_FLAGSHIP;
+%rename(STC_LEX_CSOUND) wxSTC_LEX_CSOUND;
+%rename(STC_LEX_FREEBASIC) wxSTC_LEX_FREEBASIC;
%rename(STC_LEX_AUTOMATIC) wxSTC_LEX_AUTOMATIC;
%rename(STC_P_DEFAULT) wxSTC_P_DEFAULT;
%rename(STC_P_COMMENTLINE) wxSTC_P_COMMENTLINE;
%rename(STC_P_IDENTIFIER) wxSTC_P_IDENTIFIER;
%rename(STC_P_COMMENTBLOCK) wxSTC_P_COMMENTBLOCK;
%rename(STC_P_STRINGEOL) wxSTC_P_STRINGEOL;
+%rename(STC_P_WORD2) wxSTC_P_WORD2;
+%rename(STC_P_DECORATOR) wxSTC_P_DECORATOR;
%rename(STC_C_DEFAULT) wxSTC_C_DEFAULT;
%rename(STC_C_COMMENT) wxSTC_C_COMMENT;
%rename(STC_C_COMMENTLINE) wxSTC_C_COMMENTLINE;
%rename(STC_PL_ARRAY) wxSTC_PL_ARRAY;
%rename(STC_PL_HASH) wxSTC_PL_HASH;
%rename(STC_PL_SYMBOLTABLE) wxSTC_PL_SYMBOLTABLE;
+%rename(STC_PL_VARIABLE_INDEXER) wxSTC_PL_VARIABLE_INDEXER;
%rename(STC_PL_REGEX) wxSTC_PL_REGEX;
%rename(STC_PL_REGSUBST) wxSTC_PL_REGSUBST;
%rename(STC_PL_LONGQUOTE) wxSTC_PL_LONGQUOTE;
%rename(STC_PL_STRING_QX) wxSTC_PL_STRING_QX;
%rename(STC_PL_STRING_QR) wxSTC_PL_STRING_QR;
%rename(STC_PL_STRING_QW) wxSTC_PL_STRING_QW;
+%rename(STC_PL_POD_VERB) wxSTC_PL_POD_VERB;
+%rename(STC_RB_DEFAULT) wxSTC_RB_DEFAULT;
+%rename(STC_RB_ERROR) wxSTC_RB_ERROR;
+%rename(STC_RB_COMMENTLINE) wxSTC_RB_COMMENTLINE;
+%rename(STC_RB_POD) wxSTC_RB_POD;
+%rename(STC_RB_NUMBER) wxSTC_RB_NUMBER;
+%rename(STC_RB_WORD) wxSTC_RB_WORD;
+%rename(STC_RB_STRING) wxSTC_RB_STRING;
+%rename(STC_RB_CHARACTER) wxSTC_RB_CHARACTER;
+%rename(STC_RB_CLASSNAME) wxSTC_RB_CLASSNAME;
+%rename(STC_RB_DEFNAME) wxSTC_RB_DEFNAME;
+%rename(STC_RB_OPERATOR) wxSTC_RB_OPERATOR;
+%rename(STC_RB_IDENTIFIER) wxSTC_RB_IDENTIFIER;
+%rename(STC_RB_REGEX) wxSTC_RB_REGEX;
+%rename(STC_RB_GLOBAL) wxSTC_RB_GLOBAL;
+%rename(STC_RB_SYMBOL) wxSTC_RB_SYMBOL;
+%rename(STC_RB_MODULE_NAME) wxSTC_RB_MODULE_NAME;
+%rename(STC_RB_INSTANCE_VAR) wxSTC_RB_INSTANCE_VAR;
+%rename(STC_RB_CLASS_VAR) wxSTC_RB_CLASS_VAR;
+%rename(STC_RB_BACKTICKS) wxSTC_RB_BACKTICKS;
+%rename(STC_RB_DATASECTION) wxSTC_RB_DATASECTION;
+%rename(STC_RB_HERE_DELIM) wxSTC_RB_HERE_DELIM;
+%rename(STC_RB_HERE_Q) wxSTC_RB_HERE_Q;
+%rename(STC_RB_HERE_QQ) wxSTC_RB_HERE_QQ;
+%rename(STC_RB_HERE_QX) wxSTC_RB_HERE_QX;
+%rename(STC_RB_STRING_Q) wxSTC_RB_STRING_Q;
+%rename(STC_RB_STRING_QQ) wxSTC_RB_STRING_QQ;
+%rename(STC_RB_STRING_QX) wxSTC_RB_STRING_QX;
+%rename(STC_RB_STRING_QR) wxSTC_RB_STRING_QR;
+%rename(STC_RB_STRING_QW) wxSTC_RB_STRING_QW;
+%rename(STC_RB_WORD_DEMOTED) wxSTC_RB_WORD_DEMOTED;
+%rename(STC_RB_STDIN) wxSTC_RB_STDIN;
+%rename(STC_RB_STDOUT) wxSTC_RB_STDOUT;
+%rename(STC_RB_STDERR) wxSTC_RB_STDERR;
+%rename(STC_RB_UPPER_BOUND) wxSTC_RB_UPPER_BOUND;
%rename(STC_B_DEFAULT) wxSTC_B_DEFAULT;
%rename(STC_B_COMMENT) wxSTC_B_COMMENT;
%rename(STC_B_NUMBER) wxSTC_B_NUMBER;
%rename(STC_B_KEYWORD4) wxSTC_B_KEYWORD4;
%rename(STC_B_CONSTANT) wxSTC_B_CONSTANT;
%rename(STC_B_ASM) wxSTC_B_ASM;
+%rename(STC_B_LABEL) wxSTC_B_LABEL;
+%rename(STC_B_ERROR) wxSTC_B_ERROR;
+%rename(STC_B_HEXNUMBER) wxSTC_B_HEXNUMBER;
+%rename(STC_B_BINNUMBER) wxSTC_B_BINNUMBER;
%rename(STC_PROPS_DEFAULT) wxSTC_PROPS_DEFAULT;
%rename(STC_PROPS_COMMENT) wxSTC_PROPS_COMMENT;
%rename(STC_PROPS_SECTION) wxSTC_PROPS_SECTION;
%rename(STC_LISP_COMMENT) wxSTC_LISP_COMMENT;
%rename(STC_LISP_NUMBER) wxSTC_LISP_NUMBER;
%rename(STC_LISP_KEYWORD) wxSTC_LISP_KEYWORD;
+%rename(STC_LISP_KEYWORD_KW) wxSTC_LISP_KEYWORD_KW;
+%rename(STC_LISP_SYMBOL) wxSTC_LISP_SYMBOL;
%rename(STC_LISP_STRING) wxSTC_LISP_STRING;
%rename(STC_LISP_STRINGEOL) wxSTC_LISP_STRINGEOL;
%rename(STC_LISP_IDENTIFIER) wxSTC_LISP_IDENTIFIER;
%rename(STC_LISP_OPERATOR) wxSTC_LISP_OPERATOR;
+%rename(STC_LISP_SPECIAL) wxSTC_LISP_SPECIAL;
+%rename(STC_LISP_MULTI_COMMENT) wxSTC_LISP_MULTI_COMMENT;
%rename(STC_EIFFEL_DEFAULT) wxSTC_EIFFEL_DEFAULT;
%rename(STC_EIFFEL_COMMENTLINE) wxSTC_EIFFEL_COMMENTLINE;
%rename(STC_EIFFEL_NUMBER) wxSTC_EIFFEL_NUMBER;
%rename(STC_CSS_DOUBLESTRING) wxSTC_CSS_DOUBLESTRING;
%rename(STC_CSS_SINGLESTRING) wxSTC_CSS_SINGLESTRING;
%rename(STC_CSS_IDENTIFIER2) wxSTC_CSS_IDENTIFIER2;
+%rename(STC_CSS_ATTRIBUTE) wxSTC_CSS_ATTRIBUTE;
%rename(STC_POV_DEFAULT) wxSTC_POV_DEFAULT;
%rename(STC_POV_COMMENT) wxSTC_POV_COMMENT;
%rename(STC_POV_COMMENTLINE) wxSTC_POV_COMMENTLINE;
%rename(STC_NSIS_MACRODEF) wxSTC_NSIS_MACRODEF;
%rename(STC_NSIS_STRINGVAR) wxSTC_NSIS_STRINGVAR;
%rename(STC_NSIS_NUMBER) wxSTC_NSIS_NUMBER;
+%rename(STC_NSIS_SECTIONGROUP) wxSTC_NSIS_SECTIONGROUP;
+%rename(STC_NSIS_PAGEEX) wxSTC_NSIS_PAGEEX;
+%rename(STC_NSIS_FUNCTIONDEF) wxSTC_NSIS_FUNCTIONDEF;
+%rename(STC_NSIS_COMMENTBOX) wxSTC_NSIS_COMMENTBOX;
%rename(STC_MMIXAL_LEADWS) wxSTC_MMIXAL_LEADWS;
%rename(STC_MMIXAL_COMMENT) wxSTC_MMIXAL_COMMENT;
%rename(STC_MMIXAL_LABEL) wxSTC_MMIXAL_LABEL;
%rename(STC_CLW_PICTURE_STRING) wxSTC_CLW_PICTURE_STRING;
%rename(STC_CLW_KEYWORD) wxSTC_CLW_KEYWORD;
%rename(STC_CLW_COMPILER_DIRECTIVE) wxSTC_CLW_COMPILER_DIRECTIVE;
+%rename(STC_CLW_RUNTIME_EXPRESSIONS) wxSTC_CLW_RUNTIME_EXPRESSIONS;
%rename(STC_CLW_BUILTIN_PROCEDURES_FUNCTION) wxSTC_CLW_BUILTIN_PROCEDURES_FUNCTION;
%rename(STC_CLW_STRUCTURE_DATA_TYPE) wxSTC_CLW_STRUCTURE_DATA_TYPE;
%rename(STC_CLW_ATTRIBUTE) wxSTC_CLW_ATTRIBUTE;
%rename(STC_CLW_STANDARD_EQUATE) wxSTC_CLW_STANDARD_EQUATE;
%rename(STC_CLW_ERROR) wxSTC_CLW_ERROR;
+%rename(STC_CLW_DEPRECATED) wxSTC_CLW_DEPRECATED;
%rename(STC_LOT_DEFAULT) wxSTC_LOT_DEFAULT;
%rename(STC_LOT_HEADER) wxSTC_LOT_HEADER;
%rename(STC_LOT_BREAK) wxSTC_LOT_BREAK;
%rename(STC_AU3_SENT) wxSTC_AU3_SENT;
%rename(STC_AU3_PREPROCESSOR) wxSTC_AU3_PREPROCESSOR;
%rename(STC_AU3_SPECIAL) wxSTC_AU3_SPECIAL;
+%rename(STC_AU3_EXPAND) wxSTC_AU3_EXPAND;
+%rename(STC_AU3_COMOBJ) wxSTC_AU3_COMOBJ;
%rename(STC_APDL_DEFAULT) wxSTC_APDL_DEFAULT;
%rename(STC_APDL_COMMENT) wxSTC_APDL_COMMENT;
%rename(STC_APDL_COMMENTBLOCK) wxSTC_APDL_COMMENTBLOCK;
%rename(STC_VHDL_STDPACKAGE) wxSTC_VHDL_STDPACKAGE;
%rename(STC_VHDL_STDTYPE) wxSTC_VHDL_STDTYPE;
%rename(STC_VHDL_USERWORD) wxSTC_VHDL_USERWORD;
+%rename(STC_CAML_DEFAULT) wxSTC_CAML_DEFAULT;
+%rename(STC_CAML_IDENTIFIER) wxSTC_CAML_IDENTIFIER;
+%rename(STC_CAML_TAGNAME) wxSTC_CAML_TAGNAME;
+%rename(STC_CAML_KEYWORD) wxSTC_CAML_KEYWORD;
+%rename(STC_CAML_KEYWORD2) wxSTC_CAML_KEYWORD2;
+%rename(STC_CAML_KEYWORD3) wxSTC_CAML_KEYWORD3;
+%rename(STC_CAML_LINENUM) wxSTC_CAML_LINENUM;
+%rename(STC_CAML_OPERATOR) wxSTC_CAML_OPERATOR;
+%rename(STC_CAML_NUMBER) wxSTC_CAML_NUMBER;
+%rename(STC_CAML_CHAR) wxSTC_CAML_CHAR;
+%rename(STC_CAML_STRING) wxSTC_CAML_STRING;
+%rename(STC_CAML_COMMENT) wxSTC_CAML_COMMENT;
+%rename(STC_CAML_COMMENT1) wxSTC_CAML_COMMENT1;
+%rename(STC_CAML_COMMENT2) wxSTC_CAML_COMMENT2;
+%rename(STC_CAML_COMMENT3) wxSTC_CAML_COMMENT3;
+%rename(STC_HA_DEFAULT) wxSTC_HA_DEFAULT;
+%rename(STC_HA_IDENTIFIER) wxSTC_HA_IDENTIFIER;
+%rename(STC_HA_KEYWORD) wxSTC_HA_KEYWORD;
+%rename(STC_HA_NUMBER) wxSTC_HA_NUMBER;
+%rename(STC_HA_STRING) wxSTC_HA_STRING;
+%rename(STC_HA_CHARACTER) wxSTC_HA_CHARACTER;
+%rename(STC_HA_CLASS) wxSTC_HA_CLASS;
+%rename(STC_HA_MODULE) wxSTC_HA_MODULE;
+%rename(STC_HA_CAPITAL) wxSTC_HA_CAPITAL;
+%rename(STC_HA_DATA) wxSTC_HA_DATA;
+%rename(STC_HA_IMPORT) wxSTC_HA_IMPORT;
+%rename(STC_HA_OPERATOR) wxSTC_HA_OPERATOR;
+%rename(STC_HA_INSTANCE) wxSTC_HA_INSTANCE;
+%rename(STC_HA_COMMENTLINE) wxSTC_HA_COMMENTLINE;
+%rename(STC_HA_COMMENTBLOCK) wxSTC_HA_COMMENTBLOCK;
+%rename(STC_HA_COMMENTBLOCK2) wxSTC_HA_COMMENTBLOCK2;
+%rename(STC_HA_COMMENTBLOCK3) wxSTC_HA_COMMENTBLOCK3;
+%rename(STC_T3_DEFAULT) wxSTC_T3_DEFAULT;
+%rename(STC_T3_X_DEFAULT) wxSTC_T3_X_DEFAULT;
+%rename(STC_T3_PREPROCESSOR) wxSTC_T3_PREPROCESSOR;
+%rename(STC_T3_BLOCK_COMMENT) wxSTC_T3_BLOCK_COMMENT;
+%rename(STC_T3_LINE_COMMENT) wxSTC_T3_LINE_COMMENT;
+%rename(STC_T3_OPERATOR) wxSTC_T3_OPERATOR;
+%rename(STC_T3_KEYWORD) wxSTC_T3_KEYWORD;
+%rename(STC_T3_NUMBER) wxSTC_T3_NUMBER;
+%rename(STC_T3_IDENTIFIER) wxSTC_T3_IDENTIFIER;
+%rename(STC_T3_S_STRING) wxSTC_T3_S_STRING;
+%rename(STC_T3_D_STRING) wxSTC_T3_D_STRING;
+%rename(STC_T3_X_STRING) wxSTC_T3_X_STRING;
+%rename(STC_T3_LIB_DIRECTIVE) wxSTC_T3_LIB_DIRECTIVE;
+%rename(STC_T3_MSG_PARAM) wxSTC_T3_MSG_PARAM;
+%rename(STC_T3_HTML_TAG) wxSTC_T3_HTML_TAG;
+%rename(STC_T3_HTML_DEFAULT) wxSTC_T3_HTML_DEFAULT;
+%rename(STC_T3_HTML_STRING) wxSTC_T3_HTML_STRING;
+%rename(STC_T3_USER1) wxSTC_T3_USER1;
+%rename(STC_T3_USER2) wxSTC_T3_USER2;
+%rename(STC_T3_USER3) wxSTC_T3_USER3;
+%rename(STC_REBOL_DEFAULT) wxSTC_REBOL_DEFAULT;
+%rename(STC_REBOL_COMMENTLINE) wxSTC_REBOL_COMMENTLINE;
+%rename(STC_REBOL_COMMENTBLOCK) wxSTC_REBOL_COMMENTBLOCK;
+%rename(STC_REBOL_PREFACE) wxSTC_REBOL_PREFACE;
+%rename(STC_REBOL_OPERATOR) wxSTC_REBOL_OPERATOR;
+%rename(STC_REBOL_CHARACTER) wxSTC_REBOL_CHARACTER;
+%rename(STC_REBOL_QUOTEDSTRING) wxSTC_REBOL_QUOTEDSTRING;
+%rename(STC_REBOL_BRACEDSTRING) wxSTC_REBOL_BRACEDSTRING;
+%rename(STC_REBOL_NUMBER) wxSTC_REBOL_NUMBER;
+%rename(STC_REBOL_PAIR) wxSTC_REBOL_PAIR;
+%rename(STC_REBOL_TUPLE) wxSTC_REBOL_TUPLE;
+%rename(STC_REBOL_BINARY) wxSTC_REBOL_BINARY;
+%rename(STC_REBOL_MONEY) wxSTC_REBOL_MONEY;
+%rename(STC_REBOL_ISSUE) wxSTC_REBOL_ISSUE;
+%rename(STC_REBOL_TAG) wxSTC_REBOL_TAG;
+%rename(STC_REBOL_FILE) wxSTC_REBOL_FILE;
+%rename(STC_REBOL_EMAIL) wxSTC_REBOL_EMAIL;
+%rename(STC_REBOL_URL) wxSTC_REBOL_URL;
+%rename(STC_REBOL_DATE) wxSTC_REBOL_DATE;
+%rename(STC_REBOL_TIME) wxSTC_REBOL_TIME;
+%rename(STC_REBOL_IDENTIFIER) wxSTC_REBOL_IDENTIFIER;
+%rename(STC_REBOL_WORD) wxSTC_REBOL_WORD;
+%rename(STC_REBOL_WORD2) wxSTC_REBOL_WORD2;
+%rename(STC_REBOL_WORD3) wxSTC_REBOL_WORD3;
+%rename(STC_REBOL_WORD4) wxSTC_REBOL_WORD4;
+%rename(STC_REBOL_WORD5) wxSTC_REBOL_WORD5;
+%rename(STC_REBOL_WORD6) wxSTC_REBOL_WORD6;
+%rename(STC_REBOL_WORD7) wxSTC_REBOL_WORD7;
+%rename(STC_REBOL_WORD8) wxSTC_REBOL_WORD8;
+%rename(STC_SQL_DEFAULT) wxSTC_SQL_DEFAULT;
+%rename(STC_SQL_COMMENT) wxSTC_SQL_COMMENT;
+%rename(STC_SQL_COMMENTLINE) wxSTC_SQL_COMMENTLINE;
+%rename(STC_SQL_COMMENTDOC) wxSTC_SQL_COMMENTDOC;
+%rename(STC_SQL_NUMBER) wxSTC_SQL_NUMBER;
+%rename(STC_SQL_WORD) wxSTC_SQL_WORD;
+%rename(STC_SQL_STRING) wxSTC_SQL_STRING;
+%rename(STC_SQL_CHARACTER) wxSTC_SQL_CHARACTER;
+%rename(STC_SQL_SQLPLUS) wxSTC_SQL_SQLPLUS;
+%rename(STC_SQL_SQLPLUS_PROMPT) wxSTC_SQL_SQLPLUS_PROMPT;
+%rename(STC_SQL_OPERATOR) wxSTC_SQL_OPERATOR;
+%rename(STC_SQL_IDENTIFIER) wxSTC_SQL_IDENTIFIER;
+%rename(STC_SQL_SQLPLUS_COMMENT) wxSTC_SQL_SQLPLUS_COMMENT;
+%rename(STC_SQL_COMMENTLINEDOC) wxSTC_SQL_COMMENTLINEDOC;
+%rename(STC_SQL_WORD2) wxSTC_SQL_WORD2;
+%rename(STC_SQL_COMMENTDOCKEYWORD) wxSTC_SQL_COMMENTDOCKEYWORD;
+%rename(STC_SQL_COMMENTDOCKEYWORDERROR) wxSTC_SQL_COMMENTDOCKEYWORDERROR;
+%rename(STC_SQL_USER1) wxSTC_SQL_USER1;
+%rename(STC_SQL_USER2) wxSTC_SQL_USER2;
+%rename(STC_SQL_USER3) wxSTC_SQL_USER3;
+%rename(STC_SQL_USER4) wxSTC_SQL_USER4;
+%rename(STC_SQL_QUOTEDIDENTIFIER) wxSTC_SQL_QUOTEDIDENTIFIER;
+%rename(STC_ST_DEFAULT) wxSTC_ST_DEFAULT;
+%rename(STC_ST_STRING) wxSTC_ST_STRING;
+%rename(STC_ST_NUMBER) wxSTC_ST_NUMBER;
+%rename(STC_ST_COMMENT) wxSTC_ST_COMMENT;
+%rename(STC_ST_SYMBOL) wxSTC_ST_SYMBOL;
+%rename(STC_ST_BINARY) wxSTC_ST_BINARY;
+%rename(STC_ST_BOOL) wxSTC_ST_BOOL;
+%rename(STC_ST_SELF) wxSTC_ST_SELF;
+%rename(STC_ST_SUPER) wxSTC_ST_SUPER;
+%rename(STC_ST_NIL) wxSTC_ST_NIL;
+%rename(STC_ST_GLOBAL) wxSTC_ST_GLOBAL;
+%rename(STC_ST_RETURN) wxSTC_ST_RETURN;
+%rename(STC_ST_SPECIAL) wxSTC_ST_SPECIAL;
+%rename(STC_ST_KWSEND) wxSTC_ST_KWSEND;
+%rename(STC_ST_ASSIGN) wxSTC_ST_ASSIGN;
+%rename(STC_ST_CHARACTER) wxSTC_ST_CHARACTER;
+%rename(STC_ST_SPEC_SEL) wxSTC_ST_SPEC_SEL;
+%rename(STC_FS_DEFAULT) wxSTC_FS_DEFAULT;
+%rename(STC_FS_COMMENT) wxSTC_FS_COMMENT;
+%rename(STC_FS_COMMENTLINE) wxSTC_FS_COMMENTLINE;
+%rename(STC_FS_COMMENTDOC) wxSTC_FS_COMMENTDOC;
+%rename(STC_FS_COMMENTLINEDOC) wxSTC_FS_COMMENTLINEDOC;
+%rename(STC_FS_COMMENTDOCKEYWORD) wxSTC_FS_COMMENTDOCKEYWORD;
+%rename(STC_FS_COMMENTDOCKEYWORDERROR) wxSTC_FS_COMMENTDOCKEYWORDERROR;
+%rename(STC_FS_KEYWORD) wxSTC_FS_KEYWORD;
+%rename(STC_FS_KEYWORD2) wxSTC_FS_KEYWORD2;
+%rename(STC_FS_KEYWORD3) wxSTC_FS_KEYWORD3;
+%rename(STC_FS_KEYWORD4) wxSTC_FS_KEYWORD4;
+%rename(STC_FS_NUMBER) wxSTC_FS_NUMBER;
+%rename(STC_FS_STRING) wxSTC_FS_STRING;
+%rename(STC_FS_PREPROCESSOR) wxSTC_FS_PREPROCESSOR;
+%rename(STC_FS_OPERATOR) wxSTC_FS_OPERATOR;
+%rename(STC_FS_IDENTIFIER) wxSTC_FS_IDENTIFIER;
+%rename(STC_FS_DATE) wxSTC_FS_DATE;
+%rename(STC_FS_STRINGEOL) wxSTC_FS_STRINGEOL;
+%rename(STC_FS_CONSTANT) wxSTC_FS_CONSTANT;
+%rename(STC_FS_ASM) wxSTC_FS_ASM;
+%rename(STC_FS_LABEL) wxSTC_FS_LABEL;
+%rename(STC_FS_ERROR) wxSTC_FS_ERROR;
+%rename(STC_FS_HEXNUMBER) wxSTC_FS_HEXNUMBER;
+%rename(STC_FS_BINNUMBER) wxSTC_FS_BINNUMBER;
+%rename(STC_CSOUND_DEFAULT) wxSTC_CSOUND_DEFAULT;
+%rename(STC_CSOUND_COMMENT) wxSTC_CSOUND_COMMENT;
+%rename(STC_CSOUND_NUMBER) wxSTC_CSOUND_NUMBER;
+%rename(STC_CSOUND_OPERATOR) wxSTC_CSOUND_OPERATOR;
+%rename(STC_CSOUND_INSTR) wxSTC_CSOUND_INSTR;
+%rename(STC_CSOUND_IDENTIFIER) wxSTC_CSOUND_IDENTIFIER;
+%rename(STC_CSOUND_OPCODE) wxSTC_CSOUND_OPCODE;
+%rename(STC_CSOUND_HEADERSTMT) wxSTC_CSOUND_HEADERSTMT;
+%rename(STC_CSOUND_USERKEYWORD) wxSTC_CSOUND_USERKEYWORD;
+%rename(STC_CSOUND_COMMENTBLOCK) wxSTC_CSOUND_COMMENTBLOCK;
+%rename(STC_CSOUND_PARAM) wxSTC_CSOUND_PARAM;
+%rename(STC_CSOUND_ARATE_VAR) wxSTC_CSOUND_ARATE_VAR;
+%rename(STC_CSOUND_KRATE_VAR) wxSTC_CSOUND_KRATE_VAR;
+%rename(STC_CSOUND_IRATE_VAR) wxSTC_CSOUND_IRATE_VAR;
+%rename(STC_CSOUND_GLOBAL_VAR) wxSTC_CSOUND_GLOBAL_VAR;
+%rename(STC_CSOUND_STRINGEOL) wxSTC_CSOUND_STRINGEOL;
%rename(STC_CMD_REDO) wxSTC_CMD_REDO;
%rename(STC_CMD_SELECTALL) wxSTC_CMD_SELECTALL;
%rename(STC_CMD_UNDO) wxSTC_CMD_UNDO;
EVT_STC_HOTSPOT_CLICK = wx.PyEventBinder( wxEVT_STC_HOTSPOT_CLICK, 1 )
EVT_STC_HOTSPOT_DCLICK = wx.PyEventBinder( wxEVT_STC_HOTSPOT_DCLICK, 1 )
EVT_STC_CALLTIP_CLICK = wx.PyEventBinder( wxEVT_STC_CALLTIP_CLICK, 1 )
+EVT_STC_AUTOCOMP_SELECTION = wx.PyEventBinder( wxEVT_STC_AUTOCOMP_SELECTION, 1 )
}
//---------------------------------------------------------------------------